exisjs 0.7.11 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -39
- package/dist/cli/commands/dev.d.ts +4 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +136 -32
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/run.d.ts +7 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +99 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/index.js +29 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/manifest.d.ts.map +1 -1
- package/dist/cli/manifest.js +18 -3
- package/dist/cli/manifest.js.map +1 -1
- package/dist/cli/routes.d.ts +6 -0
- package/dist/cli/routes.d.ts.map +1 -1
- package/dist/cli/routes.js +224 -135
- package/dist/cli/routes.js.map +1 -1
- package/dist/config/config.d.ts +2 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +30 -9
- package/dist/config/types.d.ts.map +1 -1
- package/dist/database/lifecycle.d.ts +6 -1
- package/dist/database/lifecycle.d.ts.map +1 -1
- package/dist/database/lifecycle.js +15 -4
- package/dist/database/lifecycle.js.map +1 -1
- package/dist/decorators/params.d.ts +21 -0
- package/dist/decorators/params.d.ts.map +1 -1
- package/dist/decorators/params.js +21 -1
- package/dist/decorators/params.js.map +1 -1
- package/dist/di/container.d.ts +15 -6
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/container.js +26 -3
- package/dist/di/container.js.map +1 -1
- package/dist/di/index.d.ts +1 -1
- package/dist/di/index.d.ts.map +1 -1
- package/dist/di/index.js.map +1 -1
- package/dist/di/inject.d.ts +2 -1
- package/dist/di/inject.d.ts.map +1 -1
- package/dist/di/inject.js +2 -1
- package/dist/di/inject.js.map +1 -1
- package/dist/docs/BENCHMARKS.md +4 -4
- package/dist/docs/content/README.md +43 -44
- package/dist/docs/content/boundaries.mdx +141 -48
- package/dist/docs/content/cli/commands.mdx +161 -107
- package/dist/docs/content/cli/overview.mdx +61 -46
- package/dist/docs/content/cli/usage.mdx +107 -30
- package/dist/docs/content/config.mdx +145 -147
- package/dist/docs/content/controllers.mdx +193 -464
- package/dist/docs/content/cron.mdx +183 -69
- package/dist/docs/content/decorators.mdx +449 -154
- package/dist/docs/content/errors.mdx +202 -305
- package/dist/docs/content/exisjs-mcp.mdx +59 -49
- package/dist/docs/content/installation.mdx +243 -157
- package/dist/docs/content/introduction.mdx +220 -48
- package/dist/docs/content/middleware.mdx +171 -497
- package/dist/docs/content/modules.mdx +141 -83
- package/dist/docs/content/providers.mdx +216 -180
- package/dist/docs/content/requests.mdx +168 -488
- package/dist/docs/content/responses.mdx +200 -533
- package/dist/docs/content/routing.mdx +239 -558
- package/dist/docs/content/security.mdx +233 -57
- package/dist/docs/content/structure.mdx +151 -240
- package/dist/docs/content/swagger.mdx +192 -91
- package/dist/docs/content/testing.mdx +205 -74
- package/dist/docs/content/validation.mdx +479 -341
- package/dist/docs/reference/README.md +34 -2
- package/dist/docs/reference/config.mdx +277 -73
- package/dist/docs/reference/context.mdx +197 -106
- package/dist/docs/reference/cron.mdx +266 -152
- package/dist/docs/reference/database.mdx +135 -53
- package/dist/docs/reference/decorators.mdx +234 -116
- package/dist/docs/reference/di.mdx +146 -112
- package/dist/docs/reference/error.mdx +155 -178
- package/dist/docs/reference/exis.mdx +141 -70
- package/dist/docs/reference/logger.mdx +110 -126
- package/dist/docs/reference/middleware.mdx +235 -158
- package/dist/docs/reference/plugin.mdx +136 -64
- package/dist/docs/reference/router.mdx +277 -251
- package/dist/docs/reference/sanitize.mdx +91 -87
- package/dist/docs/reference/swagger.mdx +280 -100
- package/dist/docs/reference/testing.mdx +223 -89
- package/dist/docs/reference/validator.mdx +194 -206
- package/dist/lib/inspect-routes.d.ts +2 -0
- package/dist/lib/inspect-routes.d.ts.map +1 -0
- package/dist/lib/inspect-routes.js +148 -0
- package/dist/lib/inspect-routes.js.map +1 -0
- package/dist/lib/start-server.js +13 -8
- package/dist/lib/start-server.js.map +1 -1
- package/dist/module/module.d.ts +6 -3
- package/dist/module/module.d.ts.map +1 -1
- package/dist/module/module.js +17 -3
- package/dist/module/module.js.map +1 -1
- package/dist/router/controller-registrar.d.ts.map +1 -1
- package/dist/router/controller-registrar.js +26 -4
- package/dist/router/controller-registrar.js.map +1 -1
- package/dist/router/scanner/cron-mounter.d.ts.map +1 -1
- package/dist/router/scanner/cron-mounter.js +9 -2
- package/dist/router/scanner/cron-mounter.js.map +1 -1
- package/dist/server/app.d.ts +3 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +29 -8
- package/dist/server/app.js.map +1 -1
- package/dist/server/define.d.ts.map +1 -1
- package/dist/server/define.js +5 -0
- package/dist/server/define.js.map +1 -1
- package/dist/server/request.d.ts +2 -0
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +11 -0
- package/dist/server/request.js.map +1 -1
- package/dist/swagger/generator.d.ts.map +1 -1
- package/dist/swagger/generator.js +130 -10
- package/dist/swagger/generator.js.map +1 -1
- package/dist/telemetry/index.d.ts +12 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +121 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/testing/client.d.ts +1 -0
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +4 -1
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +20 -4
- package/dist/testing/index.js.map +1 -1
- package/dist/validator/builder.d.ts +26 -1
- package/dist/validator/builder.d.ts.map +1 -1
- package/dist/validator/builder.js +31 -0
- package/dist/validator/builder.js.map +1 -1
- package/dist/validator/engine.d.ts +23 -0
- package/dist/validator/engine.d.ts.map +1 -1
- package/dist/validator/engine.js +228 -31
- package/dist/validator/engine.js.map +1 -1
- package/dist/validator/index.d.ts +8 -4
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js +4 -1
- package/dist/validator/index.js.map +1 -1
- package/dist/validator/tex-types.d.ts +15 -0
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/dist/validator/tex-types.js +102 -0
- package/dist/validator/tex-types.js.map +1 -1
- package/dist/validator/tex.d.ts +1 -1
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/tex.js +3 -1
- package/dist/validator/tex.js.map +1 -1
- package/dist/validator/types.d.ts +1 -0
- package/dist/validator/types.d.ts.map +1 -1
- package/package.json +47 -14
- package/dist/docs/content/dataloader.mdx +0 -170
- package/dist/docs/reference/dataloader.mdx +0 -91
|
@@ -1,47 +1,51 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
title: "OpenAPI and Swagger Documentation"
|
|
3
|
+
description: "Automatically generate OpenAPI 3.1 specifications and host interactive Swagger UI and Scalar documentation in ExisJS."
|
|
4
|
+
nextUrl: "/docs/testing"
|
|
5
|
+
nextTitle: "Testing Framework"
|
|
4
6
|
---
|
|
5
7
|
|
|
6
|
-
#
|
|
8
|
+
# OpenAPI & Swagger Documentation
|
|
7
9
|
|
|
8
|
-
ExisJS
|
|
10
|
+
ExisJS includes a native **OpenAPI 3.1** documentation engine. It automatically introspects registered routes, parses `tex` and Zod validation schemas, and serves interactive documentation UIs alongside raw JSON specifications.
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
12
|
-
##
|
|
14
|
+
## Enabling Documentation
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
Configure documentation in `exis.config.ts` using `defineConfig`:
|
|
15
17
|
|
|
16
18
|
```typescript filename="exis.config.ts"
|
|
17
19
|
import { defineConfig } from 'exisjs/config'
|
|
18
20
|
|
|
19
21
|
export default defineConfig({
|
|
20
22
|
docs: {
|
|
21
|
-
enabled: true, // Mounts UI
|
|
23
|
+
enabled: true, // Mounts interactive UI and spec endpoint
|
|
24
|
+
path: '/docs', // Base path for UI (default: '/docs')
|
|
25
|
+
specPath: '/docs/json', // OpenAPI 3.1 JSON endpoint (default: '/docs/json')
|
|
22
26
|
title: 'Store API Documentation',
|
|
23
27
|
version: '1.0.0',
|
|
24
|
-
description: '
|
|
28
|
+
description: 'REST API reference with native schema introspection',
|
|
25
29
|
ui: 'swagger-ui', // 'swagger-ui' | 'scalar'
|
|
26
30
|
}
|
|
27
31
|
})
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
When enabled:
|
|
35
|
+
- **Interactive UI**: Navigate to `http://localhost:3000/docs` in your browser.
|
|
36
|
+
- **OpenAPI 3.1 Spec**: Access the JSON schema at `http://localhost:3000/docs/json` (or `/docs/openapi.json`).
|
|
33
37
|
|
|
34
38
|
---
|
|
35
39
|
|
|
36
40
|
## Interactive Documentation UIs
|
|
37
41
|
|
|
38
|
-
ExisJS supports two
|
|
42
|
+
ExisJS supports two documentation renderers:
|
|
39
43
|
|
|
40
44
|
### 1. Swagger UI (`ui: 'swagger-ui'`, default)
|
|
41
|
-
The
|
|
45
|
+
The standard interactive OpenAPI explorer featuring live request execution (**Try it out**), parameter testing, and schema validation previews.
|
|
42
46
|
|
|
43
47
|
### 2. Scalar API Reference (`ui: 'scalar'`)
|
|
44
|
-
A modern,
|
|
48
|
+
A modern, dark-mode-first API reference viewer featuring integrated multi-language code snippets, instant search, and response previews.
|
|
45
49
|
|
|
46
50
|
```typescript filename="exis.config.ts"
|
|
47
51
|
import { defineConfig } from 'exisjs/config'
|
|
@@ -49,16 +53,16 @@ import { defineConfig } from 'exisjs/config'
|
|
|
49
53
|
export default defineConfig({
|
|
50
54
|
docs: {
|
|
51
55
|
enabled: true,
|
|
52
|
-
ui: 'scalar', //
|
|
56
|
+
ui: 'scalar', // Use Scalar instead of Swagger UI
|
|
53
57
|
}
|
|
54
58
|
})
|
|
55
59
|
```
|
|
56
60
|
|
|
57
61
|
---
|
|
58
62
|
|
|
59
|
-
##
|
|
63
|
+
## 1. Functional Paradigm (`route.*`)
|
|
60
64
|
|
|
61
|
-
In
|
|
65
|
+
In functional file-system routing, specify documentation metadata directly inside `route.get()`, `route.post()`, and other method definitions. Schema properties (`query`, `params`, `headers`, `body`) defined using `tex` are automatically converted to OpenAPI 3.1 parameter and request body schemas.
|
|
62
66
|
|
|
63
67
|
```typescript filename="src/http/users/route.ts"
|
|
64
68
|
import { controller, route } from 'exisjs/router'
|
|
@@ -72,25 +76,30 @@ export default controller({
|
|
|
72
76
|
query: tex.pagination({ defaultLimit: 25, maxLimit: 100 }),
|
|
73
77
|
responses: {
|
|
74
78
|
200: {
|
|
75
|
-
description: 'Paginated user
|
|
79
|
+
description: 'Paginated user collection',
|
|
76
80
|
schema: tex.object({
|
|
77
|
-
data: tex.array(
|
|
81
|
+
data: tex.array(
|
|
82
|
+
tex.object({
|
|
83
|
+
id: tex.uuid(),
|
|
84
|
+
name: tex.string(),
|
|
85
|
+
email: tex.email(),
|
|
86
|
+
})
|
|
87
|
+
),
|
|
78
88
|
total: tex.number(),
|
|
89
|
+
skip: tex.number(),
|
|
90
|
+
limit: tex.number(),
|
|
79
91
|
}),
|
|
80
92
|
},
|
|
81
|
-
400: { description: 'Invalid query parameters' },
|
|
93
|
+
400: { description: 'Invalid query pagination parameters' },
|
|
82
94
|
},
|
|
83
95
|
async handle({ query }) {
|
|
84
96
|
const { skip, limit } = getPaginationSkip(query)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
skip,
|
|
92
|
-
limit,
|
|
93
|
-
}
|
|
97
|
+
const [data, total] = await Promise.all([
|
|
98
|
+
db.users.findMany({ skip, take: limit }),
|
|
99
|
+
db.users.count(),
|
|
100
|
+
])
|
|
101
|
+
|
|
102
|
+
return { data, total, skip, limit }
|
|
94
103
|
},
|
|
95
104
|
}),
|
|
96
105
|
|
|
@@ -100,26 +109,29 @@ export default controller({
|
|
|
100
109
|
body: tex.object({
|
|
101
110
|
name: tex.string({ min: 2 }),
|
|
102
111
|
email: tex.email(),
|
|
112
|
+
role: tex.enum(['admin', 'member', 'guest']).optional(),
|
|
103
113
|
}),
|
|
104
114
|
responses: {
|
|
105
115
|
201: { description: 'User successfully created' },
|
|
106
|
-
400: { description: 'Validation
|
|
116
|
+
400: { description: 'Validation failure' },
|
|
107
117
|
},
|
|
108
118
|
async handle({ body }) {
|
|
109
|
-
return
|
|
119
|
+
return await db.users.create(body)
|
|
110
120
|
},
|
|
111
121
|
}),
|
|
112
122
|
|
|
113
123
|
getById: route.get('/:id', {
|
|
114
|
-
summary: 'Get user by
|
|
124
|
+
summary: 'Get user details by ID',
|
|
115
125
|
tags: ['Users'],
|
|
116
|
-
params: tex.object({
|
|
126
|
+
params: tex.object({
|
|
127
|
+
id: tex.uuid(),
|
|
128
|
+
}),
|
|
117
129
|
responses: {
|
|
118
130
|
200: { description: 'User details found' },
|
|
119
131
|
404: { description: 'User not found' },
|
|
120
132
|
},
|
|
121
133
|
async handle({ params }) {
|
|
122
|
-
return
|
|
134
|
+
return await db.users.findById(params.id)
|
|
123
135
|
},
|
|
124
136
|
}),
|
|
125
137
|
})
|
|
@@ -127,9 +139,9 @@ export default controller({
|
|
|
127
139
|
|
|
128
140
|
---
|
|
129
141
|
|
|
130
|
-
##
|
|
142
|
+
## 2. Class-Based (OOP) Paradigm (`@Api*` Decorators)
|
|
131
143
|
|
|
132
|
-
|
|
144
|
+
In class-based controllers in `route.ts`, annotate classes and route methods with documentation decorators from `exisjs/swagger`:
|
|
133
145
|
|
|
134
146
|
```typescript filename="src/http/products/route.ts"
|
|
135
147
|
import { Controller, Get, Post, Body, Param, Query } from 'exisjs/decorators'
|
|
@@ -148,21 +160,22 @@ export default class ProductsController {
|
|
|
148
160
|
@Get('/')
|
|
149
161
|
@ApiOperation({
|
|
150
162
|
summary: 'List products',
|
|
151
|
-
description: 'Fetches paginated
|
|
163
|
+
description: 'Fetches paginated catalog items',
|
|
152
164
|
})
|
|
153
|
-
@ApiResponse({ status: 200, description: 'List of products' })
|
|
165
|
+
@ApiResponse({ status: 200, description: 'List of catalog products' })
|
|
154
166
|
async list(@Query('page') page: number = 1) {
|
|
155
167
|
return [
|
|
156
|
-
{ id:
|
|
157
|
-
{ id:
|
|
168
|
+
{ id: 'prod_1', name: 'Mechanical Keyboard', price: 99 },
|
|
169
|
+
{ id: 'prod_2', name: 'Ergonomic Mouse', price: 49 },
|
|
158
170
|
]
|
|
159
171
|
}
|
|
160
172
|
|
|
161
173
|
@Post('/')
|
|
162
174
|
@ApiOperation({ summary: 'Create new product' })
|
|
163
|
-
@ApiResponse({ status: 201, description: 'Product created' })
|
|
175
|
+
@ApiResponse({ status: 201, description: 'Product created successfully' })
|
|
176
|
+
@ApiResponse({ status: 400, description: 'Invalid product payload' })
|
|
164
177
|
async create(@Body() dto: { name: string; price: number }) {
|
|
165
|
-
return { id:
|
|
178
|
+
return { id: 'prod_3', ...dto }
|
|
166
179
|
}
|
|
167
180
|
|
|
168
181
|
@Get('/:id')
|
|
@@ -174,18 +187,30 @@ export default class ProductsController {
|
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
@Get('/internal/metrics')
|
|
177
|
-
@ApiExclude() // Excluded from Swagger documentation
|
|
178
|
-
async
|
|
190
|
+
@ApiExclude() // Excluded from generated Swagger documentation
|
|
191
|
+
async getInternalMetrics() {
|
|
179
192
|
return { uptime: process.uptime() }
|
|
180
193
|
}
|
|
181
194
|
}
|
|
182
195
|
```
|
|
183
196
|
|
|
197
|
+
### Decorator Reference
|
|
198
|
+
|
|
199
|
+
| Decorator | Target | Description |
|
|
200
|
+
| :--- | :--- | :--- |
|
|
201
|
+
| `@ApiTags(...tags)` | Class / Method | Groups operations under specified tag sections in the documentation UI. |
|
|
202
|
+
| `@ApiOperation(options)` | Method | Specifies `summary`, `description`, `operationId`, and `deprecated` status. |
|
|
203
|
+
| `@ApiResponse(options)` | Method | Documents response status codes, descriptions, and schemas. |
|
|
204
|
+
| `@ApiBearerAuth(name?)` | Class / Method | Applies Bearer JWT authentication requirement to the endpoint. |
|
|
205
|
+
| `@ApiSecurity(name, scopes?)` | Class / Method | Applies a custom security scheme requirement to the endpoint. |
|
|
206
|
+
| `@ApiExclude()` | Class / Method | Excludes the controller or endpoint from generated documentation. |
|
|
207
|
+
| `@ApiProperty(options)` | Class Property | Annotates DTO class properties with description, examples, and enums. |
|
|
208
|
+
|
|
184
209
|
---
|
|
185
210
|
|
|
186
|
-
## Cascading
|
|
211
|
+
## Boundary Cascading Documentation (`boundary.ts`)
|
|
187
212
|
|
|
188
|
-
|
|
213
|
+
Boundaries (`boundary.ts`) apply shared tags or security requirements to all nested routes within a directory hierarchy:
|
|
189
214
|
|
|
190
215
|
```typescript filename="src/http/admin/boundary.ts"
|
|
191
216
|
import { defineBoundary } from 'exisjs/router'
|
|
@@ -198,9 +223,96 @@ export const config = defineBoundary({
|
|
|
198
223
|
|
|
199
224
|
---
|
|
200
225
|
|
|
201
|
-
##
|
|
226
|
+
## Schema Introspection & Multi-Validator Support
|
|
227
|
+
|
|
228
|
+
The OpenAPI generator inspects route validation schemas and automatically translates them into OpenAPI 3.1 JSON Schemas.
|
|
229
|
+
|
|
230
|
+
### 1. Native `tex` Schemas
|
|
231
|
+
|
|
232
|
+
All `tex` primitives, options, and metadata methods translate into OpenAPI properties:
|
|
233
|
+
|
|
234
|
+
```typescript filename="src/http/users/schema.ts"
|
|
235
|
+
import { tex } from 'exisjs/validator'
|
|
236
|
+
|
|
237
|
+
export const UserRegistrationSchema = tex.object({
|
|
238
|
+
username: tex.string({ min: 3, max: 30 })
|
|
239
|
+
.describe('Unique alphanumeric handle')
|
|
240
|
+
.example('alex_dev'),
|
|
241
|
+
email: tex.email()
|
|
242
|
+
.describe('Primary contact email address')
|
|
243
|
+
.example('alex@example.com'),
|
|
244
|
+
age: tex.number({ min: 18 })
|
|
245
|
+
.describe('User age in years')
|
|
246
|
+
.example(25),
|
|
247
|
+
role: tex.enum(['admin', 'member', 'guest'] as const)
|
|
248
|
+
.describe('Assigned account authorization level')
|
|
249
|
+
.example('member'),
|
|
250
|
+
})
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### Discriminated Unions in OpenAPI
|
|
254
|
+
|
|
255
|
+
When using `tex.discriminatedUnion()`, the generator generates an OpenAPI `oneOf` schema along with the `discriminator` mapping:
|
|
256
|
+
|
|
257
|
+
```typescript filename="src/http/events/schema.ts"
|
|
258
|
+
export const PaymentEvent = tex.discriminatedUnion('method', [
|
|
259
|
+
tex.object({ method: tex.literal('card'), cardNumber: tex.creditCard() }),
|
|
260
|
+
tex.object({ method: tex.literal('crypto'), walletAddress: tex.string() }),
|
|
261
|
+
])
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Translates to OpenAPI 3.1:
|
|
265
|
+
|
|
266
|
+
```json
|
|
267
|
+
{
|
|
268
|
+
"oneOf": [
|
|
269
|
+
{
|
|
270
|
+
"type": "object",
|
|
271
|
+
"properties": { "method": { "type": "string", "enum": ["card"] }, "cardNumber": { "type": "string" } },
|
|
272
|
+
"required": ["method", "cardNumber"]
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"type": "object",
|
|
276
|
+
"properties": { "method": { "type": "string", "enum": ["crypto"] }, "walletAddress": { "type": "string" } },
|
|
277
|
+
"required": ["method", "walletAddress"]
|
|
278
|
+
}
|
|
279
|
+
],
|
|
280
|
+
"discriminator": {
|
|
281
|
+
"propertyName": "method"
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### 2. Third-Party Validators (Zod, ArkType, JSON Schema)
|
|
287
|
+
|
|
288
|
+
ExisJS uses multi-validator duck typing to introspect external schemas without requiring adapter packages:
|
|
289
|
+
|
|
290
|
+
```typescript filename="src/http/orders/route.ts"
|
|
291
|
+
import { controller, route } from 'exisjs/router'
|
|
292
|
+
import { z } from 'zod'
|
|
293
|
+
|
|
294
|
+
const OrderSchema = z.object({
|
|
295
|
+
item: z.string().min(2).describe('Product title'),
|
|
296
|
+
quantity: z.number().int().positive().describe('Item count'),
|
|
297
|
+
coupon: z.string().optional(),
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
export default controller({
|
|
301
|
+
create: route.post('/', {
|
|
302
|
+
summary: 'Place an order',
|
|
303
|
+
body: OrderSchema,
|
|
304
|
+
async handle({ body }) {
|
|
305
|
+
return { success: true, order: body }
|
|
306
|
+
},
|
|
307
|
+
}),
|
|
308
|
+
})
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Security Schemes Configuration
|
|
202
314
|
|
|
203
|
-
Define
|
|
315
|
+
Define authentication mechanisms (e.g. Bearer JWT, API Keys, OAuth2) in `exis.config.ts`:
|
|
204
316
|
|
|
205
317
|
```typescript filename="exis.config.ts"
|
|
206
318
|
import { defineConfig } from 'exisjs/config'
|
|
@@ -219,8 +331,10 @@ export default defineConfig({
|
|
|
219
331
|
type: 'apiKey',
|
|
220
332
|
in: 'header',
|
|
221
333
|
name: 'X-API-KEY',
|
|
334
|
+
description: 'Static API Key passed in headers',
|
|
222
335
|
},
|
|
223
336
|
},
|
|
337
|
+
// Global default security (can be overridden per route)
|
|
224
338
|
security: [
|
|
225
339
|
{ bearerAuth: [] },
|
|
226
340
|
],
|
|
@@ -230,60 +344,47 @@ export default defineConfig({
|
|
|
230
344
|
|
|
231
345
|
---
|
|
232
346
|
|
|
233
|
-
##
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return spec
|
|
255
|
-
},
|
|
256
|
-
},
|
|
257
|
-
})
|
|
258
|
-
```
|
|
347
|
+
## Configuration Reference (`SwaggerConfig`)
|
|
348
|
+
|
|
349
|
+
The full set of options supported under `docs` in `exis.config.ts`:
|
|
350
|
+
|
|
351
|
+
| Option | Type | Default | Description |
|
|
352
|
+
| :--- | :--- | :--- | :--- |
|
|
353
|
+
| `enabled` | `boolean` | `false` | Enables documentation mounting and OpenAPI spec generation. |
|
|
354
|
+
| `path` | `string` | `'/docs'` | URL path where the interactive documentation UI is served. |
|
|
355
|
+
| `specPath` | `string` | `'/docs/json'` | URL path where the raw OpenAPI 3.1 JSON specification is served. |
|
|
356
|
+
| `title` | `string` | `'ExisJS API Documentation'` | Title displayed in the documentation header. |
|
|
357
|
+
| `version` | `string` | `'1.0.0'` | API Version displayed in documentation. |
|
|
358
|
+
| `description` | `string` | — | API description markdown shown below the header. |
|
|
359
|
+
| `termsOfService` | `string` | — | URL to terms of service agreement. |
|
|
360
|
+
| `contact` | `object` | — | Contact information (`name`, `url`, `email`). |
|
|
361
|
+
| `license` | `object` | — | License information (`name`, `url`). |
|
|
362
|
+
| `servers` | `OpenApiServer[]` | — | Target environments (e.g., Production, Staging). |
|
|
363
|
+
| `tags` | `OpenApiTag[]` | — | Global list of tag metadata and external documentation links. |
|
|
364
|
+
| `ui` | `'swagger-ui' \| 'scalar'` | `'swagger-ui'` | Interactive documentation UI renderer. |
|
|
365
|
+
| `customCss` | `string` | — | Custom CSS styles injected into the Swagger/Scalar page. |
|
|
366
|
+
| `customFavicon` | `string` | — | Custom favicon URL for the documentation page. |
|
|
367
|
+
| `transformSpec` | `(spec) => spec` | — | Synchronous hook to programmatically mutate the generated OpenAPI spec. |
|
|
259
368
|
|
|
260
369
|
---
|
|
261
370
|
|
|
262
|
-
##
|
|
371
|
+
## Programmatic Mount Helper (`swagger()`)
|
|
263
372
|
|
|
264
|
-
You can also
|
|
373
|
+
You can also mount Swagger documentation programmatically inside custom server bootstrapping in `server.ts`:
|
|
265
374
|
|
|
266
|
-
### Functional Paradigm
|
|
267
375
|
```typescript filename="src/http/server.ts"
|
|
268
376
|
import { exis } from 'exisjs'
|
|
377
|
+
import { swagger } from 'exisjs/swagger'
|
|
269
378
|
|
|
270
379
|
export default exis({
|
|
271
|
-
onStart(app) {
|
|
272
|
-
|
|
380
|
+
async onStart(app) {
|
|
381
|
+
swagger({
|
|
382
|
+
title: 'Custom API Gateway',
|
|
383
|
+
version: '2.0.0',
|
|
384
|
+
path: '/api/docs',
|
|
385
|
+
})(app)
|
|
273
386
|
},
|
|
274
387
|
})
|
|
275
388
|
```
|
|
276
389
|
|
|
277
|
-
### Class-Based (OOP) Paradigm
|
|
278
|
-
```typescript filename="src/http/server.ts"
|
|
279
|
-
import { Server } from 'exisjs/decorators'
|
|
280
|
-
import type { App } from 'exisjs'
|
|
281
|
-
|
|
282
|
-
@Server()
|
|
283
|
-
export default class RootServer {
|
|
284
|
-
async onStart(app: App) {
|
|
285
|
-
console.log('[API] Swagger documentation ready at /docs')
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
```
|
|
289
390
|
|