### Install Standard Env and Validation Library Source: https://github.com/alandotcom/standardenv/blob/main/README.md Install standardenv using bun. Also, install your preferred validation library like arktype, zod, or valibot. ```bash bun add standardenv # Also install your preferred validation library bun add arktype # or zod, valibot, etc. ``` -------------------------------- ### Install and Build Dependencies Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/README.md Commands to install dependencies, compile TypeScript, and check types. ```bash bun install # Install dependencies bun run build # Compile TypeScript bun run typecheck # Check types ``` -------------------------------- ### Library Compatibility Examples Source: https://github.com/alandotcom/standardenv/blob/main/README.md Shows how `envParse` integrates with different validation libraries like Arktype, Zod, and Valibot. ```APIDOC ## Library Compatibility Works with any [Standard Schema](https://standardschema.dev/) compatible library. ### Arktype ```typescript import { type } from "arktype"; const config = envParse(process.env, { port: { format: type("string.numeric.parse"), env: "PORT", }, }); ``` ### Zod ```typescript import { z } from "zod"; const config = envParse(process.env, { port: { format: z.string().transform(Number), env: "PORT", }, }); ``` ### Valibot ```typescript import * as v from "valibot"; const config = envParse(process.env, { port: { format: v.pipe(v.string(), v.transform(Number)), env: "PORT", }, }); ``` ``` -------------------------------- ### StandardSchemaV1 Implementations Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/api-reference.md Demonstrates how to satisfy the StandardSchemaV1 interface using ArkType, Zod, and Valibot. Ensure the respective libraries are installed. ```typescript import type { StandardSchemaV1 } from "standardenv"; // Any of these satisfies StandardSchemaV1: import { type } from "arktype"; import { z } from "zod"; import * as v from "valibot"; const arktypeValidator: StandardSchemaV1 = type("string.numeric.parse"); const zodValidator: StandardSchemaV1 = z.string().transform(Number); const valibotValidator: StandardSchemaV1 = v.pipe(v.string(), v.transform(Number)); ``` -------------------------------- ### Configuration Definition Example Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Defines a configuration structure using Zod schemas, specifying input formats, default values, and environment variable names. ```typescript const configDef = { port: { format: z.string().transform(Number), // Input: string, Output: number default: 3000, env: "PORT", }, url: { format: z.string(), // Input: string, Output: string env: "DATABASE_URL", }, }; ``` -------------------------------- ### InferConfig Behavior Example Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/types.md Illustrates how InferConfig transforms a sample ConfigDefinition into a resulting TypeScript type, showing inferred optionality and nesting. ```typescript { required_with_default: { format: z.string(), default: "value", env: "ENV_VAR", }, required_no_default: { format: z.string(), env: "ANOTHER_VAR", }, optional_with_default: { format: z.string(), default: "value", env: "THIRD_VAR", optional: true, }, optional_no_default: { format: z.string(), env: "FOURTH_VAR", optional: true, }, nested: { deep: { url: { format: z.string(), env: "DEEP_URL", }, }, }, } ``` ```typescript { required_with_default: string; // Required required_no_default: string; // Required optional_with_default: string; // Required (has default) optional_no_default?: string | undefined; // Optional nested: { deep: { url: string; // Recursively inferred }; }; } ``` -------------------------------- ### Quick Start: Parse Environment Variables with Standard Env Source: https://github.com/alandotcom/standardenv/blob/main/README.md Demonstrates parsing environment variables using standardenv and arktype for validation. Defines nested configuration for server port, node environment, and database URL with default values and type inference. ```typescript import { envParse } from "standardenv"; import { type } from "arktype"; const config = envParse(process.env, { server: { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, nodeEnv: { format: type('"development" | "production" | "test"'), default: "development", env: "NODE_ENV", }, }, db: { url: { format: type("string"), env: "DATABASE_URL", }, }, }); // config.server.port is number (3000) // config.server.nodeEnv is string ('development' | 'production' | 'test') // config.db.url is string // All fully typed with zero additional type definitions needed! ✨ ``` -------------------------------- ### Nested Configuration with ArkType Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Organizes configuration into nested objects using ArkType for validation and transformation. Ensure ArkType is installed. ```typescript import { envParse } from "standardenv"; import { type } from "arktype"; const config = envParse(process.env, { server: { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, host: { format: type("string"), default: "0.0.0.0", env: "HOST", }, }, database: { url: { format: type("string"), env: "DATABASE_URL", }, maxConnections: { format: type("string.numeric.parse"), default: 10, env: "DB_MAX_CONNECTIONS", }, }, }); // Access nested config console.log(config.server.port); console.log(config.database.url); console.log(config.database.maxConnections); ``` -------------------------------- ### Basic Flat Configuration with Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Defines a flat configuration object with basic types and defaults using Zod for validation and transformation. Ensure Zod is installed. ```typescript import { envParse } from "standardenv"; import { z } from "zod"; const config = envParse(process.env, { port: { format: z.string().transform(Number), default: 3000, env: "PORT", }, nodeEnv: { format: z.enum(["development", "production", "test"]), default: "development", env: "NODE_ENV", }, apiKey: { format: z.string(), env: "API_KEY", }, }); // Usage console.log(config.port); console.log(config.nodeEnv); console.log(config.apiKey); ``` -------------------------------- ### Example Configuration Structure Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/README.md Defines a nested configuration object where leaf nodes are ConfigProperty instances. This structure is used to declare how environment variables map to typed configuration values. ```typescript { server: { port: { format: z.string().transform(Number), env: "PORT", default: 3000, }, }, database: { url: { format: z.string(), env: "DATABASE_URL", }, }, } ``` -------------------------------- ### Composable Validators Example Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Demonstrates validator composition patterns from different libraries like ArkType, Zod, and Valibot. StandardEnv delegates composition to these libraries. ```typescript // arktype composition type("string.numeric.parse") ``` ```typescript // zod composition z.string().transform(Number) ``` ```typescript // valibot composition v.pipe(v.string(), v.transform(Number)) ``` -------------------------------- ### Arktype Integration for Configuration Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/validator-integration.md Demonstrates how to use Arktype validators with standardenv to parse and validate environment variables. This example shows defining a 'port' configuration with a numeric string format and a default value. ```typescript import { type } from "arktype"; import { envParse } from "standardenv"; const config = envParse(process.env, { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, }); ``` -------------------------------- ### Handling Optional Properties with Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Illustrates how to define and handle optional environment variables, with and without defaults, using Zod. This ensures type safety for properties that may not be present. Ensure Zod is installed. ```typescript import { envParse } from "standardenv"; import { z } from "zod"; const config = envParse(process.env, { // Required (no default, not optional) databaseUrl: { format: z.string(), env: "DATABASE_URL", }, // Optional, no default (undefined if not set) sentryDsn: { format: z.string(), env: "SENTRY_DSN", optional: true, }, // Has default (always defined) port: { format: z.string().transform(Number), default: 3000, env: "PORT", }, // Optional with default (always defined) logLevel: { format: z.enum(["debug", "info", "warn", "error"]), default: "info", env: "LOG_LEVEL", optional: true, }, }); // Type checking const databaseUrl: string = config.databaseUrl; // Required const sentryDsn: string | undefined = config.sentryDsn; // Optional const port: number = config.port; // Required (has default) const logLevel: string = config.logLevel; // Required (has default) // Safe usage with optional properties if (config.sentryDsn) { initializeSentry(config.sentryDsn); } ``` -------------------------------- ### Using StandardEnv with Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Configure environment variables using Zod for validation. This example demonstrates parsing a numeric string, an enum, and a comma-separated string into an array. ```typescript import { envParse } from "standardenv"; import { z } from "zod"; const config = envParse(process.env, { port: { format: z.string().regex(/^\d+$/).transform(Number), default: 3000, env: "PORT", }, nodeEnv: { format: z.enum(["development", "production", "test"]), default: "development", env: "NODE_ENV", }, allowedOrigins: { format: z .string() .transform((s) => s.split(",").map((o) => o.trim())), default: ["http://localhost:3000"], env: "ALLOWED_ORIGINS", }, }); ``` -------------------------------- ### Basic Valibot Integration Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/validator-integration.md Parse environment variables using Valibot for schema definition. This example shows how to parse a port number, defaulting to 3000 if not provided. ```typescript import * as v from "valibot"; import { envParse } from "standardenv"; const config = envParse(process.env, { port: { format: v.pipe(v.string(), v.transform(Number)), default: 3000, env: "PORT", }, }); ``` -------------------------------- ### Using StandardEnv with Arktype Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Configure environment variables using Arktype for validation. This example shows parsing a numeric string, an enum, and a comma-separated string into an array. ```typescript import { envParse } from "standardenv"; import { type } from "arktype"; const config = envParse(process.env, { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, nodeEnv: { format: type('"development" | "production" | "test"'), default: "development", env: "NODE_ENV", }, allowedOrigins: { format: type("string").pipe((s) => s.split(",").map((o) => o.trim())), default: ["http://localhost:3000"], env: "ALLOWED_ORIGINS", }, }); ``` -------------------------------- ### Using StandardEnv with Valibot Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Configure environment variables using Valibot for validation. This example shows parsing a numeric string, an enum, and a comma-separated string into an array. ```typescript import { envParse } from "standardenv"; import * as v from "valibot"; const config = envParse(process.env, { port: { format: v.pipe(v.string(), v.transform(Number)), default: 3000, env: "PORT", }, nodeEnv: { format: v.enum(["development", "production", "test"]), default: "development", env: "NODE_ENV", }, allowedOrigins: { format: v.pipe( v.string(), v.transform((s) => s.split(",").map((o) => o.trim())) ), default: ["http://localhost:3000"], env: "ALLOWED_ORIGINS", }, }); ``` -------------------------------- ### Type Transformations with Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Demonstrates various type transformations using Zod, including string to number, boolean, array, JSON object, and URL objects. Ensure Zod is installed. ```typescript import { envParse } from "standardenv"; import { z } from "zod"; const config = envParse(process.env, { // String to number port: { format: z.string().regex(/^\d+$/).transform(Number), default: 3000, env: "PORT", }, // String to boolean debug: { format: z.string().transform((s) => s === "true" || s === "1"), default: false, env: "DEBUG", }, // String to array (comma-separated) allowedOrigins: { format: z.string().transform((s) => s.split(",").map((o) => o.trim())), default: ["http://localhost:3000"], env: "ALLOWED_ORIGINS", }, // String to JSON object featureFlags: { format: z.string().transform((s) => { try { return JSON.parse(s); } catch { return {}; } }), default: {}, env: "FEATURE_FLAGS", }, // Chained transformations databaseUrl: { format: z .string() .url() .transform((url) => new URL(url)), env: "DATABASE_URL", }, }); // Result types inferred correctly const port: number = config.port; const debug: boolean = config.debug; const origins: string[] = config.allowedOrigins; const flags: Record = config.featureFlags; const dbUrl: URL = config.databaseUrl; ``` -------------------------------- ### Implement Standard Schema Validator Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/validator-integration.md Create a custom validator by implementing the Standard Schema interface. This example validates for a non-empty string and converts it to uppercase. ```typescript import type { StandardSchemaV1 } from "standardenv"; const myValidator: StandardSchemaV1 = { "~standard": { vendor: "my-validator", validate(input) { if (typeof input === "string" && input.length > 0) { return { value: input.toUpperCase() }; } return { issues: [ { message: "Expected non-empty string", path: undefined, }, ], }; }, }, }; // Use in envParse const config = envParse(process.env, { myVar: { format: myValidator, env: "MY_VAR", }, }); ``` -------------------------------- ### Type Transformations with Standard Env and Arktype Source: https://github.com/alandotcom/standardenv/blob/main/README.md Shows common type transformations for environment variables using standardenv and arktype. Includes converting strings to numbers, booleans, arrays, and JSON objects, with examples for port, debug flags, allowed origins, and feature flags. ```typescript import { envParse } from "standardenv"; import { type } from "arktype"; const config = envParse(process.env, { server: { // String to number port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, // String to boolean debug: { format: type("string").pipe((s) => s === "true" || s === "1"), default: false, env: "DEBUG", }, // String to array allowedOrigins: { format: type("string").pipe((s) => s.split(",").map((origin) => origin.trim())), default: ["http://localhost:3000"], env: "ALLOWED_ORIGINS", }, // String to JSON object featureFlags: { format: type("string").pipe((s): Record => { try { return JSON.parse(s); } catch { return {}; } }), default: {}, env: "FEATURE_FLAGS", }, }, }); // Result types: // config.server.port: number // config.server.debug: boolean // config.server.allowedOrigins: string[] // config.server.featureFlags: Record ``` -------------------------------- ### Handle Validation Errors Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/api-reference.md This example demonstrates how to catch and handle `EnvValidationError` when environment variable parsing fails. It shows how to access the error message, detailed issues, and the vendor library used for validation. ```typescript import { EnvValidationError } from "standardenv"; try { const config = envParse(process.env, { port: { format: type("string.numeric.parse"), env: "PORT", }, }); } catch (error) { if (error instanceof EnvValidationError) { console.error(error.message); // Output: Environment validation failed (using arktype): // - PORT: Must be numeric string console.error(error.issues); // [{ message: "...", path: ["PORT"] }] console.error(error.vendor); // "arktype" } } ``` -------------------------------- ### Parse Environment Variables with Nested Configuration Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/api-reference.md Parse environment variables into a structured configuration object using envParse. This example demonstrates defining nested objects and leaf properties with validation and environment variable mapping. ```typescript import { envParse } from "standardenv"; import { type } from "arktype"; const config = envParse(process.env, { // Nested object (ConfigDefinition) database: { // Another nested object primary: { // Leaf node (ConfigProperty) url: { format: type("string"), env: "DATABASE_URL", }, }, cache: { redis: { url: { format: type("string"), env: "REDIS_URL", optional: true, }, }, }, }, server: { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, }, }); ``` -------------------------------- ### Release Beta Version Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Create a beta release for the project. This is useful for pre-release testing. ```bash bun run release:beta # 0.1.0 → 0.1.0-beta.0 ``` -------------------------------- ### StandardEnv Parsing Flow Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Illustrates the step-by-step process of parsing environment variables against a configuration definition, including validation and default value handling. ```text Input: env: Record config: ConfigDefinition ↓ processConfig(config, env, result) ├─ For each key in config: │ ├─ If value is ConfigProperty: │ │ ├─ Get env variable value │ │ ├─ If undefined: │ │ │ ├─ If default exists: use default │ │ │ ├─ Else if optional: leave undefined │ │ │ └─ Else: add validation issue │ │ └─ If defined: │ │ ├─ Call validator via format["~standard"].validate() │ │ ├─ If validation succeeds: store result │ │ └─ If validation fails: add issues to array │ └─ Else if value is ConfigDefinition: │ └─ Recursively call processConfig() └─ Track vendor names from all validators ↓ If issues exist: └─ Throw EnvValidationError(issues, vendorLabel) Else: └─ Return result as InferConfig ``` -------------------------------- ### Run Tests Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/README.md Command to execute the project's test suite. ```bash bun test # Run tests ``` -------------------------------- ### Extract Output Type from ConfigProperty Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/types.md Infers the output type of a schema defined within a ConfigProperty. Use this to get the validated data type. ```typescript type PropertyOutput

