UNPKG

env-schema-checker

Version:

A zero-config, type-safe, schema-driven .env validator with automatic error reporting, autocomplete, and runtime checks

1 lines 8.94 kB
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { config } from 'dotenv';\nimport { z } from 'zod';\nimport {\n EnvSchema,\n LoadEnvOptions,\n ValidationError,\n ValidationResult,\n TypeGeneratorOptions,\n} from './types';\n\n// Define a type for Node.js errors\ninterface NodeError extends Error {\n code?: string;\n}\n\nfunction createZodSchema(schema: EnvSchema): z.ZodObject<any> {\n const zodSchema: Record<string, z.ZodType> = {};\n\n for (const [key, value] of Object.entries(schema)) {\n if (value instanceof z.ZodType) {\n zodSchema[key] = value;\n } else if (Array.isArray(value)) {\n zodSchema[key] = z.enum(value as [string, ...string[]]);\n } else {\n switch (value) {\n case 'string':\n zodSchema[key] = z.string();\n break;\n case 'number':\n zodSchema[key] = z.string()\n .refine((val) => !isNaN(Number(val)), {\n message: 'Invalid number format',\n })\n .transform((val) => Number(val));\n break;\n case 'boolean':\n zodSchema[key] = z.enum(['true', 'false']).transform((val) => val === 'true');\n break;\n case 'array':\n zodSchema[key] = z.string().refine((val) => {\n try {\n const parsed = JSON.parse(val);\n return Array.isArray(parsed);\n } catch {\n // fallback: allow comma-separated string as array\n return val.includes(',');\n }\n }, { message: 'Must be a JSON array or comma-separated values' })\n .transform((val) => {\n try {\n const parsed = JSON.parse(val);\n if (Array.isArray(parsed)) return parsed;\n } catch { }\n return val.split(',');\n });\n break;\n case 'object':\n zodSchema[key] = z.string().transform((val) => {\n const parsed = JSON.parse(val);\n if (typeof parsed !== 'object' || Array.isArray(parsed) || parsed === null) {\n throw new Error('Must be a JSON object');\n }\n return parsed;\n });\n break;\n default:\n zodSchema[key] = z.string();\n }\n }\n }\n\n return z.object(zodSchema);\n}\n\nexport function loadEnv(options: LoadEnvOptions): ValidationResult {\n const { schema, path, encoding, override, debug } = options;\n\n // Load environment variables from .env file if path is provided\n if (path) {\n try {\n const result = config({ path, encoding, override, debug });\n if (result.error) {\n throw result.error;\n }\n } catch (error: unknown) {\n const nodeError = error as NodeError;\n if (nodeError.code !== 'ENOENT') {\n throw error;\n }\n // Ignore missing .env file\n }\n }\n\n const zodSchema = createZodSchema(schema);\n const validationResult = zodSchema.safeParse(process.env);\n\n if (!validationResult.success) {\n const errors: ValidationError[] = validationResult.error.errors.map((err) => ({\n key: err.path.join('.'),\n message: err.message,\n value: process.env[err.path[0] as string],\n }));\n\n return {\n success: false,\n errors,\n env: {},\n };\n }\n\n return {\n success: true,\n env: validationResult.data,\n };\n}\n\nexport function generateTypes(options: TypeGeneratorOptions): string {\n const { schema, outputPath } = options;\n let typeDefinitions = 'declare global {\\n namespace NodeJS {\\n interface ProcessEnv {\\n';\n\n for (const [key, value] of Object.entries(schema)) {\n let type: string;\n\n if (value instanceof z.ZodType) {\n type = 'string'; // Default to string for custom Zod types\n } else if (Array.isArray(value)) {\n type = value.map((v) => `'${v}'`).join(' | ');\n } else {\n switch (value) {\n case 'number':\n type = 'number';\n break;\n case 'boolean':\n type = 'boolean';\n break;\n case 'array':\n type = 'string[]';\n break;\n case 'object':\n type = 'Record<string, unknown>';\n break;\n default:\n type = 'string';\n }\n }\n\n typeDefinitions += ` ${key}: ${type};\\n`;\n }\n\n typeDefinitions += ' }\\n }\\n}\\n\\nexport {};';\n\n if (outputPath) {\n // TODO: Implement file writing\n }\n\n return typeDefinitions;\n}\n\nexport function validateEnv(schema: EnvSchema): ValidationResult {\n return loadEnv({ schema });\n}\n\nexport function parseEnvFile(path: string): Record<string, string> {\n const result = config({ path });\n if (result.error) {\n throw result.error;\n }\n return result.parsed || {};\n}"]}