Skip to content

AsenaJs/asena-openapi

Repository files navigation

@asenajs/asena-openapi

Version License: MIT Bun Version

Automatic OpenAPI 3.1 spec generation for AsenaJS — zero config, uses your existing validators.

Your existing @Controller routes and validator schemas (json(), query(), param(), response()) are automatically converted to a full OpenAPI specification. No extra annotations needed.

Features

  • Zero Config - Extracts schemas from existing validators, no extra annotations needed
  • OpenAPI 3.1 - Generates JSON Schema draft-2020-12 compatible spec
  • Zero Runtime Dependencies - Only peer deps (asena, reflect-metadata, zod)
  • Built-in Swagger UI - CDN-based UI page, no npm install required
  • @Hidden Decorator - Class and method level exclusion from spec
  • Zod v4 Native - Uses z.toJSONSchema() for accurate conversion
  • Pluggable Converters - SchemaConverter interface for custom schema types
  • IoC Integrated - PostProcessor pattern, auto-discovers controllers during bootstrap

Requirements

Installation

bun add @asenajs/asena-openapi

Quick Start

import { OpenApi, OpenApiPostProcessor } from '@asenajs/asena-openapi';

@OpenApi({
  info: { title: 'My API', version: '1.0.0' },
  path: '/api/openapi',
  ui: true, // Swagger UI at /api/openapi/ui
})
export class AppOpenApi extends OpenApiPostProcessor {}

Asena automatically discovers it — that's it.

Now:

  • GET /api/openapi → OpenAPI 3.1 JSON spec
  • GET /api/openapi/ui → Swagger UI page

How It Works

The OpenApiPostProcessor automatically:

  1. Intercepts every @Controller during IoC setup
  2. Extracts route metadata (@Get, @Post, @Put, @Delete)
  3. Resolves validators and converts their Zod schemas to JSON Schema
  4. Generates a complete OpenAPI 3.1 spec
  5. Registers GET endpoints on the adapter for spec and Swagger UI

Your existing validators do double duty — they validate requests AND generate documentation:

@Middleware({ validator: true })
export class CreateUserValidator extends ValidationService {
  // → requestBody (application/json)
  json() {
    return z.object({
      name: z.string().min(1),
      email: z.string().email(),
    });
  }

  // → query parameters
  query() {
    return z.object({
      page: z.coerce.number().optional(),
    });
  }

  // → path parameters
  param() {
    return z.object({
      id: z.string().uuid(),
    });
  }

  // → response schemas by status code
  response() {
    return {
      201: z.object({ id: z.string(), name: z.string() }),
      400: { schema: z.object({ error: z.string() }), description: 'Validation error' },
    };
  }
}

@Hidden

Hide controllers or individual routes from the spec:

// Hide entire controller
@Hidden()
@Controller('/internal')
export class InternalController { ... }

// Hide single route
@Controller('/api')
export class ApiController {
  @Hidden()
  @Get('/health')
  healthCheck() {}

  @Get('/users')  // this route IS in the spec
  listUsers() {}
}

Configuration

OpenApiDecoratorOptions

@OpenApi({
  info: {
    title: 'My API', // Required
    version: '1.0.0', // Required
    description: 'My app', // Optional
  },
  path: '/api/openapi', // Default: '/openapi'
  ui: true, // Default: false — enables Swagger UI at {path}/ui
  servers: [
    // Optional
    { url: 'https://api.example.com', description: 'Production' },
  ],
  converters: [
    // Default: [ZodSchemaConverter]
    new ZodSchemaConverter(),
  ],
})
export class AppOpenApi extends OpenApiPostProcessor {}

Swagger UI

When ui: true, a Swagger UI page is served at {path}/ui. It loads from CDN — zero npm dependencies:

  • Uses swagger-ui-dist@5 from unpkg CDN
  • No build step required
  • Works in development and production

OpenApiGenerator (Legacy)

For manual spec generation without the PostProcessor:

import { OpenApiGenerator, ZodSchemaConverter } from '@asenajs/asena-openapi';

const generator = new OpenApiGenerator({
  info: { title: 'My API', version: '1.0.0' },
  converters: [new ZodSchemaConverter()],
});

const spec = await generator.generate(server.coreContainer.container);

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Maintain test coverage for critical paths
  2. Follow existing code style and linting rules
  3. Test with both Hono and Ergenecore adapters

Submit a Pull Request on GitHub.

License

MIT

Support

Issues or questions? Open an issue on GitHub.

About

OpenAPI 3.1 spec generation for AsenaJS - automatic schema extraction from validators and route decorators

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors