import path from "node:path"; import fs from "node:fs"; import { fileURLToPath } from "node:url"; export const defaultMonorepoRoot = (): string => { const fromEnv = process.env.SMART_IDE_MONOREPO_ROOT?.trim(); if (fromEnv) { return path.resolve(fromEnv); } const here = path.dirname(fileURLToPath(import.meta.url)); return path.resolve(here, "..", "..", ".."); }; const extraPrefixes = (): string[] => { const raw = process.env.TOOLS_ALLOWED_PATH_PREFIXES?.trim(); if (!raw) { return []; } return raw .split(",") .map((s) => path.resolve(s.trim())) .filter((s) => s.length > 0); }; export const isPathAllowed = (absPath: string, monorepoRoot: string): boolean => { const norm = path.resolve(absPath); const roots = [path.resolve(monorepoRoot), ...extraPrefixes()]; return roots.some((r) => norm === r || norm.startsWith(r + path.sep)); }; export const assertAllowedFile = (p: string, monorepoRoot: string): string => { const abs = path.resolve(p); if (!isPathAllowed(abs, monorepoRoot)) { throw new Error(`Path not allowed under SMART_IDE_MONOREPO_ROOT: ${abs}`); } if (!fs.existsSync(abs)) { throw new Error(`Path does not exist: ${abs}`); } return abs; }; /** Output directory (may not exist yet); must resolve under an allowed root. */ export const assertAllowedDirPath = (p: string, monorepoRoot: string): string => { const abs = path.resolve(p); if (!isPathAllowed(abs, monorepoRoot)) { throw new Error(`Path not allowed under SMART_IDE_MONOREPO_ROOT: ${abs}`); } return abs; };