import { join } from "node:path"; import { splitLeadingEnvAssignments } from "./shell-env-prefix.js"; const RTK_DB_PATH_ENV_NAME = "RTK_DB_PATH"; const SINGLE_QUOTED_SHELL_VALUE_PATTERN = "'(?:'\\\\''|[^'])*'"; const SHELL_ENV_VALUE_PATTERN = `(?:"[^"]*"|${SINGLE_QUOTED_SHELL_VALUE_PATTERN}|[^\\s;]+)`; const RTK_DB_PATH_ASSIGNMENT_PATTERN = new RegExp( `(?:^|\\s)RTK_DB_PATH=${SHELL_ENV_VALUE_PATTERN}(?=\\s|$)`, ); const RTK_DB_PATH_EXPORT_PATTERN = new RegExp(`^export\\s+RTK_DB_PATH=${SHELL_ENV_VALUE_PATTERN}(?=\\s*(?:;|$))`); function resolveTemporaryDirectory(): string { if (process.platform === "win32") { const windowsTempDir = process.env.TEMP ?? process.env.TMP; if (windowsTempDir && windowsTempDir.trim()) { return windowsTempDir; } const localAppData = process.env.LOCALAPPDATA; if (localAppData && localAppData.trim()) { return join(localAppData, "Temp"); } const userProfile = process.env.USERPROFILE; if (userProfile && userProfile.trim()) { return join(userProfile, "AppData", "Local", "Temp"); } const systemRoot = process.env.SystemRoot ?? process.env.WINDIR; if (systemRoot && systemRoot.trim()) { return join(systemRoot, "Temp"); } return "C:/Windows/Temp"; } const posixTempDir = process.env.TMPDIR ?? process.env.TMP; if (posixTempDir && posixTempDir.trim()) { return posixTempDir; } return "/tmp"; } function getTemporaryRtkHistoryDbPath(): string { return join(resolveTemporaryDirectory(), "pi-rtk-optimizer", "history.db"); } function quoteForShellEnv(value: string): string { const normalizedValue = process.platform === "win32" ? value.replace(/\\/g, "/") : value; return `'${normalizedValue.replace(/'/g, `'\\''`)}'`; } function hasLeadingRtkDbPathAssignment(command: string): boolean { const trimmed = command.trimStart(); return ( RTK_DB_PATH_ASSIGNMENT_PATTERN.test(splitLeadingEnvAssignments(trimmed).envPrefix) || RTK_DB_PATH_EXPORT_PATTERN.test(trimmed) ); } function hasInheritedRtkDbPath(): boolean { return Boolean(process.env[RTK_DB_PATH_ENV_NAME]?.trim()); } export function applyRtkCommandEnvironment(command: string): string { if (!command.trim()) { return command; } if (hasLeadingRtkDbPathAssignment(command) || hasInheritedRtkDbPath()) { return command; } return `export ${RTK_DB_PATH_ENV_NAME}=${quoteForShellEnv(getTemporaryRtkHistoryDbPath())}; ${command}`; }