API Reference
Complete API documentation for safe-env.
env()
Function Signature
function env<T extends SchemaDefinition>(
schema: T,
options?: { env?: EnvSource }
): InferSchema<T>Parameters
schema(required)
Object mapping environment variable names to DSL strings.
{
DATABASE_URL: "string:url",
PORT: "number:default=3000",
}options(optional)
Configuration object with optional environment source override.
options.env - Custom environment source (defaults to process.env if available)
{
env: {
DATABASE_URL: "https://custom-db.com",
PORT: "8080",
},
}Returns
Fully typed object matching your schema. TypeScript infers the correct types:
// Input schema
const ENV = env({
PORT: "number:default=3000",
NODE_ENV: "enum:development,production",
});
// TypeScript infers:
// ENV.PORT: number
// ENV.NODE_ENV: "development" | "production"Throws
EnvValidationError - When validation fails
import { env, EnvValidationError } from "@liahus/safe-env";
try {
const ENV = env({
DATABASE_URL: "string:url",
});
} catch (error) {
if (error instanceof EnvValidationError) {
// Handle validation error
console.error(error.message);
console.error(error.errors);
}
}EnvValidationError
Class Definition
class EnvValidationError extends Error {
message: string;
errors: Array<{ key: string; message: string }>;
}Properties
message
Human-readable error message. Secrets are automatically masked.
"Environment variable validation failed:
DATABASE_URL: Invalid url (received: undefined)
JWT_SECRET: String must contain at least 32 character(s) (received: [REDACTED (length: 12)])"errors
Array of individual validation errors. No secrets exposed.
[
{ key: "DATABASE_URL", message: "Invalid url" },
{ key: "JWT_SECRET", message: "String must contain at least 32 character(s)" },
]Usage Example
import { env, EnvValidationError } from "@liahus/safe-env";
try {
const ENV = env({
DATABASE_URL: "string:url",
PORT: "number",
JWT_SECRET: "string:min=32:secret",
});
} catch (error) {
if (error instanceof EnvValidationError) {
// Log the full message
console.error(error.message);
// Iterate over individual errors
error.errors.forEach((err) => {
console.error(`${err.key}: ${err.message}`);
});
// Exit with error code
process.exit(1);
}
}Type Inference
safe-env provides full TypeScript type inference from your schema:
import { env } from "@liahus/safe-env";
const ENV = env({
STRING_VAR: "string",
NUMBER_VAR: "number",
ENUM_VAR: "enum:val1,val2,val3",
PORT: "number:default=3000",
});
// TypeScript knows:
// ENV.STRING_VAR: string
// ENV.NUMBER_VAR: number
// ENV.ENUM_VAR: "val1" | "val2" | "val3"
// ENV.PORT: number
// Type errors if you try to use incorrectly:
// ENV.PORT.toUpperCase() // ❌ Error: Property 'toUpperCase' does not exist on type 'number'
// ENV.ENUM_VAR === "invalid" // ❌ Error: This comparison appears to be unintentionalEnvironment Source
By default, safe-env uses process.env if available. You can override this:
import { env } from "@liahus/safe-env";
// Use process.env (default)
const ENV1 = env({
PORT: "number:default=3000",
});
// Use custom environment source
const ENV2 = env(
{
PORT: "number:default=3000",
},
{
env: {
PORT: "8080", // Custom value
},
}
);
// Useful for testing
const testEnv = env(
{
API_KEY: "string:min=10",
},
{
env: {
API_KEY: "test-api-key-12345",
},
}
);