@xlameiro/env-typegen 0.1.1 → 0.1.2
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.
- package/CHANGELOG.md +40 -2
- package/README.md +37 -20
- package/dist/cli.js +123 -44
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +63 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -6
- package/dist/index.d.ts +24 -6
- package/dist/index.js +63 -33
- package/dist/index.js.map +1 -1
- package/package.json +19 -23
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parser/comment-parser.ts","../src/inferrer/rules.ts","../src/inferrer/type-inferrer.ts","../src/parser/env-parser.ts","../src/generators/typescript-generator.ts","../src/generators/zod-generator.ts","../src/generators/declaration-generator.ts","../src/generators/t3-generator.ts","../src/config.ts","../src/utils/file.ts","../src/utils/format.ts","../src/utils/logger.ts","../src/pipeline.ts"],"names":["readFileSync","path","existsSync","pathToFileURL","readFile","mkdir","writeFile","format","green"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { EnvVarType } from \"./types.js\";\n\n/**\n * Structured annotations extracted from a JSDoc-style comment block\n * that precedes an env var declaration.\n *\n * @example\n * ```\n * # @description PostgreSQL connection string\n * # @required\n * # @type string\n * DATABASE_URL=\n * ```\n */\nexport type CommentAnnotations = {\n /** Type explicitly declared with `@type` in the comment block */\n annotatedType?: EnvVarType;\n\n /** Description from `@description` or the first free-form comment line */\n description?: string;\n\n /** true when the `@required` annotation is present in the comment block */\n isRequired: boolean;\n};\n\nconst VALID_ENV_VAR_TYPES = new Set<string>([\n \"string\",\n \"number\",\n \"boolean\",\n \"url\",\n \"email\",\n \"semver\",\n \"json\",\n \"unknown\",\n]);\n\nfunction isEnvVarType(value: string): value is EnvVarType {\n return VALID_ENV_VAR_TYPES.has(value);\n}\n\n/**\n * Parse a block of consecutive comment lines (each starting with `#`) and\n * extract JSDoc-style annotations.\n *\n * Recognised annotations:\n * - `@description <text>` — sets the variable description\n * - `@required` — marks the variable as required regardless of value\n * - `@optional` — informational (isRequired stays false)\n * - `@type <EnvVarType>` — overrides the inferred type\n *\n * Non-annotation comment lines act as a fallback description when no\n * `@description` annotation is present (first non-empty line wins).\n *\n * @param lines - Raw comment lines from the .env file, e.g. `[\"# @required\"]`\n */\nexport function parseCommentBlock(lines: readonly string[]): CommentAnnotations {\n let annotatedType: EnvVarType | undefined;\n let description: string | undefined;\n let isRequired = false;\n\n for (const line of lines) {\n // Strip the leading `#` and any trailing whitespace\n const content = line.replace(/^#\\s*/, \"\").trimEnd();\n\n if (content.startsWith(\"@description \")) {\n description = content.slice(\"@description \".length).trim();\n } else if (content.startsWith(\"@type \")) {\n const typeStr = content.slice(\"@type \".length).trim();\n if (isEnvVarType(typeStr)) {\n annotatedType = typeStr;\n }\n } else if (content.trim() === \"@required\") {\n isRequired = true;\n } else if (content.trim() === \"@optional\") {\n // Informational only — isRequired stays false (which is already the default)\n } else if (description === undefined && content.trim().length > 0) {\n // First non-empty, non-annotation line is a fallback description\n description = content.trim();\n }\n }\n\n const result: CommentAnnotations = { isRequired };\n if (annotatedType !== undefined) result.annotatedType = annotatedType;\n if (description !== undefined) result.description = description;\n return result;\n}\n","import type { EnvVarType } from \"../parser/types.js\";\n\nexport type InferenceRule = {\n id: string;\n priority: number;\n match: (key: string, value: string) => boolean;\n type: EnvVarType;\n};\n\nexport const inferenceRules: readonly InferenceRule[] = [\n {\n id: \"P2_key_url_suffix\",\n priority: 2,\n match: (key: string) => key.toUpperCase().endsWith(\"_URL\"),\n type: \"url\",\n },\n {\n id: \"P3_key_email_from_suffix\",\n priority: 3,\n match: (key: string) => {\n const normalizedKey = key.toUpperCase();\n return normalizedKey.endsWith(\"_EMAIL\") || normalizedKey.endsWith(\"_FROM\");\n },\n type: \"email\",\n },\n {\n id: \"P4_boolean_prefix\",\n priority: 4,\n match: (key: string) => {\n const normalizedKey = key.toUpperCase();\n return (\n normalizedKey.startsWith(\"ENABLE_\") ||\n normalizedKey.startsWith(\"DISABLE_\") ||\n normalizedKey.startsWith(\"IS_\") ||\n normalizedKey.startsWith(\"DEBUG\") ||\n normalizedKey.startsWith(\"FEATURE_\")\n );\n },\n type: \"boolean\",\n },\n {\n id: \"P5_key_port\",\n priority: 5,\n match: (key: string) => {\n const normalizedKey = key.toUpperCase();\n return normalizedKey.endsWith(\"_PORT\") || normalizedKey === \"PORT\";\n },\n type: \"number\",\n },\n {\n id: \"P6_empty_unknown\",\n priority: 6,\n match: (_key: string, value: string) => value.length === 0,\n type: \"unknown\",\n },\n {\n id: \"P7_boolean_literal\",\n priority: 7,\n match: (_key: string, value: string) => {\n const lower = value.toLowerCase();\n return lower === \"true\" || lower === \"false\";\n },\n type: \"boolean\",\n },\n {\n id: \"P8_numeric_literal\",\n priority: 8,\n match: (_key: string, value: string) => /^\\d+(\\.\\d+)?$/.test(value),\n type: \"number\",\n },\n {\n id: \"P9_semver\",\n priority: 9,\n match: (_key: string, value: string) => /^\\d+\\.\\d+\\.\\d+/.test(value),\n type: \"semver\",\n },\n {\n id: \"P10_url_scheme\",\n priority: 10,\n match: (_key: string, value: string) => /^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\//.test(value),\n type: \"url\",\n },\n {\n id: \"P11_email_literal\",\n priority: 11,\n match: (_key: string, value: string) => /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(value),\n type: \"email\",\n },\n {\n id: \"P12_json_object_array\",\n priority: 12,\n match: (_key: string, value: string) => {\n try {\n const parsed: unknown = JSON.parse(value);\n return typeof parsed === \"object\" && parsed !== null;\n } catch {\n return false;\n }\n },\n type: \"json\",\n },\n] as const;\n","import type { EnvVarType } from \"../parser/types.js\";\nimport { inferenceRules } from \"./rules.js\";\n\nexport type InferTypeOptions = {\n fallbackType?: EnvVarType;\n};\n\nconst sortedRules = [...inferenceRules].sort((left, right) => left.priority - right.priority);\n\nexport function inferType(key: string, value: string, options?: InferTypeOptions): EnvVarType {\n for (const rule of sortedRules) {\n if (rule.match(key, value)) {\n return rule.type;\n }\n }\n\n return options?.fallbackType ?? \"string\";\n}\n\nexport function inferTypesFromParsedVars(\n parsed: { vars: Array<{ key: string; rawValue: string }> },\n options?: InferTypeOptions,\n): EnvVarType[] {\n return parsed.vars.map((item) => inferType(item.key, item.rawValue, options));\n}","import { readFileSync } from \"node:fs\";\n\nimport { inferType } from \"../inferrer/type-inferrer.js\";\nimport { parseCommentBlock } from \"./comment-parser.js\";\nimport type { ParsedEnvFile, ParsedEnvVar } from \"./types.js\";\n\nexport { inferType } from \"../inferrer/type-inferrer.js\";\n\n/** Matches a valid env var declaration: KEY=VALUE (value may be empty) */\nconst ENV_VAR_RE = /^([A-Z_][A-Z0-9_]*)=(.*)$/;\n\n/**\n * Matches a section header comment of the form:\n * `# --- SectionName ---` or `# === SectionName ===`\n */\nconst SECTION_HEADER_RE = /^#\\s+[-=]{3,}\\s+(.+?)\\s+[-=]{3,}\\s*$/;\n\n/**\n * Parse the string content of a `.env.example` file into a `ParsedEnvFile`.\n *\n * Exposed separately from `parseEnvFile` to enable unit testing without\n * filesystem access.\n *\n * @param content - Raw file content as a UTF-8 string\n * @param filePath - Used to populate `ParsedEnvFile.filePath` only\n */\nexport function parseEnvFileContent(content: string, filePath: string): ParsedEnvFile {\n const lines = content.split(\"\\n\");\n const vars: ParsedEnvVar[] = [];\n const groups: string[] = [];\n\n let currentGroup: string | undefined;\n let commentBlock: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const lineNumber = i + 1;\n const trimmed = line.trim();\n\n // Blank line — break the comment block association\n if (trimmed === \"\") {\n commentBlock = [];\n continue;\n }\n\n // Section header — update current group and reset comment block\n const sectionMatch = SECTION_HEADER_RE.exec(trimmed);\n if (sectionMatch !== null) {\n const groupName = (sectionMatch[1] ?? \"\").trim();\n currentGroup = groupName;\n if (!groups.includes(groupName)) {\n groups.push(groupName);\n }\n commentBlock = [];\n continue;\n }\n\n // Comment line — accumulate for the next env var\n if (trimmed.startsWith(\"#\")) {\n commentBlock.push(line);\n continue;\n }\n\n // Env var declaration\n const envMatch = ENV_VAR_RE.exec(trimmed);\n if (envMatch !== null) {\n const key = envMatch[1] ?? \"\";\n const rawValue = envMatch[2] ?? \"\";\n const annotations = parseCommentBlock(commentBlock);\n const inferredType = inferType(key, rawValue);\n const isRequired = rawValue.length > 0 || annotations.isRequired;\n const isOptional = rawValue.length === 0 && !annotations.isRequired;\n const isClientSide = key.startsWith(\"NEXT_PUBLIC_\");\n\n const parsedVar: ParsedEnvVar = {\n key,\n rawValue,\n inferredType,\n isRequired,\n isOptional,\n isClientSide,\n lineNumber,\n };\n\n // Only set optional fields when they have a value (exactOptionalPropertyTypes)\n if (annotations.annotatedType !== undefined) {\n parsedVar.annotatedType = annotations.annotatedType;\n }\n if (annotations.description !== undefined) {\n parsedVar.description = annotations.description;\n }\n if (currentGroup !== undefined) {\n parsedVar.group = currentGroup;\n }\n\n vars.push(parsedVar);\n commentBlock = [];\n } else {\n // Unrecognised line — reset comment block\n commentBlock = [];\n }\n }\n\n return { filePath, vars, groups };\n}\n\n/**\n * Read and parse a `.env.example` file from disk.\n *\n * @param filePath - Absolute or relative path to the file\n */\nexport function parseEnvFile(filePath: string): ParsedEnvFile {\n const content = readFileSync(filePath, \"utf8\");\n return parseEnvFileContent(content, filePath);\n}\n","import path from \"node:path\";\n\nimport type { EnvVarType, ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Maps an EnvVarType to its TypeScript primitive equivalent.\n * url, email, semver, json, and unknown all map to `string` because\n * TypeScript has no built-in branded types for these.\n */\nfunction toTsType(envVarType: EnvVarType): string {\n if (envVarType === \"number\") return \"number\";\n if (envVarType === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Generates a TypeScript source file from a parsed .env.example file.\n *\n * Output structure:\n * 1. Header comments — generated-by notice, source file name, ISO timestamp\n * 2. `declare namespace NodeJS { interface ProcessEnv { ... } }` — global augmentation\n * where all properties are typed as `readonly string` (the runtime reality).\n * Number and boolean vars include an inline coercion hint comment.\n * 3. `export type EnvVars = { ... }` — typed module export using semantic types\n * (number, boolean, string).\n * 4. `ServerEnvVars` / `ClientEnvVars` — emitted only when `NEXT_PUBLIC_` vars exist.\n *\n * The output is valid as both a `.ts` and `.d.ts` file.\n * For an ambient-only `.d.ts` (without `export type` statements), use\n * `generateDeclaration` instead.\n *\n * `annotatedType` takes precedence over `inferredType` when both are set.\n */\nexport function generateTypeScriptTypes(parsed: ParsedEnvFile): string {\n const clientVars = parsed.vars.filter((v) => v.isClientSide);\n const hasClientVars = clientVars.length > 0;\n const fileName = path.basename(parsed.filePath);\n const timestamp = new Date().toISOString();\n const lines: string[] = [];\n\n // Header\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push(`// Source: ${fileName}`);\n lines.push(`// Generated at: ${timestamp}`);\n lines.push(\"\");\n\n // NodeJS.ProcessEnv augmentation — all props are runtime strings with optional coercion hints\n lines.push(\"declare namespace NodeJS {\");\n lines.push(\" interface ProcessEnv {\");\n for (const variable of parsed.vars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const optional = variable.isOptional ? \"?\" : \"\";\n if (variable.description !== undefined) {\n lines.push(` /** ${variable.description} */`);\n }\n let propLine = ` readonly ${variable.key}${optional}: string;`;\n if (effectiveType === \"number\") {\n propLine += ` // coerce to number: Number(process.env.${variable.key})`;\n } else if (effectiveType === \"boolean\") {\n propLine += ` // coerce to boolean: process.env.${variable.key} === 'true'`;\n }\n lines.push(propLine);\n }\n lines.push(\" }\");\n lines.push(\"}\");\n lines.push(\"\");\n\n // EnvVars type with semantic TypeScript types\n lines.push(\"export type EnvVars = {\");\n for (const variable of parsed.vars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const tsType = toTsType(effectiveType);\n const optional = variable.isOptional ? \"?\" : \"\";\n lines.push(` ${variable.key}${optional}: ${tsType};`);\n }\n lines.push(\"};\");\n\n // ServerEnvVars / ClientEnvVars — only emitted when NEXT_PUBLIC_ vars exist\n if (hasClientVars) {\n const clientKeyUnion = clientVars.map((v) => `\"${v.key}\"`).join(\" | \");\n lines.push(\"\");\n lines.push(`export type ServerEnvVars = Omit<EnvVars, ${clientKeyUnion}>;`);\n lines.push(`export type ClientEnvVars = Pick<EnvVars, ${clientKeyUnion}>;`);\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Generates a runtime `validateEnv()` function that throws when any required\n * environment variable is absent from `process.env`.\n */\nexport function generateEnvValidation(parsed: ParsedEnvFile): string {\n const required = parsed.vars.filter((v) => v.isRequired).map((v) => v.key);\n const lines: string[] = [];\n\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push(\"\");\n lines.push(\"export function validateEnv(): void {\");\n\n if (required.length === 0) {\n lines.push(\" // No required environment variables defined\");\n } else {\n const keyList = required.map((k) => `\"${k}\"`).join(\", \");\n lines.push(` const required = [${keyList}];`);\n lines.push(\" for (const key of required) {\");\n lines.push(\" if (!process.env[key]) {\");\n lines.push(\" throw new Error(`Missing required environment variable: ${key}`);\");\n lines.push(\" }\");\n lines.push(\" }\");\n }\n\n lines.push(\"}\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import type { EnvVarType, ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Maps an EnvVarType to its Zod schema expression.\n *\n * - `number` → `z.coerce.number()` (env vars are strings; coerce handles the cast)\n * - `boolean` → `z.coerce.boolean()` (env vars are strings; coerce handles truthy cast)\n * - `url` → `z.string().url()`\n * - `email` → `z.string().email()`\n * - everything else → `z.string()` (string | semver | json | unknown)\n */\nfunction toZodType(envVarType: EnvVarType): string {\n if (envVarType === \"number\") return \"z.coerce.number()\";\n if (envVarType === \"boolean\") return \"z.coerce.boolean()\";\n if (envVarType === \"url\") return \"z.string().url()\";\n if (envVarType === \"email\") return \"z.string().email()\";\n return \"z.string()\";\n}\n\n/**\n * Generates a Zod schema file from a parsed .env.example file.\n *\n * Output structure:\n * ```\n * // Generated by env-typegen — do not edit manually\n * import { z } from \"zod\";\n *\n * export const serverEnvSchema = z.object({\n * DATABASE_URL: z.string().url(),\n * PORT: z.coerce.number(),\n * });\n *\n * export const clientEnvSchema = z.object({\n * NEXT_PUBLIC_API_URL: z.string().url(),\n * });\n *\n * export const envSchema = serverEnvSchema.merge(clientEnvSchema);\n * export type Env = z.infer<typeof envSchema>;\n * ```\n *\n * - Server-side vars (non-`NEXT_PUBLIC_`) go into `serverEnvSchema`\n * - Client-side vars (`NEXT_PUBLIC_` prefix) go into `clientEnvSchema`\n * - `envSchema` is the merged union of both, for full-stack validation\n * - `annotatedType` takes precedence over `inferredType` when both are set\n * - Optional vars have `.optional()` appended to their Zod expression\n */\nexport function generateZodSchema(parsed: ParsedEnvFile): string {\n const serverVars = parsed.vars.filter((v) => !v.isClientSide);\n const clientVars = parsed.vars.filter((v) => v.isClientSide);\n const lines: string[] = [];\n\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push('import { z } from \"zod\";');\n lines.push(\"\");\n\n // serverEnvSchema — non-NEXT_PUBLIC_ vars\n lines.push(\"export const serverEnvSchema = z.object({\");\n for (const variable of serverVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const zodExpr = variable.isOptional\n ? `${toZodType(effectiveType)}.optional()`\n : toZodType(effectiveType);\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\"});\");\n lines.push(\"\");\n\n // clientEnvSchema — NEXT_PUBLIC_ vars\n lines.push(\"export const clientEnvSchema = z.object({\");\n for (const variable of clientVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const zodExpr = variable.isOptional\n ? `${toZodType(effectiveType)}.optional()`\n : toZodType(effectiveType);\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\"});\");\n lines.push(\"\");\n\n // Merged schema — the full validation object for use in lib/env.ts\n lines.push(\"export const envSchema = serverEnvSchema.merge(clientEnvSchema);\");\n lines.push(\"export type Env = z.infer<typeof envSchema>;\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import path from \"node:path\";\n\nimport type { ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Generates an ambient `.d.ts` declaration file from a parsed .env.example.\n *\n * Output is a pure `NodeJS.ProcessEnv` augmentation — no `export type` statements.\n * This makes the file valid as a global ambient declaration that can be dropped\n * into `lib/` or `types/` without affecting module resolution.\n *\n * Output structure:\n * ```\n * // Generated by env-typegen — do not edit manually\n * // Source: .env.example\n *\n * declare namespace NodeJS {\n * interface ProcessEnv {\n * readonly KEY: string; // all vars are runtime strings\n * readonly OPT?: string; // optional vars use ?: string\n * readonly NUM: string; // coerce to number: Number(process.env.NUM)\n * readonly FLAG: string; // coerce to boolean: process.env.FLAG === 'true'\n * }\n * }\n * ```\n *\n * For a `.ts` output with typed `export type EnvVars` / `ServerEnvVars` /\n * `ClientEnvVars`, use `generateTypeScriptTypes` instead.\n *\n * - `ProcessEnv` uses `readonly string` for every variable (runtime reality)\n * - Number and boolean vars include an inline coercion hint comment\n * - `annotatedType` takes precedence over `inferredType`\n */\nexport function generateDeclaration(parsed: ParsedEnvFile): string {\n const fileName = path.basename(parsed.filePath);\n const lines: string[] = [];\n\n // Header\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push(`// Source: ${fileName}`);\n lines.push(\"\");\n\n // NodeJS.ProcessEnv augmentation — ambient only, no exports\n lines.push(\"declare namespace NodeJS {\");\n lines.push(\" interface ProcessEnv {\");\n for (const variable of parsed.vars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const optional = variable.isOptional ? \"?\" : \"\";\n if (variable.description !== undefined) {\n lines.push(` /** ${variable.description} */`);\n }\n let propLine = ` readonly ${variable.key}${optional}: string;`;\n if (effectiveType === \"number\") {\n propLine += ` // coerce to number: Number(process.env.${variable.key})`;\n } else if (effectiveType === \"boolean\") {\n propLine += ` // coerce to boolean: process.env.${variable.key} === 'true'`;\n }\n lines.push(propLine);\n }\n lines.push(\" }\");\n lines.push(\"}\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import type { EnvVarType, ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Maps an EnvVarType to its Zod schema expression for use in t3-env createEnv().\n *\n * Note: boolean uses `z.coerce.boolean()` here (not the `.transform()` approach\n * in the standalone zod-generator) because @t3-oss/env-nextjs handles coercion\n * internally with `z.coerce`.\n */\nfunction toT3ZodType(envVarType: EnvVarType): string {\n if (envVarType === \"number\") return \"z.coerce.number()\";\n if (envVarType === \"boolean\") return \"z.coerce.boolean()\";\n if (envVarType === \"url\") return \"z.string().url()\";\n if (envVarType === \"email\") return \"z.string().email()\";\n return \"z.string()\";\n}\n\n/**\n * Generates a `@t3-oss/env-nextjs` configuration file from a parsed .env.example.\n *\n * Output structure:\n * ```\n * import { createEnv } from \"@t3-oss/env-nextjs\";\n * import { z } from \"zod\";\n *\n * export const env = createEnv({\n * server: { /* non-NEXT_PUBLIC_ vars *\\/ },\n * client: { /* NEXT_PUBLIC_ vars *\\/ },\n * runtimeEnv: { /* all vars mapped to process.env *\\/ },\n * });\n * ```\n *\n * - `server:` is omitted when there are no server-side vars\n * - `client:` is omitted when there are no client-side vars (NEXT_PUBLIC_ prefix)\n * - `runtimeEnv:` always includes all vars\n * - `annotatedType` takes precedence over `inferredType`\n * - Optional vars have `.optional()` appended\n * - Vars with a description have `.describe(\"text\")` appended (before `.optional()`)\n */\nexport function generateT3Env(parsed: ParsedEnvFile): string {\n const serverVars = parsed.vars.filter((v) => !v.isClientSide);\n const clientVars = parsed.vars.filter((v) => v.isClientSide);\n const lines: string[] = [];\n\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push('import { createEnv } from \"@t3-oss/env-nextjs\";');\n lines.push('import { z } from \"zod\";');\n lines.push(\"\");\n lines.push(\"export const env = createEnv({\");\n\n if (serverVars.length > 0) {\n lines.push(\" server: {\");\n for (const variable of serverVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n let zodExpr = toT3ZodType(effectiveType);\n if (variable.description !== undefined) {\n zodExpr += `.describe(\"${variable.description}\")`;\n }\n if (variable.isOptional) {\n zodExpr += \".optional()\";\n }\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\" },\");\n }\n\n if (clientVars.length > 0) {\n lines.push(\" client: {\");\n for (const variable of clientVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n let zodExpr = toT3ZodType(effectiveType);\n if (variable.description !== undefined) {\n zodExpr += `.describe(\"${variable.description}\")`;\n }\n if (variable.isOptional) {\n zodExpr += \".optional()\";\n }\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\" },\");\n }\n\n lines.push(\" runtimeEnv: {\");\n for (const variable of parsed.vars) {\n lines.push(` ${variable.key}: process.env.${variable.key},`);\n }\n lines.push(\" },\");\n lines.push(\"});\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\n/** Generator identifiers supported by env-typegen. */\nexport type GeneratorName = \"typescript\" | \"zod\" | \"t3\" | \"declaration\";\n\n/** Configuration shape accepted by env-typegen's CLI and programmatic API. */\nexport type EnvTypegenConfig = {\n /** Path to the .env.example file to parse. */\n input: string;\n /** Output directory for generated files. Defaults to the input file's directory. */\n output?: string;\n /** Which generators to run. When omitted, all four generators run. */\n generators?: GeneratorName[];\n /** Format generated output with prettier. Defaults to true. */\n format?: boolean;\n};\n\n/** Config file names searched in order when calling loadConfig(). */\nconst CONFIG_FILE_NAMES = [\n \"env-typegen.config.ts\",\n \"env-typegen.config.mjs\",\n \"env-typegen.config.js\",\n] as const;\n\n/**\n * Type-safe config helper.\n * Returns the config object unchanged — exists purely for IDE autocompletion\n * and compile-time validation of the config shape.\n */\nexport function defineConfig(config: EnvTypegenConfig): EnvTypegenConfig {\n return config;\n}\n\n/**\n * Loads env-typegen config by searching for a config file in `cwd`.\n * Searches for env-typegen.config.ts → .mjs → .js in order.\n * Returns `undefined` when no config file is found.\n */\nexport async function loadConfig(\n cwd: string = process.cwd(),\n): Promise<EnvTypegenConfig | undefined> {\n for (const name of CONFIG_FILE_NAMES) {\n const filePath = path.resolve(cwd, name);\n if (existsSync(filePath)) {\n const fileUrl = pathToFileURL(filePath).href;\n const mod = (await import(fileUrl)) as { default?: EnvTypegenConfig };\n return mod.default;\n }\n }\n return undefined;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Reads a .env file from `filePath` and returns its full text content.\n * Rejects with a Node.js filesystem error if the file does not exist.\n */\nexport async function readEnvFile(filePath: string): Promise<string> {\n return readFile(path.resolve(filePath), \"utf8\");\n}\n\n/**\n * Writes `content` to `filePath`, creating intermediate directories as needed.\n * Overwrites any existing file at that path.\n */\nexport async function writeOutput(filePath: string, content: string): Promise<void> {\n const resolved = path.resolve(filePath);\n await mkdir(path.dirname(resolved), { recursive: true });\n await writeFile(resolved, content, \"utf8\");\n}\n","import { format } from \"prettier\";\n\n/**\n * Formats `content` using prettier with the specified `parser`.\n * Defaults to the \"typescript\" parser, which is correct for all generator outputs.\n * Returns the original content unchanged if prettier throws (e.g., invalid syntax).\n */\nexport async function formatOutput(\n content: string,\n parser: string = \"typescript\",\n): Promise<string> {\n try {\n return await format(content, { parser });\n } catch {\n return content;\n }\n}\n","import { green, red, yellow } from \"picocolors\";\n\n/** Prints a plain informational message to stdout. */\nexport function log(message: string): void {\n console.log(message);\n}\n\n/** Prints a yellow ⚠ warning message to stderr. */\nexport function warn(message: string): void {\n console.warn(yellow(`⚠ ${message}`));\n}\n\n/** Prints a red ✖ error message to stderr. */\nexport function error(message: string): void {\n console.error(red(`✖ ${message}`));\n}\n\n/** Prints a green ✔ success message to stdout. */\nexport function success(message: string): void {\n console.log(green(`✔ ${message}`));\n}\n","import path from \"node:path\";\n\nimport { type GeneratorName } from \"./config.js\";\nimport { generateDeclaration } from \"./generators/declaration-generator.js\";\nimport { generateT3Env } from \"./generators/t3-generator.js\";\nimport { generateTypeScriptTypes } from \"./generators/typescript-generator.js\";\nimport { generateZodSchema } from \"./generators/zod-generator.js\";\nimport { parseEnvFileContent } from \"./parser/env-parser.js\";\nimport type { ParsedEnvFile } from \"./parser/types.js\";\nimport { readEnvFile, writeOutput } from \"./utils/file.js\";\nimport { formatOutput } from \"./utils/format.js\";\nimport { success } from \"./utils/logger.js\";\n\n/** Options accepted by the runGenerate pipeline. */\nexport type RunGenerateOptions = {\n input: string;\n output: string;\n generators: GeneratorName[];\n format: boolean;\n stdout?: boolean;\n dryRun?: boolean;\n silent?: boolean;\n};\n\n/** Derive the output file path for a generator when multiple generators are in use. */\nfunction deriveOutputPath(base: string, generator: GeneratorName, isSingle: boolean): string {\n if (isSingle) return base;\n const ext = path.extname(base);\n const noExt = ext.length > 0 ? base.slice(0, -ext.length) : base;\n // The declaration generator produces ambient TypeScript declarations (.d.ts).\n // Use the correct extension so IDEs and tsc pick it up as a declaration file.\n const baseExt = ext.length > 0 ? ext : \".ts\";\n const outExt = generator === \"declaration\" ? \".d.ts\" : baseExt;\n return `${noExt}.${generator}${outExt}`;\n}\n\n/** Invoke the correct generator function for the given name. */\nfunction buildOutput(generator: GeneratorName, parsed: ParsedEnvFile): string {\n switch (generator) {\n case \"typescript\":\n return generateTypeScriptTypes(parsed);\n case \"zod\":\n return generateZodSchema(parsed);\n case \"t3\":\n return generateT3Env(parsed);\n case \"declaration\":\n return generateDeclaration(parsed);\n }\n}\n\nasync function persistOutput(params: {\n generated: string;\n generator: GeneratorName;\n outputPath: string;\n isSingle: boolean;\n stdout: boolean;\n dryRun: boolean;\n silent: boolean;\n}): Promise<void> {\n const { generated, generator, outputPath, isSingle, stdout, dryRun, silent } = params;\n\n if (stdout) {\n if (isSingle) {\n console.log(generated);\n } else {\n console.log(`// --- ${generator}:${outputPath} ---`);\n console.log(generated);\n }\n return;\n }\n\n if (dryRun) {\n if (!silent) {\n success(`Dry run: ${outputPath}`);\n }\n return;\n }\n\n await writeOutput(outputPath, generated);\n if (!silent) {\n success(`Generated ${outputPath}`);\n }\n}\n\n/**\n * Reads the input file, runs the requested generators, optionally formats each\n * output, and writes the results to disk.\n *\n * Exported for unit testing — call this directly rather than spawning a child process.\n */\nexport async function runGenerate(options: RunGenerateOptions): Promise<void> {\n const {\n input,\n output,\n generators,\n format: shouldFormat,\n stdout = false,\n dryRun = false,\n silent = false,\n } = options;\n const isSingle = generators.length === 1;\n\n const content = await readEnvFile(input);\n const parsed = parseEnvFileContent(content, input);\n\n for (const generator of generators) {\n let generated = buildOutput(generator, parsed);\n if (shouldFormat) {\n generated = await formatOutput(generated);\n }\n const outputPath = deriveOutputPath(output, generator, isSingle);\n await persistOutput({\n generated,\n generator,\n outputPath,\n isSingle,\n stdout,\n dryRun,\n silent,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/parser/comment-parser.ts","../src/inferrer/rules.ts","../src/inferrer/type-inferrer.ts","../src/parser/env-parser.ts","../src/generators/typescript-generator.ts","../src/generators/zod-generator.ts","../src/generators/declaration-generator.ts","../src/generators/t3-generator.ts","../src/config.ts","../src/utils/file.ts","../src/utils/format.ts","../src/utils/logger.ts","../src/pipeline.ts"],"names":["readFileSync","path","existsSync","pathToFileURL","readFile","mkdir","writeFile","format","green","inferenceRules"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { EnvVarType } from \"./types.js\";\n\n/**\n * Structured annotations extracted from a JSDoc-style comment block\n * that precedes an env var declaration.\n *\n * @example\n * ```\n * # @description PostgreSQL connection string\n * # @required\n * # @type string\n * DATABASE_URL=\n * ```\n */\nexport type CommentAnnotations = {\n /** Type explicitly declared with `@type` in the comment block */\n annotatedType?: EnvVarType;\n\n /** Description from `@description` or the first free-form comment line */\n description?: string;\n\n /** true when the `@required` annotation is present in the comment block */\n isRequired: boolean;\n};\n\nconst VALID_ENV_VAR_TYPES = new Set<string>([\n \"string\",\n \"number\",\n \"boolean\",\n \"url\",\n \"email\",\n \"semver\",\n \"json\",\n \"unknown\",\n]);\n\nfunction isEnvVarType(value: string): value is EnvVarType {\n return VALID_ENV_VAR_TYPES.has(value);\n}\n\n/**\n * Parse a block of consecutive comment lines (each starting with `#`) and\n * extract JSDoc-style annotations.\n *\n * Recognised annotations:\n * - `@description <text>` — sets the variable description\n * - `@required` — marks the variable as required regardless of value\n * - `@optional` — informational (isRequired stays false)\n * - `@type <EnvVarType>` — overrides the inferred type\n *\n * Non-annotation comment lines act as a fallback description when no\n * `@description` annotation is present (first non-empty line wins).\n *\n * @param lines - Raw comment lines from the .env file, e.g. `[\"# @required\"]`\n */\nexport function parseCommentBlock(lines: readonly string[]): CommentAnnotations {\n let annotatedType: EnvVarType | undefined;\n let description: string | undefined;\n let isRequired = false;\n\n for (const line of lines) {\n // Strip the leading `#` and any trailing whitespace\n const content = line.replace(/^#\\s*/, \"\").trimEnd();\n\n if (content.startsWith(\"@description \")) {\n description = content.slice(\"@description \".length).trim();\n } else if (content.startsWith(\"@type \")) {\n const typeStr = content.slice(\"@type \".length).trim();\n if (isEnvVarType(typeStr)) {\n annotatedType = typeStr;\n }\n } else if (content.trim() === \"@required\") {\n isRequired = true;\n } else if (content.trim() === \"@optional\") {\n // Informational only — isRequired stays false (which is already the default)\n } else if (description === undefined && content.trim().length > 0) {\n // First non-empty, non-annotation line is a fallback description\n description = content.trim();\n }\n }\n\n const result: CommentAnnotations = { isRequired };\n if (annotatedType !== undefined) result.annotatedType = annotatedType;\n if (description !== undefined) result.description = description;\n return result;\n}\n","import type { EnvVarType } from \"../parser/types.js\";\n\nexport type InferenceRule = {\n id: string;\n priority: number;\n match: (key: string, value: string) => boolean;\n type: EnvVarType;\n};\n\nexport const inferenceRules: readonly InferenceRule[] = [\n {\n id: \"P2_key_url_suffix\",\n priority: 2,\n match: (key: string) => key.toUpperCase().endsWith(\"_URL\"),\n type: \"url\",\n },\n {\n id: \"P3_key_email_from_suffix\",\n priority: 3,\n match: (key: string) => {\n const normalizedKey = key.toUpperCase();\n return normalizedKey.endsWith(\"_EMAIL\") || normalizedKey.endsWith(\"_FROM\");\n },\n type: \"email\",\n },\n {\n id: \"P4_boolean_prefix\",\n priority: 4,\n match: (key: string) => {\n const normalizedKey = key.toUpperCase();\n return (\n normalizedKey.startsWith(\"ENABLE_\") ||\n normalizedKey.startsWith(\"DISABLE_\") ||\n normalizedKey.startsWith(\"IS_\") ||\n normalizedKey.startsWith(\"DEBUG\") ||\n normalizedKey.startsWith(\"FEATURE_\")\n );\n },\n type: \"boolean\",\n },\n {\n id: \"P5_key_port\",\n priority: 5,\n match: (key: string) => {\n const normalizedKey = key.toUpperCase();\n return normalizedKey.endsWith(\"_PORT\") || normalizedKey === \"PORT\";\n },\n type: \"number\",\n },\n {\n id: \"P6_empty_unknown\",\n priority: 6,\n match: (_key: string, value: string) => value.length === 0,\n type: \"unknown\",\n },\n {\n id: \"P7_boolean_literal\",\n priority: 7,\n match: (_key: string, value: string) => {\n const lower = value.toLowerCase();\n return lower === \"true\" || lower === \"false\";\n },\n type: \"boolean\",\n },\n {\n id: \"P8_numeric_literal\",\n priority: 8,\n match: (_key: string, value: string) => /^\\d+(\\.\\d+)?$/.test(value),\n type: \"number\",\n },\n {\n id: \"P9_semver\",\n priority: 9,\n match: (_key: string, value: string) => /^\\d+\\.\\d+\\.\\d+/.test(value),\n type: \"semver\",\n },\n {\n id: \"P10_url_scheme\",\n priority: 10,\n match: (_key: string, value: string) => /^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\//.test(value),\n type: \"url\",\n },\n {\n id: \"P11_email_literal\",\n priority: 11,\n match: (_key: string, value: string) => /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(value),\n type: \"email\",\n },\n {\n id: \"P12_json_object_array\",\n priority: 12,\n match: (_key: string, value: string) => {\n try {\n const parsed: unknown = JSON.parse(value);\n return typeof parsed === \"object\" && parsed !== null;\n } catch {\n return false;\n }\n },\n type: \"json\",\n },\n] as const;\n","import type { EnvVarType } from \"../parser/types.js\";\nimport type { InferenceRule } from \"./rules.js\";\nimport { inferenceRules } from \"./rules.js\";\n\ntype InferTypeOptions = {\n fallbackType?: EnvVarType;\n /**\n * Additional rules to check before the built-in rules.\n * Within extraRules, lower priority number = higher precedence.\n */\n extraRules?: InferenceRule[];\n};\n\nconst sortedRules = [...inferenceRules].sort((left, right) => left.priority - right.priority);\n\nexport function inferType(key: string, value: string, options?: InferTypeOptions): EnvVarType {\n const extra = options?.extraRules;\n const rules =\n extra && extra.length > 0\n ? [...extra].sort((a, b) => a.priority - b.priority).concat(sortedRules)\n : sortedRules;\n\n for (const rule of rules) {\n if (rule.match(key, value)) {\n return rule.type;\n }\n }\n\n return options?.fallbackType ?? \"string\";\n}\n\nexport function inferTypesFromParsedVars(\n parsed: { vars: Array<{ key: string; rawValue: string }> },\n options?: InferTypeOptions,\n): EnvVarType[] {\n return parsed.vars.map((item) => inferType(item.key, item.rawValue, options));\n}\n","import { readFileSync } from \"node:fs\";\n\nimport type { InferenceRule } from \"../inferrer/rules.js\";\nimport { inferType } from \"../inferrer/type-inferrer.js\";\nimport { parseCommentBlock } from \"./comment-parser.js\";\nimport type { ParsedEnvFile, ParsedEnvVar } from \"./types.js\";\n\nexport { inferType } from \"../inferrer/type-inferrer.js\";\n\n/** Options forwarded to the type-inference step during parsing. */\ntype ParseOptions = {\n /** Additional inference rules to evaluate before the built-in rules. */\n inferenceRules?: InferenceRule[];\n};\n\n/** Matches a valid env var declaration: KEY=VALUE (value may be empty) */\nconst ENV_VAR_RE = /^([A-Z_][A-Z0-9_]*)=(.*)$/;\n\n/**\n * Matches a section header comment of the form:\n * `# --- SectionName ---` or `# === SectionName ===`\n */\nconst SECTION_HEADER_RE = /^#\\s+[-=]{3,}\\s+(.+?)\\s+[-=]{3,}\\s*$/;\n\n/**\n * Parse the string content of a `.env.example` file into a `ParsedEnvFile`.\n *\n * Exposed separately from `parseEnvFile` to enable unit testing without\n * filesystem access.\n *\n * @param content - Raw file content as a UTF-8 string\n * @param filePath - Used to populate `ParsedEnvFile.filePath` only\n * @param options - Optional parse configuration (custom inference rules)\n */\nexport function parseEnvFileContent(\n content: string,\n filePath: string,\n options?: ParseOptions,\n): ParsedEnvFile {\n const lines = content.split(\"\\n\");\n const vars: ParsedEnvVar[] = [];\n const groups: string[] = [];\n\n let currentGroup: string | undefined;\n let commentBlock: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const lineNumber = i + 1;\n const trimmed = line.trim();\n\n // Blank line — break the comment block association\n if (trimmed === \"\") {\n commentBlock = [];\n continue;\n }\n\n // Section header — update current group and reset comment block\n const sectionMatch = SECTION_HEADER_RE.exec(trimmed);\n if (sectionMatch !== null) {\n const groupName = (sectionMatch[1] ?? \"\").trim();\n currentGroup = groupName;\n if (!groups.includes(groupName)) {\n groups.push(groupName);\n }\n commentBlock = [];\n continue;\n }\n\n // Comment line — accumulate for the next env var\n if (trimmed.startsWith(\"#\")) {\n commentBlock.push(line);\n continue;\n }\n\n // Env var declaration\n const envMatch = ENV_VAR_RE.exec(trimmed);\n if (envMatch !== null) {\n const key = envMatch[1] ?? \"\";\n const rawValue = envMatch[2] ?? \"\";\n const annotations = parseCommentBlock(commentBlock);\n const inferredType = inferType(\n key,\n rawValue,\n ...(options?.inferenceRules !== undefined ? [{ extraRules: options.inferenceRules }] : []),\n );\n const isRequired = rawValue.length > 0 || annotations.isRequired;\n const isOptional = rawValue.length === 0 && !annotations.isRequired;\n const isClientSide = key.startsWith(\"NEXT_PUBLIC_\");\n\n const parsedVar: ParsedEnvVar = {\n key,\n rawValue,\n inferredType,\n isRequired,\n isOptional,\n isClientSide,\n lineNumber,\n };\n\n // Only set optional fields when they have a value (exactOptionalPropertyTypes)\n if (annotations.annotatedType !== undefined) {\n parsedVar.annotatedType = annotations.annotatedType;\n }\n if (annotations.description !== undefined) {\n parsedVar.description = annotations.description;\n }\n if (currentGroup !== undefined) {\n parsedVar.group = currentGroup;\n }\n\n vars.push(parsedVar);\n commentBlock = [];\n } else {\n // Unrecognised line — reset comment block\n commentBlock = [];\n }\n }\n\n return { filePath, vars, groups };\n}\n\n/**\n * Read and parse a `.env.example` file from disk.\n *\n * @param filePath - Absolute or relative path to the file\n */\nexport function parseEnvFile(filePath: string): ParsedEnvFile {\n const content = readFileSync(filePath, \"utf8\");\n return parseEnvFileContent(content, filePath);\n}\n","import path from \"node:path\";\n\nimport type { EnvVarType, ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Maps an EnvVarType to its TypeScript primitive equivalent.\n * url, email, semver, json, and unknown all map to `string` because\n * TypeScript has no built-in branded types for these.\n */\nfunction toTsType(envVarType: EnvVarType): string {\n if (envVarType === \"number\") return \"number\";\n if (envVarType === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Generates a TypeScript source file from a parsed .env.example file.\n *\n * Output structure:\n * 1. Header comments — generated-by notice, source file name, ISO timestamp\n * 2. `declare namespace NodeJS { interface ProcessEnv { ... } }` — global augmentation\n * where all properties are typed as `readonly string` (the runtime reality).\n * Number and boolean vars include an inline coercion hint comment.\n * 3. `export type EnvVars = { ... }` — typed module export using semantic types\n * (number, boolean, string).\n * 4. `ServerEnvVars` / `ClientEnvVars` — emitted only when `NEXT_PUBLIC_` vars exist.\n *\n * The output is valid as both a `.ts` and `.d.ts` file.\n * For an ambient-only `.d.ts` (without `export type` statements), use\n * `generateDeclaration` instead.\n *\n * `annotatedType` takes precedence over `inferredType` when both are set.\n */\nexport function generateTypeScriptTypes(parsed: ParsedEnvFile): string {\n const clientVars = parsed.vars.filter((v) => v.isClientSide);\n const hasClientVars = clientVars.length > 0;\n const fileName = path.basename(parsed.filePath);\n const timestamp = new Date().toISOString();\n const lines: string[] = [];\n\n // Header\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push(`// Source: ${fileName}`);\n lines.push(`// Generated at: ${timestamp}`);\n lines.push(\"\");\n\n // NodeJS.ProcessEnv augmentation — all props are runtime strings with optional coercion hints\n lines.push(\"declare namespace NodeJS {\");\n lines.push(\" interface ProcessEnv {\");\n for (const variable of parsed.vars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const optional = variable.isOptional ? \"?\" : \"\";\n if (variable.description !== undefined) {\n lines.push(` /** ${variable.description} */`);\n }\n let propLine = ` readonly ${variable.key}${optional}: string;`;\n if (effectiveType === \"number\") {\n propLine += ` // coerce to number: Number(process.env.${variable.key})`;\n } else if (effectiveType === \"boolean\") {\n propLine += ` // coerce to boolean: process.env.${variable.key} === 'true'`;\n }\n lines.push(propLine);\n }\n lines.push(\" }\");\n lines.push(\"}\");\n lines.push(\"\");\n\n // EnvVars type with semantic TypeScript types\n lines.push(\"export type EnvVars = {\");\n for (const variable of parsed.vars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const tsType = toTsType(effectiveType);\n const optional = variable.isOptional ? \"?\" : \"\";\n lines.push(` ${variable.key}${optional}: ${tsType};`);\n }\n lines.push(\"};\");\n\n // ServerEnvVars / ClientEnvVars — only emitted when NEXT_PUBLIC_ vars exist\n if (hasClientVars) {\n const clientKeyUnion = clientVars.map((v) => `\"${v.key}\"`).join(\" | \");\n lines.push(\"\");\n lines.push(`export type ServerEnvVars = Omit<EnvVars, ${clientKeyUnion}>;`);\n lines.push(`export type ClientEnvVars = Pick<EnvVars, ${clientKeyUnion}>;`);\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Generates a runtime `validateEnv()` function that throws when any required\n * environment variable is absent from `process.env`.\n */\nexport function generateEnvValidation(parsed: ParsedEnvFile): string {\n const required = parsed.vars.filter((v) => v.isRequired).map((v) => v.key);\n const lines: string[] = [];\n\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push(\"\");\n lines.push(\"export function validateEnv(): void {\");\n\n if (required.length === 0) {\n lines.push(\" // No required environment variables defined\");\n } else {\n const keyList = required.map((k) => `\"${k}\"`).join(\", \");\n lines.push(` const required = [${keyList}];`);\n lines.push(\" for (const key of required) {\");\n lines.push(\" if (!process.env[key]) {\");\n lines.push(\" throw new Error(`Missing required environment variable: ${key}`);\");\n lines.push(\" }\");\n lines.push(\" }\");\n }\n\n lines.push(\"}\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import type { EnvVarType, ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Maps an EnvVarType to its Zod schema expression.\n *\n * - `number` → `z.coerce.number()` (env vars are strings; coerce handles the cast)\n * - `boolean` → `z.coerce.boolean()` (env vars are strings; coerce handles truthy cast)\n * - `url` → `z.string().url()`\n * - `email` → `z.string().email()`\n * - everything else → `z.string()` (string | semver | json | unknown)\n */\nfunction toZodType(envVarType: EnvVarType): string {\n if (envVarType === \"number\") return \"z.coerce.number()\";\n if (envVarType === \"boolean\") return \"z.coerce.boolean()\";\n if (envVarType === \"url\") return \"z.string().url()\";\n if (envVarType === \"email\") return \"z.string().email()\";\n return \"z.string()\";\n}\n\n/**\n * Generates a Zod schema file from a parsed .env.example file.\n *\n * Output structure:\n * ```\n * // Generated by env-typegen — do not edit manually\n * import { z } from \"zod\";\n *\n * export const serverEnvSchema = z.object({\n * DATABASE_URL: z.string().url(),\n * PORT: z.coerce.number(),\n * });\n *\n * export const clientEnvSchema = z.object({\n * NEXT_PUBLIC_API_URL: z.string().url(),\n * });\n *\n * export const envSchema = serverEnvSchema.merge(clientEnvSchema);\n * export type Env = z.infer<typeof envSchema>;\n * ```\n *\n * - Server-side vars (non-`NEXT_PUBLIC_`) go into `serverEnvSchema`\n * - Client-side vars (`NEXT_PUBLIC_` prefix) go into `clientEnvSchema`\n * - `envSchema` is the merged union of both, for full-stack validation\n * - `annotatedType` takes precedence over `inferredType` when both are set\n * - Optional vars have `.optional()` appended to their Zod expression\n */\nexport function generateZodSchema(parsed: ParsedEnvFile): string {\n const serverVars = parsed.vars.filter((v) => !v.isClientSide);\n const clientVars = parsed.vars.filter((v) => v.isClientSide);\n const lines: string[] = [];\n\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push('import { z } from \"zod\";');\n lines.push(\"\");\n\n // serverEnvSchema — non-NEXT_PUBLIC_ vars\n lines.push(\"export const serverEnvSchema = z.object({\");\n for (const variable of serverVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const zodExpr = variable.isOptional\n ? `${toZodType(effectiveType)}.optional()`\n : toZodType(effectiveType);\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\"});\");\n lines.push(\"\");\n\n // clientEnvSchema — NEXT_PUBLIC_ vars\n lines.push(\"export const clientEnvSchema = z.object({\");\n for (const variable of clientVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const zodExpr = variable.isOptional\n ? `${toZodType(effectiveType)}.optional()`\n : toZodType(effectiveType);\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\"});\");\n lines.push(\"\");\n\n // Merged schema — the full validation object for use in lib/env.ts\n lines.push(\"export const envSchema = serverEnvSchema.merge(clientEnvSchema);\");\n lines.push(\"export type Env = z.infer<typeof envSchema>;\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import path from \"node:path\";\n\nimport type { ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Generates an ambient `.d.ts` declaration file from a parsed .env.example.\n *\n * Output is a pure `NodeJS.ProcessEnv` augmentation — no `export type` statements.\n * This makes the file valid as a global ambient declaration that can be dropped\n * into `lib/` or `types/` without affecting module resolution.\n *\n * Output structure:\n * ```\n * // Generated by env-typegen — do not edit manually\n * // Source: .env.example\n *\n * declare namespace NodeJS {\n * interface ProcessEnv {\n * readonly KEY: string; // all vars are runtime strings\n * readonly OPT?: string; // optional vars use ?: string\n * readonly NUM: string; // coerce to number: Number(process.env.NUM)\n * readonly FLAG: string; // coerce to boolean: process.env.FLAG === 'true'\n * }\n * }\n * ```\n *\n * For a `.ts` output with typed `export type EnvVars` / `ServerEnvVars` /\n * `ClientEnvVars`, use `generateTypeScriptTypes` instead.\n *\n * - `ProcessEnv` uses `readonly string` for every variable (runtime reality)\n * - Number and boolean vars include an inline coercion hint comment\n * - `annotatedType` takes precedence over `inferredType`\n */\nexport function generateDeclaration(parsed: ParsedEnvFile): string {\n const fileName = path.basename(parsed.filePath);\n const lines: string[] = [];\n\n // Header\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push(`// Source: ${fileName}`);\n lines.push(\"\");\n\n // NodeJS.ProcessEnv augmentation — ambient only, no exports\n lines.push(\"declare namespace NodeJS {\");\n lines.push(\" interface ProcessEnv {\");\n for (const variable of parsed.vars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n const optional = variable.isOptional ? \"?\" : \"\";\n if (variable.description !== undefined) {\n lines.push(` /** ${variable.description} */`);\n }\n let propLine = ` readonly ${variable.key}${optional}: string;`;\n if (effectiveType === \"number\") {\n propLine += ` // coerce to number: Number(process.env.${variable.key})`;\n } else if (effectiveType === \"boolean\") {\n propLine += ` // coerce to boolean: process.env.${variable.key} === 'true'`;\n }\n lines.push(propLine);\n }\n lines.push(\" }\");\n lines.push(\"}\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import type { EnvVarType, ParsedEnvFile } from \"../parser/types.js\";\n\n/**\n * Maps an EnvVarType to its Zod schema expression for use in t3-env createEnv().\n *\n * Note: boolean uses `z.coerce.boolean()` here (not the `.transform()` approach\n * in the standalone zod-generator) because @t3-oss/env-nextjs handles coercion\n * internally with `z.coerce`.\n */\nfunction toT3ZodType(envVarType: EnvVarType): string {\n if (envVarType === \"number\") return \"z.coerce.number()\";\n if (envVarType === \"boolean\") return \"z.coerce.boolean()\";\n if (envVarType === \"url\") return \"z.string().url()\";\n if (envVarType === \"email\") return \"z.string().email()\";\n return \"z.string()\";\n}\n\n/**\n * Generates a `@t3-oss/env-nextjs` configuration file from a parsed .env.example.\n *\n * Output structure:\n * ```\n * import { createEnv } from \"@t3-oss/env-nextjs\";\n * import { z } from \"zod\";\n *\n * export const env = createEnv({\n * server: { /* non-NEXT_PUBLIC_ vars *\\/ },\n * client: { /* NEXT_PUBLIC_ vars *\\/ },\n * runtimeEnv: { /* all vars mapped to process.env *\\/ },\n * });\n * ```\n *\n * - `server:` is omitted when there are no server-side vars\n * - `client:` is omitted when there are no client-side vars (NEXT_PUBLIC_ prefix)\n * - `runtimeEnv:` always includes all vars\n * - `annotatedType` takes precedence over `inferredType`\n * - Optional vars have `.optional()` appended\n * - Vars with a description have `.describe(\"text\")` appended (before `.optional()`)\n */\nexport function generateT3Env(parsed: ParsedEnvFile): string {\n const serverVars = parsed.vars.filter((v) => !v.isClientSide);\n const clientVars = parsed.vars.filter((v) => v.isClientSide);\n const lines: string[] = [];\n\n lines.push(\"// Generated by env-typegen — do not edit manually\");\n lines.push('import { createEnv } from \"@t3-oss/env-nextjs\";');\n lines.push('import { z } from \"zod\";');\n lines.push(\"\");\n lines.push(\"export const env = createEnv({\");\n\n if (serverVars.length > 0) {\n lines.push(\" server: {\");\n for (const variable of serverVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n let zodExpr = toT3ZodType(effectiveType);\n if (variable.description !== undefined) {\n zodExpr += `.describe(\"${variable.description.replace(/\"/g, '\\\\\"')}\")`;\n }\n if (variable.isOptional) {\n zodExpr += \".optional()\";\n }\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\" },\");\n }\n\n if (clientVars.length > 0) {\n lines.push(\" client: {\");\n for (const variable of clientVars) {\n const effectiveType = variable.annotatedType ?? variable.inferredType;\n let zodExpr = toT3ZodType(effectiveType);\n if (variable.description !== undefined) {\n zodExpr += `.describe(\"${variable.description.replace(/\"/g, '\\\\\"')}\")`;\n }\n if (variable.isOptional) {\n zodExpr += \".optional()\";\n }\n lines.push(` ${variable.key}: ${zodExpr},`);\n }\n lines.push(\" },\");\n }\n\n lines.push(\" runtimeEnv: {\");\n for (const variable of parsed.vars) {\n lines.push(` ${variable.key}: process.env.${variable.key},`);\n }\n lines.push(\" },\");\n lines.push(\"});\");\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { InferenceRule } from \"./inferrer/rules.js\";\n\nexport type { InferenceRule };\n\n/** Generator identifiers supported by env-typegen. */\nexport type GeneratorName = \"typescript\" | \"zod\" | \"t3\" | \"declaration\";\n\n/** Configuration shape accepted by env-typegen's CLI and programmatic API. */\nexport type EnvTypegenConfig = {\n /** Path(s) to the .env.example file(s) to parse. */\n input: string | string[];\n /** Output directory for generated files. Defaults to the input file's directory. */\n output?: string;\n /** Which generators to run. When omitted, all four generators run. */\n generators?: GeneratorName[];\n /** Format generated output with prettier. Defaults to true. */\n format?: boolean;\n /**\n * Additional inference rules to prepend before the built-in rules.\n * Rules are matched in ascending priority order; lower numbers win.\n */\n inferenceRules?: InferenceRule[];\n};\n\n/** Config file names searched in order when calling loadConfig(). */\nexport const CONFIG_FILE_NAMES = [\n \"env-typegen.config.ts\",\n \"env-typegen.config.mjs\",\n \"env-typegen.config.js\",\n] as const;\n\n/**\n * Type-safe config helper.\n * Returns the config object unchanged — exists purely for IDE autocompletion\n * and compile-time validation of the config shape.\n */\nexport function defineConfig(config: EnvTypegenConfig): EnvTypegenConfig {\n return config;\n}\n\n/**\n * Loads env-typegen config by searching for a config file in `cwd`.\n * Searches for env-typegen.config.ts → .mjs → .js in order.\n * Returns `undefined` when no config file is found.\n */\nexport async function loadConfig(\n cwd: string = process.cwd(),\n): Promise<EnvTypegenConfig | undefined> {\n for (const name of CONFIG_FILE_NAMES) {\n const filePath = path.resolve(cwd, name);\n if (existsSync(filePath)) {\n const fileUrl = pathToFileURL(filePath).href;\n const mod = (await import(fileUrl)) as { default?: EnvTypegenConfig };\n return mod.default;\n }\n }\n return undefined;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Reads a .env file from `filePath` and returns its full text content.\n * Rejects with a Node.js filesystem error if the file does not exist.\n */\nexport async function readEnvFile(filePath: string): Promise<string> {\n return readFile(path.resolve(filePath), \"utf8\");\n}\n\n/**\n * Writes `content` to `filePath`, creating intermediate directories as needed.\n * Overwrites any existing file at that path.\n */\nexport async function writeOutput(filePath: string, content: string): Promise<void> {\n const resolved = path.resolve(filePath);\n await mkdir(path.dirname(resolved), { recursive: true });\n await writeFile(resolved, content, \"utf8\");\n}\n","import { format } from \"prettier\";\n\n/**\n * Formats `content` using prettier with the specified `parser`.\n * Defaults to the \"typescript\" parser, which is correct for all generator outputs.\n * Returns the original content unchanged if prettier throws (e.g., invalid syntax).\n */\nexport async function formatOutput(\n content: string,\n parser: string = \"typescript\",\n): Promise<string> {\n try {\n return await format(content, { parser });\n } catch (err) {\n console.warn(\n \"env-typegen: Prettier formatting failed, writing unformatted output.\",\n err instanceof Error ? err.message : String(err),\n );\n return content;\n }\n}\n","import { green, red, yellow } from \"picocolors\";\n\n/** Prints a plain informational message to stdout. */\nexport function log(message: string): void {\n console.log(message);\n}\n\n/** Prints a yellow ⚠ warning message to stderr. */\nexport function warn(message: string): void {\n console.warn(yellow(`⚠ ${message}`));\n}\n\n/** Prints a red ✖ error message to stderr. */\nexport function error(message: string): void {\n console.error(red(`✖ ${message}`));\n}\n\n/** Prints a green ✔ success message to stdout. */\nexport function success(message: string): void {\n console.log(green(`✔ ${message}`));\n}\n","import path from \"node:path\";\n\nimport { type GeneratorName, type InferenceRule } from \"./config.js\";\nimport { generateDeclaration } from \"./generators/declaration-generator.js\";\nimport { generateT3Env } from \"./generators/t3-generator.js\";\nimport { generateTypeScriptTypes } from \"./generators/typescript-generator.js\";\nimport { generateZodSchema } from \"./generators/zod-generator.js\";\nimport { parseEnvFileContent } from \"./parser/env-parser.js\";\nimport type { ParsedEnvFile } from \"./parser/types.js\";\nimport { readEnvFile, writeOutput } from \"./utils/file.js\";\nimport { formatOutput } from \"./utils/format.js\";\nimport { success } from \"./utils/logger.js\";\n\n/** Options accepted by the runGenerate pipeline. */\nexport type RunGenerateOptions = {\n input: string | string[];\n output: string;\n generators: GeneratorName[];\n format: boolean;\n stdout?: boolean;\n dryRun?: boolean;\n silent?: boolean;\n /** Additional inference rules to prepend before built-in rules. */\n inferenceRules?: InferenceRule[];\n};\n\n/** Derive the output file path for a generator when multiple generators are in use. */\nfunction deriveOutputPath(base: string, generator: GeneratorName, isSingle: boolean): string {\n if (isSingle) return base;\n const ext = path.extname(base);\n const noExt = ext.length > 0 ? base.slice(0, -ext.length) : base;\n // The declaration generator produces ambient TypeScript declarations (.d.ts).\n // Use the correct extension so IDEs and tsc pick it up as a declaration file.\n const baseExt = ext.length > 0 ? ext : \".ts\";\n const outExt = generator === \"declaration\" ? \".d.ts\" : baseExt;\n return `${noExt}.${generator}${outExt}`;\n}\n\n/**\n * When running against multiple input files, derive a per-input output base so\n * each file produces a distinct set of outputs. The input's basename (without\n * extension) is used as the stem; directory and extension come from the\n * user-supplied `output` option.\n */\nfunction deriveOutputBaseForInput(output: string, inputPath: string): string {\n const dir = path.dirname(output);\n const ext = path.extname(output);\n const stem = path.basename(inputPath, path.extname(inputPath));\n return path.join(dir, `${stem}${ext}`);\n}\n\n/** Invoke the correct generator function for the given name. */\nfunction buildOutput(generator: GeneratorName, parsed: ParsedEnvFile): string {\n switch (generator) {\n case \"typescript\":\n return generateTypeScriptTypes(parsed);\n case \"zod\":\n return generateZodSchema(parsed);\n case \"t3\":\n return generateT3Env(parsed);\n case \"declaration\":\n return generateDeclaration(parsed);\n }\n}\n\nasync function persistOutput(params: {\n generated: string;\n generator: GeneratorName;\n outputPath: string;\n isSingle: boolean;\n stdout: boolean;\n dryRun: boolean;\n silent: boolean;\n}): Promise<void> {\n const { generated, generator, outputPath, isSingle, stdout, dryRun, silent } = params;\n\n if (stdout) {\n if (isSingle) {\n console.log(generated);\n } else {\n console.log(`// --- ${generator}:${outputPath} ---`);\n console.log(generated);\n }\n return;\n }\n\n if (dryRun) {\n if (!silent) {\n if (!isSingle) {\n console.log(`// --- ${generator}: ${outputPath} ---`);\n }\n console.log(generated);\n success(`Dry run: would write ${outputPath}`);\n }\n return;\n }\n\n await writeOutput(outputPath, generated);\n if (!silent) {\n success(`Generated ${outputPath}`);\n }\n}\n\n/**\n * Reads the input file(s), runs the requested generators, optionally formats each\n * output, and writes the results to disk.\n *\n * Exported for unit testing — call this directly rather than spawning a child process.\n */\nexport async function runGenerate(options: RunGenerateOptions): Promise<void> {\n const {\n input,\n output,\n generators,\n format: shouldFormat,\n stdout = false,\n dryRun = false,\n silent = false,\n inferenceRules,\n } = options;\n const inputs = Array.isArray(input) ? input : [input];\n const hasMultipleInputs = inputs.length > 1;\n const isSingle = generators.length === 1;\n\n for (const inputPath of inputs) {\n const outputBase = hasMultipleInputs ? deriveOutputBaseForInput(output, inputPath) : output;\n const content = await readEnvFile(inputPath);\n const parsed = parseEnvFileContent(\n content,\n inputPath,\n inferenceRules !== undefined ? { inferenceRules } : undefined,\n );\n\n for (const generator of generators) {\n let generated = buildOutput(generator, parsed);\n if (shouldFormat && !dryRun) {\n generated = await formatOutput(generated);\n }\n const outputPath = deriveOutputPath(outputBase, generator, isSingle);\n await persistOutput({\n generated,\n generator,\n outputPath,\n isSingle,\n stdout,\n dryRun,\n silent,\n });\n }\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -89,6 +89,11 @@ declare const inferenceRules: readonly InferenceRule[];
|
|
|
89
89
|
|
|
90
90
|
type InferTypeOptions = {
|
|
91
91
|
fallbackType?: EnvVarType;
|
|
92
|
+
/**
|
|
93
|
+
* Additional rules to check before the built-in rules.
|
|
94
|
+
* Within extraRules, lower priority number = higher precedence.
|
|
95
|
+
*/
|
|
96
|
+
extraRules?: InferenceRule[];
|
|
92
97
|
};
|
|
93
98
|
declare function inferType(key: string, value: string, options?: InferTypeOptions): EnvVarType;
|
|
94
99
|
declare function inferTypesFromParsedVars(parsed: {
|
|
@@ -98,6 +103,11 @@ declare function inferTypesFromParsedVars(parsed: {
|
|
|
98
103
|
}>;
|
|
99
104
|
}, options?: InferTypeOptions): EnvVarType[];
|
|
100
105
|
|
|
106
|
+
/** Options forwarded to the type-inference step during parsing. */
|
|
107
|
+
type ParseOptions = {
|
|
108
|
+
/** Additional inference rules to evaluate before the built-in rules. */
|
|
109
|
+
inferenceRules?: InferenceRule[];
|
|
110
|
+
};
|
|
101
111
|
/**
|
|
102
112
|
* Parse the string content of a `.env.example` file into a `ParsedEnvFile`.
|
|
103
113
|
*
|
|
@@ -106,8 +116,9 @@ declare function inferTypesFromParsedVars(parsed: {
|
|
|
106
116
|
*
|
|
107
117
|
* @param content - Raw file content as a UTF-8 string
|
|
108
118
|
* @param filePath - Used to populate `ParsedEnvFile.filePath` only
|
|
119
|
+
* @param options - Optional parse configuration (custom inference rules)
|
|
109
120
|
*/
|
|
110
|
-
declare function parseEnvFileContent(content: string, filePath: string): ParsedEnvFile;
|
|
121
|
+
declare function parseEnvFileContent(content: string, filePath: string, options?: ParseOptions): ParsedEnvFile;
|
|
111
122
|
/**
|
|
112
123
|
* Read and parse a `.env.example` file from disk.
|
|
113
124
|
*
|
|
@@ -228,14 +239,19 @@ declare function generateT3Env(parsed: ParsedEnvFile): string;
|
|
|
228
239
|
type GeneratorName = "typescript" | "zod" | "t3" | "declaration";
|
|
229
240
|
/** Configuration shape accepted by env-typegen's CLI and programmatic API. */
|
|
230
241
|
type EnvTypegenConfig = {
|
|
231
|
-
/** Path to the .env.example file to parse. */
|
|
232
|
-
input: string;
|
|
242
|
+
/** Path(s) to the .env.example file(s) to parse. */
|
|
243
|
+
input: string | string[];
|
|
233
244
|
/** Output directory for generated files. Defaults to the input file's directory. */
|
|
234
245
|
output?: string;
|
|
235
246
|
/** Which generators to run. When omitted, all four generators run. */
|
|
236
247
|
generators?: GeneratorName[];
|
|
237
248
|
/** Format generated output with prettier. Defaults to true. */
|
|
238
249
|
format?: boolean;
|
|
250
|
+
/**
|
|
251
|
+
* Additional inference rules to prepend before the built-in rules.
|
|
252
|
+
* Rules are matched in ascending priority order; lower numbers win.
|
|
253
|
+
*/
|
|
254
|
+
inferenceRules?: InferenceRule[];
|
|
239
255
|
};
|
|
240
256
|
/**
|
|
241
257
|
* Type-safe config helper.
|
|
@@ -252,20 +268,22 @@ declare function loadConfig(cwd?: string): Promise<EnvTypegenConfig | undefined>
|
|
|
252
268
|
|
|
253
269
|
/** Options accepted by the runGenerate pipeline. */
|
|
254
270
|
type RunGenerateOptions = {
|
|
255
|
-
input: string;
|
|
271
|
+
input: string | string[];
|
|
256
272
|
output: string;
|
|
257
273
|
generators: GeneratorName[];
|
|
258
274
|
format: boolean;
|
|
259
275
|
stdout?: boolean;
|
|
260
276
|
dryRun?: boolean;
|
|
261
277
|
silent?: boolean;
|
|
278
|
+
/** Additional inference rules to prepend before built-in rules. */
|
|
279
|
+
inferenceRules?: InferenceRule[];
|
|
262
280
|
};
|
|
263
281
|
/**
|
|
264
|
-
* Reads the input file, runs the requested generators, optionally formats each
|
|
282
|
+
* Reads the input file(s), runs the requested generators, optionally formats each
|
|
265
283
|
* output, and writes the results to disk.
|
|
266
284
|
*
|
|
267
285
|
* Exported for unit testing — call this directly rather than spawning a child process.
|
|
268
286
|
*/
|
|
269
287
|
declare function runGenerate(options: RunGenerateOptions): Promise<void>;
|
|
270
288
|
|
|
271
|
-
export { type CommentAnnotations, type EnvTypegenConfig, type EnvVarType, type GeneratorName, type InferenceRule, type ParsedEnvFile, type ParsedEnvVar, type RunGenerateOptions, defineConfig, generateDeclaration, generateEnvValidation, generateT3Env, generateTypeScriptTypes
|
|
289
|
+
export { type CommentAnnotations, type EnvTypegenConfig, type EnvVarType, type GeneratorName, type InferenceRule, type ParsedEnvFile, type ParsedEnvVar, type RunGenerateOptions, defineConfig, generateDeclaration, generateEnvValidation, generateT3Env, generateTypeScriptTypes, generateZodSchema, inferType, inferTypesFromParsedVars as inferTypes, inferenceRules, loadConfig, parseCommentBlock, parseEnvFile, parseEnvFileContent, runGenerate };
|
package/dist/index.d.ts
CHANGED
|
@@ -89,6 +89,11 @@ declare const inferenceRules: readonly InferenceRule[];
|
|
|
89
89
|
|
|
90
90
|
type InferTypeOptions = {
|
|
91
91
|
fallbackType?: EnvVarType;
|
|
92
|
+
/**
|
|
93
|
+
* Additional rules to check before the built-in rules.
|
|
94
|
+
* Within extraRules, lower priority number = higher precedence.
|
|
95
|
+
*/
|
|
96
|
+
extraRules?: InferenceRule[];
|
|
92
97
|
};
|
|
93
98
|
declare function inferType(key: string, value: string, options?: InferTypeOptions): EnvVarType;
|
|
94
99
|
declare function inferTypesFromParsedVars(parsed: {
|
|
@@ -98,6 +103,11 @@ declare function inferTypesFromParsedVars(parsed: {
|
|
|
98
103
|
}>;
|
|
99
104
|
}, options?: InferTypeOptions): EnvVarType[];
|
|
100
105
|
|
|
106
|
+
/** Options forwarded to the type-inference step during parsing. */
|
|
107
|
+
type ParseOptions = {
|
|
108
|
+
/** Additional inference rules to evaluate before the built-in rules. */
|
|
109
|
+
inferenceRules?: InferenceRule[];
|
|
110
|
+
};
|
|
101
111
|
/**
|
|
102
112
|
* Parse the string content of a `.env.example` file into a `ParsedEnvFile`.
|
|
103
113
|
*
|
|
@@ -106,8 +116,9 @@ declare function inferTypesFromParsedVars(parsed: {
|
|
|
106
116
|
*
|
|
107
117
|
* @param content - Raw file content as a UTF-8 string
|
|
108
118
|
* @param filePath - Used to populate `ParsedEnvFile.filePath` only
|
|
119
|
+
* @param options - Optional parse configuration (custom inference rules)
|
|
109
120
|
*/
|
|
110
|
-
declare function parseEnvFileContent(content: string, filePath: string): ParsedEnvFile;
|
|
121
|
+
declare function parseEnvFileContent(content: string, filePath: string, options?: ParseOptions): ParsedEnvFile;
|
|
111
122
|
/**
|
|
112
123
|
* Read and parse a `.env.example` file from disk.
|
|
113
124
|
*
|
|
@@ -228,14 +239,19 @@ declare function generateT3Env(parsed: ParsedEnvFile): string;
|
|
|
228
239
|
type GeneratorName = "typescript" | "zod" | "t3" | "declaration";
|
|
229
240
|
/** Configuration shape accepted by env-typegen's CLI and programmatic API. */
|
|
230
241
|
type EnvTypegenConfig = {
|
|
231
|
-
/** Path to the .env.example file to parse. */
|
|
232
|
-
input: string;
|
|
242
|
+
/** Path(s) to the .env.example file(s) to parse. */
|
|
243
|
+
input: string | string[];
|
|
233
244
|
/** Output directory for generated files. Defaults to the input file's directory. */
|
|
234
245
|
output?: string;
|
|
235
246
|
/** Which generators to run. When omitted, all four generators run. */
|
|
236
247
|
generators?: GeneratorName[];
|
|
237
248
|
/** Format generated output with prettier. Defaults to true. */
|
|
238
249
|
format?: boolean;
|
|
250
|
+
/**
|
|
251
|
+
* Additional inference rules to prepend before the built-in rules.
|
|
252
|
+
* Rules are matched in ascending priority order; lower numbers win.
|
|
253
|
+
*/
|
|
254
|
+
inferenceRules?: InferenceRule[];
|
|
239
255
|
};
|
|
240
256
|
/**
|
|
241
257
|
* Type-safe config helper.
|
|
@@ -252,20 +268,22 @@ declare function loadConfig(cwd?: string): Promise<EnvTypegenConfig | undefined>
|
|
|
252
268
|
|
|
253
269
|
/** Options accepted by the runGenerate pipeline. */
|
|
254
270
|
type RunGenerateOptions = {
|
|
255
|
-
input: string;
|
|
271
|
+
input: string | string[];
|
|
256
272
|
output: string;
|
|
257
273
|
generators: GeneratorName[];
|
|
258
274
|
format: boolean;
|
|
259
275
|
stdout?: boolean;
|
|
260
276
|
dryRun?: boolean;
|
|
261
277
|
silent?: boolean;
|
|
278
|
+
/** Additional inference rules to prepend before built-in rules. */
|
|
279
|
+
inferenceRules?: InferenceRule[];
|
|
262
280
|
};
|
|
263
281
|
/**
|
|
264
|
-
* Reads the input file, runs the requested generators, optionally formats each
|
|
282
|
+
* Reads the input file(s), runs the requested generators, optionally formats each
|
|
265
283
|
* output, and writes the results to disk.
|
|
266
284
|
*
|
|
267
285
|
* Exported for unit testing — call this directly rather than spawning a child process.
|
|
268
286
|
*/
|
|
269
287
|
declare function runGenerate(options: RunGenerateOptions): Promise<void>;
|
|
270
288
|
|
|
271
|
-
export { type CommentAnnotations, type EnvTypegenConfig, type EnvVarType, type GeneratorName, type InferenceRule, type ParsedEnvFile, type ParsedEnvVar, type RunGenerateOptions, defineConfig, generateDeclaration, generateEnvValidation, generateT3Env, generateTypeScriptTypes
|
|
289
|
+
export { type CommentAnnotations, type EnvTypegenConfig, type EnvVarType, type GeneratorName, type InferenceRule, type ParsedEnvFile, type ParsedEnvVar, type RunGenerateOptions, defineConfig, generateDeclaration, generateEnvValidation, generateT3Env, generateTypeScriptTypes, generateZodSchema, inferType, inferTypesFromParsedVars as inferTypes, inferenceRules, loadConfig, parseCommentBlock, parseEnvFile, parseEnvFileContent, runGenerate };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'fs';
|
|
2
|
-
import
|
|
2
|
+
import path5 from 'path';
|
|
3
3
|
import { pathToFileURL } from 'url';
|
|
4
4
|
import { readFile, mkdir, writeFile } from 'fs/promises';
|
|
5
5
|
import { format } from 'prettier';
|
|
@@ -136,7 +136,9 @@ var inferenceRules = [
|
|
|
136
136
|
// src/inferrer/type-inferrer.ts
|
|
137
137
|
var sortedRules = [...inferenceRules].sort((left, right) => left.priority - right.priority);
|
|
138
138
|
function inferType(key, value, options) {
|
|
139
|
-
|
|
139
|
+
const extra = options?.extraRules;
|
|
140
|
+
const rules = extra && extra.length > 0 ? [...extra].sort((a, b) => a.priority - b.priority).concat(sortedRules) : sortedRules;
|
|
141
|
+
for (const rule of rules) {
|
|
140
142
|
if (rule.match(key, value)) {
|
|
141
143
|
return rule.type;
|
|
142
144
|
}
|
|
@@ -148,7 +150,7 @@ function inferTypesFromParsedVars(parsed, options) {
|
|
|
148
150
|
}
|
|
149
151
|
var ENV_VAR_RE = /^([A-Z_][A-Z0-9_]*)=(.*)$/;
|
|
150
152
|
var SECTION_HEADER_RE = /^#\s+[-=]{3,}\s+(.+?)\s+[-=]{3,}\s*$/;
|
|
151
|
-
function parseEnvFileContent(content, filePath) {
|
|
153
|
+
function parseEnvFileContent(content, filePath, options) {
|
|
152
154
|
const lines = content.split("\n");
|
|
153
155
|
const vars = [];
|
|
154
156
|
const groups = [];
|
|
@@ -181,7 +183,11 @@ function parseEnvFileContent(content, filePath) {
|
|
|
181
183
|
const key = envMatch[1] ?? "";
|
|
182
184
|
const rawValue = envMatch[2] ?? "";
|
|
183
185
|
const annotations = parseCommentBlock(commentBlock);
|
|
184
|
-
const inferredType = inferType(
|
|
186
|
+
const inferredType = inferType(
|
|
187
|
+
key,
|
|
188
|
+
rawValue,
|
|
189
|
+
...options?.inferenceRules !== void 0 ? [{ extraRules: options.inferenceRules }] : []
|
|
190
|
+
);
|
|
185
191
|
const isRequired = rawValue.length > 0 || annotations.isRequired;
|
|
186
192
|
const isOptional = rawValue.length === 0 && !annotations.isRequired;
|
|
187
193
|
const isClientSide = key.startsWith("NEXT_PUBLIC_");
|
|
@@ -223,7 +229,7 @@ function toTsType(envVarType) {
|
|
|
223
229
|
function generateTypeScriptTypes(parsed) {
|
|
224
230
|
const clientVars = parsed.vars.filter((v) => v.isClientSide);
|
|
225
231
|
const hasClientVars = clientVars.length > 0;
|
|
226
|
-
const fileName =
|
|
232
|
+
const fileName = path5.basename(parsed.filePath);
|
|
227
233
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
228
234
|
const lines = [];
|
|
229
235
|
lines.push("// Generated by env-typegen \u2014 do not edit manually");
|
|
@@ -322,7 +328,7 @@ function generateZodSchema(parsed) {
|
|
|
322
328
|
return lines.join("\n") + "\n";
|
|
323
329
|
}
|
|
324
330
|
function generateDeclaration(parsed) {
|
|
325
|
-
const fileName =
|
|
331
|
+
const fileName = path5.basename(parsed.filePath);
|
|
326
332
|
const lines = [];
|
|
327
333
|
lines.push("// Generated by env-typegen \u2014 do not edit manually");
|
|
328
334
|
lines.push(`// Source: ${fileName}`);
|
|
@@ -371,7 +377,7 @@ function generateT3Env(parsed) {
|
|
|
371
377
|
const effectiveType = variable.annotatedType ?? variable.inferredType;
|
|
372
378
|
let zodExpr = toT3ZodType(effectiveType);
|
|
373
379
|
if (variable.description !== void 0) {
|
|
374
|
-
zodExpr += `.describe("${variable.description}")`;
|
|
380
|
+
zodExpr += `.describe("${variable.description.replace(/"/g, '\\"')}")`;
|
|
375
381
|
}
|
|
376
382
|
if (variable.isOptional) {
|
|
377
383
|
zodExpr += ".optional()";
|
|
@@ -386,7 +392,7 @@ function generateT3Env(parsed) {
|
|
|
386
392
|
const effectiveType = variable.annotatedType ?? variable.inferredType;
|
|
387
393
|
let zodExpr = toT3ZodType(effectiveType);
|
|
388
394
|
if (variable.description !== void 0) {
|
|
389
|
-
zodExpr += `.describe("${variable.description}")`;
|
|
395
|
+
zodExpr += `.describe("${variable.description.replace(/"/g, '\\"')}")`;
|
|
390
396
|
}
|
|
391
397
|
if (variable.isOptional) {
|
|
392
398
|
zodExpr += ".optional()";
|
|
@@ -413,7 +419,7 @@ function defineConfig(config) {
|
|
|
413
419
|
}
|
|
414
420
|
async function loadConfig(cwd = process.cwd()) {
|
|
415
421
|
for (const name of CONFIG_FILE_NAMES) {
|
|
416
|
-
const filePath =
|
|
422
|
+
const filePath = path5.resolve(cwd, name);
|
|
417
423
|
if (existsSync(filePath)) {
|
|
418
424
|
const fileUrl = pathToFileURL(filePath).href;
|
|
419
425
|
const mod = await import(fileUrl);
|
|
@@ -423,17 +429,21 @@ async function loadConfig(cwd = process.cwd()) {
|
|
|
423
429
|
return void 0;
|
|
424
430
|
}
|
|
425
431
|
async function readEnvFile(filePath) {
|
|
426
|
-
return readFile(
|
|
432
|
+
return readFile(path5.resolve(filePath), "utf8");
|
|
427
433
|
}
|
|
428
434
|
async function writeOutput(filePath, content) {
|
|
429
|
-
const resolved =
|
|
430
|
-
await mkdir(
|
|
435
|
+
const resolved = path5.resolve(filePath);
|
|
436
|
+
await mkdir(path5.dirname(resolved), { recursive: true });
|
|
431
437
|
await writeFile(resolved, content, "utf8");
|
|
432
438
|
}
|
|
433
439
|
async function formatOutput(content, parser = "typescript") {
|
|
434
440
|
try {
|
|
435
441
|
return await format(content, { parser });
|
|
436
|
-
} catch {
|
|
442
|
+
} catch (err) {
|
|
443
|
+
console.warn(
|
|
444
|
+
"env-typegen: Prettier formatting failed, writing unformatted output.",
|
|
445
|
+
err instanceof Error ? err.message : String(err)
|
|
446
|
+
);
|
|
437
447
|
return content;
|
|
438
448
|
}
|
|
439
449
|
}
|
|
@@ -444,12 +454,18 @@ function success(message) {
|
|
|
444
454
|
// src/pipeline.ts
|
|
445
455
|
function deriveOutputPath(base, generator, isSingle) {
|
|
446
456
|
if (isSingle) return base;
|
|
447
|
-
const ext =
|
|
457
|
+
const ext = path5.extname(base);
|
|
448
458
|
const noExt = ext.length > 0 ? base.slice(0, -ext.length) : base;
|
|
449
459
|
const baseExt = ext.length > 0 ? ext : ".ts";
|
|
450
460
|
const outExt = generator === "declaration" ? ".d.ts" : baseExt;
|
|
451
461
|
return `${noExt}.${generator}${outExt}`;
|
|
452
462
|
}
|
|
463
|
+
function deriveOutputBaseForInput(output, inputPath) {
|
|
464
|
+
const dir = path5.dirname(output);
|
|
465
|
+
const ext = path5.extname(output);
|
|
466
|
+
const stem = path5.basename(inputPath, path5.extname(inputPath));
|
|
467
|
+
return path5.join(dir, `${stem}${ext}`);
|
|
468
|
+
}
|
|
453
469
|
function buildOutput(generator, parsed) {
|
|
454
470
|
switch (generator) {
|
|
455
471
|
case "typescript":
|
|
@@ -475,7 +491,11 @@ async function persistOutput(params) {
|
|
|
475
491
|
}
|
|
476
492
|
if (dryRun) {
|
|
477
493
|
if (!silent) {
|
|
478
|
-
|
|
494
|
+
if (!isSingle) {
|
|
495
|
+
console.log(`// --- ${generator}: ${outputPath} ---`);
|
|
496
|
+
}
|
|
497
|
+
console.log(generated);
|
|
498
|
+
success(`Dry run: would write ${outputPath}`);
|
|
479
499
|
}
|
|
480
500
|
return;
|
|
481
501
|
}
|
|
@@ -492,29 +512,39 @@ async function runGenerate(options) {
|
|
|
492
512
|
format: shouldFormat,
|
|
493
513
|
stdout = false,
|
|
494
514
|
dryRun = false,
|
|
495
|
-
silent = false
|
|
515
|
+
silent = false,
|
|
516
|
+
inferenceRules: inferenceRules2
|
|
496
517
|
} = options;
|
|
518
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
519
|
+
const hasMultipleInputs = inputs.length > 1;
|
|
497
520
|
const isSingle = generators.length === 1;
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
521
|
+
for (const inputPath of inputs) {
|
|
522
|
+
const outputBase = hasMultipleInputs ? deriveOutputBaseForInput(output, inputPath) : output;
|
|
523
|
+
const content = await readEnvFile(inputPath);
|
|
524
|
+
const parsed = parseEnvFileContent(
|
|
525
|
+
content,
|
|
526
|
+
inputPath,
|
|
527
|
+
inferenceRules2 !== void 0 ? { inferenceRules: inferenceRules2 } : void 0
|
|
528
|
+
);
|
|
529
|
+
for (const generator of generators) {
|
|
530
|
+
let generated = buildOutput(generator, parsed);
|
|
531
|
+
if (shouldFormat && !dryRun) {
|
|
532
|
+
generated = await formatOutput(generated);
|
|
533
|
+
}
|
|
534
|
+
const outputPath = deriveOutputPath(outputBase, generator, isSingle);
|
|
535
|
+
await persistOutput({
|
|
536
|
+
generated,
|
|
537
|
+
generator,
|
|
538
|
+
outputPath,
|
|
539
|
+
isSingle,
|
|
540
|
+
stdout,
|
|
541
|
+
dryRun,
|
|
542
|
+
silent
|
|
543
|
+
});
|
|
504
544
|
}
|
|
505
|
-
const outputPath = deriveOutputPath(output, generator, isSingle);
|
|
506
|
-
await persistOutput({
|
|
507
|
-
generated,
|
|
508
|
-
generator,
|
|
509
|
-
outputPath,
|
|
510
|
-
isSingle,
|
|
511
|
-
stdout,
|
|
512
|
-
dryRun,
|
|
513
|
-
silent
|
|
514
|
-
});
|
|
515
545
|
}
|
|
516
546
|
}
|
|
517
547
|
|
|
518
|
-
export { defineConfig, generateDeclaration, generateEnvValidation, generateT3Env, generateTypeScriptTypes
|
|
548
|
+
export { defineConfig, generateDeclaration, generateEnvValidation, generateT3Env, generateTypeScriptTypes, generateZodSchema, inferType, inferTypesFromParsedVars as inferTypes, inferenceRules, loadConfig, parseCommentBlock, parseEnvFile, parseEnvFileContent, runGenerate };
|
|
519
549
|
//# sourceMappingURL=index.js.map
|
|
520
550
|
//# sourceMappingURL=index.js.map
|