node-safe-env 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors/EnvValidationError.ts","../src/createEnv.ts","../src/flattenSchema.ts","../src/findUnknownEnvKeys.ts","../src/loadEnvFiles.ts","../src/mergeSources.ts","../src/applyTransform.ts","../src/validators/boolean.ts","../src/validators/enum.ts","../src/validators/json.ts","../src/validators/number.ts","../src/validators/port.ts","../src/validators/string.ts","../src/validators/url.ts","../src/validators/int.ts","../src/validators/float.ts","../src/validators/array.ts","../src/validators/custom.ts","../src/validators/email.ts","../src/validators/date.ts","../src/validators/index.ts","../src/parseValue.ts","../src/setNestedValue.ts","../src/defineEnv.ts","../src/maskEnv.ts","../src/traceEnv.ts","../src/validateExampleEnv.ts","../src/readEnvFileSource.ts","../src/validateExampleEnvFile.ts"],"sourcesContent":["export { createEnv } from \"./createEnv\";\nexport { defineEnv } from \"./defineEnv\";\nexport { EnvValidationError } from \"./errors/EnvValidationError\";\nexport { maskEnv } from \"./maskEnv\";\nexport { mergeSources } from \"./mergeSources\";\nexport { traceEnv } from \"./traceEnv\";\nexport { validateExampleEnv } from \"./validateExampleEnv\";\nexport { readEnvFileSource, resolveExampleEnvPath } from \"./readEnvFileSource\";\nexport { validateExampleEnvFile } from \"./validateExampleEnvFile\";\n\nexport type {\n EnvSchema,\n EnvRule,\n EnvValidationIssue,\n EnvValidationIssueCode,\n EnvDebugReport,\n EnvDebugKeyEntry,\n EnvDebugLoadedFile,\n EnvDebugStatus,\n EnvDebugSource,\n EnvDebugDefaultKind,\n EnvDebugOptions,\n ParsedEnv,\n CreateEnvOptions,\n ValidateExampleEnvFileOptions,\n} from \"./types/schema\";\n","import type { EnvValidationIssue } from \"../types/schema\";\n\nexport class EnvValidationError extends Error {\n public readonly issues: EnvValidationIssue[];\n\n constructor(issues: EnvValidationIssue[]) {\n super(\n [\n \"Environment validation failed:\",\n ...issues.map((issue) => `- [${issue.code}] ${issue.message}`),\n ].join(\"\\n\"),\n );\n\n this.name = \"EnvValidationError\";\n this.issues = issues;\n }\n}\n","import { EnvValidationError } from \"./errors/EnvValidationError\";\nimport path from \"node:path\";\nimport { findUnknownEnvKeys } from \"./findUnknownEnvKeys\";\nimport { flattenSchema } from \"./flattenSchema\";\nimport { loadEnvFiles } from \"./loadEnvFiles\";\nimport { mergeSources } from \"./mergeSources\";\nimport { parseValue } from \"./parseValue\";\nimport { setNestedValue } from \"./setNestedValue\";\nimport type {\n CreateEnvOptions,\n EnvDebugDefaultKind,\n EnvDebugKeyEntry,\n EnvDebugLoadedFile,\n EnvDebugReport,\n EnvDebugSource,\n EnvRule,\n EnvSchema,\n EnvValidationIssue,\n EnvValueSource,\n LoadedEnvFiles,\n ParsedEnv,\n} from \"./types/schema\";\n\nfunction isEmptyString(value: string): boolean {\n return value.trim() === \"\";\n}\n\nfunction defaultToRawValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n return JSON.stringify(value);\n}\n\nfunction resolveDefaultValue(value: unknown): unknown {\n return typeof value === \"function\" ? (value as () => unknown)() : value;\n}\n\nfunction parseDefaultValue(\n envKey: string,\n rule: EnvRule,\n): ReturnType<typeof parseValue> & {\n defaultKind: EnvDebugDefaultKind;\n rawDefault?: string;\n} {\n const defaultKind: EnvDebugDefaultKind =\n typeof rule.default === \"function\" ? \"function\" : \"static\";\n let resolvedDefault: unknown;\n\n try {\n resolvedDefault = resolveDefaultValue(rule.default);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n issue: {\n key: envKey,\n code: \"invalid_default\",\n message: `Default function for \"${envKey}\" threw an error: ${message}`,\n },\n defaultKind,\n };\n }\n\n const rawDefault = defaultToRawValue(resolvedDefault);\n\n return {\n ...parseValue(envKey, rawDefault, rule),\n defaultKind,\n rawDefault,\n };\n}\n\ntype SourceTrace = Record<string, { source: EnvValueSource; raw: string }>;\n\nfunction countKeys(source: Record<string, string | undefined>): number {\n return Object.values(source).filter((value) => typeof value === \"string\")\n .length;\n}\n\nfunction buildLoadedFileReport(\n loadedFiles: LoadedEnvFiles,\n cwd: string,\n nodeEnv: string,\n envFile?: string,\n): EnvDebugLoadedFile[] {\n return [\n {\n source: \".env\",\n path: path.join(cwd, \".env\"),\n keyCount: countKeys(loadedFiles.base),\n },\n {\n source: \".env.local\",\n path: path.join(cwd, \".env.local\"),\n keyCount: countKeys(loadedFiles.local),\n },\n {\n source: \".env.environment\",\n path: path.join(cwd, `.env.${nodeEnv}`),\n keyCount: countKeys(loadedFiles.environment),\n },\n {\n source: \"custom\",\n path: envFile ? path.resolve(cwd, envFile) : undefined,\n keyCount: countKeys(loadedFiles.custom),\n },\n ];\n}\n\nfunction buildSourceTrace(\n loadedFiles: LoadedEnvFiles,\n runtimeValues: Record<string, string | undefined>,\n): SourceTrace {\n const trace: SourceTrace = Object.create(null) as SourceTrace;\n\n const applySource = (\n source: Record<string, string | undefined>,\n label: EnvValueSource,\n ): void => {\n for (const [key, raw] of Object.entries(source)) {\n if (typeof raw === \"string\") {\n trace[key] = { source: label, raw };\n }\n }\n };\n\n applySource(loadedFiles.base, \".env\");\n applySource(loadedFiles.local, \".env.local\");\n applySource(loadedFiles.environment, \".env.environment\");\n applySource(loadedFiles.custom, \"custom\");\n applySource(runtimeValues, \"process.env\");\n\n return trace;\n}\n\nfunction maskDebugValue(value: unknown, sensitive: boolean): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n return sensitive ? \"***\" : value;\n}\n\nfunction resolveDebugLogger(\n debug: CreateEnvOptions[\"debug\"],\n): ((report: EnvDebugReport) => void) | undefined {\n if (debug === true) {\n return (report: EnvDebugReport): void => {\n console.info(report);\n };\n }\n\n if (debug && typeof debug === \"object\" && debug.logger) {\n return debug.logger;\n }\n\n return undefined;\n}\n\nexport function createEnv<S extends EnvSchema>(\n schema: S,\n options: CreateEnvOptions = {},\n): ParsedEnv<S> {\n const debugEnabled = options.debug !== undefined && options.debug !== false;\n const debugLogger = debugEnabled\n ? resolveDebugLogger(options.debug)\n : undefined;\n const debugKeys: EnvDebugKeyEntry[] = [];\n\n let source: Record<string, string | undefined>;\n let loadedFileReport: EnvDebugLoadedFile[] = [];\n let sourceTrace: SourceTrace = Object.create(null) as SourceTrace;\n\n if (options.source) {\n source = options.source;\n\n if (debugEnabled) {\n for (const [key, raw] of Object.entries(source)) {\n if (typeof raw === \"string\") {\n sourceTrace[key] = { source: \"process.env\", raw };\n }\n }\n }\n } else {\n const loadedFiles = loadEnvFiles({\n cwd: options.cwd,\n nodeEnv: options.nodeEnv,\n envFile: options.envFile,\n });\n source = mergeSources(loadedFiles, process.env);\n\n if (debugEnabled) {\n const cwd = options.cwd ?? process.cwd();\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV ?? \"development\";\n loadedFileReport = buildLoadedFileReport(\n loadedFiles,\n cwd,\n nodeEnv,\n options.envFile,\n );\n sourceTrace = buildSourceTrace(loadedFiles, process.env);\n }\n }\n\n const issues: EnvValidationIssue[] = [];\n const result: Record<string, unknown> = {};\n const flattenedSchema = flattenSchema(schema as Record<string, unknown>);\n\n if (options.strict) {\n issues.push(\n ...findUnknownEnvKeys(schema as Record<string, unknown>, source),\n );\n }\n\n for (const entry of flattenedSchema) {\n const { path, envKey, rule } = entry;\n const currentValue = source[envKey];\n const sourceInfo = sourceTrace[envKey];\n const sensitive = rule.sensitive === true;\n const defaultKind: EnvDebugDefaultKind | undefined =\n rule.default === undefined\n ? undefined\n : typeof rule.default === \"function\"\n ? \"function\"\n : \"static\";\n\n const pushDebugEntry = (\n status: EnvDebugKeyEntry[\"status\"],\n values: {\n source: EnvDebugSource;\n usedDefault: boolean;\n raw?: string;\n parsed?: unknown;\n issue?: EnvValidationIssue;\n defaultKind?: EnvDebugDefaultKind;\n },\n ): void => {\n if (!debugEnabled) {\n return;\n }\n\n debugKeys.push({\n key: envKey,\n ruleType: rule.type,\n source: values.source,\n usedDefault: values.usedDefault,\n defaultKind: values.defaultKind,\n raw: maskDebugValue(values.raw, sensitive) as string | undefined,\n parsed: maskDebugValue(values.parsed, sensitive),\n status,\n issue: values.issue,\n });\n };\n\n if (typeof currentValue !== \"string\") {\n if (rule.default !== undefined) {\n const parsedDefault = parseDefaultValue(envKey, rule);\n\n if (parsedDefault.issue) {\n issues.push(parsedDefault.issue);\n pushDebugEntry(\"issue\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n issue: parsedDefault.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"defaulted\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n parsed: parsedDefault.value,\n });\n setNestedValue(result, path, parsedDefault.value);\n continue;\n }\n\n if (rule.required) {\n const issue = {\n key: envKey,\n code: \"missing\",\n message: `Missing required environment variable \"${envKey}\".`,\n } as const;\n\n issues.push(issue);\n pushDebugEntry(\"missing\", {\n source: \"missing\",\n usedDefault: false,\n defaultKind,\n issue,\n });\n } else {\n pushDebugEntry(\"missing\", {\n source: \"missing\",\n usedDefault: false,\n defaultKind,\n });\n }\n\n continue;\n }\n\n const rawValue = currentValue;\n\n if (!rule.allowEmpty && isEmptyString(rawValue)) {\n if (rule.default !== undefined) {\n const parsedDefault = parseDefaultValue(envKey, rule);\n\n if (parsedDefault.issue) {\n issues.push(parsedDefault.issue);\n pushDebugEntry(\"issue\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n issue: parsedDefault.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"defaulted\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n parsed: parsedDefault.value,\n });\n setNestedValue(result, path, parsedDefault.value);\n continue;\n }\n\n const issue = {\n key: envKey,\n code: \"empty\",\n message: `Environment variable \"${envKey}\" cannot be empty.`,\n } as const;\n\n issues.push(issue);\n pushDebugEntry(\"empty\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n issue,\n });\n continue;\n }\n\n const parsed = parseValue(envKey, rawValue, rule);\n\n if (parsed.issue) {\n issues.push(parsed.issue);\n pushDebugEntry(\"issue\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n issue: parsed.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"parsed\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n parsed: parsed.value,\n });\n setNestedValue(result, path, parsed.value);\n }\n\n if (debugLogger) {\n debugLogger({\n loadedFiles: loadedFileReport,\n keys: debugKeys,\n });\n }\n\n if (issues.length > 0) {\n throw new EnvValidationError(issues);\n }\n\n return result as unknown as ParsedEnv<S>;\n}\n","import type { EnvRule } from \"./types/schema\";\r\n\r\nexport type FlattenedSchemaEntry = {\r\n path: string[];\r\n envKey: string;\r\n rule: EnvRule;\r\n};\r\n\r\nfunction isEnvRule(value: unknown): value is EnvRule {\r\n return (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n \"type\" in value &&\r\n typeof (value as { type?: unknown }).type === \"string\"\r\n );\r\n}\r\n\r\nfunction toEnvKey(path: string[]): string {\r\n return path.map((segment) => segment.toUpperCase()).join(\"_\");\r\n}\r\n\r\nexport function flattenSchema(\r\n schema: Record<string, unknown>,\r\n parentPath: string[] = [],\r\n): FlattenedSchemaEntry[] {\r\n const entries: FlattenedSchemaEntry[] = [];\r\n\r\n for (const [key, value] of Object.entries(schema)) {\r\n const currentPath = [...parentPath, key];\r\n\r\n if (isEnvRule(value)) {\r\n entries.push({\r\n path: currentPath,\r\n envKey: toEnvKey(currentPath),\r\n rule: value,\r\n });\r\n\r\n continue;\r\n }\r\n\r\n if (typeof value === \"object\" && value !== null) {\r\n entries.push(\r\n ...flattenSchema(value as Record<string, unknown>, currentPath),\r\n );\r\n }\r\n }\r\n\r\n return entries;\r\n}\r\n","import { flattenSchema } from \"./flattenSchema\";\r\nimport type { EnvSource, EnvValidationIssue } from \"./types/schema\";\r\n\r\nexport function findUnknownEnvKeys(\r\n schema: Record<string, unknown>,\r\n source: EnvSource,\r\n): EnvValidationIssue[] {\r\n const knownKeys = new Set(flattenSchema(schema).map((entry) => entry.envKey));\r\n const issues: EnvValidationIssue[] = [];\r\n\r\n for (const key of Object.keys(source)) {\r\n if (source[key] === undefined) {\r\n continue;\r\n }\r\n\r\n if (knownKeys.has(key)) {\r\n continue;\r\n }\r\n\r\n issues.push({\r\n key,\r\n code: \"unknown_key\",\r\n message: `Environment variable \"${key}\" is not defined in the schema.`,\r\n });\r\n }\r\n\r\n return issues;\r\n}\r\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type {\n LoadEnvFilesOptions,\n EnvSource,\n LoadedEnvFiles,\n} from \"./types/schema\";\n\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nfunction stripInlineComment(input: string): string {\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let isEscaped = false;\n\n for (let index = 0; index < input.length; index += 1) {\n const char = input[index];\n\n if (isEscaped) {\n isEscaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n isEscaped = true;\n continue;\n }\n\n if (char === '\"' && !inSingleQuote) {\n inDoubleQuote = !inDoubleQuote;\n continue;\n }\n\n if (char === \"'\" && !inDoubleQuote) {\n inSingleQuote = !inSingleQuote;\n continue;\n }\n\n if (\n char === \"#\" &&\n !inSingleQuote &&\n !inDoubleQuote &&\n (index === 0 || /\\s/.test(input[index - 1] ?? \"\"))\n ) {\n return input.slice(0, index).trimEnd();\n }\n }\n\n return input.trimEnd();\n}\n\nfunction parseEnvFile(filePath: string): EnvSource {\n if (!fs.existsSync(filePath)) {\n return Object.create(null) as EnvSource;\n }\n\n const content = fs.readFileSync(filePath, \"utf8\");\n const result = Object.create(null) as EnvSource;\n\n for (const rawLine of content.split(/\\r?\\n/)) {\n let line = rawLine.trim();\n\n if (!line || line.startsWith(\"#\")) {\n continue;\n }\n\n if (line.startsWith(\"export \")) {\n line = line.slice(\"export \".length).trim();\n\n if (!line) {\n continue;\n }\n }\n\n const equalIndex = line.indexOf(\"=\");\n\n if (equalIndex <= 0) {\n continue;\n }\n\n const key = line.slice(0, equalIndex).trim();\n\n if (!ENV_KEY_PATTERN.test(key)) {\n continue;\n }\n\n let value = stripInlineComment(line.slice(equalIndex + 1)).trim();\n\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n result[key] = value;\n }\n\n return result;\n}\n\nexport function loadEnvFiles(\n options: LoadEnvFilesOptions = {},\n): LoadedEnvFiles {\n const cwd = options.cwd ?? process.cwd();\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV ?? \"development\";\n\n const base = parseEnvFile(path.join(cwd, \".env\"));\n const local = parseEnvFile(path.join(cwd, \".env.local\"));\n const environment = parseEnvFile(path.join(cwd, `.env.${nodeEnv}`));\n const custom = options.envFile\n ? parseEnvFile(path.resolve(cwd, options.envFile))\n : (Object.create(null) as EnvSource);\n\n return {\n base,\n local,\n environment,\n custom,\n };\n}\n","import type { EnvSource, LoadedEnvFiles } from \"./types/schema\";\n\nexport function mergeSources(\n files: LoadedEnvFiles,\n runtimeValues: EnvSource = process.env,\n): EnvSource {\n return Object.assign(\n Object.create(null),\n files.base,\n files.local,\n files.environment,\n files.custom,\n runtimeValues,\n ) as EnvSource;\n}\n","import type { EnvRule, EnvValidationIssue } from \"./types/schema\";\r\nimport type { ParseResult } from \"./validators\";\r\n\r\nexport function applyTransform(\r\n key: string,\r\n rule: EnvRule,\r\n result: ParseResult,\r\n): ParseResult {\r\n if (result.issue || result.value === undefined || !rule.transform) {\r\n return result;\r\n }\r\n\r\n try {\r\n return {\r\n value: rule.transform(result.value as never),\r\n };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message\r\n ? error.message\r\n : `Environment variable \"${key}\" failed transform.`;\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_custom\",\r\n message,\r\n } satisfies EnvValidationIssue,\r\n };\r\n }\r\n}\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nconst TRUE_VALUES = new Set([\"true\", \"1\", \"yes\", \"on\"]);\r\nconst FALSE_VALUES = new Set([\"false\", \"0\", \"no\", \"off\"]);\r\n\r\nexport const validateBoolean: EnvValidator = ({ key, rawValue }) => {\r\n const normalized = rawValue.trim().toLowerCase();\r\n\r\n if (TRUE_VALUES.has(normalized)) {\r\n return { value: true };\r\n }\r\n\r\n if (FALSE_VALUES.has(normalized)) {\r\n return { value: false };\r\n }\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_boolean\",\r\n message: `Environment variable \"${key}\" must be a valid boolean.`,\r\n },\r\n };\r\n};\r\n","import type { EnumRule } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateEnum: EnvValidator = ({ key, rawValue, rule }) => {\r\n const enumRule = rule as EnumRule;\r\n\r\n if (!enumRule.values.includes(rawValue)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_enum\",\r\n message: `Environment variable \"${key}\" must be one of: ${enumRule.values.join(\", \")}.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: rawValue };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateJson: EnvValidator = ({ key, rawValue }) => {\r\n try {\r\n const parsed = JSON.parse(rawValue);\r\n\r\n return { value: parsed };\r\n } catch {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_json\",\r\n message: `Environment variable \"${key}\" must contain valid JSON.`,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateNumber: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isFinite(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid number.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validatePort: EnvValidator = ({ key, rawValue }) => {\r\n const num = Number(rawValue);\r\n\r\n if (!Number.isInteger(num) || num < 1 || num > 65535) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_port\",\r\n message: `Environment variable \"${key}\" must be a valid port (1–65535).`,\r\n },\r\n };\r\n }\r\n\r\n return { value: num };\r\n};","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateString: EnvValidator = ({ rawValue }) => {\r\n return { value: rawValue };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateUrl: EnvValidator = ({ key, rawValue }) => {\r\n try {\r\n new URL(rawValue);\r\n\r\n return { value: rawValue };\r\n } catch {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_url\",\r\n message: `Environment variable \"${key}\" must be a valid URL.`,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateInt: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isInteger(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid integer.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateFloat: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isFinite(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid float.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { ArrayRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateArray: EnvValidator = ({ key, rawValue, rule }) => {\r\n const arrayRule = rule as ArrayRule;\r\n const separator = arrayRule.separator ?? \",\";\r\n const trimItems = arrayRule.trimItems ?? true;\r\n const allowEmptyItems = arrayRule.allowEmptyItems ?? false;\r\n const splitValues = rawValue.split(separator);\r\n\r\n const parsed = trimItems\r\n ? splitValues.map((item) => item.trim())\r\n : splitValues;\r\n\r\n if (!allowEmptyItems && parsed.some((item) => item === \"\")) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_array\",\r\n message: `Environment variable \"${key}\" cannot contain empty array items`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { CustomRule } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateCustom: EnvValidator = ({ key, rawValue, rule }) => {\r\n const customRule = rule as CustomRule;\r\n\r\n try {\r\n const parsed = customRule.parse(rawValue);\r\n\r\n return { value: parsed };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message\r\n ? error.message\r\n : `Environment variable \"${key}\" failed custom validation.`;\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_custom\",\r\n message,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EmailRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateEmail: EnvValidator = ({ key, rawValue, rule }) => {\r\n const emailRule = rule as EmailRule;\r\n void emailRule;\r\n\r\n const value = rawValue.trim();\r\n\r\n if (!value) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n if (/\\s/.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n\r\n if (!emailRegex.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n return {\r\n value,\r\n };\r\n};","import type { DateRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nfunction isValidDate(date: Date): boolean {\r\n return !Number.isNaN(date.getTime());\r\n}\r\n\r\nexport const validateDate: EnvValidator = ({ key, rawValue, rule }) => {\r\n const dateRule = rule as DateRule;\r\n void dateRule;\r\n\r\n const value = rawValue.trim();\r\n\r\n if (!value) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid ISO date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n const isoDateTimeRegex =\r\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,3})?)?(Z|[+-]\\d{2}:\\d{2})$/;\r\n\r\n if (!isoDateRegex.test(value) && !isoDateTimeRegex.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid ISO date string`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const parsed = new Date(value);\r\n\r\n if (!isValidDate(parsed)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n if (isoDateRegex.test(value)) {\r\n const [year, month, day] = value.split(\"-\").map(Number);\r\n\r\n if (\r\n parsed.getUTCFullYear() !== year ||\r\n parsed.getUTCMonth() + 1 !== month ||\r\n parsed.getUTCDate() !== day\r\n ) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a real calendar date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n }\r\n\r\n return {\r\n value: parsed,\r\n };\r\n};\r\n","import { validateBoolean } from \"./boolean\";\r\nimport { validateEnum } from \"./enum\";\r\nimport { validateJson } from \"./json\";\r\nimport { validateNumber } from \"./number\";\r\nimport { validatePort } from \"./port\";\r\nimport { validateString } from \"./string\";\r\nimport { validateUrl } from \"./url\";\r\nimport type { EnvValidator } from \"./types\";\r\nimport { validateInt } from \"./int\";\r\nimport { validateFloat } from \"./float\";\r\nimport { validateArray } from \"./array\";\r\nimport { validateCustom } from \"./custom\";\r\nimport { validateEmail } from \"./email\";\r\nimport { validateDate } from \"./date\";\r\n\r\nexport const validators = {\r\n string: validateString,\r\n number: validateNumber,\r\n boolean: validateBoolean,\r\n enum: validateEnum,\r\n url: validateUrl,\r\n port: validatePort,\r\n json: validateJson,\r\n int: validateInt,\r\n float: validateFloat,\r\n array: validateArray,\r\n custom: validateCustom,\r\n email: validateEmail,\r\n date: validateDate,\r\n} as const satisfies {\r\n string: EnvValidator;\r\n number: EnvValidator;\r\n boolean: EnvValidator;\r\n enum: EnvValidator;\r\n url: EnvValidator;\r\n port: EnvValidator;\r\n json: EnvValidator;\r\n int: EnvValidator;\r\n float: EnvValidator;\r\n array: EnvValidator;\r\n custom: EnvValidator;\r\n email: EnvValidator;\r\n date: EnvValidator;\r\n};\r\n\r\nexport type { ParseResult, EnvValidator } from \"./types\";\r\n","import { applyTransform } from \"./applyTransform\";\nimport type { EnvRule } from \"./types/schema\";\nimport { validators } from \"./validators\";\nimport type { ParseResult } from \"./validators\";\n\nexport function parseValue(\n key: string,\n rawValue: string,\n rule: EnvRule,\n): ParseResult {\n const validator = validators[rule.type];\n\n const result = validator({\n key,\n rawValue,\n rule,\n });\n\n return applyTransform(key, rule, result);\n}\n","export function setNestedValue(\r\n target: Record<string, unknown>,\r\n path: string[],\r\n value: unknown,\r\n): void {\r\n let current: Record<string, unknown> = target;\r\n\r\n for (let index = 0; index < path.length - 1; index += 1) {\r\n const segment = path[index];\r\n const existing = current[segment];\r\n\r\n if (\r\n typeof existing !== \"object\" ||\r\n existing === null ||\r\n Array.isArray(existing)\r\n ) {\r\n current[segment] = {};\r\n }\r\n\r\n current = current[segment] as Record<string, unknown>;\r\n }\r\n\r\n current[path[path.length - 1]] = value;\r\n}\r\n","import type { EnvSchema } from \"./types/schema\";\r\n\r\nexport function defineEnv<const S extends EnvSchema>(schema: S): S {\r\n return schema;\r\n}\r\n","import type { EnvSchema, ParsedEnv } from \"./types/schema\";\r\n\r\nfunction maskValue(): string {\r\n return \"***\";\r\n}\r\n\r\nexport function maskEnv<S extends EnvSchema>(\r\n schema: S,\r\n env: ParsedEnv<S>,\r\n): Partial<Record<keyof S, unknown>> {\r\n const masked: Partial<Record<keyof S, unknown>> = {};\r\n const envRecord = env as unknown as Partial<Record<keyof S, unknown>>;\r\n\r\n for (const key of Object.keys(schema) as Array<keyof S>) {\r\n const value = envRecord[key];\r\n\r\n if (value === undefined) {\r\n continue;\r\n }\r\n\r\n masked[key] = schema[key].sensitive ? maskValue() : value;\r\n }\r\n\r\n return masked;\r\n}\r\n","import type { EnvSchema, ParsedEnv, EnvTraceEntry } from \"./types/schema\";\r\n\r\nexport function traceEnv<S extends EnvSchema>(\r\n schema: S,\r\n sources: Record<string, { source: string; raw: string }>,\r\n env: ParsedEnv<S>,\r\n): Partial<Record<keyof S, EnvTraceEntry>> {\r\n const traced: Partial<Record<keyof S, EnvTraceEntry>> = {};\r\n const envRecord = env as unknown as Partial<Record<keyof S, unknown>>;\r\n\r\n for (const key of Object.keys(schema) as Array<keyof S>) {\r\n const value = envRecord[key];\r\n\r\n if (value === undefined) {\r\n continue;\r\n }\r\n\r\n const sourceInfo = sources[key as string];\r\n\r\n if (!sourceInfo) {\r\n continue;\r\n }\r\n\r\n traced[key] = {\r\n source: sourceInfo.source as EnvTraceEntry[\"source\"],\r\n raw: sourceInfo.raw,\r\n parsed: value,\r\n };\r\n }\r\n\r\n return traced;\r\n}\r\n","import { flattenSchema } from \"./flattenSchema\";\r\nimport type { EnvSchema, EnvSource, EnvValidationIssue } from \"./types/schema\";\r\n\r\nexport function validateExampleEnv(\r\n schema: EnvSchema,\r\n exampleSource: EnvSource,\r\n): EnvValidationIssue[] {\r\n const issues: EnvValidationIssue[] = [];\r\n const flattenedSchema = flattenSchema(schema);\r\n const expectedKeys = new Set(flattenedSchema.map((entry) => entry.envKey));\r\n\r\n for (const entry of flattenedSchema) {\r\n const { envKey } = entry;\r\n\r\n if (!(envKey in exampleSource)) {\r\n issues.push({\r\n key: envKey,\r\n code: \"missing_example_key\",\r\n message: `Environment variable \"${envKey}\" is missing from .env.example.`,\r\n });\r\n }\r\n }\r\n\r\n for (const key of Object.keys(exampleSource)) {\r\n if (exampleSource[key] === undefined) {\r\n continue;\r\n }\r\n\r\n if (expectedKeys.has(key)) {\r\n continue;\r\n }\r\n\r\n issues.push({\r\n key,\r\n code: \"unknown_example_key\",\r\n message: `Environment variable \"${key}\" in .env.example is not defined in the schema.`,\r\n });\r\n }\r\n\r\n return issues;\r\n}\r\n","import { existsSync, readFileSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\nimport type { EnvSource } from \"./types/schema\";\r\n\r\nfunction stripQuotes(value: string): string {\r\n if (\r\n (value.startsWith('\"') && value.endsWith('\"')) ||\r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\r\n ) {\r\n return value.slice(1, -1);\r\n }\r\n\r\n return value;\r\n}\r\n\r\nexport function readEnvFileSource(filePath: string): EnvSource {\r\n if (!existsSync(filePath)) {\r\n return {};\r\n }\r\n\r\n const content = readFileSync(filePath, \"utf8\");\r\n const source: EnvSource = {};\r\n\r\n for (const line of content.split(/\\r?\\n/)) {\r\n const trimmed = line.trim();\r\n\r\n if (!trimmed || trimmed.startsWith(\"#\")) {\r\n continue;\r\n }\r\n\r\n const equalsIndex = trimmed.indexOf(\"=\");\r\n\r\n if (equalsIndex === -1) {\r\n continue;\r\n }\r\n\r\n const key = trimmed.slice(0, equalsIndex).trim();\r\n const rawValue = trimmed.slice(equalsIndex + 1).trim();\r\n\r\n if (!key) {\r\n continue;\r\n }\r\n\r\n source[key] = stripQuotes(rawValue);\r\n }\r\n\r\n return source;\r\n}\r\n\r\nexport function resolveExampleEnvPath(\r\n cwd: string = process.cwd(),\r\n exampleFile: string = \".env.example\",\r\n): string {\r\n return resolve(cwd, exampleFile);\r\n}\r\n","import { readEnvFileSource, resolveExampleEnvPath } from \"./readEnvFileSource\";\r\nimport { validateExampleEnv } from \"./validateExampleEnv\";\r\nimport type {\r\n EnvSchema,\r\n EnvValidationIssue,\r\n ValidateExampleEnvFileOptions,\r\n} from \"./types/schema\";\r\n\r\nexport function validateExampleEnvFile(\r\n schema: EnvSchema,\r\n options: ValidateExampleEnvFileOptions = {},\r\n): EnvValidationIssue[] {\r\n const filePath = resolveExampleEnvPath(options.cwd, options.exampleFile);\r\n const exampleSource = readEnvFileSource(filePath);\r\n\r\n return validateExampleEnv(schema, exampleSource);\r\n}\r\n"],"mappings":"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","names":["import_node_path","path","fs","path","path","path","import_node_fs","import_node_path"]}
@@ -0,0 +1,196 @@
1
+ type EnvValidationIssueCode = "missing" | "empty" | "invalid_enum" | "invalid_number" | "invalid_boolean" | "invalid_url" | "invalid_port" | "invalid_json" | "invalid_array" | "invalid_custom" | "invalid_email" | "invalid_date" | "invalid_default" | "unknown_key" | "missing_example_key" | "unknown_example_key";
2
+ type EnvValidationIssue = {
3
+ key: string;
4
+ code: EnvValidationIssueCode;
5
+ message: string;
6
+ };
7
+ type BaseRule<TDefault = unknown, TOutput = TDefault> = {
8
+ readonly required?: boolean;
9
+ readonly default?: TDefault | (() => TDefault);
10
+ readonly allowEmpty?: boolean;
11
+ readonly transform?: (value: TOutput) => TOutput;
12
+ readonly sensitive?: boolean;
13
+ };
14
+ type StringRule = BaseRule<string, string> & {
15
+ readonly type: "string";
16
+ };
17
+ type NumberRule = BaseRule<number, number> & {
18
+ readonly type: "number";
19
+ };
20
+ type BooleanRule = BaseRule<boolean, boolean> & {
21
+ readonly type: "boolean";
22
+ };
23
+ type EnumRule<TValues extends readonly string[] = readonly string[]> = BaseRule<TValues[number], TValues[number]> & {
24
+ readonly type: "enum";
25
+ readonly values: TValues;
26
+ };
27
+ type UrlRule = BaseRule<string, string> & {
28
+ readonly type: "url";
29
+ };
30
+ type PortRule = BaseRule<number, number> & {
31
+ readonly type: "port";
32
+ };
33
+ type JsonRule = BaseRule<unknown, unknown> & {
34
+ readonly type: "json";
35
+ };
36
+ type IntRule = BaseRule<number, number> & {
37
+ readonly type: "int";
38
+ };
39
+ type FloatRule = BaseRule<number, number> & {
40
+ readonly type: "float";
41
+ };
42
+ type ArrayRule = BaseRule<string[], string[]> & {
43
+ readonly type: "array";
44
+ readonly separator?: string;
45
+ readonly trimItems?: boolean;
46
+ readonly allowEmptyItems?: boolean;
47
+ };
48
+ type CustomRule<TOutput = unknown> = BaseRule<TOutput, TOutput> & {
49
+ readonly type: "custom";
50
+ readonly parse: (rawValue: string) => TOutput;
51
+ };
52
+ type EmailRule = BaseRule<string, string> & {
53
+ readonly type: "email";
54
+ };
55
+ type DateRule = BaseRule<string | Date, Date> & {
56
+ readonly type: "date";
57
+ };
58
+ type EnvRule = StringRule | NumberRule | BooleanRule | EnumRule<readonly string[]> | UrlRule | IntRule | FloatRule | PortRule | JsonRule | ArrayRule | CustomRule | EmailRule | DateRule;
59
+ type EnvSchemaNode = {
60
+ readonly [key: string]: EnvRule | EnvSchemaNode;
61
+ };
62
+ type EnvSchema = EnvSchemaNode;
63
+ type IsAlwaysPresent<R extends {
64
+ readonly required?: boolean;
65
+ readonly default?: unknown;
66
+ }> = R extends {
67
+ readonly required: true;
68
+ } ? true : R extends {
69
+ readonly default: unknown;
70
+ } ? true : false;
71
+ type IsRuleLike<T> = T extends {
72
+ readonly type: string;
73
+ } ? true : false;
74
+ type RuleOutputFrom<T> = T extends {
75
+ readonly type: "string";
76
+ } ? string : T extends {
77
+ readonly type: "number";
78
+ } ? number : T extends {
79
+ readonly type: "boolean";
80
+ } ? boolean : T extends {
81
+ readonly type: "enum";
82
+ readonly values: readonly (infer TValue)[];
83
+ } ? TValue & string : T extends {
84
+ readonly type: "url";
85
+ } ? string : T extends {
86
+ readonly type: "port";
87
+ } ? number : T extends {
88
+ readonly type: "json";
89
+ } ? unknown : T extends {
90
+ readonly type: "int";
91
+ } ? number : T extends {
92
+ readonly type: "float";
93
+ } ? number : T extends {
94
+ readonly type: "array";
95
+ } ? string[] : T extends {
96
+ readonly type: "email";
97
+ } ? string : T extends {
98
+ readonly type: "date";
99
+ } ? Date : T extends {
100
+ readonly type: "custom";
101
+ readonly parse: (rawValue: string) => infer TOutput;
102
+ } ? TOutput : never;
103
+ type NodeOutput<T> = IsRuleLike<T> extends true ? RuleOutputFrom<T> : T extends Record<string, unknown> ? ParsedEnv<T> : never;
104
+ type HasGuaranteedDescendant<T> = IsRuleLike<T> extends true ? IsAlwaysPresent<T & {
105
+ readonly required?: boolean;
106
+ readonly default?: unknown;
107
+ }> : T extends Record<string, unknown> ? true extends {
108
+ [K in keyof T]: HasGuaranteedDescendant<T[K]>;
109
+ }[keyof T] ? true : false : false;
110
+ type RequiredParsedKeys<S extends Record<string, unknown>> = {
111
+ [K in keyof S]-?: HasGuaranteedDescendant<S[K]> extends true ? K : never;
112
+ }[keyof S];
113
+ type OptionalParsedKeys<S extends Record<string, unknown>> = Exclude<keyof S, RequiredParsedKeys<S>>;
114
+ type ParsedEnv<S extends Record<string, unknown>> = {
115
+ [K in RequiredParsedKeys<S>]: NodeOutput<S[K]>;
116
+ } & {
117
+ [K in OptionalParsedKeys<S>]?: NodeOutput<S[K]>;
118
+ };
119
+ type EnvSource = Record<string, string | undefined>;
120
+ type LoadedEnvFiles = {
121
+ base: EnvSource;
122
+ local: EnvSource;
123
+ environment: EnvSource;
124
+ custom: EnvSource;
125
+ };
126
+ type CreateEnvOptions = {
127
+ source?: EnvSource;
128
+ cwd?: string;
129
+ nodeEnv?: string;
130
+ envFile?: string;
131
+ strict?: boolean;
132
+ debug?: boolean | EnvDebugOptions;
133
+ };
134
+ type EnvValueSource = "process.env" | ".env" | ".env.local" | ".env.environment" | "custom";
135
+ type EnvTraceEntry = {
136
+ source: EnvValueSource;
137
+ raw: string;
138
+ parsed: unknown;
139
+ };
140
+ type EnvDebugSource = EnvValueSource | "default" | "missing";
141
+ type EnvDebugStatus = "parsed" | "defaulted" | "missing" | "empty" | "issue";
142
+ type EnvDebugDefaultKind = "static" | "function";
143
+ type EnvDebugLoadedFile = {
144
+ source: Exclude<EnvValueSource, "process.env">;
145
+ path?: string;
146
+ keyCount: number;
147
+ };
148
+ type EnvDebugKeyEntry = {
149
+ key: string;
150
+ ruleType: EnvRule["type"];
151
+ source: EnvDebugSource;
152
+ usedDefault: boolean;
153
+ defaultKind?: EnvDebugDefaultKind;
154
+ raw?: string;
155
+ parsed?: unknown;
156
+ status: EnvDebugStatus;
157
+ issue?: EnvValidationIssue;
158
+ };
159
+ type EnvDebugReport = {
160
+ loadedFiles: EnvDebugLoadedFile[];
161
+ keys: EnvDebugKeyEntry[];
162
+ };
163
+ type EnvDebugOptions = {
164
+ logger?: (report: EnvDebugReport) => void;
165
+ };
166
+ type ValidateExampleEnvFileOptions = {
167
+ cwd?: string;
168
+ exampleFile?: string;
169
+ };
170
+
171
+ declare function createEnv<S extends EnvSchema>(schema: S, options?: CreateEnvOptions): ParsedEnv<S>;
172
+
173
+ declare function defineEnv<const S extends EnvSchema>(schema: S): S;
174
+
175
+ declare class EnvValidationError extends Error {
176
+ readonly issues: EnvValidationIssue[];
177
+ constructor(issues: EnvValidationIssue[]);
178
+ }
179
+
180
+ declare function maskEnv<S extends EnvSchema>(schema: S, env: ParsedEnv<S>): Partial<Record<keyof S, unknown>>;
181
+
182
+ declare function mergeSources(files: LoadedEnvFiles, runtimeValues?: EnvSource): EnvSource;
183
+
184
+ declare function traceEnv<S extends EnvSchema>(schema: S, sources: Record<string, {
185
+ source: string;
186
+ raw: string;
187
+ }>, env: ParsedEnv<S>): Partial<Record<keyof S, EnvTraceEntry>>;
188
+
189
+ declare function validateExampleEnv(schema: EnvSchema, exampleSource: EnvSource): EnvValidationIssue[];
190
+
191
+ declare function readEnvFileSource(filePath: string): EnvSource;
192
+ declare function resolveExampleEnvPath(cwd?: string, exampleFile?: string): string;
193
+
194
+ declare function validateExampleEnvFile(schema: EnvSchema, options?: ValidateExampleEnvFileOptions): EnvValidationIssue[];
195
+
196
+ export { type CreateEnvOptions, type EnvDebugDefaultKind, type EnvDebugKeyEntry, type EnvDebugLoadedFile, type EnvDebugOptions, type EnvDebugReport, type EnvDebugSource, type EnvDebugStatus, type EnvRule, type EnvSchema, EnvValidationError, type EnvValidationIssue, type EnvValidationIssueCode, type ParsedEnv, type ValidateExampleEnvFileOptions, createEnv, defineEnv, maskEnv, mergeSources, readEnvFileSource, resolveExampleEnvPath, traceEnv, validateExampleEnv, validateExampleEnvFile };
@@ -0,0 +1,196 @@
1
+ type EnvValidationIssueCode = "missing" | "empty" | "invalid_enum" | "invalid_number" | "invalid_boolean" | "invalid_url" | "invalid_port" | "invalid_json" | "invalid_array" | "invalid_custom" | "invalid_email" | "invalid_date" | "invalid_default" | "unknown_key" | "missing_example_key" | "unknown_example_key";
2
+ type EnvValidationIssue = {
3
+ key: string;
4
+ code: EnvValidationIssueCode;
5
+ message: string;
6
+ };
7
+ type BaseRule<TDefault = unknown, TOutput = TDefault> = {
8
+ readonly required?: boolean;
9
+ readonly default?: TDefault | (() => TDefault);
10
+ readonly allowEmpty?: boolean;
11
+ readonly transform?: (value: TOutput) => TOutput;
12
+ readonly sensitive?: boolean;
13
+ };
14
+ type StringRule = BaseRule<string, string> & {
15
+ readonly type: "string";
16
+ };
17
+ type NumberRule = BaseRule<number, number> & {
18
+ readonly type: "number";
19
+ };
20
+ type BooleanRule = BaseRule<boolean, boolean> & {
21
+ readonly type: "boolean";
22
+ };
23
+ type EnumRule<TValues extends readonly string[] = readonly string[]> = BaseRule<TValues[number], TValues[number]> & {
24
+ readonly type: "enum";
25
+ readonly values: TValues;
26
+ };
27
+ type UrlRule = BaseRule<string, string> & {
28
+ readonly type: "url";
29
+ };
30
+ type PortRule = BaseRule<number, number> & {
31
+ readonly type: "port";
32
+ };
33
+ type JsonRule = BaseRule<unknown, unknown> & {
34
+ readonly type: "json";
35
+ };
36
+ type IntRule = BaseRule<number, number> & {
37
+ readonly type: "int";
38
+ };
39
+ type FloatRule = BaseRule<number, number> & {
40
+ readonly type: "float";
41
+ };
42
+ type ArrayRule = BaseRule<string[], string[]> & {
43
+ readonly type: "array";
44
+ readonly separator?: string;
45
+ readonly trimItems?: boolean;
46
+ readonly allowEmptyItems?: boolean;
47
+ };
48
+ type CustomRule<TOutput = unknown> = BaseRule<TOutput, TOutput> & {
49
+ readonly type: "custom";
50
+ readonly parse: (rawValue: string) => TOutput;
51
+ };
52
+ type EmailRule = BaseRule<string, string> & {
53
+ readonly type: "email";
54
+ };
55
+ type DateRule = BaseRule<string | Date, Date> & {
56
+ readonly type: "date";
57
+ };
58
+ type EnvRule = StringRule | NumberRule | BooleanRule | EnumRule<readonly string[]> | UrlRule | IntRule | FloatRule | PortRule | JsonRule | ArrayRule | CustomRule | EmailRule | DateRule;
59
+ type EnvSchemaNode = {
60
+ readonly [key: string]: EnvRule | EnvSchemaNode;
61
+ };
62
+ type EnvSchema = EnvSchemaNode;
63
+ type IsAlwaysPresent<R extends {
64
+ readonly required?: boolean;
65
+ readonly default?: unknown;
66
+ }> = R extends {
67
+ readonly required: true;
68
+ } ? true : R extends {
69
+ readonly default: unknown;
70
+ } ? true : false;
71
+ type IsRuleLike<T> = T extends {
72
+ readonly type: string;
73
+ } ? true : false;
74
+ type RuleOutputFrom<T> = T extends {
75
+ readonly type: "string";
76
+ } ? string : T extends {
77
+ readonly type: "number";
78
+ } ? number : T extends {
79
+ readonly type: "boolean";
80
+ } ? boolean : T extends {
81
+ readonly type: "enum";
82
+ readonly values: readonly (infer TValue)[];
83
+ } ? TValue & string : T extends {
84
+ readonly type: "url";
85
+ } ? string : T extends {
86
+ readonly type: "port";
87
+ } ? number : T extends {
88
+ readonly type: "json";
89
+ } ? unknown : T extends {
90
+ readonly type: "int";
91
+ } ? number : T extends {
92
+ readonly type: "float";
93
+ } ? number : T extends {
94
+ readonly type: "array";
95
+ } ? string[] : T extends {
96
+ readonly type: "email";
97
+ } ? string : T extends {
98
+ readonly type: "date";
99
+ } ? Date : T extends {
100
+ readonly type: "custom";
101
+ readonly parse: (rawValue: string) => infer TOutput;
102
+ } ? TOutput : never;
103
+ type NodeOutput<T> = IsRuleLike<T> extends true ? RuleOutputFrom<T> : T extends Record<string, unknown> ? ParsedEnv<T> : never;
104
+ type HasGuaranteedDescendant<T> = IsRuleLike<T> extends true ? IsAlwaysPresent<T & {
105
+ readonly required?: boolean;
106
+ readonly default?: unknown;
107
+ }> : T extends Record<string, unknown> ? true extends {
108
+ [K in keyof T]: HasGuaranteedDescendant<T[K]>;
109
+ }[keyof T] ? true : false : false;
110
+ type RequiredParsedKeys<S extends Record<string, unknown>> = {
111
+ [K in keyof S]-?: HasGuaranteedDescendant<S[K]> extends true ? K : never;
112
+ }[keyof S];
113
+ type OptionalParsedKeys<S extends Record<string, unknown>> = Exclude<keyof S, RequiredParsedKeys<S>>;
114
+ type ParsedEnv<S extends Record<string, unknown>> = {
115
+ [K in RequiredParsedKeys<S>]: NodeOutput<S[K]>;
116
+ } & {
117
+ [K in OptionalParsedKeys<S>]?: NodeOutput<S[K]>;
118
+ };
119
+ type EnvSource = Record<string, string | undefined>;
120
+ type LoadedEnvFiles = {
121
+ base: EnvSource;
122
+ local: EnvSource;
123
+ environment: EnvSource;
124
+ custom: EnvSource;
125
+ };
126
+ type CreateEnvOptions = {
127
+ source?: EnvSource;
128
+ cwd?: string;
129
+ nodeEnv?: string;
130
+ envFile?: string;
131
+ strict?: boolean;
132
+ debug?: boolean | EnvDebugOptions;
133
+ };
134
+ type EnvValueSource = "process.env" | ".env" | ".env.local" | ".env.environment" | "custom";
135
+ type EnvTraceEntry = {
136
+ source: EnvValueSource;
137
+ raw: string;
138
+ parsed: unknown;
139
+ };
140
+ type EnvDebugSource = EnvValueSource | "default" | "missing";
141
+ type EnvDebugStatus = "parsed" | "defaulted" | "missing" | "empty" | "issue";
142
+ type EnvDebugDefaultKind = "static" | "function";
143
+ type EnvDebugLoadedFile = {
144
+ source: Exclude<EnvValueSource, "process.env">;
145
+ path?: string;
146
+ keyCount: number;
147
+ };
148
+ type EnvDebugKeyEntry = {
149
+ key: string;
150
+ ruleType: EnvRule["type"];
151
+ source: EnvDebugSource;
152
+ usedDefault: boolean;
153
+ defaultKind?: EnvDebugDefaultKind;
154
+ raw?: string;
155
+ parsed?: unknown;
156
+ status: EnvDebugStatus;
157
+ issue?: EnvValidationIssue;
158
+ };
159
+ type EnvDebugReport = {
160
+ loadedFiles: EnvDebugLoadedFile[];
161
+ keys: EnvDebugKeyEntry[];
162
+ };
163
+ type EnvDebugOptions = {
164
+ logger?: (report: EnvDebugReport) => void;
165
+ };
166
+ type ValidateExampleEnvFileOptions = {
167
+ cwd?: string;
168
+ exampleFile?: string;
169
+ };
170
+
171
+ declare function createEnv<S extends EnvSchema>(schema: S, options?: CreateEnvOptions): ParsedEnv<S>;
172
+
173
+ declare function defineEnv<const S extends EnvSchema>(schema: S): S;
174
+
175
+ declare class EnvValidationError extends Error {
176
+ readonly issues: EnvValidationIssue[];
177
+ constructor(issues: EnvValidationIssue[]);
178
+ }
179
+
180
+ declare function maskEnv<S extends EnvSchema>(schema: S, env: ParsedEnv<S>): Partial<Record<keyof S, unknown>>;
181
+
182
+ declare function mergeSources(files: LoadedEnvFiles, runtimeValues?: EnvSource): EnvSource;
183
+
184
+ declare function traceEnv<S extends EnvSchema>(schema: S, sources: Record<string, {
185
+ source: string;
186
+ raw: string;
187
+ }>, env: ParsedEnv<S>): Partial<Record<keyof S, EnvTraceEntry>>;
188
+
189
+ declare function validateExampleEnv(schema: EnvSchema, exampleSource: EnvSource): EnvValidationIssue[];
190
+
191
+ declare function readEnvFileSource(filePath: string): EnvSource;
192
+ declare function resolveExampleEnvPath(cwd?: string, exampleFile?: string): string;
193
+
194
+ declare function validateExampleEnvFile(schema: EnvSchema, options?: ValidateExampleEnvFileOptions): EnvValidationIssue[];
195
+
196
+ export { type CreateEnvOptions, type EnvDebugDefaultKind, type EnvDebugKeyEntry, type EnvDebugLoadedFile, type EnvDebugOptions, type EnvDebugReport, type EnvDebugSource, type EnvDebugStatus, type EnvRule, type EnvSchema, EnvValidationError, type EnvValidationIssue, type EnvValidationIssueCode, type ParsedEnv, type ValidateExampleEnvFileOptions, createEnv, defineEnv, maskEnv, mergeSources, readEnvFileSource, resolveExampleEnvPath, traceEnv, validateExampleEnv, validateExampleEnvFile };