/** * Shell escaping utilities for safe command execution. * * These utilities ensure paths and arguments with spaces, quotes, and special * characters are properly escaped when passed to shell commands via execSync. * * Why this is critical: * - macOS default directories contain spaces (e.g., "Application Support") * - Unquoted paths break shell commands mysteriously * - Security: prevents command injection from malicious paths */ /** * Escapes a single path or argument for safe shell usage. * * Handles: * - Spaces * - Single quotes (') * - Double quotes (") * - Special shell characters ($, `, !, etc.) * * Strategy: * - Wrap in single quotes (safest for most characters) * - Escape any single quotes inside by replacing ' with '\'' * * @param path - Path or argument to escape * @returns Shell-escaped string safe for command execution * * @example * ```typescript * // Path with spaces * shellEscape('/Users/user/Application Support') * // Returns: '/Users/user/Application Support' * * // Path with single quote * shellEscape("/Users/user/Bob's Files") * // Returns: '/Users/user/Bob'\''s Files' * * // Use in execSync * execSync(`cd ${shellEscape(modulePath)} && npm install`); * ``` */ export function shellEscape(path: string): string { if (!path) { throw new Error('Cannot escape empty or null path'); } // Single-quote escaping strategy: // 1. Wrap entire string in single quotes // 2. Any single quotes inside are escaped as: '\'' // - Close the quoted string with ' // - Add an escaped single quote \' // - Open a new quoted string with ' // // Example: Bob's -> 'Bob'\''s' const escaped = path.replace(/'/g, "'\\''"); return `'${escaped}'`; }