From aa4cc6ad41989223fea2c34340801d0e4378d414 Mon Sep 17 00:00:00 2001 From: Nick Nisi Date: Tue, 17 Feb 2026 18:04:42 -0600 Subject: [PATCH] fix: replace dotenv devDependency with inline env parser in doctor dotenv was listed as a devDependency but imported at runtime, causing ERR_MODULE_NOT_FOUND when running `workos doctor` via npx. --- src/doctor/checks/environment.ts | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/doctor/checks/environment.ts b/src/doctor/checks/environment.ts index 4853980..cf33fdb 100644 --- a/src/doctor/checks/environment.ts +++ b/src/doctor/checks/environment.ts @@ -1,12 +1,36 @@ import { readFileSync, existsSync } from 'node:fs'; import { join } from 'node:path'; -import { parse as parseDotenv } from 'dotenv'; import type { EnvironmentInfo, EnvironmentCheckResult, DoctorOptions } from '../types.js'; +function parseEnvFile(content: string): Record { + const result: Record = {}; + + for (const line of content.split('\n')) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith('#')) continue; + + // Strip optional `export ` prefix + const entry = trimmed.startsWith('export ') ? trimmed.slice(7) : trimmed; + const eqIndex = entry.indexOf('='); + if (eqIndex === -1) continue; + + const key = entry.slice(0, eqIndex).trim(); + let value = entry.slice(eqIndex + 1).trim(); + + // Remove surrounding quotes (single or double) + if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { + value = value.slice(1, -1); + } + + result[key] = value; + } + + return result; +} + /** * Load environment variables from project's .env files. * Priority: .env.local > .env (matching Next.js/Vite conventions) - * Uses dotenv parser for proper handling of quotes, multiline, exports, etc. */ function loadProjectEnv(installDir: string): Record { const env: Record = {}; @@ -19,8 +43,7 @@ function loadProjectEnv(installDir: string): Record { if (existsSync(filePath)) { try { const content = readFileSync(filePath, 'utf-8'); - const parsed = parseDotenv(content); - Object.assign(env, parsed); + Object.assign(env, parseEnvFile(content)); } catch { // Ignore read errors }