• Stars
    star
    163
  • Rank 231,141 (Top 5 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created about 2 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

โœ… Vite plugin for validating your environment variables

This Vite plugin allows you to validate your environment variables at build or dev time. This allows your build/dev-server to fail-fast if your setup is misconfigured.

No more CI to restart because you are missing an environment variable, or to realize after 10 minutes of debugging that you forgot a variable ๐Ÿฅฒ

Features

  • Validate your environment variables at build time only. No runtime overhead
  • Totally type-safe
  • Support multiple validation librairies ( Zod, and @poppinss/validator-lite )
  • Parsing, validation and transformation of your variables
  • Custom rules and error messages

Installation

pnpm add -D @julr/vite-plugin-validate-env

Usage

vite-plugin-validate-env plugin allows you to validate your env, either with a very simplified builtin validation lib, or with Zod in the most complex cases when you want a very strict validation.

Plugin options

The easiest way to define the options is to directly define the scheme as follows:

// vite.config.ts
import { defineConfig } from "vite";
import { Schema, ValidateEnv } from "@julr/vite-plugin-validate-env";

export default defineConfig({
  plugins: [
    ValidateEnv({
      VITE_MY_VAR: Schema.string()
    }),
  ],
})

In case you want to change some plugin options, in particular change the validator (for Zod), you have to set your options as follows:

import { defineConfig } from "vite";
import { z } from 'zod'
import { ValidateEnv } from "@julr/vite-plugin-validate-env";

export default defineConfig({
  plugins: [
    ValidateEnv({
      validator: 'zod',
      schema: {
        VITE_MY_VAR: z.string()
      }
    }),
  ],
})

If you want to see what values are being evaluated for the build, for example when running in CI. You can pass the debug option as follows:

import { defineConfig } from "vite";
import { Schema, ValidateEnv } from "@julr/vite-plugin-validate-env";

export default defineConfig({
  plugins: [
    ValidateEnv({
      debug: true,
      schema: {
        VITE_MY_VAR: Schema.string()
      }
    }),
  ],
})

Built-in validator

import { Schema, ValidateEnv } from "@julr/vite-plugin-validate-env"
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [
    ValidateEnv({
      // Data types
      VITE_STRING_VARIABLE: Schema.string(),
      VITE_BOOLEAN_VARIABLE: Schema.boolean(),
      VITE_NUMBER_VARIABLE: Schema.number(),
      VITE_ENUM_VARIABLE: Schema.enum(['foo', 'bar'] as const),
      
      // Optional variable
      VITE_OPTIONAL_VARIABLE: Schema.boolean.optional(),

      // Specify string format
      VITE_AUTH_API_URL: Schema.string({ format: 'url', protocol: true }),

      // Specify error message
      VITE_APP_PORT: Schema.number({ message: 'You must set a port !' }),

      // Custom validator
      VITE_CUSTOM_VARIABLE: (key, value) => {
        if (!value) {
          throw new Error(`Missing ${key} env variable`)
        }

        if (value.endsWith('foo')) {
          throw new Error('Value cannot end with "foo"')
        }

        return value
      },
    }),
  ],
})

Zod Validator

To use the Zod validator, you must first install it if you have not already done so

pnpm install zod

Then, you can use it as follows:

// env.ts
import { defineConfig } from '@julr/vite-plugin-validate-env'
import { z } from 'zod'

export default defineConfig({
  validator: 'zod',
  schema: {
    VITE_MY_STRING: z.string().min(5, 'This is too short !'),
    VITE_ENUM: z.enum(['a', 'b', 'c']),
    VITE_BOOLEAN_VARIABLE: z.boolean(),
  }
})

Beware, there are some limitations if you use Zod. For example, you can't use a boolean or number type directly. Because everything that comes from your .env file is a string by default.

So to validate other types than string you must use preprocess, and transform, like this:

// env.ts
import { defineConfig } from '@julr/vite-plugin-validate-env'
import { z } from 'zod'

export default defineConfig({
  validator: 'zod',
  schema: {
    // This will transform the string 'true' or '1' to a boolean
    VITE_BOOLEAN_VARIABLE: z
      .preprocess((value) => value === 'true' || value === '1', z.boolean()),

    // Will convert the string to a number
    VITE_NUMBER: z.preprocess((value) => Number(value), z.number()),

    // Will parse the string to an object
    VITE_OBJECT: z.preprocess(
      (value) => JSON.parse(value as string),
      z.object({
        a: z.string(),
        b: z.number(),
      }),
    ),
  }
})

In this case, true and 1 will be transformed to true and your variable will be valid and considered as a boolean.

Dedicated config file

You can also add a env.ts file at the root of your project to define your environment variables.

// vite.config.ts
import { defineConfig } from 'vite'
import { ValidateEnv } from "@julr/vite-plugin-validate-env";

export default defineConfig({
  plugins: [ValidateEnv()],
})
// env.ts
import { defineConfig, Schema } from '@julr/vite-plugin-validate-env'

export default defineConfig({
 VITE_MY_VAR: Schema.enum(['foo', 'bar'] as const),
})

Custom config file path

By default, the plugin is looking for a file named env.ts at the root of your project. If you want to use a different file, you can specify the path to your file in the plugin options.

// vite.config.ts
import { defineConfig } from 'vite'
import { ValidateEnv } from "@julr/vite-plugin-validate-env";

export default defineConfig({
  plugins: [ValidateEnv({ configFile: 'config/env' })],
})

This will look for a file named env.ts in the config folder at the root of your project. Make sure to not include the file extension in the path as the plugin will automatically search for .js, .ts and other valid file extensions.

Transforming variables

In addition to the validation of your variables, there is also a parsing that is done. This means that you can modify the value of an environment variable before it is injected.

