Changelog
Changelog
Section titled “Changelog”All notable changes to Veloce-TS are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Section titled “[Unreleased]”[0.4.5] - 2026-03-29
Section titled “[0.4.5] - 2026-03-29”- CORS on error responses: error handler responses (401, 422, 500,
application/problem+json, etc.) now includeAccess-Control-Allow-Originand the rest of the configured CORS headers, consistent with successful responses (mergeVeloceCorsHeaders,VELOCE_CORS_HEADERS_KEY,VeloceCorsHeadersSnapshot).
- Same CORS fix as attempted in 0.4.4; npm does not allow republishing an unpublished version, so 0.4.5 is the installable release.
[0.4.4] - 2026-03-28
Section titled “[0.4.4] - 2026-03-28”Do not use: the npm tarball was broken (404). After unpublish, the registry blocks reusing this version number. Use 0.4.5 for the CORS fix.
[0.4.3] - 2026-03-27
Section titled “[0.4.3] - 2026-03-27”- RFC 9457 (Problem Details): error responses default to
Content-Type: application/problem+jsonwithtype,title,status,detail,instance, and extensions (violations/detailsfor validation;debugon 500 in development only). VeloceTSConfig.errorResponseFormat:'rfc9457'(default) or'legacy'for the previous{ error, statusCode, details? }JSON shape.- Exported helpers:
problemTypeUri,resolveProblemType,resolveProblemTitle,buildProblemInstance,toLegacyErrorBody,sendErrorResponse,PROBLEM_JSON_MEDIA_TYPE,DEFAULT_PROBLEM_TYPE_BASE. HTTPExceptionOptions: optionalproblemTypeandtitleonHTTPException.
Changed
Section titled “Changed”- Auth exceptions (
AuthenticationException,AuthorizationException) use the unified error format withauthentication-error/authorization-errorproblem types.
Documentation
Section titled “Documentation”@moduleheaders across core, errors, validation, DI, responses, logging, middleware, adapters, testing, and barrels.- Benchmarks refreshed for v0.4.3.
- Error JSON still includes
errorandstatusCodealongside RFC 9457 fields. Clients that requireapplication/jsonon errors can seterrorResponseFormat: 'legacy'.
[0.4.2] - 2026-03-27
Section titled “[0.4.2] - 2026-03-27”- HealthCheckPlugin: checker names are set in a Bun-safe way (
Object.defineProperty+ fallback) so assigning.nameon async checkers no longer throws. @Reqexport: the parameter decorator is now exported from the main package entry (import { Req } from 'veloce-ts').
Documentation
Section titled “Documentation”- Guides and API reference updated for
@Ctx(),@Req(), and the real HealthCheckPlugin API (checksarray,HealthCheckers.database/memory/disk).
[0.4.1] - 2026-03-27
Section titled “[0.4.1] - 2026-03-27”include()no longer drops decorator-set route fields such asstatusCode(@HttpCode) andresponseSchema(@ResponseSchema) when registering controller routes.
- Comprehensive test suite (53 tests) covering functional API routing, decorator routing, body/query validation, HTTP exceptions, and DI container.
- Console-based fallback logger: if
pinois not installed the framework falls back silently toconsoleinstead of crashing.
Changed
Section titled “Changed”pino,pino-pretty, andioredismoved tooptionalDependencies— no longer installed automatically (~7 MB lighter install by default). Install explicitly withbun add pino pino-prettyorbun add ioredisif needed.winstonremoved from dependencies (it was listed but never used).- Core bundle reduced from 444 KB → 408 KB (minified ESM).
Deprecated
Section titled “Deprecated”FastAPITSnamed export: useVeloceTSor the shorterVelocealias.FastAPITSwill be removed in v1.0.0.
[0.4.0] - 2026-03-27
Section titled “[0.4.0] - 2026-03-27”This release is the largest update since the initial launch — over 25 new features spread across three waves of work (high, medium, and low priority), covering the full chain from route generation to OpenAPI documentation, testing, ORM, and the CLI.
🚀 New Decorators
Section titled “🚀 New Decorators”OpenAPI Shorthand Decorators
Section titled “OpenAPI Shorthand Decorators”Five one-liner decorators as a concise alternative to @ApiDoc({...}):
@Summary(text)— short description visible in the Swagger UI route list@Description(text)— long description shown in the operation detail panel@Tag(name)— assigns a single tag; stackable with multiple@Tag@Tags(...names)— assigns several tags in a single decorator@Deprecated()— marks the route as deprecated (shown with strikethrough in Swagger UI)
@Get('/products')@Summary('List all products')@Description('Returns a paginated list of all available products')@Tags('Products', 'Catalog')async listProducts() { return products;}
@Delete('/products/:id')@Deprecated()@Summary('Delete a product (deprecated)')async deleteProduct(@Param('id') id: string) { return { success: true };}Response Control Decorators
Section titled “Response Control Decorators”@HttpCode(statusCode)— overrides the HTTP response code for the handler (e.g.201for creation). Also used by the OpenAPI generator as the documented success code@ResponseSchema(schema, statusCode?)— validates and sanitizes the handler response with a Zod schema; informs the response model in the OpenAPI spec
@Post('/products')@HttpCode(201)@ResponseSchema(ProductSchema)async createProduct(@Body(CreateProductSchema) data: any) { return await db.create(data);}Declarative Per-Route Middleware
Section titled “Declarative Per-Route Middleware”@Timeout(ms, message?)— aborts the request with 408 Request Timeout if the handler exceeds the limit. Automatically injects the middleware at the start of the pipeline and emits theX-Timeout-Msheader@RateLimit(options)— applies rate-limiting at the individual route level using the same configuration ascreateRateLimitMiddleware(). StandardX-RateLimit-*headers are sent automatically
@Get('/slow-operation')@Timeout(5000, 'Operation timed out')async slowOperation() { await heavyProcessing(); return result;}
@Post('/submit')@RateLimit({ windowMs: 60_000, max: 5 })async submitForm(@Body(FormSchema) data: any) { return process(data);}🛠️ Core Framework Improvements
Section titled “🛠️ Core Framework Improvements”OpenAPI Generator
Section titled “OpenAPI Generator”- Auto-tagging: automatically derives tags from the first path segment (
/products/:id→ tag"Products") without manual annotation - Bearer security scheme: adds
components.securitySchemes.bearerAuthto the spec and appliessecurity: [{ bearerAuth: [] }]to protected routes automatically - Automatic 401: protected routes receive a documented
401 Unauthorizedresponse without additional configuration @HttpCodesupport: uses the decorator’sstatusCodeas the key for the success block inresponses@ResponseSchemain spec: when present, the Zod schema is converted to JSON Schema format for the response content block
HTTP Exception System
Section titled “HTTP Exception System”Six new exception classes for common error cases:
ConflictException(409)GoneException(410)PayloadTooLargeException(413)UnprocessableEntityException(422)TooManyRequestsException(429)ServiceUnavailableException(503)
Structured Logger in ErrorHandler
Section titled “Structured Logger in ErrorHandler”- 5xx errors are logged with
getLogger().errorincluding path, method, status, and stack - 4xx errors are logged as
warnin development environment - Generic uncaught errors also pass through Pino
Decorator Order Fixes
Section titled “Decorator Order Fixes”@UseMiddleware: now always callsMetadataRegistry.defineRouteso middleware is not lost regardless of decorator execution order@Cache/@CacheInvalidate: same pattern — metadata is correctly merged regardless of stacking order
MetadataCompiler — Lazy Cache with Snapshots
Section titled “MetadataCompiler — Lazy Cache with Snapshots”- Lazy compilation: a route is only recompiled if its metadata changed (JSON snapshot comparison)
- Unique IDs for functional handlers via
WeakMap<Function, number>— prevents cache collisions when different app instances register the same path with different handlers (critical bug in parallel tests) clearCache()method exposed to clean state between tests
🧪 TestClient — Fluent API and Auth Helpers
Section titled “🧪 TestClient — Fluent API and Auth Helpers”Complete rewrite of TestClient:
TestResponse— new response class withstatus,headers,body,text,okproperties and chainable assertion methods:expectStatus(code),expectOk(),expectCreated(),expectNotFound(), etc.expectJson(partialObject)— partial body checkexpectField(field, value?)— verify a specific fieldexpectHeader(name, value?)— verify a response headerexpectArrayLength(n)— verify array length in response
withToken(token)— creates an immutable client instance with theAuthorization: Bearerheader already setwithHeaders(headers)— creates an immutable instance with additional headersloginAs(credentials, endpoint?)— logs in, extracts the JWT, and injects it into the current client for subsequent requestsregisterAndLogin(user, endpoints?)— registers and logs in with a single callclearAuth()— clears the stored token
const client = new TestClient(app);
// Fluent assertionsconst response = await client.get('/users');await response.expectOk().expectArrayLength(2);
// Auth helpersconst authClient = await client.loginAs({ email: 'user@example.com', password: 'pass' });await authClient.get('/profile').then(r => r.expectOk());
// Chain assertionsconst res = await client.post('/products', productData);await res.expectCreated().expectField('id').expectJson({ name: 'Product A' });🔌 Plugins and Middleware
Section titled “🔌 Plugins and Middleware”HealthCheckers.disk
Section titled “HealthCheckers.disk”- Uses
fs.statfs(Node 18+ / Bun) to obtain real disk metrics: total, free, used, and percentage - Graceful fallback to
"healthy"on unsupported platforms
CLI — Fixed Fullstack Template
Section titled “CLI — Fixed Fullstack Template”- The
fullstacktemplate now generatessrc/index.tswithGraphQLPluginandWebSocketPlugincorrectly imported and instantiated
Subpath Exports in Build
Section titled “Subpath Exports in Build”- Added
./src/auth/index.ts,./src/adapters/base.ts,./src/adapters/hono.ts,./src/adapters/express.tsas explicit entrypoints soveloce-ts/authandveloce-ts/adapters/*imports work correctly
🗄️ Drizzle ORM — DI Integration
Section titled “🗄️ Drizzle ORM — DI Integration”New module to connect Drizzle (or another ORM) to the dependency injection container:
import { registerDrizzle, InjectDB } from 'veloce-ts';
// Register the DB instanceregisterDrizzle(app, db);
// Inject into controllers@Get('/')async list(@InjectDB() db: DrizzleDB) { return await db.select().from(products);}DB_TOKEN— default symbol for the injection tokenregisterDrizzle(app, db, token?)— registers as singleton in theDIContainer@InjectDB(token?)— parameter decorator, alias of@Depends(DB_TOKEN)
📊 Improved Pagination
Section titled “📊 Improved Pagination”Metadata Enrichment
Section titled “Metadata Enrichment”PaginationMetaincludesfromandto(1-based range, e.g.from: 11, to: 20)CursorPaginatedResultincludescount(actual items returned in the page)
More Precise Cursor Pagination
Section titled “More Precise Cursor Pagination”createCursorPaginatedResult(data, limit, cursorField, hadPrevCursor)— the newhadPrevCursorparameter correctly activateshasPrev: truewhen navigating forward with cursorcreateMultiCursor(entity, fields[])— creates composite cursors by multiple fields for stable ordering (e.g.{ createdAt, id })decodeMultiCursor(cursor)— decodes a multi-field cursor back to an object
Standalone Helpers
Section titled “Standalone Helpers”paginate<T>(data, total, page, limit)— builds{ data, meta }in one call, without instantiatingPaginationHelperparseCursorQuery(query, defaultLimit?, maxLimit?)— extractscursorandlimitfrom query params without throwing exceptionsPaginationHelper.parsePaginationQuery(query, defaultLimit?, maxLimit?)— equivalent for offset pagination
🔌 Express Adapter — ESM Compatibility
Section titled “🔌 Express Adapter — ESM Compatibility”Complete rewrite of the adapter:
- Loads Express lazily and safely using
Function('return require')()for ESM compatibility without needingdeclare const require: any - Accepts a pre-created Express instance as the second constructor argument (to add your own middleware before the bridge)
- Correct handling of raw body (
Buffer) vs parsed body (JSON/urlencoded) - Omits the
transfer-encodingheader when forwarding responses (was a source of errors in Express) - Delegates unexpected errors to the Express error pipeline via
next(err)instead of responding with 500 directly
🐛 Bug Fixes
Section titled “🐛 Bug Fixes”ZodErrorcross-module:instanceof ZodErrorfailed when the consuming app had a different Zod instance than the framework (common withbun link). Added fallbackerror.name === 'ZodError'to guarantee 422 responses in all cases- GET routes marked public returned 401:
app.use()applied middleware to all methods; fixed usingapp.on(['POST', 'PUT', 'DELETE'], path, middleware)to restrict only write methods - Cache collision in MetadataCompiler: different functional handlers with the same path in different app instances shared the incorrect compiled result; fixed with unique IDs per function
@Cache/@UseMiddlewarelost metadata: when stacked in reverse order of decorator execution, metadata could be overwritten; fixed by explicitly updating the registry in each decorator
📋 Improved Validation Messages
Section titled “📋 Improved Validation Messages”The 422 error response now includes additional structured information:
fieldin conventional format:items[0].priceinstead ofitems.0.pricereceived— received type (when Zod reports it)expected— expected type (when applicable)minimum/maximum— numeric limits in range errors
{ "error": "Validation Error", "statusCode": 422, "details": [ { "field": "email", "message": "Invalid email", "code": "invalid_string" }, { "field": "age", "message": "Number must be ≥ 18", "code": "too_small", "minimum": 18 }, { "field": "tags[1]", "message": "String must not be empty", "code": "too_small" } ]}💥 Breaking Changes
Section titled “💥 Breaking Changes”None — all changes are backward compatible. The createCursorPaginatedResult signature has a new optional hadPrevCursor parameter (fourth argument, false by default).
[0.3.3] - 2025-10-31
Section titled “[0.3.3] - 2025-10-31”🐛 Critical Bug Fixes
Section titled “🐛 Critical Bug Fixes”- JSON Response Serialization: Fixed critical bug where JSON responses were not being serialized correctly
- CLI Version Resolution: Confirmed CLI correctly fetches and uses latest npm version
- Application Compilation: Fixed missing
await app.compile()call in generated templates
🔧 CLI Improvements
Section titled “🔧 CLI Improvements”- Version Fetching: CLI now correctly fetches latest version from npm registry
- Template Generation: All templates now include proper
await app.compile()call - Error Handling: Improved error handling in CLI operations
[0.3.2] - 2025-10-31
Section titled “[0.3.2] - 2025-10-31”Patch release with internal build fixes. No functional changes.
[0.3.1] - 2025-10-31
Section titled “[0.3.1] - 2025-10-31”🛠️ CLI Improvements
Section titled “🛠️ CLI Improvements”- Latest Version Fetching: CLI now automatically fetches the latest VeloceTS version from npm registry
- Improved Error Handling: Better error messages and cleanup on project creation failure
- Type Safety: Fixed TypeScript errors in CLI with proper type definitions for npm registry API
- Better User Experience: Enhanced progress messages and visual feedback during project creation
- Robust Fallbacks: Multiple fallback strategies for version detection when npm is unavailable
- npm Registry Integration: Fixed CLI to use correct npm registry endpoint
- Template Compilation: All generated templates include mandatory
await app.compile()call
[0.3.0] - 2025-10-29
Section titled “[0.3.0] - 2025-10-29”🚀 Major Features Added
Section titled “🚀 Major Features Added”Response Caching System
Section titled “Response Caching System”- In-Memory Cache Store: Fast LRU-based caching with automatic cleanup
- Redis Cache Store: Distributed caching support for multi-instance deployments
@Cache()Decorator: Declarative response caching with flexible TTL configuration@CacheInvalidate()Decorator: Pattern-based cache invalidation for mutations- TTL Support: Flexible time-to-live with string format (
'5m','1h','1d') or seconds - Pattern Invalidation: Wildcard pattern matching for cache invalidation (
'products:*') - Cache Headers: Automatic
X-Cacheheaders (HIT/MISS) in responses
@Get('/products')@Cache({ ttl: '5m', key: 'products:list' })async getProducts() { return await db.products.findAll();}
@Post('/products')@CacheInvalidate('products:*')async createProduct(@Body(ProductSchema) data: any) { return await db.products.create(data);}Enhanced Request Context
Section titled “Enhanced Request Context”- Automatic Request IDs: UUID generation for every request
@RequestId()Decorator: Inject request ID into controller methods@AbortSignal()Decorator: Request cancellation support for long-running operations- Request Timeouts: Configurable timeouts per route or globally
X-Request-IDheader: Automatic header in all responses
@Get('/data')async getData( @RequestId() requestId: string, @AbortSignal() signal: AbortSignal) { logger.info({ requestId }, 'Processing request'); return await longRunningQuery(signal);}Logging with Pino
Section titled “Logging with Pino”- Request Context Integration: Automatic request ID in all log entries
- Child Loggers: Enhanced contextual logging with inheritance
- Structured Logging: JSON-formatted logs for production
- Pretty Printing: Human-readable logs for development
🔧 New Middleware
Section titled “🔧 New Middleware”createRequestContextMiddleware(): Initialize request context with ID, timeout, and loggingcreateSimpleRequestIdMiddleware(): Minimal request ID middlewarecreateCacheMiddleware(): Functional API route cachingcreateCacheInvalidationMiddleware(): Functional API cache invalidation
💥 Breaking Changes
Section titled “💥 Breaking Changes”None — all changes are additive and backward compatible.
[0.2.6] - 2025-10-15
Section titled “[0.2.6] - 2025-10-15”- Query Export: Added missing
Queryexport from main index to resolve import conflicts - Parameter Decorators: HTTP
@Querydecorator now properly exported alongside GraphQL decorators - Import Resolution: Fixed “Export named ‘Query’ not found” error in applications
[0.2.5] - 2025-10-15
Section titled “[0.2.5] - 2025-10-15”- GraphQL Query Conflict: Removed conflicting alias
Queryfrom GraphQL decorators - Import Resolution: GraphQL decorators now use
GQLQueryto avoid conflicts with HTTP@Querydecorator - Type Safety: Eliminated TypeScript errors caused by decorator name conflicts
Breaking Changes
Section titled “Breaking Changes”- GraphQL queries now use
@GQLQueryinstead of@Queryto avoid conflicts with HTTP parameter decorator
[0.2.4] - 2025-10-15
Section titled “[0.2.4] - 2025-10-15”- Query Decorator: Fixed
@Querydecorator to properly handle parameters without schemas - Query Parameter Extraction: Improved query parameter handling in router compiler
- Validation: Added proper validation for query parameters with optional Zod schemas
- Error Handling: Fixed missing
ValidationErrorimport, now usingBadRequestException
Improved
Section titled “Improved”- Query Decorator Flexibility:
@Querynow supports multiple usage patterns:@Query()- Extract all query parameters@Query('param')- Extract specific parameter@Query(Schema)- Validate with Zod schema
- Router Compiler: Enhanced parameter extraction and validation logic
- Type Safety: Better TypeScript support for query parameter handling
Breaking Changes
Section titled “Breaking Changes”- None
[0.2.3] - 2025-10-14
Section titled “[0.2.3] - 2025-10-14”- WebSocket Exports: Fixed missing
WebSocketdecorator export from WebSocket module - Import Resolution: WebSocket decorators now properly exported from
veloce-ts/websocket
[0.2.2] - 2025-10-14
Section titled “[0.2.2] - 2025-10-14”- GraphQL Decorators: Added missing
Query,Mutation, andSubscriptionaliases for GraphQL decorators - Import Conflicts: Fixed naming conflicts between params and GraphQL decorators
- GraphQL Aliases: More intuitive names for GraphQL decorators:
@GQLQuery→@Query(GraphQL)@GQLMutation→@Mutation(GraphQL)@GQLSubscription→@Subscription(GraphQL)
[0.2.1] - 2025-10-14
Section titled “[0.2.1] - 2025-10-14”- CLI Version Resolution: Fixed CLI template to always use latest compatible version
- Package Generation: Improved
package.jsongeneration in CLI
[0.2.0] - 2025-10-14
Section titled “[0.2.0] - 2025-10-14”- Major Feature Release: Complete rewrite with enhanced functionality
- Authentication System: JWT-based authentication with refresh tokens
- Role-Based Access Control (RBAC): Hierarchical roles and permissions
- GraphQL Support: Full GraphQL integration with schema generation
- WebSocket Support: Real-time communication capabilities
- SQLite Integration: Built-in database support
- OpenAPI Documentation: Automatic API documentation generation
- CLI Tool: Project scaffolding and code generation
- Dependency Injection: Advanced DI container with scopes
- Middleware System: Custom middleware support
- Validation Engine: Zod-based request validation
- Error Handling: Comprehensive error handling system
Enhanced
Section titled “Enhanced”- Type Safety: Improved TypeScript support throughout
- Performance: Optimized routing and request handling
- Developer Experience: Better debugging and development tools
Breaking Changes
Section titled “Breaking Changes”- Complete API redesign from v0.1.x
- New decorator syntax and patterns
- Updated project structure
[0.1.7] - 2025-10-13
Section titled “[0.1.7] - 2025-10-13”- Minor bug fixes and improvements
[0.1.6] - 2025-10-13
Section titled “[0.1.6] - 2025-10-13”- Basic decorator support
- Simple routing system
[0.1.5] - 2025-10-12
Section titled “[0.1.5] - 2025-10-12”- Initial framework structure
- Core application class
[0.1.4] - 2025-10-12
Section titled “[0.1.4] - 2025-10-12”- Project setup and configuration
[0.1.3] - 2025-10-12
Section titled “[0.1.3] - 2025-10-12”- Basic TypeScript support
[0.1.2] - 2025-10-12
Section titled “[0.1.2] - 2025-10-12”- Initial package configuration
[0.1.1] - 2025-10-12
Section titled “[0.1.1] - 2025-10-12”- Package metadata and basic structure
[0.1.0] - 2025-10-12
Section titled “[0.1.0] - 2025-10-12”- Initial release
- Basic framework structure
- Package setup
:::tip Latest Version We recommend always using the latest version of Veloce-TS for the best experience and latest features. :::
:::note Breaking Changes Breaking changes are clearly marked in each release. Please review the changelog before upgrading to a new major version. :::