Referencia API
Referencia API
Sección titulada «Referencia API»Referencia API completa para el framework Veloce-TS.
Tabla de Contenidos
Sección titulada «Tabla de Contenidos»- Clases Principales
- Decoradores
- Sistema de Plugins
- Integración Drizzle ORM
- Utilidades de Prueba
- Clases de Error
- Tipos
Clases Principales
Sección titulada «Clases Principales»VeloceTS / Veloce
Sección titulada «VeloceTS / Veloce»Clase principal de la aplicación. Veloce es un alias exportado de VeloceTS (la misma clase).
Constructor
Sección titulada «Constructor»new VeloceTS(config?: VeloceTSConfig)// equivalente: new Veloce(config?: VeloceTSConfig)Parámetros:
config(opcional): Objeto de configuración
Interfaz VeloceTSConfig:
interface VeloceTSConfig { adapter?: 'hono' | 'express' | 'native'; title?: string; version?: string; description?: string; docs?: boolean | { path?: string; openapi?: string }; cors?: CorsOptions | boolean; /** `rfc9457` (defecto desde v0.4.3) o `legacy` */ errorResponseFormat?: 'rfc9457' | 'legacy';}Ejemplo:
const app = new Veloce({ title: 'Mi API', version: '1.0.0', description: 'API para mi aplicación', docs: true, cors: true,});Métodos Principales
Sección titulada «Métodos Principales»include(controller: Class): void
Sección titulada «include(controller: Class): void»Registra una clase controlador con la aplicación.
@Controller('/users')class UserController { @Get('/') async list() { return []; }}
app.include(UserController);get/post/put/delete/patch(path: string, config: RouteConfig): void
Sección titulada «get/post/put/delete/patch(path: string, config: RouteConfig): void»Registra rutas usando la API funcional.
app.get('/users', { handler: async (c) => { return [{ id: 1, name: 'John' }]; },});usePlugin(plugin: Plugin): void
Sección titulada «usePlugin(plugin: Plugin): void»Registra un plugin con la aplicación.
import { OpenAPIPlugin } from 'veloce-ts';
app.usePlugin(new OpenAPIPlugin({ path: '/openapi.json', docsPath: '/docs',}));listen(port: number, callback?: () => void): Server
Sección titulada «listen(port: number, callback?: () => void): Server»Inicia el servidor en el puerto especificado.
app.listen(3000, () => { console.log('Servidor ejecutándose en http://localhost:3000');});getContainer(): DIContainer
Sección titulada «getContainer(): DIContainer»Obtiene el contenedor de inyección de dependencias.
const container = app.getContainer();container.register(DatabaseService, { scope: 'singleton' });Decoradores
Sección titulada «Decoradores»Decoradores de Clase
Sección titulada «Decoradores de Clase»@Controller(prefix?: string)
Sección titulada «@Controller(prefix?: string)»Marca una clase como controlador y opcionalmente establece un prefijo de ruta.
@Controller('/api/users')class UserController { @Get('/') async list() { return []; }}@WebSocket(path: string)
Sección titulada «@WebSocket(path: string)»Marca una clase como manejador de WebSocket.
@WebSocket('/chat')class ChatHandler { @OnConnect() handleConnect(client: WebSocketConnection) { console.log('Conectado'); }}@Resolver()
Sección titulada «@Resolver()»Marca una clase como resolver de GraphQL.
@Resolver()class UserResolver { @Query() async users() { return []; }}Decoradores de Método
Sección titulada «Decoradores de Método»Decoradores de Métodos HTTP
Sección titulada «Decoradores de Métodos HTTP»@Get(path?: string)- Registra una ruta GET@Post(path?: string)- Registra una ruta POST@Put(path?: string)- Registra una ruta PUT@Delete(path?: string)- Registra una ruta DELETE@Patch(path?: string)- Registra una ruta PATCH@All(path?: string)- Responde a todos los métodos HTTP
Ejemplo:
@Get('/users')async getUsers() { return [];}
@Post('/users')async createUser(@Body(UserSchema) user: User) { return user;}Decoradores de GraphQL
Sección titulada «Decoradores de GraphQL»@Query()- Define una consulta GraphQL@Mutation()- Define una mutación GraphQL@Subscription()- Define una suscripción GraphQL
Decoradores de WebSocket
Sección titulada «Decoradores de WebSocket»@OnConnect()- Maneja eventos de conexión@OnMessage(schema?: ZodSchema)- Maneja eventos de mensaje@OnDisconnect()- Maneja eventos de desconexión
Decoradores de Parámetro
Sección titulada «Decoradores de Parámetro»@Body(schema?: ZodSchema)
Sección titulada «@Body(schema?: ZodSchema)»Extrae y valida el cuerpo de la petición.
const UserSchema = z.object({ name: z.string().min(2), email: z.string().email(),});
@Post('/users')async createUser(@Body(UserSchema) user: z.infer<typeof UserSchema>) { return user;}@Query(schema?: ZodSchema)
Sección titulada «@Query(schema?: ZodSchema)»Extrae y valida parámetros de consulta.
const SearchSchema = z.object({ q: z.string(), page: z.string().transform(Number).default('1'),});
@Get('/search')async search(@Query(SearchSchema) query: z.infer<typeof SearchSchema>) { return { query: query.q, page: query.page };}@Param(name?: string)
Sección titulada «@Param(name?: string)»Extrae parámetros de ruta.
@Get('/users/:id')async getUser(@Param('id') id: string) { return { id };}@Header(name?: string, schema?: ZodSchema)
Sección titulada «@Header(name?: string, schema?: ZodSchema)»Extrae y valida encabezados.
@Get('/protected')async getProtected(@Header('authorization') auth: string) { return { auth };}@Cookie(name?: string, schema?: ZodSchema)
Sección titulada «@Cookie(name?: string, schema?: ZodSchema)»Extrae y valida cookies.
@Get('/profile')async getProfile(@Cookie('session') sessionId: string) { return { sessionId };}Inyecta el contexto de Hono (Context). Para el Request estándar de la Web API, usa c.req.raw.
import type { Context } from 'hono';
@Post('/echo')async echo(@Ctx() c: Context) { return await c.req.json();}Inyecta el objeto de petición de Hono (c.req). Se exporta desde veloce-ts. Para el Request (Fetch API), usa @Ctx() y c.req.raw.
@Get('/path')path(@Req() req: import('hono').HonoRequest) { return { path: req.path };}@Depends(provider: Provider, scope?: Scope)
Sección titulada «@Depends(provider: Provider, scope?: Scope)»Inyecta dependencias.
class UserService { async getUsers() { return []; }}
@Controller('/users')class UserController { @Get('/') async list(@Depends(UserService) userService: UserService) { return await userService.getUsers(); }}Sistema de Plugins
Sección titulada «Sistema de Plugins»Interfaz de Plugin
Sección titulada «Interfaz de Plugin»interface Plugin { name: string; version?: string; dependencies?: string[]; install(app: VeloceTS): void | Promise<void>;}Creando un Plugin
Sección titulada «Creando un Plugin»class MyPlugin implements Plugin { name = 'my-plugin'; version = '1.0.0';
install(app: VeloceTS) { // Agregar rutas app.get('/plugin-route', { handler: async (c) => { return { message: 'Desde el plugin' }; }, }); }}Plugins Integrados
Sección titulada «Plugins Integrados»OpenAPIPlugin
Sección titulada «OpenAPIPlugin»import { OpenAPIPlugin } from 'veloce-ts';
app.usePlugin(new OpenAPIPlugin({ path: '/openapi.json', docsPath: '/docs', title: 'Mi API', version: '1.0.0',}));GraphQLPlugin
Sección titulada «GraphQLPlugin»import { GraphQLPlugin } from 'veloce-ts';
app.usePlugin(new GraphQLPlugin({ path: '/graphql', playground: true,}));Integración Drizzle ORM
Sección titulada «Integración Drizzle ORM»Conecta Drizzle (u otro ORM) al contenedor de inyección de dependencias.
registerDrizzle(app, db, token?)
Sección titulada «registerDrizzle(app, db, token?)»Registra una instancia de base de datos como singleton en el DIContainer.
Parámetros:
app: Instancia de la aplicación VeloceTSdb: Instancia de la base de datos (Drizzle u otro ORM)token(opcional): Token de inyección personalizado (por defectoDB_TOKEN)
Ejemplo:
import { registerDrizzle } from 'veloce-ts';import { drizzle } from 'drizzle-orm/bun-sqlite';
const db = drizzle(new Database('mi-base.db'));registerDrizzle(app, db);@InjectDB(token?)
Sección titulada «@InjectDB(token?)»Decorador de parámetro que inyecta la instancia de base de datos registrada. Es un alias de @Depends(DB_TOKEN).
Ejemplo:
import { InjectDB } from 'veloce-ts';
@Controller('/productos')class ProductoController { @Get('/') async listar(@InjectDB() db: typeof drizzleDb) { return await db.select().from(productos); }
@Post('/') @HttpCode(201) async crear( @Body(CreateProductoSchema) data: any, @InjectDB() db: typeof drizzleDb ) { return await db.insert(productos).values(data).returning(); }}DB_TOKEN
Sección titulada «DB_TOKEN»Símbolo por defecto usado como token de inyección para la instancia de base de datos.
Utilidades de Prueba
Sección titulada «Utilidades de Prueba»createTestApp(config?: VeloceTSConfig): VeloceTS
Sección titulada «createTestApp(config?: VeloceTSConfig): VeloceTS»Crea una instancia de prueba de la aplicación.
import { createTestApp } from 'veloce-ts/testing';
const app = createTestApp();app.include(UserController);TestClient
Sección titulada «TestClient»Cliente HTTP para hacer peticiones de prueba con una API de aserciones fluente.
Métodos de petición:
get(path, options?),post(path, body?, options?),put(path, body?, options?),delete(path, options?),patch(path, body?, options?)
Helpers de autenticación:
withToken(token)— instancia inmutable conAuthorization: Bearer <token>pre-establecidowithHeaders(headers)— instancia inmutable con headers adicionalesloginAs(credentials, endpoint?)— hace login y devuelve un cliente autenticadoregisterAndLogin(user, endpoints?)— registra y hace login en una sola llamadaclearAuth()— limpia el token almacenado
TestResponse
Sección titulada «TestResponse»Envoltorio de respuesta con métodos de aserción encadenables.
Propiedades: status, ok, headers, body, text
Métodos de aserción:
expectStatus(code),expectOk(),expectCreated(),expectNotFound(),expectUnauthorized()expectJson(partialObject)— verificación parcial del bodyexpectField(field, value?)— verificar un campo específicoexpectHeader(name, value?)— verificar un header de respuestaexpectArrayLength(n)— verificar longitud de array
import { TestClient } from 'veloce-ts/testing';
const client = new TestClient(app);
// Aserciones fluentesconst response = await client.get('/usuarios');await response.expectOk().expectArrayLength(2);
// Helper de autenticaciónconst authClient = await client.loginAs({ email: 'usuario@ejemplo.com', password: 'contraseña123'});await authClient.get('/perfil').then(r => r.expectOk());
// Aserciones encadenadasconst res = await client.post('/productos', { nombre: 'Producto A', precio: 29.99 });await res.expectCreated().expectField('id').expectJson({ nombre: 'Producto A' });mockDependency(provider: Class, mock: any): void
Sección titulada «mockDependency(provider: Class, mock: any): void»Simula una dependencia en el contenedor DI.
import { mockDependency } from 'veloce-ts/testing';
const mockUserService = { getUsers: async () => [{ id: 1, name: 'Prueba' }],};
mockDependency(UserService, mockUserService);Clases de Error
Sección titulada «Clases de Error»HTTPException
Sección titulada «HTTPException»Clase de excepción base para errores HTTP.
import { HTTPException } from 'veloce-ts';
@Get('/users/:id')async getUser(@Param('id') id: string) { const user = await db.getUserById(id);
if (!user) { throw new HTTPException(404, 'Usuario no encontrado'); }
return user;}ValidationException
Sección titulada «ValidationException»Excepción para errores de validación (422). La respuesta incluye detalles estructurados con field, message, code, y opcionalmente received, expected, minimum, maximum.
import { ValidationException } from 'veloce-ts';throw new ValidationException([{ path: 'email', message: 'Email inválido' }]);NotFoundException
Sección titulada «NotFoundException»Excepción para recursos no encontrados (404).
import { NotFoundException } from 'veloce-ts';throw new NotFoundException('Usuario no encontrado');UnauthorizedException
Sección titulada «UnauthorizedException»Excepción para errores de autenticación (401).
import { UnauthorizedException } from 'veloce-ts';throw new UnauthorizedException('Credenciales inválidas');ForbiddenException
Sección titulada «ForbiddenException»Excepción para acceso prohibido (403).
import { ForbiddenException } from 'veloce-ts';throw new ForbiddenException('Acceso denegado');ConflictException
Sección titulada «ConflictException»Excepción para conflictos de datos (409).
import { ConflictException } from 'veloce-ts';throw new ConflictException('El email ya está registrado');GoneException
Sección titulada «GoneException»Excepción para recursos eliminados permanentemente (410).
import { GoneException } from 'veloce-ts';throw new GoneException('Este recurso ya no existe');PayloadTooLargeException
Sección titulada «PayloadTooLargeException»Excepción para cuerpos de petición demasiado grandes (413).
import { PayloadTooLargeException } from 'veloce-ts';throw new PayloadTooLargeException('El archivo supera el límite de 10MB');UnprocessableEntityException
Sección titulada «UnprocessableEntityException»Excepción para fallos de validación semántica (422).
import { UnprocessableEntityException } from 'veloce-ts';throw new UnprocessableEntityException('La edad debe ser mayor de 18 años');TooManyRequestsException
Sección titulada «TooManyRequestsException»Excepción para límite de peticiones excedido (429).
import { TooManyRequestsException } from 'veloce-ts';throw new TooManyRequestsException('Demasiadas peticiones. Intenta de nuevo en 1 minuto.');ServiceUnavailableException
Sección titulada «ServiceUnavailableException»Excepción para servicio no disponible (503).
import { ServiceUnavailableException } from 'veloce-ts';throw new ServiceUnavailableException('La base de datos no está disponible temporalmente');VeloceTSConfig
Sección titulada «VeloceTSConfig»interface VeloceTSConfig { adapter?: 'hono' | 'express' | 'native'; title?: string; version?: string; description?: string; docs?: boolean | { path?: string; openapi?: string }; cors?: CorsOptions | boolean; errorResponseFormat?: 'rfc9457' | 'legacy';}Los plugins se registran con app.usePlugin(new AlgunPlugin()); no existe el campo plugins: [] en esta configuración.
Middleware
Sección titulada «Middleware»type Middleware = (c: Context, next: () => Promise<void>) => Promise<void> | void;type Scope = 'singleton' | 'request' | 'transient';WebSocketConnection
Sección titulada «WebSocketConnection»interface WebSocketConnection { id: string; send(data: any): void; broadcast(data: any, includeSelf?: boolean): void; join(room: string): void; leave(room: string): void; close(): void;}Próximos Pasos
Sección titulada «Próximos Pasos»- Lee la Guía de Decoradores
- Aprende sobre Inyección de Dependencias
- Explora Plugins
- Revisa la Guía de Pruebas
- Ve la Guía de Inicio