Let's imagine the following case: you want to expose a variable VITE_AUTH_API_URL in order to use it to call an API. However, you absolutely need a trailing slash at the end of this environment variable. Here's how it can be done :

// Built-in validation
import { defineConfig, Schema } from '@julr/vite-plugin-validate-env'

export default defineConfig({
  VITE_AUTH_API_URL: (key, value) => {
    if (!value) {
      throw new Error(`Missing ${key} env variable`)
    }

    if (!value.endsWith('/')) {
      return `${value}/`
    }

    return value
  },
})
// Zod validation
import { defineConfig } from '@julr/vite-plugin-validate-env'
import { z } from 'zod'

export default defineConfig({
  validator: 'zod',
  schema: {
    VITE_AUTH_API_URL: z
      .string()
      .transform((value) => value.endsWith('/') ? value : `${value}/`),
  },
})

Now, in your client front-end code, when you call import.meta.env.VITE_AUTH_API_URL, you can be sure that it will always end with a slash.

Typing import.meta.env

In order to have a type-safe import.meta.env, the ideal is to use the dedicated configuration file env.ts. Once this is done, you would only need to add an env.d.ts in src/ folder to augment ImportMetaEnv (as suggested here ) with the following content:

/// <reference types="vite/client" />

type ImportMetaEnvAugmented = import('@julr/vite-plugin-validate-env').ImportMetaEnvAugmented<
  typeof import('../env').default
>

interface ImportMetaEnv extends ImportMetaEnvAugmented {
  // Now import.meta.env is totally type-safe and based on your `env.ts` schema definition
  // You can also add custom variables that are not defined in your schema
}

License

MIT License ยฉ 2022 Julien Ripouteau

More Repositories

1

bentocache

๐Ÿฑ Bentocache is a robust multi-tier caching solution for Node.js applications
TypeScript
381
star
2

cli-candlestick-chart

๐Ÿ“ˆ Display candlestick charts right into your terminal.
Rust
253
star
3

verrou

๐Ÿ”’ Verrou is a library for managing Locks in Node.js. Support multiple drivers
TypeScript
174
star
4

hot-hook

๐Ÿช Simple HMR for NodeJS + ESM
TypeScript
158
star
5

fast-ssh

โŒจ๏ธ FastSSH is a TUI that allows you to quickly connect to your services by navigating through your SSH config.
Rust
150
star
6

pino-loki

๐Ÿ”‰ This package provides a transport for pino that forwards messages to Loki.
TypeScript
111
star
7

adonis-sail

โ›ตGenerate a ready-to-use local docker environment for your Adonis application
TypeScript
97
star
8

adonis-vscode-extension

๐Ÿ’ป VSCode Extension for AdonisJS
TypeScript
64
star
9

unocss-preset-forms

๐Ÿ“‹ Port of @tailwindcss/forms for UnoCSS.
TypeScript
56
star
10

adonisjs-prometheus

๐Ÿ“Š Prometheus Provider for AdonisJS with some builtins metrics for monitoring your application.
TypeScript
42
star
11

unocss-preset-heropatterns

๐Ÿ UnoCSS preset that integrates Hero Patterns.
TypeScript
27
star
12

unocss-preset-flowbite

๐Ÿ’… An adaptation of the Flowbite Tailwind plugin for UnoCSS
TypeScript
27
star
13

pretty-list-routes

๐Ÿ›ฃ๏ธ A beautiful `list:routes` for AdonisJS
TypeScript
25
star
14

adoscope

๐Ÿ”ญ An elegant development assistant for your AdonisJS Application
TypeScript
22
star
15

factorify

๐Ÿญ Framework-agnostic model factory system for clean testing
TypeScript
19
star
16

japa-vscode

๐Ÿงช A Japa extension for VSCode
TypeScript
17
star
17

adonis-grpc-consumer

๐Ÿ•ธ๏ธ Adonis gRPC client provider for easily communicate with gRPC services.
TypeScript
13
star
18

cron-expression-generator

๐Ÿ”ง Generate crontab expression using friendly and declarative API
TypeScript
10
star
19

socket.io-prometheus

๐Ÿ“ก Exposes metrics endpoint for Prometheus to collect data about Socket.io.
TypeScript
5
star
20

lit-valtio-state

๐Ÿช A simple state management library for Lit components
TypeScript
3
star
21

japa-database-plugin

๐Ÿ’ฝ Database assertions and testing helpers for Japa
TypeScript
3
star
22

adonis-packages

TypeScript
3
star
23

adonis-extension-pack

๐Ÿ“ฆ Collection of extensions for Adonis.js development
2
star
24

tooling-configs

๐Ÿ‘Œ My custom tool configurations ( ESLint, TS, Prettier ... )
TypeScript
2
star
25

module-methods-extractor

๐Ÿช› Utility module to extract public methods for a given default export.
TypeScript
1
star
26

crypto-rss-news-app

Nativescript application that displays crypto market news from various RSS feeds.
Vue
1
star
27

music-ddl

Simple music downloader built on top of octlif, that downloads music from multiples DDL sites as sources.
TypeScript
1
star
28

Wolf3D

A Wolfenstein 3D like game, using raycasting.
C
1
star
29

Julien-R44

1
star
30

gitlab-slack-release-notifier

๐Ÿค– A small service that sends a notification on Slack when a release has been published on GitLab.
TypeScript
1
star
31

binance-scanner-wma-sma-cross

Program that analyzes the charts of all symbols on Binance Futures, and when a WMA/SMA cross is found on a certain UT, a notification is sent on a discord channel.
TypeScript
1
star
32

tuyau-stackblitz-demo

TypeScript
1
star