UNPKG

smart-renamer

Version:

🚀 Intelligent file naming suggestions based on project-specific naming conventions. Interactive CLI tool that asks yes/no for each file renaming.

98 lines • 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NamingValidator = void 0; class NamingValidator { static CONVENTION_PATTERNS = { 'camelCase': /^[a-z][a-zA-Z0-9]*$/, 'snake_case': /^[a-z][a-z0-9_]*$/, 'kebab-case': /^[a-z][a-z0-9-]*$/, 'PascalCase': /^[A-Z][a-zA-Z0-9]*$/, 'UPPER_SNAKE_CASE': /^[A-Z][A-Z0-9_]*$/ }; static validateName(name, convention, exceptions = []) { const baseName = this.getBaseName(name); if (exceptions.includes(baseName.toLowerCase())) { return { isValid: true, convention, message: `File '${name}' is in the exceptions list` }; } const pattern = this.CONVENTION_PATTERNS[convention]; const isValid = pattern.test(baseName); if (isValid) { return { isValid: true, convention, message: `File '${name}' follows ${convention} convention` }; } const expectedName = this.convertToConvention(baseName, convention); return { isValid: false, expectedName: expectedName + this.getExtension(name), convention, message: `File '${name}' should be '${expectedName + this.getExtension(name)}' to follow ${convention} convention` }; } static convertToConvention(name, convention) { const baseName = this.getBaseName(name); const words = this.extractWords(baseName); switch (convention) { case 'camelCase': return words[0]?.toLowerCase() + words.slice(1).map(this.capitalize).join(''); case 'snake_case': return words.map(w => w.toLowerCase()).join('_'); case 'kebab-case': return words.map(w => w.toLowerCase()).join('-'); case 'PascalCase': return words.map(this.capitalize).join(''); case 'UPPER_SNAKE_CASE': return words.map(w => w.toUpperCase()).join('_'); default: return baseName; } } static detectConvention(names) { const scores = { 'camelCase': 0, 'snake_case': 0, 'kebab-case': 0, 'PascalCase': 0, 'UPPER_SNAKE_CASE': 0 }; for (const name of names) { const baseName = this.getBaseName(name); for (const [convention, pattern] of Object.entries(this.CONVENTION_PATTERNS)) { if (pattern.test(baseName)) { scores[convention]++; } } } const maxScore = Math.max(...Object.values(scores)); if (maxScore === 0) return null; const detectedConvention = Object.entries(scores).find(([, score]) => score === maxScore)?.[0]; return detectedConvention || null; } static getBaseName(filename) { const lastDotIndex = filename.lastIndexOf('.'); return lastDotIndex > 0 ? filename.substring(0, lastDotIndex) : filename; } static getExtension(filename) { const lastDotIndex = filename.lastIndexOf('.'); return lastDotIndex > 0 ? filename.substring(lastDotIndex) : ''; } static extractWords(name) { return name .replace(/([a-z])([A-Z])/g, '$1 $2') .replace(/[_-]/g, ' ') .split(/\s+/) .filter(word => word.length > 0); } static capitalize(word) { return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); } } exports.NamingValidator = NamingValidator; //# sourceMappingURL=naming-validator.js.map