diff --git a/src/generators/clean-arch.generator.ts b/src/generators/clean-arch.generator.ts index b4b34f7..d9b0203 100644 --- a/src/generators/clean-arch.generator.ts +++ b/src/generators/clean-arch.generator.ts @@ -3,6 +3,7 @@ import path from 'path'; import mustache from 'mustache'; import { logStep, logSuccess, logInfo } from '../utils/logger'; import { mapSwaggerTypeToTs } from '../utils/type-mapper'; +import { toCamelCase } from '../utils/name-formatter'; import type { SwaggerAnalysis, OpenApiSchema, @@ -58,8 +59,8 @@ export function generateCleanArchitecture( { model: { classname: baseName, - classFilename: baseName.toLowerCase(), - classVarName: baseName.charAt(0).toLowerCase() + baseName.slice(1), + classFilename: toCamelCase(baseName), + classVarName: toCamelCase(baseName), description: schemaObj.description || '', vars: varsMap } @@ -75,8 +76,8 @@ export function generateCleanArchitecture( { operations: { classname: baseName, - classFilename: baseName.toLowerCase(), - classVarName: baseName.charAt(0).toLowerCase() + baseName.slice(1) + classFilename: toCamelCase(baseName), + classVarName: toCamelCase(baseName) } } ] @@ -88,14 +89,10 @@ export function generateCleanArchitecture( if (fs.existsSync(modelTemplatePath)) { const template = fs.readFileSync(modelTemplatePath, 'utf8'); const output = mustache.render(template, modelViewData); - const destPath = path.join( - outputDir, - 'entities/models', - `${baseName.toLowerCase()}.model.ts` - ); + const destPath = path.join(outputDir, 'entities/models', `${toCamelCase(baseName)}.model.ts`); fs.writeFileSync(destPath, output); generatedCount.models++; - logInfo(` ${baseName.toLowerCase()}.model.ts → ${path.relative(process.cwd(), destPath)}`); + logInfo(` ${toCamelCase(baseName)}.model.ts → ${path.relative(process.cwd(), destPath)}`); } // Mapper @@ -103,7 +100,7 @@ export function generateCleanArchitecture( if (fs.existsSync(mapperTemplatePath)) { const template = fs.readFileSync(mapperTemplatePath, 'utf8'); const output = mustache.render(template, mapperViewData); - const destPath = path.join(outputDir, 'data/mappers', `${baseName.toLowerCase()}.mapper.ts`); + const destPath = path.join(outputDir, 'data/mappers', `${toCamelCase(baseName)}.mapper.ts`); fs.writeFileSync(destPath, output); generatedCount.mappers++; } @@ -192,8 +189,8 @@ export function generateCleanArchitecture( if (tagsMap[tag].some((op) => op.returnType === s || op.returnType === `Array<${s}>`)) { imports.push({ classname: s, - classFilename: s.toLowerCase(), - classVarName: s.charAt(0).toLowerCase() + s.slice(1) + classFilename: toCamelCase(s), + classVarName: toCamelCase(s) }); } }); @@ -204,7 +201,7 @@ export function generateCleanArchitecture( { operations: { classname: tag, - classFilename: tag.toLowerCase(), + classFilename: toCamelCase(tag), constantName: tag.toUpperCase().replace(/[^A-Z0-9]/g, '_'), operation: tagsMap[tag], imports: imports @@ -218,7 +215,7 @@ export function generateCleanArchitecture( templatesDir, 'api.use-cases.contract.mustache', apiViewData, - path.join(outputDir, 'domain/use-cases', `${tag.toLowerCase()}.use-cases.contract.ts`), + path.join(outputDir, 'domain/use-cases', `${toCamelCase(tag)}.use-cases.contract.ts`), generatedCount, 'useCases' ); @@ -227,7 +224,7 @@ export function generateCleanArchitecture( templatesDir, 'api.use-cases.impl.mustache', apiViewData, - path.join(outputDir, 'domain/use-cases', `${tag.toLowerCase()}.use-cases.impl.ts`), + path.join(outputDir, 'domain/use-cases', `${toCamelCase(tag)}.use-cases.impl.ts`), generatedCount, 'useCases' ); @@ -236,7 +233,7 @@ export function generateCleanArchitecture( templatesDir, 'api.repository.contract.mustache', apiViewData, - path.join(outputDir, 'domain/repositories', `${tag.toLowerCase()}.repository.contract.ts`), + path.join(outputDir, 'domain/repositories', `${toCamelCase(tag)}.repository.contract.ts`), generatedCount, 'repositories' ); @@ -245,7 +242,7 @@ export function generateCleanArchitecture( templatesDir, 'api.repository.impl.mustache', apiViewData, - path.join(outputDir, 'data/repositories', `${tag.toLowerCase()}.repository.impl.ts`), + path.join(outputDir, 'data/repositories', `${toCamelCase(tag)}.repository.impl.ts`), generatedCount, 'repositories' ); @@ -254,7 +251,7 @@ export function generateCleanArchitecture( templatesDir, 'use-cases.provider.mustache', apiViewData, - path.join(outputDir, 'di/use-cases', `${tag.toLowerCase()}.use-cases.provider.ts`), + path.join(outputDir, 'di/use-cases', `${toCamelCase(tag)}.use-cases.provider.ts`), generatedCount, 'providers' ); @@ -263,7 +260,7 @@ export function generateCleanArchitecture( templatesDir, 'repository.provider.mustache', apiViewData, - path.join(outputDir, 'di/repositories', `${tag.toLowerCase()}.repository.provider.ts`), + path.join(outputDir, 'di/repositories', `${toCamelCase(tag)}.repository.provider.ts`), generatedCount, 'providers' ); diff --git a/src/utils/name-formatter.ts b/src/utils/name-formatter.ts new file mode 100644 index 0000000..c6ff94b --- /dev/null +++ b/src/utils/name-formatter.ts @@ -0,0 +1,12 @@ +/** + * Converts a PascalCase name to camelCase by lowercasing the first character. + * Used to derive class filenames and variable names from schema/tag names. + * + * @example + * toCamelCase('ProductResponse') // 'productResponse' + * toCamelCase('UserSchema') // 'userSchema' + */ +export function toCamelCase(name: string): string { + if (!name) return name; + return name.charAt(0).toLowerCase() + name.slice(1); +}