diff --git a/main.ts b/main.ts index 53278ca..3664d84 100755 --- a/main.ts +++ b/main.ts @@ -21,7 +21,7 @@ import type { SelectionFilter } from './src/types'; import type { CliOptions } from './src/types'; import packageJson from './package.json'; -// Desactivar escape HTML para que los literales < y > generen tipos genéricos válidos de TS. +// Disable HTML escaping so that < and > produce valid TypeScript generic types. (mustache as { escape: (text: string) => string }).escape = function (text: string): string { return text; }; diff --git a/package-lock.json b/package-lock.json index 020f844..8afc3f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@blas/openapi-clean-arch-generator", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@blas/openapi-clean-arch-generator", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "dependencies": { "chalk": "^4.1.2", diff --git a/src/generators/clean-arch.generator.ts b/src/generators/clean-arch.generator.ts index 50726c3..a9e10c8 100644 --- a/src/generators/clean-arch.generator.ts +++ b/src/generators/clean-arch.generator.ts @@ -58,7 +58,7 @@ export function extractTagsWithOperations(analysis: SwaggerAnalysis): TagSummary return [...map.values()]; } -/** Genera todos los artefactos de Clean Architecture (modelos, mappers, repos, use cases, providers) usando Mustache. */ +/** Generates all Clean Architecture artefacts (models, mappers, repos, use cases, providers) using Mustache. */ export function generateCleanArchitecture( analysis: SwaggerAnalysis, outputDir: string, @@ -66,7 +66,7 @@ export function generateCleanArchitecture( tagApiKeyMap: Record = {}, selectionFilter: SelectionFilter = {} ): GeneratedCount { - logStep('Generando artefactos de Clean Architecture usando Mustache...'); + logStep('Generating Clean Architecture artefacts using Mustache...'); const generatedCount: GeneratedCount = { models: 0, repositories: 0, @@ -79,7 +79,7 @@ export function generateCleanArchitecture( (analysis.swagger as { components?: { schemas?: Record } }).components ?.schemas || {}; - // 1. Generar Modelos, Entidades y Mappers a partir de Schemas + // 1. Generate Models, Entities and Mappers from Schemas Object.keys(schemas).forEach((schemaName) => { const baseName = schemaName.replace(/Dto$/, ''); @@ -168,7 +168,7 @@ export function generateCleanArchitecture( } }); - // 2. Generar Casos de Uso y Repositorios a partir de Paths/Tags + // 2. Generate Use Cases and Repositories from Paths/Tags const tagsMap: Record = {}; Object.keys(analysis.paths).forEach((pathKey) => { @@ -257,7 +257,7 @@ export function generateCleanArchitecture( }); } - // Generar por cada Tag + // Generate per tag Object.keys(tagsMap).forEach((tag) => { const returnImports: { classname: string; classFilename: string; classVarName: string }[] = []; const paramImports: { classname: string; classFilename: string; classVarName: string }[] = []; @@ -365,7 +365,7 @@ export function generateCleanArchitecture( return generatedCount; } -/** Renderiza un template Mustache e incrementa el contador correspondiente. */ +/** Renders a Mustache template and increments the corresponding counter. */ function renderTemplate( templatesDir: string, templateName: string, diff --git a/src/generators/dto.generator.ts b/src/generators/dto.generator.ts index 83a7747..fbe0629 100644 --- a/src/generators/dto.generator.ts +++ b/src/generators/dto.generator.ts @@ -3,9 +3,9 @@ import fs from 'fs-extra'; import path from 'path'; import { logStep, logSuccess, logError, logInfo } from '../utils/logger'; -/** Invoca `openapi-generator-cli` para generar DTOs en un directorio temporal. */ +/** Invokes `openapi-generator-cli` to generate DTOs into a temporary directory. */ export function generateCode(swaggerFile: string, templatesDir: string): string { - logStep('Generando código desde OpenAPI...'); + logStep('Generating code from OpenAPI spec...'); const tempDir = path.join(process.cwd(), '.temp-generated'); @@ -23,11 +23,11 @@ export function generateCode(swaggerFile: string, templatesDir: string): string --additional-properties=ngVersion=17.0.0,modelFileSuffix=.dto,modelNameSuffix=Dto`; execSync(command, { stdio: 'inherit' }); - logSuccess('Código generado correctamente'); + logSuccess('Code generated successfully'); return tempDir; } catch (_error) { - logError('Error al generar código'); + logError('Error generating code'); if (fs.existsSync(tempDir)) { fs.removeSync(tempDir); } @@ -35,9 +35,9 @@ export function generateCode(swaggerFile: string, templatesDir: string): string } } -/** Copia los DTOs generados desde el directorio temporal al directorio de salida. */ +/** Copies the generated DTOs from the temporary directory to the output directory. */ export function organizeFiles(tempDir: string, outputDir: string): void { - logStep('Organizando archivos DTO generados...'); + logStep('Organising generated DTO files...'); const sourceDir = path.join(tempDir, 'model'); const destDir = path.join(outputDir, 'data/dtos'); @@ -58,12 +58,12 @@ export function organizeFiles(tempDir: string, outputDir: string): void { }); } - logSuccess(`${filesMoved} DTOs movidos correctamente`); + logSuccess(`${filesMoved} DTOs moved successfully`); } -/** Post-procesa los DTOs generados añadiendo imports y normalizando Array → T[]. */ +/** Post-processes the generated DTOs: adds cross-DTO imports and normalises Array → T[]. */ export function addDtoImports(outputDir: string): void { - logStep('Añadiendo imports a los DTOs generados...'); + logStep('Post-processing generated DTOs...'); const dtosDir = path.join(outputDir, 'data/dtos'); @@ -123,5 +123,5 @@ export function addDtoImports(outputDir: string): void { } }); - logSuccess(`Imports añadidos a ${filesProcessed} DTOs`); + logSuccess(`${filesProcessed} DTOs post-processed`); } diff --git a/src/generators/report.generator.ts b/src/generators/report.generator.ts index 5a786d0..166bf0f 100644 --- a/src/generators/report.generator.ts +++ b/src/generators/report.generator.ts @@ -3,9 +3,9 @@ import path from 'path'; import { logStep, logSuccess } from '../utils/logger'; import type { SwaggerAnalysis, GenerationReport } from '../types'; -/** Genera y persiste el reporte `generation-report.json` con las estadísticas del proceso. */ +/** Generates and persists the `generation-report.json` file with process statistics. */ export function generateReport(outputDir: string, analysis: SwaggerAnalysis): GenerationReport { - logStep('Generando reporte de generación...'); + logStep('Generating report...'); const report: GenerationReport = { timestamp: new Date().toISOString(), @@ -26,7 +26,7 @@ export function generateReport(outputDir: string, analysis: SwaggerAnalysis): Ge const reportPath = path.join(process.cwd(), 'generation-report.json'); fs.writeJsonSync(reportPath, report, { spaces: 2 }); - logSuccess(`Reporte guardado en: ${reportPath}`); + logSuccess(`Report saved to: ${reportPath}`); return report; } diff --git a/src/swagger/analyzer.ts b/src/swagger/analyzer.ts index 98764b4..fc09e31 100644 --- a/src/swagger/analyzer.ts +++ b/src/swagger/analyzer.ts @@ -3,9 +3,9 @@ import yaml from 'js-yaml'; import { logStep, logInfo, logError } from '../utils/logger'; import type { SwaggerAnalysis } from '../types'; -/** Parsea un archivo OpenAPI/Swagger y extrae tags, paths y el documento completo. */ +/** Parses an OpenAPI/Swagger file and extracts tags, paths and the full document. */ export function analyzeSwagger(swaggerFile: string): SwaggerAnalysis { - logStep('Analizando archivo OpenAPI...'); + logStep('Analysing OpenAPI file...'); try { const fileContent = fs.readFileSync(swaggerFile, 'utf8'); @@ -14,18 +14,18 @@ export function analyzeSwagger(swaggerFile: string): SwaggerAnalysis { const tags = Array.isArray(swagger.tags) ? swagger.tags : []; const paths = (swagger.paths as Record) || {}; - logInfo(`Encontrados ${tags.length} tags en el API`); - logInfo(`Encontrados ${Object.keys(paths).length} endpoints`); + logInfo(`Found ${tags.length} tags in the API`); + logInfo(`Found ${Object.keys(paths).length} endpoints`); tags.forEach((tag: unknown) => { const t = tag as { name: string; description?: string }; - logInfo(` - ${t.name}: ${t.description || 'Sin descripción'}`); + logInfo(` - ${t.name}: ${t.description || 'No description'}`); }); return { tags, paths, swagger }; } catch (error: unknown) { const err = error as Error; - logError(`Error al leer el archivo Swagger: ${err.message}`); + logError(`Error reading the Swagger file: ${err.message}`); process.exit(1); } } diff --git a/src/types/cli.types.ts b/src/types/cli.types.ts index 53ea263..bea1609 100644 --- a/src/types/cli.types.ts +++ b/src/types/cli.types.ts @@ -1,6 +1,6 @@ /** - * Opciones recibidas desde la línea de comandos (Commander). - * Desacoplada del framework CLI para permitir su uso desde un backend u otro entrypoint. + * Options received from the command line (Commander). + * Decoupled from the CLI framework to allow use from a backend or other entry points. */ export interface CliOptions { input: string; diff --git a/src/types/generation.types.ts b/src/types/generation.types.ts index 5b88149..56f8d9d 100644 --- a/src/types/generation.types.ts +++ b/src/types/generation.types.ts @@ -1,5 +1,5 @@ /** - * Contadores acumulativos de artefactos generados durante el proceso. + * Cumulative counters of artifacts generated during the process. */ export interface GeneratedCount { models: number; @@ -10,7 +10,7 @@ export interface GeneratedCount { } /** - * Reporte final de generación que se persiste como `generation-report.json`. + * Final generation report persisted as `generation-report.json`. */ export interface GenerationReport { timestamp: string; diff --git a/src/types/index.ts b/src/types/index.ts index 7b54850..7540a33 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,6 +1,6 @@ /** * @module types - * @description Barrel que re-exporta todos los tipos e interfaces compartidos del proyecto. + * @description Barrel that re-exports all shared types and interfaces for the project. */ export * from './cli.types'; export * from './swagger.types'; diff --git a/src/types/openapi.types.ts b/src/types/openapi.types.ts index c5cf082..a9a1bb3 100644 --- a/src/types/openapi.types.ts +++ b/src/types/openapi.types.ts @@ -1,5 +1,5 @@ /** - * Resumen de un endpoint para mostrar en la pantalla de selección interactiva. + * Summary of a single endpoint for display on the interactive selection screen. */ export interface OperationSummary { nickname: string; @@ -9,7 +9,7 @@ export interface OperationSummary { } /** - * Tag con sus endpoints resumidos, para la pantalla de selección interactiva. + * Tag with its summarised endpoints, used on the interactive selection screen. */ export interface TagSummary { tag: string; @@ -17,13 +17,13 @@ export interface TagSummary { } /** - * Mapa de filtro de selección: tag → array de nicknames de operaciones seleccionadas. + * Selection filter map: tag → array of selected operation nicknames. */ export type SelectionFilter = Record; /** - * Representación simplificada de un schema de componente OpenAPI. - * Se utiliza para generar modelos (entidades) y mappers. + * Simplified representation of an OpenAPI component schema. + * Used to generate domain models (entities) and mappers. */ export interface OpenApiSchema { properties?: Record< @@ -40,8 +40,8 @@ export interface OpenApiSchema { } /** - * Representación de una operación OpenAPI (GET, POST, etc.) dentro de un path. - * Contiene la información necesaria para generar repositorios y casos de uso. + * Representation of an OpenAPI operation (GET, POST, etc.) within a path. + * Contains the information needed to generate repositories and use cases. */ export interface OpenApiOperation { tags?: string[]; @@ -85,8 +85,7 @@ export interface OpenApiOperation { } /** - * Operación normalizada y lista para ser consumida por los templates Mustache. - * Cada instancia representa un endpoint agrupado bajo un tag del API. + * A single parameter of a normalised API operation, ready for Mustache template consumption. */ export interface TagOperationParam { paramName: string; @@ -96,6 +95,10 @@ export interface TagOperationParam { '-last': boolean; } +/** + * Normalised operation ready to be consumed by Mustache templates. + * Each instance represents an endpoint grouped under an API tag. + */ export interface TagOperation { nickname: string; summary: string; diff --git a/src/types/swagger.types.ts b/src/types/swagger.types.ts index 95d7e2b..9a7a7a2 100644 --- a/src/types/swagger.types.ts +++ b/src/types/swagger.types.ts @@ -1,6 +1,6 @@ /** - * Resultado del análisis de un archivo OpenAPI/Swagger. - * Contiene las estructuras crudas extraídas del spec para su posterior procesamiento. + * Result of parsing an OpenAPI/Swagger file. + * Contains the raw structures extracted from the spec for further processing. */ export interface SwaggerAnalysis { tags: unknown[]; diff --git a/src/utils/environment-finder.ts b/src/utils/environment-finder.ts index d358eb0..2bd9296 100644 --- a/src/utils/environment-finder.ts +++ b/src/utils/environment-finder.ts @@ -8,6 +8,10 @@ export interface ApiKeyInfo { const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', '.angular', 'coverage', '.cache']); +/** + * Recursively searches for an `environment.ts` file starting from `dir`, + * up to `maxDepth` directory levels deep. + */ export function findEnvironmentFile(dir: string, maxDepth = 8, currentDepth = 0): string | null { if (currentDepth > maxDepth) return null; try { diff --git a/src/utils/filesystem.ts b/src/utils/filesystem.ts index 959b8be..7eaf2a1 100644 --- a/src/utils/filesystem.ts +++ b/src/utils/filesystem.ts @@ -2,7 +2,7 @@ import fs from 'fs-extra'; import path from 'path'; import { logSuccess, logInfo } from './logger'; -/** Crea la estructura de directorios necesaria para Clean Architecture (idempotente). */ +/** Creates the required Clean Architecture directory structure (idempotent). */ export function createDirectoryStructure(baseDir: string): void { const dirs = [ path.join(baseDir, 'data/dtos'), @@ -19,13 +19,13 @@ export function createDirectoryStructure(baseDir: string): void { fs.ensureDirSync(dir); }); - logSuccess('Estructura de directorios creada'); + logSuccess('Directory structure created'); } -/** Elimina un directorio temporal y todo su contenido. */ +/** Removes a temporary directory and all its contents. */ export function cleanup(tempDir: string): void { if (fs.existsSync(tempDir)) { fs.removeSync(tempDir); - logInfo('Archivos temporales eliminados'); + logInfo('Temporary files removed'); } } diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 04e211a..79ae5cd 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -10,32 +10,32 @@ const colors = { type Color = keyof typeof colors; -/** Imprime un mensaje en consola con el color ANSI indicado. */ +/** Prints a console message with the given ANSI colour. */ export function log(message: string, color: Color = 'reset'): void { console.log(`${colors[color]}${message}${colors.reset}`); } -/** Imprime un mensaje de éxito (verde). */ +/** Prints a success message (green). */ export function logSuccess(message: string): void { log(`✅ ${message}`, 'green'); } -/** Imprime un mensaje informativo (azul). */ +/** Prints an informational message (blue). */ export function logInfo(message: string): void { log(`ℹ️ ${message}`, 'blue'); } -/** Imprime un mensaje de advertencia (amarillo). */ +/** Prints a warning message (yellow). */ export function logWarning(message: string): void { log(`⚠️ ${message}`, 'yellow'); } -/** Imprime un mensaje de error (rojo). */ +/** Prints an error message (red). */ export function logError(message: string): void { log(`❌ ${message}`, 'red'); } -/** Imprime un encabezado de paso/etapa (cian). */ +/** Prints a step/stage header (cyan). */ export function logStep(message: string): void { log(`\n🚀 ${message}`, 'cyan'); } diff --git a/src/utils/openapi-generator.ts b/src/utils/openapi-generator.ts index 2233f31..6080cc2 100644 --- a/src/utils/openapi-generator.ts +++ b/src/utils/openapi-generator.ts @@ -1,7 +1,7 @@ import { execSync } from 'child_process'; import { logStep, logSuccess, logError } from './logger'; -/** Verifica si `openapi-generator-cli` está disponible en el PATH. */ +/** Checks whether `openapi-generator-cli` is available on the PATH. */ export function checkOpenApiGenerator(): boolean { try { execSync('openapi-generator-cli version', { stdio: 'ignore' }); @@ -11,14 +11,14 @@ export function checkOpenApiGenerator(): boolean { } } -/** Instala `@openapitools/openapi-generator-cli` de forma global vía npm. */ +/** Installs `@openapitools/openapi-generator-cli` globally via npm. */ export function installOpenApiGenerator(): void { - logStep('Instalando @openapitools/openapi-generator-cli...'); + logStep('Installing @openapitools/openapi-generator-cli...'); try { execSync('npm install -g @openapitools/openapi-generator-cli', { stdio: 'inherit' }); - logSuccess('OpenAPI Generator CLI instalado correctamente'); + logSuccess('OpenAPI Generator CLI installed successfully'); } catch (_error) { - logError('Error al instalar OpenAPI Generator CLI'); + logError('Error installing OpenAPI Generator CLI'); process.exit(1); } } diff --git a/src/utils/type-mapper.ts b/src/utils/type-mapper.ts index b6529b1..a9a4486 100644 --- a/src/utils/type-mapper.ts +++ b/src/utils/type-mapper.ts @@ -1,4 +1,4 @@ -/** Traduce un tipo primitivo de OpenAPI/Swagger al equivalente TypeScript. */ +/** Translates a primitive OpenAPI/Swagger type to its TypeScript equivalent. */ export function mapSwaggerTypeToTs(type?: string): string { if (!type) return 'unknown';