= P extends { format: infer S } ? S extends StandardSchemaV1 ? StandardSchemaV1.InferOutput : unknown : never; ``` -------------------------------- ### Build Project with Bun Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Initiate the project build process using Bun. This compiles TypeScript code into JavaScript and generates type definitions. ```bash bun run build ``` -------------------------------- ### Run All Tests with Bun Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Execute all project tests using the Bun runtime. This command is essential for verifying code integrity. ```bash bun test # Run all tests bun run test # Same (via package.json script) bunx vitest --watch # Watch mode for development ``` -------------------------------- ### Parse Environment Variables with ConfigProperty Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/api-reference.md Demonstrates how to use envParse with various ConfigProperty configurations, including required, default, and optional properties. ```typescript import { envParse } from "standardenv"; import { z } from "zod"; // A required property (no default, not optional) const config1 = envParse(process.env, { apiKey: { format: z.string().min(10), env: "API_KEY", }, }); // config1.apiKey: string (required) // A property with a default const config2 = envParse(process.env, { port: { format: z.string().transform(Number), default: 3000, env: "PORT", }, }); // config2.port: number (always has a value, defaults to 3000) // An optional property without default const config3 = envParse(process.env, { sentryDsn: { format: z.string(), env: "SENTRY_DSN", optional: true, }, }); // config3.sentryDsn: string | undefined // An optional property with default const config4 = envParse(process.env, { logLevel: { format: z.enum(["debug", "info", "warn", "error"]), default: "info", env: "LOG_LEVEL", optional: true, }, }); // config4.logLevel: "debug" | "info" | "warn" | "error" (always has a value) ``` -------------------------------- ### Declarative Configuration with Standard Env Source: https://github.com/alandotcom/standardenv/blob/main/README.md Defines a nested configuration structure for database and server settings using standardenv. Includes validation formats, environment variable names, and default values. ```typescript const config = envParse(process.env, { // Nested structure for organization db: { url: { format: type("string"), // Validation schema env: "DATABASE_URL", // Environment variable name // Required by default (no default provided) }, maxConnections: { format: type("string.numeric.parse"), default: 10, // Default value env: "DB_MAX_CONNECTIONS", }, }, server: { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, debug: { format: type("string").pipe((s) => s === "true"), default: false, env: "DEBUG", }, }, }); ``` -------------------------------- ### Project Structure Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Defines the directory structure for the standardenv project. ```tree src/ index.ts # Public API entry point structured.ts # Core parsing logic and type inference errors.ts # Error class definitions ``` -------------------------------- ### Validate URLs with Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/configuration.md Validate environment variables as URLs using Zod's built-in URL validator. Includes an example for a specific protocol prefix and an optional URL. ```typescript import { z } from "zod"; import { envParse } from "standardenv"; const config = envParse(process.env, { database: { url: { format: z.string().url().startsWith("postgresql://"), env: "DATABASE_URL", }, }, webhookUrl: { format: z.string().url(), env: "WEBHOOK_URL", optional: true, }, }); ``` -------------------------------- ### ConfigProperty Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/types.md Represents a single configuration property, defining its schema, default value, environment variable, and optionality. ```APIDOC ## ConfigProperty ### Description Represents a single configuration property, defining its schema, default value, environment variable, and optionality. ### Type Definition ```typescript export interface ConfigProperty { format: TSchema; default?: StandardSchemaV1.InferOutput; env: string; optional?: boolean; } ``` ### Field Definitions | Field | Type | Required | Description | |-------|------|----------|-------------| | `format` | `TSchema extends StandardSchemaV1` | Yes | A Standard Schema–compatible validator. Generic parameter `TSchema` is inferred from the validator passed; this allows type inference of the schema's output type. | | `default` | `StandardSchemaV1.InferOutput | undefined` | No | Default value matching the output type of `format`. If provided, the property always has a value (even if the environment variable is not set). Type must match the schema output, not the input string. | | `env` | `string` | Yes | Environment variable name to read. Case-sensitive. | | `optional` | `boolean | undefined` | No | Marks the property as optional. If `true` and no `default` provided, the result property becomes `T | undefined`. | ### Usage Context - Used as the leaf node type in `ConfigDefinition`. - Generic parameter `TSchema` preserves the specific validator type for precise type inference. - Compiler ensures `default` type matches schema output type at compile time. ### Related Types - **`ConfigDefinition`** — Parent type containing `ConfigProperty` leaves. - **`InferConfig`** — Processes `ConfigProperty` instances to generate final result types. ``` -------------------------------- ### Validation with Constraints using Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/examples.md Applies various constraints and validations to environment variables using Zod, including length, URL format, enums, refinements, and email format. Ensure Zod is installed. ```typescript import { envParse } from "standardenv"; import { z } from "zod"; const config = envParse(process.env, { // String length validation apiKey: { format: z.string().min(32, "API key must be at least 32 characters"), env: "API_KEY", }, // URL validation webhookUrl: { format: z.string().url("Invalid webhook URL"), env: "WEBHOOK_URL", optional: true, }, // Enum with validation logLevel: { format: z.enum(["debug", "info", "warn", "error"]), default: "info", env: "LOG_LEVEL", }, // Refinement (custom validation) port: { format: z .string() .transform(Number) .refine((n) => n > 0 && n < 65536, "Port must be 1-65535"), default: 3000, env: "PORT", }, // Multiple constraints email: { format: z.string().email().toLowerCase(), env: "ADMIN_EMAIL", }, }); ``` -------------------------------- ### ConfigProperty Interface Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/README.md Defines the structure for a single configuration property within the declarative configuration object. ```APIDOC ## ConfigProperty Interface ### Description Represents a single property within the configuration schema. ### Interface Definition ```typescript interface ConfigProperty { format: TSchema; env: string; default?: StandardSchemaV1.InferOutput; optional?: boolean; } ``` ### Properties - **format** (`TSchema`): Required. The validator schema for the property. - **env** (`string`): Required. The name of the environment variable to read. - **default** (`StandardSchemaV1.InferOutput`): Optional. The default value if the environment variable is not set. - **optional** (`boolean`): Optional. If true, the property can be undefined even if no default is provided. ``` -------------------------------- ### Ensure Default Values Match Expected Format Source: https://github.com/alandotcom/standardenv/blob/main/README.md When providing a default value, ensure it matches the expected format defined by the 'format' property. For example, a numeric parse format expects a number, not a string. ```typescript // Don't put defaults that don't match the expected format const config = envParse(process.env, { port: { format: type("string.numeric.parse"), default: "3000", env: "PORT" }, // ❌ Default should be number }); ``` -------------------------------- ### Arktype Type Inference for Environment Variables Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/validator-integration.md Demonstrates how Arktype infers TypeScript types from validator definitions, enabling type-safe access to parsed environment variables. This example shows inferred types for 'port' (number) and 'environment' ('dev' | 'prod'). ```typescript import { type } from "arktype"; import { envParse } from "standardenv"; const config = envParse(process.env, { // Input: string, Output: number port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, // Input: string, Output: "dev" | "prod" environment: { format: type('"dev" | "prod"'), default: "dev" as const, env: "ENV", }, }); // Types are inferred: // config.port: number // config.environment: "dev" | "prod" ``` -------------------------------- ### Use Multiple Validation Libraries Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/api-reference.md Demonstrates using `envParse` with multiple validation libraries (e.g., 'arktype' and 'zod') in the same configuration. The `error.vendor` property will indicate 'mixed' if validation fails across different libraries. ```typescript import { type } from "arktype"; import { z } from "zod"; const config = envParse(process.env, { port: { format: type("string.numeric.parse"), // arktype env: "PORT", }, apiKey: { format: z.string().min(10), // zod env: "API_KEY", }, }); // If validation fails, error.vendor = "mixed(arktype,zod)" ``` -------------------------------- ### ConfigProperty Type Definition Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/api-reference.md Defines a single configuration property, specifying its format, environment variable name, and optional behavior. ```APIDOC ## `ConfigProperty` ### Description A single configuration property descriptor. Each leaf node in a config definition must be a `ConfigProperty`. ### Fields | Field | Type | Required | Default | Description | |---|---|---|---|---| | `format` | `StandardSchemaV1` | Yes | — | A Standard Schema–compatible validator (e.g., `z.string()`, `type("number")`, `v.string()`). Used to validate and transform the string value from the environment variable. | | `env` | `string` | Yes | — | The name of the environment variable to read (e.g., `"PORT"`, `"DATABASE_URL"`). | | `default` | `StandardSchemaV1.InferOutput` | No | `undefined` | Default value to use if the environment variable is not set. Must match the output type of the `format` schema. Cannot be a string for transformed schemas; must be the final output type. | | `optional` | `boolean` | No | `false` | If `true`, the property can be `undefined`. When combined with no `default`, the property becomes optional in the result type (`T | undefined`). When combined with a `default`, the property is always defined. | ### Usage Example ```typescript import { envParse } from "standardenv"; import { z } from "zod"; // A required property (no default, not optional) const config1 = envParse(process.env, { apiKey: { format: z.string().min(10), env: "API_KEY", }, }); // config1.apiKey: string (required) // A property with a default const config2 = envParse(process.env, { port: { format: z.string().transform(Number), default: 3000, env: "PORT", }, }); // config2.port: number (always has a value, defaults to 3000) // An optional property without default const config3 = envParse(process.env, { sentryDsn: { format: z.string(), env: "SENTRY_DSN", optional: true, }, }); // config3.sentryDsn: string | undefined // An optional property with default const config4 = envParse(process.env, { logLevel: { format: z.enum(["debug", "info", "warn", "error"]), default: "info", env: "LOG_LEVEL", optional: true, }, }); // config4.logLevel: "debug" | "info" | "warn" | "error" (always has a value) ``` ``` -------------------------------- ### ConfigProperty interface Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/INDEX.md Defines a single configuration property, including its type, validation rules, and default value. ```APIDOC ## ConfigProperty ### Description Represents a single property within a configuration definition. It specifies the expected type, optional validation rules, and a default value if the property is not provided. ### Fields - **type** (TSchema) - Required - The expected data type of the configuration property. - **optional** (boolean) - Optional - If true, the property is not required. - **default** (TSchema) - Optional - The default value to use if the property is not provided. - **rules** (object) - Optional - Validation rules to apply to the property's value. ### Usage Used within `ConfigDefinition` to declare individual configuration settings. ### Examples ```typescript // Example of a ConfigProperty // const port: ConfigProperty = { // type: Number, // default: 8080, // rules: { min: 1, max: 65535 } // }; ``` ``` -------------------------------- ### Handling Optional Properties in Standard Env Source: https://github.com/alandotcom/standardenv/blob/main/README.md Illustrates how to define optional environment variables using the `optional: true` flag in standardenv configuration. TypeScript correctly infers the optional properties as potentially undefined. ```typescript const config = envParse(process.env, { db: { url: { format: type("string"), env: "DATABASE_URL", // Required - will throw if missing }, redis: { url: { format: type("string"), env: "REDIS_URL", optional: true, // Optional - will be undefined if not set }, }, }, features: { analytics: { format: type("string").pipe((s) => s === "true"), env: "ENABLE_ANALYTICS", optional: true, // Optional - will be undefined if not set }, }, }); // TypeScript knows: // config.db.url: string (required) // config.db.redis.url: string | undefined (optional) // config.features.analytics: boolean | undefined (optional) ``` -------------------------------- ### ConfigProperty Interface Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/README.md Defines the structure for a single configuration property. It includes the validator, environment variable name, and optional default or optional flags. ```typescript interface ConfigProperty { format: TSchema; // Required: validator env: string; // Required: env var name default?: StandardSchemaV1.InferOutput; // Optional: default value optional?: boolean; // Optional: allow undefined } ``` -------------------------------- ### Lint and Format Code Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/README.md Commands for linting, formatting checks, and auto-formatting the codebase. ```bash bun run lint # Lint and format check bun run fmt # Auto-format ``` -------------------------------- ### Configuration Properties Source: https://github.com/alandotcom/standardenv/blob/main/README.md Defines the structure and behavior of individual configuration properties within the `config` object passed to `envParse`. ```APIDOC ## Configuration Properties Each property in your config can have the following attributes: - **`format`** (required): A StandardSchema validator that defines the expected type and validation rules for the environment variable. - **`env`** (required): The name of the environment variable to read from. - **`default`** (optional): A default value to use if the environment variable is not set. This value must be a string and will be validated by the `format`. - **`optional`** (optional): If set to `true`, the property will be treated as optional, resulting in a type of `T | undefined` instead of `T`. ``` -------------------------------- ### Catch and Handle EnvValidationError Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/errors.md Demonstrates how to use a try-catch block to intercept and process EnvValidationError. It shows how to access the error's vendor, message, and detailed issues for logging or user feedback. ```typescript import { EnvValidationError, envParse } from "standardenv"; import { z } from "zod"; try { const config = envParse(process.env, { port: { format: z.string().transform(Number), env: "PORT", }, dbUrl: { format: z.string().url(), env: "DATABASE_URL", }, }); } catch (error) { if (error instanceof EnvValidationError) { console.error("Configuration validation failed"); console.error("Vendor:", error.vendor); console.error("Message:", error.message); console.error("Issues:", error.issues); // Example processing for (const issue of error.issues) { console.log(` ${issue.path?.join(".")} failed: ${issue.message}`); } process.exit(1); } throw error; } ``` -------------------------------- ### Configure Environment Variables with Standardenv and Zod Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/configuration.md Use this configuration to parse environment variables with type safety and default values. It demonstrates common patterns for infrastructure, services, server settings, and feature flags. ```typescript const config = envParse(process.env, { // Infrastructure database: { primaryUrl: { format: z.string().url(), env: "DATABASE_URL", }, maxConnections: { format: z.string().transform(Number), default: 20, env: "DB_MAX_CONNECTIONS", }, }, // Services auth: { clerk: { secretKey: { format: z.string(), env: "CLERK_SECRET_KEY", }, publishableKey: { format: z.string(), env: "CLERK_PUBLISHABLE_KEY", }, }, }, // Server configuration server: { port: { format: z.string().transform(Number), default: 3000, env: "PORT", }, environment: { format: z.enum(["development", "production", "staging"]), default: "development", env: "NODE_ENV", }, }, // Feature flags features: { analyticsEnabled: { format: z.string().transform((s) => s === "true"), default: false, env: "ENABLE_ANALYTICS", }, newUiEnabled: { format: z.string().transform((s) => s === "true"), default: false, env: "FEATURE_NEW_UI", optional: true, }, }, }); ``` -------------------------------- ### Zod Library Compatibility Source: https://github.com/alandotcom/standardenv/blob/main/README.md Use StandardEnv with Zod for configuration validation. Import 'z' from 'zod' and use Zod's transform for type conversion. ```typescript import { z } from "zod"; const config = envParse(process.env, { port: { format: z.string().transform(Number), env: "PORT", }, }); ``` -------------------------------- ### Identify Optional Properties Without Defaults Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/types.md Identifies ConfigProperties that are optional but do not provide a default value. These properties will be truly optional in the resulting configuration type. ```typescript type IsOptionalWithoutDefault

