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

@xho/env-validator

v1.0.3

Published

Type-safe environment variable validator for Node.js

Downloads

293

Readme

@xho/env-validator

A zero-dependency, type-safe environment variable validator for Node.js applications with full TypeScript support.

Features

  • 🎯 Full TypeScript support with type inference
  • 🔒 Runtime validation of environment variables
  • ✨ Built-in validators for common types (number, boolean, url, email, json)
  • 🎨 Custom validation functions
  • 📝 Environment file handling (.env files)
  • 🔄 Environment synchronization across different configurations
  • 💪 Zero dependencies
  • 🔍 Detailed error messages

Installation

npm install @xho/env-validator

Quick Start

Basic Usage

import { EnvValidator } from "@xho/env-validator";

const schema = {
  NODE_ENV: {
    type: "string" as const,
    required: true,
    validator: (value: string) =>
      ["development", "production", "test"].includes(value),
    description: "Application environment (development/staging/production)",
  },
  PORT: {
    type: "number" as const,
    default: 3000,
    validator: (value: number) => value >= 1000 && value <= 65535,
  },
  DATABASE_URL: {
    type: "url" as const,
    required: true,
  },
  DEBUG: {
    type: "boolean" as const,
    default: false,
  },
} as const;

try {
  const env = EnvValidator.validate(schema);

  // TypeScript knows the correct types:
  env.PORT.toFixed(2); // ✓ PORT is number
  env.DEBUG && console.log(); // ✓ DEBUG is boolean

  console.log("Environment validated successfully:", env);
} catch (error) {
  if (error instanceof Error) {
    console.error("Validation failed:", error.message);
  }
  process.exit(1);
}

Schema Builder Pattern (Recommended)

import { env, defineSchema, EnvValidator } from "@xho/env-validator";

// Define reusable validators
const portValidator = (value: number) => value >= 1000 && value <= 65535;
const urlValidator = (value: string) => {
  try {
    const url = new URL(value);
    return url.protocol === "https:"; // Ensure HTTPS
  } catch {
    return false;
  }
};

// Define configuration sections
const databaseConfig = {
  DATABASE_URL: env.url({
    required: true,
    validator: urlValidator,
  }),
  DB_POOL_SIZE: env.number({
    default: 20,
    validator: (value) => value >= 5 && value <= 100,
  }),
};

const appConfig = {
  NODE_ENV: env.string({
    required: true,
    validator: (value) => ["development", "production"].includes(value),
    description: "Application environment (development/staging/production)",
  }),
  PORT: env.number({
    default: 3000,
    validator: portValidator,
  }),
};

// Combine configurations
const schema = defineSchema({
  ...appConfig,
  ...databaseConfig,
});

const env = EnvValidator.validate(schema);
// env.PORT is typed as number
// env.DATABASE_URL is typed as string
// env.DB_POOL_SIZE is typed as number

Environment File Handling

import { env, defineSchema, EnvFileHandler } from "@xho/env-validator";

const schema = defineSchema({
  NODE_ENV: env.string({
    default: "development",
    description: "Current environment (development/staging/production)",
  }),
  PORT: env.number({
    default: 3000,
    description: "Port number for the server",
  }),
  DATABASE_URL: env.url({
    required: true,
    description: "PostgreSQL connection string",
  }),
});

// Generate a documented .env.example file
await EnvFileHandler.generateExample(schema);

// Validate existing .env file
const validation = await EnvFileHandler.validate(schema);
if (validation.missing.length > 0) {
  console.error("Missing required variables:", validation.missing);
}
if (validation.invalid.length > 0) {
  console.error("Invalid variables:", validation.invalid);
}

// Sync environments
await EnvFileHandler.sync(schema, ".env", [
  ".env.development",
  ".env.staging",
  ".env.production",
]);

Generated .env.example will look like:

# Generated Environment Variables
# Generated on 2024-11-04T18:30:00.000Z

# Current environment (development/staging/production)
# Type: string
# Default: development
NODE_ENV=development

# Port number for the server
# Type: number
# Default: 3000
PORT=3000

# PostgreSQL connection string
# Type: url
# Required: true
DATABASE_URL=https://example.com

API Reference

Supported Types

  • string: Basic string validation
  • number: Numeric values with NaN checking
  • boolean: Accepts 'true', 'false', '1', '0'
  • url: Valid URL format checking
  • email: Basic email format validation
  • json: Valid JSON string that gets parsed

Configuration Options

interface EnvVarConfig<T = any> {
  // The type of environment variable
  type: "string" | "number" | "boolean" | "url" | "email" | "json";

  // Whether the variable is required (default: false)
  required?: boolean;

  // Default value if not provided
  default?: T;

  // Optional custom validation function
  validator?: (value: T) => boolean;

  // Description for documentation purposes
  description?: string;
}

Validation Errors

When validation fails, the validator throws a ValidationError with detailed error messages:

try {
  const env = EnvValidator.validate(schema);
} catch (error) {
  if (error instanceof ValidationError) {
    // Array of all validation errors
    console.error(error.errors);
  }
}

Examples

Basic Usage

const schema = {
  PORT: { type: "number", required: true },
  API_URL: { type: "url", required: true },
  DEBUG: { type: "boolean", default: false },
} as const;

const env = EnvValidator.validate(schema);

Custom Validation

const schema = {
  PORT: {
    type: "number",
    required: true,
    validator: (value) => value >= 1000 && value <= 65535,
  },
  API_KEY: {
    type: "string",
    required: true,
    validator: (value) => value.startsWith("pk_"),
  },
} as const;

With Default Values

const schema = {
  NODE_ENV: {
    type: "string",
    default: "development",
    validator: (value) => ["development", "production", "test"].includes(value),
  },
  LOG_LEVEL: {
    type: "string",
    default: "info",
    validator: (value) => ["error", "warn", "info", "debug"].includes(value),
  },
} as const;

JSON Configuration

const schema = {
  SERVER_CONFIG: {
    type: "json",
    required: true,
    validator: (value) => {
      // Validate the parsed JSON structure
      return value.hasOwnProperty("host") && value.hasOwnProperty("port");
    },
  },
} as const;

// Can be used with: process.env.SERVER_CONFIG = '{"host":"localhost","port":3000}'

Error Handling

The validator provides detailed error messages when validation fails:

try {
  const env = EnvValidator.validate({
    PORT: { type: "number", required: true },
    API_URL: { type: "url", required: true },
  });
} catch (error) {
  if (error instanceof ValidationError) {
    // Prints each validation error:
    // PORT: Required value is missing
    // API_URL: Invalid URL
    error.errors.forEach((err) => console.error(err));
  }
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

ISC