UNPKG

gitset

Version:

Enhanced git init with user configuration management

167 lines 6.23 kB
import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; import { MESSAGES, VALIDATION_CONFIG } from '../config/constants.js'; export class ValidationUtils { /** * Validate email format using standard email regex */ validateEmail(email) { const errors = []; const warnings = []; let format = false; let domain; if (!email || email.trim() === '') { errors.push('Email is required'); } else { const trimmedEmail = email.trim(); // Email regex that handles common valid patterns while rejecting obvious invalid ones // Prevents consecutive dots, leading/trailing dots, and other invalid patterns const emailRegex = /^[a-zA-Z0-9]([a-zA-Z0-9._+-]*[a-zA-Z0-9])?@[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]{2,})+$/; const hasConsecutiveDots = /\.\./.test(trimmedEmail); const hasValidDomain = /@[a-zA-Z0-9]/.test(trimmedEmail) && !/\.$/.test(trimmedEmail.split('@')[1]); format = emailRegex.test(trimmedEmail) && !hasConsecutiveDots && hasValidDomain; if (format) { domain = trimmedEmail.split('@')[1]; } else { errors.push('Invalid email format. Please use format: user@domain.com'); } } return { valid: errors.length === 0, errors, warnings, format, domain }; } /** * Validate username according to Git standards */ validateUsername(name) { const errors = []; const warnings = []; if (!name || name.trim() === '') { errors.push(MESSAGES.validation.usernameRequired); } else { const trimmedName = name.trim(); if (trimmedName.length < VALIDATION_CONFIG.username.minLength) { errors.push(MESSAGES.validation.usernameMinLength); } if (trimmedName.length > VALIDATION_CONFIG.username.maxLength) { errors.push(MESSAGES.validation.usernameMaxLength); } // Check for potentially problematic characters if (/[<>"'&]/.test(trimmedName)) { warnings.push(MESSAGES.validation.usernameSpecialChars); } } return { valid: errors.length === 0, errors, warnings }; } async validateDirectoryPath(directoryPath) { const errors = []; const warnings = []; let exists = false; let writable = false; let isEmpty = false; try { // Resolve path (handle ~, relative paths, etc.) const resolvedPath = this.resolvePath(directoryPath); // Check if directory exists try { const stats = await fs.stat(resolvedPath); exists = true; if (!stats.isDirectory()) { errors.push(MESSAGES.validation.pathNotDirectory); return { valid: false, exists, writable, isEmpty, errors, warnings }; } // Check if writable try { await fs.access(resolvedPath, fs.constants.W_OK); writable = true; } catch { errors.push(MESSAGES.validation.directoryNotWritable); } // Check if empty try { const files = await fs.readdir(resolvedPath); isEmpty = files.length === 0; if (!isEmpty) { warnings.push(MESSAGES.validation.directoryNotEmpty); } } catch { warnings.push(MESSAGES.validation.cannotReadDirectory); } } catch { exists = false; // For non-existing directories, we'll create them // Only check if the parent path structure is reasonable try { const parentDir = path.dirname(resolvedPath); // If parent is root or exists, we can create the directory if (parentDir === '/' || parentDir === '.' || parentDir === resolvedPath) { warnings.push(MESSAGES.validation.directoryWillBeCreated); } else { try { await fs.stat(parentDir); warnings.push(MESSAGES.validation.directoryWillBeCreated); } catch { // Parent doesn't exist, but we can create it recursively warnings.push('Directory and parent directories will be created'); } } } catch { warnings.push(MESSAGES.validation.directoryWillBeCreated); } } } catch (error) { errors.push(`${MESSAGES.validation.invalidPath} ${error}`); } return { valid: errors.length === 0, exists, writable, isEmpty, errors, warnings }; } resolvePath(inputPath) { // Handle home directory if (inputPath.startsWith('~/')) { return path.join(os.homedir(), inputPath.slice(2)); } if (inputPath === '~') { return os.homedir(); } // Handle relative paths if (!path.isAbsolute(inputPath)) { return path.resolve(process.cwd(), inputPath); } return inputPath; } async ensureDirectoryExists(directoryPath) { const resolvedPath = this.resolvePath(directoryPath); try { await fs.mkdir(resolvedPath, { recursive: true }); } catch (error) { throw new Error(`Failed to create directory: ${error}`); } } } //# sourceMappingURL=validation.js.map