Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
# 1.3.1
# 1.3.2 - 22 Aug 2025
Feature:
- add `withHeader` for adding custom headers to response schema
- spread all possible path for optional params
- provider can be `null` to disable provider
- export `toOpenAPI` to generate spec programmatically

Breaking change:
- rename `@elysiajs/swagger` to `@elysiajs/openapi`
- map all `swagger`, and `scalar` prefix to respective `swagger` and `scalar` properties
- rename `swaggerConfig`, and `scalarConfig` to `swagger` and `scalar` respectively
- map `excludePaths`, `excludeMethods`, `excludeTags`, `excludeStaticFiles` to property of `excludes`

Comment on lines +1 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Document the breaking changes clearly but fix formatting issues.

The changelog properly documents the major refactoring from Swagger to OpenAPI, but there are formatting issues that need to be addressed.

Apply this diff to fix the formatting issues:

-# 1.3.2 - 22 Aug 2025
-Feature:
+# 1.3.2 - 22 Aug 2025
+Features:
 - add `withHeader` for adding custom headers to response schema
 - spread all possible path for optional params
 - provider can be `null` to disable provider
 - export `toOpenAPI` to generate spec programmatically

-Breaking change:
+Breaking changes:
 - rename `@elysiajs/swagger` to `@elysiajs/openapi`
 - map all `swagger`, and `scalar` prefix to respective `swagger` and `scalar` properties
 - rename `swaggerConfig`, and `scalarConfig` to `swagger` and `scalar` respectively
-- map `excludePaths`, `excludeMethods`, `excludeTags`, `excludeStaticFiles`	 to property of `excludes`
+- map `excludePaths`, `excludeMethods`, `excludeTags`, `excludeStaticFiles` to property of `excludes`

-# 1.3.1 - 28 Jun 2025
+# 1.3.1 - 28 Jun 2025
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 1.3.2 - 22 Aug 2025
Feature:
- add `withHeader` for adding custom headers to response schema
- spread all possible path for optional params
- provider can be `null` to disable provider
- export `toOpenAPI` to generate spec programmatically
Breaking change:
- rename `@elysiajs/swagger` to `@elysiajs/openapi`
- map all `swagger`, and `scalar` prefix to respective `swagger` and `scalar` properties
- rename `swaggerConfig`, and `scalarConfig` to `swagger` and `scalar` respectively
- map `excludePaths`, `excludeMethods`, `excludeTags`, `excludeStaticFiles` to property of `excludes`
# 1.3.2 - 22 Aug 2025
Features:
- add `withHeader` for adding custom headers to response schema
- spread all possible path for optional params
- provider can be `null` to disable provider
- export `toOpenAPI` to generate spec programmatically
Breaking changes:
- rename `@elysiajs/swagger` to `@elysiajs/openapi`
- map all `swagger`, and `scalar` prefix to respective `swagger` and `scalar` properties
- rename `swaggerConfig`, and `scalarConfig` to `swagger` and `scalar` respectively
- map `excludePaths`, `excludeMethods`, `excludeTags`, `excludeStaticFiles` to property of `excludes`
# 1.3.1 - 28 Jun 2025
🧰 Tools
🪛 LanguageTool

[grammar] ~1-~1: There might be a mistake here.
Context: # 1.3.2 - 22 Aug 2025 Feature: - add withHeader for adding c...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)

12-12: Hard tabs
Column: 76

(MD010, no-hard-tabs)

