Files
agent/.agent/skills/tech-stack/elysiajs/plugins/openapi.md

4.2 KiB

OpenAPI Plugin

Installation

bun add @elysiajs/openapi

Basic Usage

import { openapi } from '@elysiajs/openapi'

new Elysia()
  .use(openapi())
  .get('/', () => 'hello')

Docs at /openapi, spec at /openapi/json.

Detail Object

Extends OpenAPI Operation Object:

.get('/', () => 'hello', {
  detail: {
    title: 'Hello',
    description: 'An example route',
    summary: 'Short summary',
    deprecated: false,
    hide: true,  // Hide from docs
    tags: ['App']
  }
})

Documentation Config

openapi({
  documentation: {
    info: {
      title: 'API',
      version: '1.0.0'
    },
    tags: [
      { name: 'App', description: 'General' }
    ],
    components: {
      securitySchemes: {
        bearerAuth: { type: 'http', scheme: 'bearer' }
      }
    }
  }
})

Standard Schema Mapping

mapJsonSchema: {
  zod: z.toJSONSchema,  // Zod 4
  valibot: toJsonSchema,
  effect: JSONSchema.make
}

Zod 3: zodToJsonSchema from zod-to-json-schema

OpenAPI Type Gen

Generate docs from types:

import { fromTypes } from '@elysiajs/openapi'

export const app = new Elysia()
  .use(openapi({
    references: fromTypes()
  }))

Production

Recommended to generate .d.ts file for production when using OpenAPI Type Gen

references: fromTypes(
  process.env.NODE_ENV === 'production'
    ? 'dist/index.d.ts'
    : 'src/index.ts'
)

Options

fromTypes('src/index.ts', {
  projectRoot: path.join('..', import.meta.dir),
  tsconfigPath: 'tsconfig.dts.json'
})

Caveat: Explicit Types

Use Prettify helper to inline when type is not showing:

type Prettify<T> = { [K in keyof T]: T[K] } & {}

function getUser(): Prettify<User> { }

Schema Description

body: t.Object({
  username: t.String(),
  password: t.String({
    minLength: 8,
    description: 'Password (8+ chars)'
  })
}, {
  description: 'Expected username and password'
}),
detail: {
  summary: 'Sign in user',
  tags: ['auth']
}

Response Headers

import { withHeader } from '@elysiajs/openapi'

response: withHeader(
  t.Literal('Hi'),
  { 'x-powered-by': t.Literal('Elysia') }
)

Annotation only - doesn't enforce. Set headers manually.

Tags

Define + assign:

.use(openapi({
  documentation: {
    tags: [
      { name: 'App', description: 'General' },
      { name: 'Auth', description: 'Auth' }
    ]
  }
}))
.get('/', () => 'hello', {
  detail: { tags: ['App'] }
})

Instance Tags

new Elysia({ tags: ['user'] })
  .get('/user', 'user')

Reference Models

Auto-generates schemas:

.model({
  User: t.Object({
    id: t.Number(),
    username: t.String()
  })
})
.get('/user', () => ({ id: 1, username: 'x' }), {
  response: { 200: 'User' },
  detail: { tags: ['User'] }
})

Guard

Apply to instance/group:

.guard({
  detail: {
    description: 'Requires auth'
  }
})
.get('/user', 'user')

Security

.use(openapi({
  documentation: {
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT'
        }
      }
    }
  }
}))

new Elysia({
  prefix: '/address',
  detail: {
    security: [{ bearerAuth: [] }]
  }
})

Secures all routes under prefix.

Config

Below is a config which is accepted by the openapi({})

enabled

@default true Enable/Disable the plugin

documentation

OpenAPI documentation information @see https://spec.openapis.org/oas/v3.0.3.html

exclude

Configuration to exclude paths or methods from documentation

exclude.methods

List of methods to exclude from documentation

exclude.paths

List of paths to exclude from documentation

exclude.staticFile

@default true

Exclude static file routes from documentation

exclude.tags

List of tags to exclude from documentation

mapJsonSchema

A custom mapping function from Standard schema to OpenAPI schema

path

@default '/openapi' The endpoint to expose OpenAPI documentation frontend

provider

@default 'scalar'

OpenAPI documentation frontend between:

  • Scalar
  • SwaggerUI
  • null: disable frontend