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

fluent-env

v0.1.3

Published

[1]: https://github.com/fastify/env-schema [2]: https://github.com/fastify/fluent-json-schema

Downloads

23

Readme

fluent-env

A convenient wrapper around env-schema and fluent-json-schema to automatically load your schemas from external files, while offering a number of additional configuration hooks.

view on npm JavaScript Style Guide

Features

  • Allows you to set your environment schema in a .env.schema file:
    • Parsed as JavaScript and ran in an isolated V8 context.
    • All methods from fluent-json-schema exposed as globals.
  • Alternatively, allows you set your environment schema via env.config.js:
    • Unlike .env.schema, an actual JavaScript module.
    • Spports importing subset of variables from another file.
    • Allows use your environment schema as a package

Install

Use your favorite package manager:

pnpm add fluent-env
bun install fluent-env
npm i fluent-env           
yarn add fluent-env

Tutorial

  1. Create a file named .env.schema with your environment schema. All methods from fluent-json-schema are sglobally available in the scope of this file, the exception is enum() which can't be a global due to its status as a reserved keyword, so it's aliased to values().

    NODE_ENV=values(['production', 'development', 'test'])
    APPLICATION_ENV=values(['production', 'development', 'staging'])
    POSTGRES_HOST=string().required()
    POSTGRES_PORT=number().default(5432)
    POSTGRES_DB=string().required()
    POSTGRES_USER=string().required()
    POSTGRES_PASS=string().required()
    REDIS_HOST=string().default('localhost')
    REDIS_PORT=number().default(6379)
    REDIS_PASS=string()

    If you want to use a different validation library, the global scope of .env.schema can be configured by providing your own createContext() hook. In that case you'll also need to override the default validateEnvironment() definition.

  2. Create a file named .env with your environment variable values:

    NODE_ENV=production
    APPLICATION_ENV=staging
    POSTGRES_HOST=localhost
    POSTGRES_PORT=5432
    POSTGRES_DB=database
    POSTGRES_USER=user
    POSTGRES_PASS=password
    REDIS_HOST=localhost
    REDIS_PORT=6379
    REDIS_PASS=redispassword
  3. In your Node.js application, import fluent-env/auto from a file at the same level as your .env and .env.schema files. The order of loading for .env and its variants follows the Vite standard.

    import 'fluent-env/auto'
       
    console.log(process.env.NODE_ENV)
    console.log(process.env.APPLICATION_ENV)
    console.log(process.env.POSTGRES_HOST)
    console.log(process.env.POSTGRES_PORT)
    console.log(process.env.POSTGRES_DB)
    console.log(process.env.POSTGRES_USER)
    console.log(process.env.POSTGRES_PASS)
    console.log(process.env.REDIS_HOST)
    console.log(process.env.REDIS_PORT)
    console.log(process.env.REDIS_PASS)

Setup

fluent-env can be automatically initialized if you import fluent-env/auto, as demonstratedd in the tutorial above. In that case, the root will be resolved to the path that contains a package.json file, the root of the current package. If you import fluent-env/auto from a subdirectory, it will traverse the file tree upwards looking for the directory that contains env.config.js or at the very least package.json to determine what the root path is. When looking for .env.schema, .env and other variants, fluent-env will traverse the file tree upwards until it can find these files, starting from the root path.

fluent-env will also detect when it being imported by another CLI, such as vitest, and will consider the parent directory of the first node_modules directory found in the path as the root.

If you want to use a different root for those files, you can import the setup() function from fluent-env (rather than fluent-env/auto) and call it with a custom root option:

import { fileURLToPath } from 'node:url'
import { join, dirname } from 'node:path'
import { setup as setupEnvironment } from 'fluent-env'

setupEnvironment({ 
  root: join(dirname(fileURLToPath(import.meta.url)), 'custom/.env/location')
})

Note that all .env file variants, .env.schema and env.config.js are all loaded from this same root path.

Configuration

fluent-env can be completely customized via the env.config.js configuration file. It will either detect its presence when you import fluent-env/auto, or load it from the path defined in the root property passed to the setup() method's parameters object as demonstrated in the previous example.

If you are using a .env.schema file and don't need any customizations, you don't need env.config.js. However, if you need to have multiple packages consume the same environment schema and a shared .env file, they can be helpful. They also allow to customize how the schema is created and validated, in case you want to use anything other than fluent-json-schema.

Every named export from env.config.js is considered to be an environment variable property definition:

import { S } from 'fluent-json-schema'

export const NODE_ENV = S.values(['production', 'development', 'test'])
export const APPLICATION_ENV = S.values(['production', 'development', 'staging'])
export const POSTGRES_HOST = S.string().required()
export const POSTGRES_PORT = S.number().default(5432)
export const POSTGRES_DB = S.string().required()
export const POSTGRES_USER = S.string().required()
export const POSTGRES_PASS = S.string().required()
export const REDIS_HOST = S.string().default('localhost')
export const REDIS_PORT = S.number().default(6379)
export const REDIS_PASS = S.string()

Unlike .env.schema, when exporting your schema from env.config.js you are working with a full blown JavaScript module, so a small amount of boilerplate code like importing fluent-json-schema manually and exporting consts is needed in this case.

Which you can then import and export from another env.config.js file:

export {
  POSTGRES_HOST,
  POSTGRES_PORT,
  POSTGRES_DB,
  POSTGRES_USER,
  POSTGRES_PASS,
} from 'your-main-app/env.config.js'

Schema

You can use a different validation library in your .env.schema file by customizing how the schema is created and used for validation in env.config.js.

By providing your own createSchema() and validateEnvironment() hooks, you can use any other validation library, and by providing your own createContext() hook, you can also inject different globals into .env.schema (which by default receives a set of global aliases to fluent-json-schema's typing functions).

Below is an example of a configuration file to use zod instead:

Execution

fluent-env has the following setup sequence:

  1. loadEnvironment() runs loading your .env files.
  2. createFlags() also runs at this point, populating env.flags.
  3. createContextGetter() and createContext() run creating the context for .env.schema.
  4. loadSchema() and createSchema()` run creating the full validation schema
  5. validateEnvironment() validates the environment against the schema
  6. createEnvironment() populates process.env by default.

All of those functions can be overriden.

See the full reference on configuration options and hooks.

Licence

Licensed under MIT.