🤖 Prompt for AI Agents
In CHANGELOG.md around lines 1 to 13, tidy the formatting of the release notes:
ensure the top-level heading is "## 1.3.2 - 22 Aug 2025" (use a consistent
markdown header level), add blank lines between the header and sections, change
"Feature:" and "Breaking change:" to bold section headings like "### Features"
and "### Breaking changes", normalize bullet items to start with "- " and keep
code identifiers wrapped in backticks (e.g., `withHeader`, `toOpenAPI`), rename
"Breaking change:" to plural and make each mapping line consistent (e.g., "-
rename `@elysiajs/swagger` to `@elysiajs/openapi`"), fix the tab/spacing issue
on the last mapping line so it reads "- map `excludePaths`, `excludeMethods`,
`excludeTags`, `excludeStaticFiles` to properties of `excludes`", and ensure
consistent capitalization and punctuation across bullets.

# 1.3.1 - 28 Jun 2025
Bug fix:
- Using relative path for specPath

Expand Down
71 changes: 48 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# @elysiajs/swagger
Plugin for [elysia](https://github.com/elysiajs/elysia) to auto-generate Swagger page.
# @elysiajs/openapi
Plugin for [elysia](https://github.com/elysiajs/elysia) to auto-generate API documentation page.

## Installation
```bash
bun add @elysiajs/swagger
bun add @elysiajs/openapi
```

## Example
```typescript
import { Elysia, t } from 'elysia'
import { swagger } from '@elysiajs/swagger'
import { openapi } from '@elysiajs/openapi'

const app = new Elysia()
.use(swagger())
.use(openapi())
.get('/', () => 'hi', { response: t.String({ description: 'sample description' }) })
.post(
'/json/:id',
Expand Down Expand Up @@ -43,34 +43,59 @@ const app = new Elysia()
.listen(8080);
```

Then go to `http://localhost:8080/swagger`.
Then go to `http://localhost:8080/openapi`.

# config

## provider
@default 'scalar'
Choose between [Scalar](https://github.com/scalar/scalar) & [SwaggerUI](https://github.com/swagger-api/swagger-ui)
## enabled
@default true
Enable/Disable the plugin

## scalar
Customize scalarConfig, refers to [Scalar config](https://github.com/scalar/scalar/blob/main/documentation/configuration.md)
## documentation
OpenAPI documentation information

## swagger
Customize Swagger config, refers to [Swagger 3.0.3 config](https://swagger.io/specification/v3)
@see https://spec.openapis.org/oas/v3.0.3.html

## path
@default '/swagger'
## exclude
Configuration to exclude paths or methods from documentation

The endpoint to expose Swagger
## exclude.methods
List of methods to exclude from documentation

## scalarCDN
Self-host the scalar bundle or point to a different CDN.
## exclude.paths
List of paths to exclude from documentation

## excludeStaticFile
## exclude.staticFile
@default true

Determine if Swagger should exclude static files.
Exclude static file routes from documentation

## exclude
@default []
## exclude.tags
List of tags to exclude from documentation

## path
@default '/openapi'

The endpoint to expose OpenAPI documentation frontend

Paths to exclude from the Swagger endpoint
## provider
@default 'scalar'

OpenAPI documentation frontend between:
- [Scalar](https://github.com/scalar/scalar)
- [SwaggerUI](https://github.com/openapi-api/openapi-ui)
- null: disable frontend

## references
Additional OpenAPI reference for each endpoint

## scalar
Scalar configuration, refers to [Scalar config](https://github.com/scalar/scalar/blob/main/documentation/configuration.md)

## specPath
@default '/${path}/json'

The endpoint to expose OpenAPI specification in JSON format

## swagger
Swagger config, refers to [Swagger config](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/)
42 changes: 21 additions & 21 deletions build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@ import { build, type Options } from 'tsup'
await $`rm -rf dist`

const tsupConfig: Options = {
entry: ['src/**/*.ts'],
splitting: false,
sourcemap: false,
clean: true,
bundle: true
entry: ['src/**/*.ts'],
splitting: false,
sourcemap: false,
clean: true,
bundle: true
} satisfies Options

await Promise.all([
// ? tsup esm
build({
outDir: 'dist',
format: 'esm',
target: 'node20',
cjsInterop: false,
...tsupConfig
}),
// ? tsup cjs
build({
outDir: 'dist/cjs',
format: 'cjs',
target: 'node20',
// dts: true,
...tsupConfig
})
// ? tsup esm
build({
outDir: 'dist',
format: 'esm',
target: 'node20',
cjsInterop: false,
...tsupConfig
}),
// ? tsup cjs
build({
outDir: 'dist/cjs',
format: 'cjs',
target: 'node20',
// dts: true,
...tsupConfig
})
])

await $`tsc --project tsconfig.dts.json`
Expand Down
95 changes: 60 additions & 35 deletions bun.lock

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions example/gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Elysia, t } from 'elysia'
import { openapi } from '../src/index'
import { fromTypes } from '../src/gen'

export const app = new Elysia()
.use(
openapi({
references: fromTypes('example/gen.ts')
})
)
.get('/', { test: 'hello' as const })
.post(
'/json',
({ body, status }) => (Math.random() > 0.5 ? status(418) : body),
{
body: t.Object({
hello: t.String()
})
}
)
.get('/id/:id/name/:name', ({ params }) => params)
.listen(3000)
78 changes: 52 additions & 26 deletions example/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { Elysia, t } from 'elysia'
import { swagger } from '../src/index'
import { openapi, withHeaders } from '../src/index'

const schema = t.Object({
test: t.Literal('hello')
})

const app = new Elysia({ prefix: '/api' })
const schema2 = t.Object({
test: t.Literal('world')
})

const user = t.Object({
name: t.String({
example: 'saltyaom'
})
})

export const app = new Elysia()
.use(
swagger({
openapi({
provider: 'scalar',
documentation: {
info: {
title: 'Elysia Scalar',
version: '0.8.1'
version: '1.3.1a'
},
tags: [
{
Expand All @@ -21,39 +31,55 @@ const app = new Elysia({ prefix: '/api' })
}
],
components: {
schemas: {
User: {
description: 'string'
}
},
securitySchemes: {
JwtAuth: {
bearer: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description: 'Enter JWT Bearer token **_only_**'
scheme: 'bearer'
},
cookie: {
type: 'apiKey',
in: 'cookie',
name: 'session_id'
}
}
}
},
swaggerOptions: {
persistAuthorization: true
}
})
)
.model({ schema })
.model({ schema, schema2, user })
.get(
'/',
() => {
return { test: 'hello' as const }
},
{ test: 'hello' as const },
{
response: {
200: t.Object({
test: t.Literal('hello')
}),
204: withHeaders(
t.Void({
title: 'Thing',
description: 'Void response'
}),
{
'X-Custom-Header': t.Literal('Elysia')
}
)
}
}
)
.post(
'/json',
({ body }) => ({
test: 'world'
}),
{
response: 'schema'
parse: ['json', 'formdata'],
body: 'user',
response: {
200: 'schema',
400: 'schema2'
}
}
)
.post('/json', ({ body }) => body, {
parse: ['json', 'formdata'],
body: 'schema',
response: 'schema'
})
.get('/id/:id/name/:name', () => {})
.listen(3000)
46 changes: 0 additions & 46 deletions example/index2.ts

This file was deleted.

Loading