= HasOptional

extends true ? (HasDefault

extends true ? false : true) : false; ``` -------------------------------- ### Arktype Library Compatibility Source: https://github.com/alandotcom/standardenv/blob/main/README.md Integrate StandardEnv with Arktype for defining configuration formats. Ensure the 'type' function is imported from 'arktype'. ```typescript import { type } from "arktype"; const config = envParse(process.env, { port: { format: type("string.numeric.parse"), env: "PORT", }, }); ``` -------------------------------- ### Organize Related Configuration Source: https://github.com/alandotcom/standardenv/blob/main/README.md Group related configuration settings into nested objects for better organization. Use meaningful default values where appropriate. ```typescript // Organize related config into nested objects const config = envParse(process.env, { database: { url: { format: type("string"), env: "DATABASE_URL" }, poolSize: { format: type("string.numeric.parse"), default: 10, env: "DB_POOL_SIZE" }, }, }); // Use meaningful default values const config = envParse(process.env, { server: { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT" }, }, }); // Mark truly optional config as optional const config = envParse(process.env, { monitoring: { sentryDsn: { format: type("string"), env: "SENTRY_DSN", optional: true }, }, }); ``` -------------------------------- ### Type Inference with Zod and Standardenv Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/validator-integration.md Demonstrates how Standardenv infers TypeScript types from Zod schemas, enabling type-safe access to parsed environment variables. ```typescript import { z } from "zod"; import { envParse } from "standardenv"; const config = envParse(process.env, { // Input: string, Output: number port: { format: z.string().transform(Number), default: 3000, env: "PORT", }, // Input: string, Output: "dev" | "prod" environment: { format: z.enum(["dev", "prod"]), default: "dev", env: "ENV", }, }); // Types are inferred: // config.port: number // config.environment: "dev" | "prod" ``` -------------------------------- ### Valibot Library Compatibility Source: https://github.com/alandotcom/standardenv/blob/main/README.md Configure StandardEnv with Valibot for validation. Import Valibot as 'v' and use its pipe and transform utilities. ```typescript import * as v from "valibot"; const config = envParse(process.env, { port: { format: v.pipe(v.string(), v.transform(Number)), env: "PORT", }, }); ``` -------------------------------- ### Default Value Handling in envParse Source: https://github.com/alandotcom/standardenv/blob/main/_autodocs/architecture.md Shows how default values are handled in `envParse`. Defaults are stored and returned as-is without validation or transformation, requiring the compiler to enforce type matching. ```typescript const config = envParse(process.env, { port: { format: z.string().transform(Number), default: 3000, // Already number, not string env: "PORT", }, }); ``` -------------------------------- ### Define and Parse Environment Configuration Source: https://github.com/alandotcom/standardenv/blob/main/README.md Use `envParse` to define a typed configuration object. Specify formats using ArkType, set default values, and map to environment variables. The resulting `config` object is fully typed. ```typescript import { envParse } from "standardenv"; import { type } from "arktype"; export const config = envParse(process.env, { app: { name: { format: type("string"), default: "my-app", env: "APP_NAME", }, version: { format: type("string"), default: "1.0.0", env: "APP_VERSION", }, }, server: { port: { format: type("string.numeric.parse"), default: 3000, env: "PORT", }, host: { format: type("string"), default: "0.0.0.0", env: "HOST", }, cors: { origins: { format: type("string").pipe((s) => s.split(",").map((o) => o.trim())), default: ["http://localhost:3000"], env: "CORS_ORIGINS", }, }, }, database: { url: { format: type("string"), env: "DATABASE_URL", }, ssl: { format: type("string").pipe((s) => s === "true"), default: false, env: "DATABASE_SSL", }, }, auth: { clerk: { secretKey: { format: type("string"), env: "CLERK_SECRET_KEY", }, publishableKey: { format: type("string"), env: "CLERK_PUBLISHABLE_KEY", }, }, }, features: { analytics: { format: type("string").pipe((s) => s === "true"), default: false, env: "ENABLE_ANALYTICS", }, monitoring: { format: type("string").pipe((s) => s === "true"), default: false, env: "ENABLE_MONITORING", optional: true, }, }, }); // config is fully typed as: // { // app: { name: string; version: string }; // server: { port: number; host: string; cors: { origins: string[] } }; // database: { url: string; ssl: boolean }; // auth: { clerk: { secretKey: string; publishableKey: string } }; // features: { analytics: boolean; monitoring?: boolean }; // } ```