smart-renamer
Version:
🚀 Intelligent file and code naming suggestions based on project-specific naming conventions. Interactive CLI tool with AST-based code analysis for variables, functions, components, and more.
163 lines • 5.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeValidator = void 0;
class CodeValidator {
convertToCamelCase(name) {
return name
.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
.replace(/^[A-Z]/, char => char.toLowerCase());
}
convertToPascalCase(name) {
return name
.replace(/[-_\s]+(.)?/g, (_, char) => char ? char.toUpperCase() : '')
.replace(/^[a-z]/, char => char.toUpperCase());
}
convertToSnakeCase(name) {
return name
.replace(/([A-Z])/g, '_$1')
.replace(/[-\s]+/g, '_')
.replace(/^_/, '')
.toLowerCase();
}
convertToKebabCase(name) {
return name
.replace(/([A-Z])/g, '-$1')
.replace(/[_\s]+/g, '-')
.replace(/^-/, '')
.toLowerCase();
}
convertToConstantCase(name) {
return name
.replace(/([A-Z])/g, '_$1')
.replace(/[-\s]+/g, '_')
.replace(/^_/, '')
.toUpperCase();
}
convertToConvention(name, convention) {
switch (convention) {
case 'camelCase':
return this.convertToCamelCase(name);
case 'PascalCase':
return this.convertToPascalCase(name);
case 'snake_case':
return this.convertToSnakeCase(name);
case 'kebab-case':
return this.convertToKebabCase(name);
case 'UPPER_SNAKE_CASE':
return this.convertToConstantCase(name);
default:
return name;
}
}
validateConvention(name, convention) {
switch (convention) {
case 'camelCase':
return /^[a-z][a-zA-Z0-9]*$/.test(name);
case 'PascalCase':
return /^[A-Z][a-zA-Z0-9]*$/.test(name);
case 'snake_case':
return /^[a-z][a-z0-9_]*$/.test(name);
case 'kebab-case':
return /^[a-z][a-z0-9-]*$/.test(name);
case 'UPPER_SNAKE_CASE':
return /^[A-Z][A-Z0-9_]*$/.test(name);
default:
return true;
}
}
getExpectedConvention(identifier, config) {
// React components should always be PascalCase regardless of function convention
if (identifier.isReactComponent) {
return 'PascalCase';
}
switch (identifier.type) {
case 'variable':
return config.variables;
case 'function':
return config.functions;
case 'class':
return config.classes;
case 'constant':
return config.constants;
case 'interface':
return config.interfaces;
case 'type':
return config.types;
case 'enum':
return config.enums;
default:
return config.variables;
}
}
validateIdentifier(identifier, config) {
const expectedConvention = this.getExpectedConvention(identifier, config);
const isValid = this.validateConvention(identifier.name, expectedConvention);
let violation = '';
let suggestedName;
if (!isValid) {
suggestedName = this.convertToConvention(identifier.name, expectedConvention);
if (identifier.isReactComponent) {
violation = `React component "${identifier.name}" should use PascalCase`;
}
else {
violation = `${identifier.type} "${identifier.name}" should use ${expectedConvention}`;
}
}
return {
identifier,
isValid,
expectedConvention,
suggestedName,
violation
};
}
validateIdentifiers(identifiers, config) {
const violations = [];
const violationsByType = {};
for (const identifier of identifiers) {
const result = this.validateIdentifier(identifier, config);
if (!result.isValid) {
violations.push(result);
const key = identifier.isReactComponent ? 'React Components' : identifier.type;
violationsByType[key] = (violationsByType[key] || 0) + 1;
}
}
return {
totalChecked: identifiers.length,
totalViolations: violations.length,
violationsByType,
violations
};
}
// Suggest fixes for common naming issues
suggestFixes(identifier, config) {
const suggestions = [];
const expectedConvention = this.getExpectedConvention(identifier, config);
// Generate suggestions for different conventions
const conventions = ['camelCase', 'PascalCase', 'snake_case', 'kebab-case', 'UPPER_SNAKE_CASE'];
for (const convention of conventions) {
if (convention !== expectedConvention) {
const converted = this.convertToConvention(identifier.name, convention);
if (converted !== identifier.name) {
suggestions.push(`${convention}: ${converted}`);
}
}
}
return suggestions;
}
// Get default configuration based on your preferences
getDefaultCodeConfig() {
return {
variables: 'camelCase',
functions: 'camelCase',
components: 'PascalCase',
constants: 'UPPER_SNAKE_CASE',
classes: 'PascalCase',
interfaces: 'PascalCase',
types: 'PascalCase',
enums: 'PascalCase'
};
}
}
exports.CodeValidator = CodeValidator;
//# sourceMappingURL=code-validator.js.map