CLI Guide
CLI Guide
Section titled “CLI Guide”Veloce-TS ships with a built-in CLI for project creation and code generation. Every generated file passes bun run typecheck out of the box.
Installation
Section titled “Installation”The veloce and veloce-ts binaries are available after installing the package:
bun add veloce-ts# or globallybun add -g veloce-tsveloce new <name>
Section titled “veloce new <name>”Scaffolds a complete project.
veloce new my-apiGenerated structure:
my-api/├── src/│ ├── index.ts # app entry with usePlugin calls│ ├── app.module.ts # app-level barrel│ └── modules/│ └── health/│ ├── health.controller.ts│ └── health.module.ts├── tests/│ └── health.test.ts├── package.json # veloce-ts dep, bun scripts├── tsconfig.json # Stage-2 decorators + reflect-metadata└── .env.exampleTemplates:
veloce new my-api # REST (default)veloce new my-api --template restveloce new my-api --template fullstack # includes GraphQL + WebSocket pluginsveloce generate
Section titled “veloce generate”Generate individual pieces of your application. All commands accept a <name> argument.
generate module <name>
Section titled “generate module <name>”Generates a full module folder: controller + service + DTO + barrel.
veloce generate module usersOutput in src/modules/users/:
users.controller.ts # @Controller('/users') with CRUD stubsusers.service.ts # @Injectable() serviceusers.dto.ts # CreateUsersDto, UpdateUsersDto (Zod)users.module.ts # barrel: re-exports controller + servicegenerate controller <name>
Section titled “generate controller <name>”veloce generate controller productsimport { 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 }; }}generate service <name>
Section titled “generate service <name>”veloce generate service productsimport { 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 }; }}generate dto <name>
Section titled “generate dto <name>”veloce generate dto create-productimport { z } from 'zod';
export const CreateProductSchema = z.object({ name: z.string().min(1),});
export type CreateProductDto = z.infer<typeof CreateProductSchema>;generate resolver <name>
Section titled “generate resolver <name>”veloce generate resolver userimport { 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 }; }}generate middleware <name>
Section titled “generate middleware <name>”veloce generate middleware authimport 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: 'Unauthorized' }, 401); } await next();}generate plugin <name>
Section titled “generate plugin <name>”veloce generate plugin analyticsimport type { VelocePlugin, VeloceTS } from 'veloce-ts';
export class AnalyticsPlugin implements VelocePlugin { name = 'analytics';
async register(app: VeloceTS): Promise<void> { // register routes or middleware here }}Placement rules
Section titled “Placement rules”| Command | Output path |
|---|---|
generate module <name> | src/modules/<name>/ |
generate controller <name> | src/controllers/<name>.controller.ts |
generate service <name> | src/services/<name>.service.ts |
generate dto <name> | src/dtos/<name>.dto.ts |
generate resolver <name> | src/resolvers/<name>.resolver.ts |
generate middleware <name> | src/middleware/<name>.middleware.ts |
generate plugin <name> | src/plugins/<name>.plugin.ts |
The CLI detects an existing src/ directory and places files there. If src/ is not found, files are placed in the current directory.
Name normalization
Section titled “Name normalization”The <name> argument is normalized automatically:
| Input | PascalCase | kebab-case |
|---|---|---|
user | User | user |
UserProfile | UserProfile | user-profile |
create-product | CreateProduct | create-product |