UNPKG

@lenne.tech/cli

Version:

lenne.Tech CLI: lt

204 lines (203 loc) 6.15 kB
"use strict"; /** * Input validation utilities for CLI commands * Provides consistent validation patterns across all commands */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidationRules = void 0; exports.sanitizeInput = sanitizeInput; exports.sanitizePath = sanitizePath; exports.toCamelCase = toCamelCase; exports.toKebabCase = toKebabCase; exports.toPascalCase = toPascalCase; exports.validateBranchName = validateBranchName; exports.validateClassName = validateClassName; exports.validateEmail = validateEmail; exports.validateFileName = validateFileName; exports.validateKebabCase = validateKebabCase; exports.validateLength = validateLength; exports.validateNpmPackage = validateNpmPackage; exports.validatePattern = validatePattern; exports.validatePropertyName = validatePropertyName; exports.validateRequired = validateRequired; /** * Validation rules for common input types */ exports.ValidationRules = { /** * Valid branch name pattern (git-compatible) */ branchName: /^(?![-./])(?!.*[-./]$)(?!.*[-./]{2})[a-zA-Z0-9._/-]+$/, /** * Valid module/class name (PascalCase) */ className: /^[A-Z][a-zA-Z0-9]*$/, /** * Valid email address pattern */ email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, /** * Valid file/directory name (no special chars) */ fileName: /^[a-zA-Z0-9._-]+$/, /** * Valid kebab-case name */ kebabCase: /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/, /** * Valid npm package name */ npmPackage: /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/, /** * Valid property name (camelCase) */ propertyName: /^[a-z][a-zA-Z0-9]*$/, /** * Valid semver version */ semver: /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/, }; /** * Sanitize input by removing potentially dangerous characters */ function sanitizeInput(input) { if (!input) return ''; return (input .trim() // Remove shell special characters .replace(/[;&|`$(){}[\]<>\\'"]/g, '') // Remove control characters .replace(/[\x00-\x1F\x7F]/g, '') // Collapse multiple spaces .replace(/\s+/g, ' ')); } /** * Sanitize a file path to prevent directory traversal */ function sanitizePath(input) { if (!input) return ''; return (input .trim() // Remove directory traversal attempts .replace(/\.\./g, '') // Remove double slashes .replace(/\/+/g, '/') // Remove leading slashes (make relative) .replace(/^\/+/, '') // Remove shell special characters .replace(/[;&|`$(){}[\]<>\\'"]/g, '')); } /** * Convert string to camelCase */ function toCamelCase(input) { if (!input) return ''; const pascal = toPascalCase(input); return pascal.charAt(0).toLowerCase() + pascal.slice(1); } /** * Convert string to kebab-case */ function toKebabCase(input) { if (!input) return ''; return input .trim() .replace(/([a-z])([A-Z])/g, '$1-$2') .replace(/[\s_]+/g, '-') .toLowerCase(); } /** * Convert string to PascalCase */ function toPascalCase(input) { if (!input) return ''; return input .trim() .replace(/[-_\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : '')) .replace(/^(.)/, (char) => char.toUpperCase()); } /** * Validate a branch name */ function validateBranchName(input) { return validatePattern(input, exports.ValidationRules.branchName, 'Invalid branch name. Use alphanumeric characters, dots, underscores, or hyphens.'); } /** * Validate a module/class name (PascalCase) */ function validateClassName(input) { return validatePattern(input, exports.ValidationRules.className, 'Invalid class name. Must start with uppercase letter and contain only alphanumeric characters.'); } /** * Validate an email address */ function validateEmail(input) { return validatePattern(input, exports.ValidationRules.email, 'Invalid email address format.'); } /** * Validate a file/directory name */ function validateFileName(input) { return validatePattern(input, exports.ValidationRules.fileName, 'Invalid file name. Use only alphanumeric characters, dots, underscores, or hyphens.'); } /** * Validate a kebab-case name */ function validateKebabCase(input) { return validatePattern(input, exports.ValidationRules.kebabCase, 'Invalid name. Must be lowercase with hyphens (kebab-case).'); } /** * Validate input length */ function validateLength(input, min, max, fieldName = 'Input') { if (!input || input.trim() === '') { return { error: `${fieldName} is required`, valid: false }; } const trimmed = input.trim(); if (trimmed.length < min) { return { error: `${fieldName} must be at least ${min} characters`, valid: false }; } if (trimmed.length > max) { return { error: `${fieldName} must be at most ${max} characters`, valid: false }; } return { valid: true, value: trimmed }; } /** * Validate an npm package name */ function validateNpmPackage(input) { return validatePattern(input, exports.ValidationRules.npmPackage, 'Invalid npm package name.'); } /** * Validate input against a pattern */ function validatePattern(input, pattern, errorMessage) { if (!input || input.trim() === '') { return { error: 'Input is required', valid: false }; } const trimmed = input.trim(); if (!pattern.test(trimmed)) { return { error: errorMessage, valid: false }; } return { valid: true, value: trimmed }; } /** * Validate a property name (camelCase) */ function validatePropertyName(input) { return validatePattern(input, exports.ValidationRules.propertyName, 'Invalid property name. Must start with lowercase letter (camelCase).'); } /** * Validate required input with custom validator */ function validateRequired(value, fieldName) { if (value === null || value === undefined || value === '') { return { error: `${fieldName} is required`, valid: false }; } return { valid: true, value: String(value) }; }