Saltearse al contenido

Guía CLI

Veloce-TS incluye una CLI integrada para crear proyectos y generar código. Todos los archivos generados superan bun run typecheck sin ningún cambio.

Los binarios veloce y veloce-ts están disponibles tras instalar el paquete:

Ventana de terminal
bun add veloce-ts
# o de forma global
bun add -g veloce-ts

Genera un proyecto completo.

Ventana de terminal
veloce new mi-api

Estructura generada:

mi-api/
├── src/
│ ├── index.ts # entrada de la app con llamadas usePlugin
│ ├── app.module.ts # barrel a nivel de app
│ └── modules/
│ └── health/
│ ├── health.controller.ts
│ └── health.module.ts
├── tests/
│ └── health.test.ts
├── package.json # dep veloce-ts, scripts bun
├── tsconfig.json # decoradores Stage-2 + reflect-metadata
└── .env.example

Templates:

Ventana de terminal
veloce new mi-api # REST (por defecto)
veloce new mi-api --template rest
veloce new mi-api --template fullstack # incluye plugins GraphQL + WebSocket

Genera piezas individuales de tu aplicación. Todos los comandos aceptan un argumento <nombre>.

Genera una carpeta de módulo completa: controlador + servicio + DTO + barrel.

Ventana de terminal
veloce generate module users

Salida en src/modules/users/:

users.controller.ts # @Controller('/users') con stubs CRUD
users.service.ts # servicio @Injectable()
users.dto.ts # CreateUsersDto, UpdateUsersDto (Zod)
users.module.ts # barrel: re-exporta controlador + servicio
Ventana de terminal
veloce generate controller products
src/controllers/products.controller.ts
import { Controller, Get, Post, Put, Delete, Param, Body } from 'veloce-ts';
import { z } from 'zod';
const CreateProductsSchema = z.object({
name: z.string().min(1),
});
@Controller('/products')
export class ProductsController {
@Get('/')
async findAll() {
return [];
}
@Get('/:id')
async findOne(@Param('id') id: string) {
return { id };
}
@Post('/')
async create(@Body(CreateProductsSchema) body: z.infer<typeof CreateProductsSchema>) {
return body;
}
@Put('/:id')
async update(@Param('id') id: string, @Body() body: unknown) {
return { id, ...body as object };
}
@Delete('/:id')
async remove(@Param('id') id: string) {
return { id, deleted: true };
}
}
Ventana de terminal
veloce generate service products
src/services/products.service.ts
import { Injectable } from 'veloce-ts';
@Injectable()
export class ProductsService {
async findAll() {
return [];
}
async findOne(id: string) {
return { id };
}
async create(data: unknown) {
return data;
}
async update(id: string, data: unknown) {
return { id, ...data as object };
}
async remove(id: string) {
return { id, deleted: true };
}
}
Ventana de terminal
veloce generate dto create-product
src/dtos/create-product.dto.ts
import { z } from 'zod';
export const CreateProductSchema = z.object({
name: z.string().min(1),
});
export type CreateProductDto = z.infer<typeof CreateProductSchema>;
Ventana de terminal
veloce generate resolver user
src/resolvers/user.resolver.ts
import { Resolver, GQLQuery, GQLMutation, Arg } from 'veloce-ts/graphql';
import { z } from 'zod';
@Resolver('user')
export class UserResolver {
@GQLQuery('getUsers')
async getAll() {
return [];
}
@GQLQuery('getUser')
async getOne(@Arg('id', z.string()) id: string) {
return { id };
}
@GQLMutation('createUser')
async create(@Arg('name', z.string()) name: string) {
return { id: Date.now().toString(), name };
}
}
Ventana de terminal
veloce generate middleware auth
src/middleware/auth.middleware.ts
import type { Context, Next } from 'hono';
export async function authMiddleware(c: Context, next: Next) {
const token = c.req.header('authorization');
if (!token) {
return c.json({ error: 'No autorizado' }, 401);
}
await next();
}
Ventana de terminal
veloce generate plugin analytics
src/plugins/analytics.plugin.ts
import type { VelocePlugin, VeloceTS } from 'veloce-ts';
export class AnalyticsPlugin implements VelocePlugin {
name = 'analytics';
async register(app: VeloceTS): Promise<void> {
// registra rutas o middleware aquí
}
}
ComandoRuta de salida
generate module <nombre>src/modules/<nombre>/
generate controller <nombre>src/controllers/<nombre>.controller.ts
generate service <nombre>src/services/<nombre>.service.ts
generate dto <nombre>src/dtos/<nombre>.dto.ts
generate resolver <nombre>src/resolvers/<nombre>.resolver.ts
generate middleware <nombre>src/middleware/<nombre>.middleware.ts
generate plugin <nombre>src/plugins/<nombre>.plugin.ts

La CLI detecta un directorio src/ existente y coloca los archivos allí. Si no se encuentra src/, los archivos se colocan en el directorio actual.

El argumento <nombre> se normaliza automáticamente:

EntradaPascalCasekebab-case
userUseruser
UserProfileUserProfileuser-profile
create-productCreateProductcreate-product