exisjs 0.7.12 → 0.7.14

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.
Files changed (132) hide show
  1. package/README.md +195 -39
  2. package/dist/cli/commands/run.d.ts.map +1 -1
  3. package/dist/cli/commands/run.js +3 -1
  4. package/dist/cli/commands/run.js.map +1 -1
  5. package/dist/config/types.d.ts +2 -2
  6. package/dist/config/types.d.ts.map +1 -1
  7. package/dist/decorators/params.d.ts +21 -0
  8. package/dist/decorators/params.d.ts.map +1 -1
  9. package/dist/decorators/params.js +21 -1
  10. package/dist/decorators/params.js.map +1 -1
  11. package/dist/di/container.d.ts +15 -6
  12. package/dist/di/container.d.ts.map +1 -1
  13. package/dist/di/container.js +26 -3
  14. package/dist/di/container.js.map +1 -1
  15. package/dist/di/index.d.ts +1 -1
  16. package/dist/di/index.d.ts.map +1 -1
  17. package/dist/di/index.js.map +1 -1
  18. package/dist/di/inject.d.ts +2 -1
  19. package/dist/di/inject.d.ts.map +1 -1
  20. package/dist/di/inject.js +2 -1
  21. package/dist/di/inject.js.map +1 -1
  22. package/dist/docs/ARCHITECTURE.md +130 -78
  23. package/dist/docs/BENCHMARKS.md +4 -4
  24. package/dist/docs/content/README.md +43 -44
  25. package/dist/docs/content/boundaries.mdx +138 -61
  26. package/dist/docs/content/cli/commands.mdx +151 -128
  27. package/dist/docs/content/cli/overview.mdx +61 -47
  28. package/dist/docs/content/cli/usage.mdx +107 -30
  29. package/dist/docs/content/config.mdx +145 -158
  30. package/dist/docs/content/controllers.mdx +193 -464
  31. package/dist/docs/content/cron.mdx +183 -69
  32. package/dist/docs/content/decorators.mdx +449 -154
  33. package/dist/docs/content/errors.mdx +202 -305
  34. package/dist/docs/content/exisjs-mcp.mdx +59 -49
  35. package/dist/docs/content/installation.mdx +243 -157
  36. package/dist/docs/content/introduction.mdx +220 -48
  37. package/dist/docs/content/middleware.mdx +171 -497
  38. package/dist/docs/content/modules.mdx +141 -83
  39. package/dist/docs/content/providers.mdx +216 -180
  40. package/dist/docs/content/requests.mdx +168 -488
  41. package/dist/docs/content/responses.mdx +200 -533
  42. package/dist/docs/content/routing.mdx +235 -598
  43. package/dist/docs/content/security.mdx +233 -57
  44. package/dist/docs/content/structure.mdx +151 -240
  45. package/dist/docs/content/swagger.mdx +192 -91
  46. package/dist/docs/content/testing.mdx +205 -74
  47. package/dist/docs/content/validation.mdx +479 -341
  48. package/dist/docs/reference/README.md +34 -2
  49. package/dist/docs/reference/config.mdx +277 -75
  50. package/dist/docs/reference/context.mdx +197 -106
  51. package/dist/docs/reference/cron.mdx +266 -152
  52. package/dist/docs/reference/database.mdx +135 -53
  53. package/dist/docs/reference/decorators.mdx +234 -116
  54. package/dist/docs/reference/di.mdx +146 -112
  55. package/dist/docs/reference/error.mdx +155 -178
  56. package/dist/docs/reference/exis.mdx +141 -70
  57. package/dist/docs/reference/logger.mdx +110 -126
  58. package/dist/docs/reference/middleware.mdx +235 -158
  59. package/dist/docs/reference/plugin.mdx +136 -64
  60. package/dist/docs/reference/router.mdx +275 -293
  61. package/dist/docs/reference/sanitize.mdx +91 -87
  62. package/dist/docs/reference/swagger.mdx +280 -100
  63. package/dist/docs/reference/testing.mdx +223 -89
  64. package/dist/docs/reference/validator.mdx +194 -206
  65. package/dist/lib/start-server.js +22 -8
  66. package/dist/lib/start-server.js.map +1 -1
  67. package/dist/module/module.d.ts +6 -3
  68. package/dist/module/module.d.ts.map +1 -1
  69. package/dist/module/module.js +17 -3
  70. package/dist/module/module.js.map +1 -1
  71. package/dist/router/controller-registrar.d.ts.map +1 -1
  72. package/dist/router/controller-registrar.js +26 -4
  73. package/dist/router/controller-registrar.js.map +1 -1
  74. package/dist/router/scanner/fs-scanner.d.ts.map +1 -1
  75. package/dist/router/scanner/fs-scanner.js +22 -0
  76. package/dist/router/scanner/fs-scanner.js.map +1 -1
  77. package/dist/router/types.d.ts +6 -4
  78. package/dist/router/types.d.ts.map +1 -1
  79. package/dist/server/app.d.ts +3 -1
  80. package/dist/server/app.d.ts.map +1 -1
  81. package/dist/server/app.js +24 -8
  82. package/dist/server/app.js.map +1 -1
  83. package/dist/server/bootstrapper.d.ts.map +1 -1
  84. package/dist/server/bootstrapper.js +19 -0
  85. package/dist/server/bootstrapper.js.map +1 -1
  86. package/dist/server/request.d.ts +2 -0
  87. package/dist/server/request.d.ts.map +1 -1
  88. package/dist/server/request.js +11 -0
  89. package/dist/server/request.js.map +1 -1
  90. package/dist/server/response.d.ts +10 -5
  91. package/dist/server/response.d.ts.map +1 -1
  92. package/dist/server/response.js +65 -18
  93. package/dist/server/response.js.map +1 -1
  94. package/dist/swagger/generator.d.ts.map +1 -1
  95. package/dist/swagger/generator.js +130 -10
  96. package/dist/swagger/generator.js.map +1 -1
  97. package/dist/telemetry/index.d.ts +12 -0
  98. package/dist/telemetry/index.d.ts.map +1 -0
  99. package/dist/telemetry/index.js +121 -0
  100. package/dist/telemetry/index.js.map +1 -0
  101. package/dist/testing/client.d.ts +1 -0
  102. package/dist/testing/client.d.ts.map +1 -1
  103. package/dist/testing/client.js +4 -1
  104. package/dist/testing/client.js.map +1 -1
  105. package/dist/testing/index.d.ts.map +1 -1
  106. package/dist/testing/index.js +11 -4
  107. package/dist/testing/index.js.map +1 -1
  108. package/dist/validator/builder.d.ts +26 -1
  109. package/dist/validator/builder.d.ts.map +1 -1
  110. package/dist/validator/builder.js +31 -0
  111. package/dist/validator/builder.js.map +1 -1
  112. package/dist/validator/engine.d.ts +23 -0
  113. package/dist/validator/engine.d.ts.map +1 -1
  114. package/dist/validator/engine.js +228 -31
  115. package/dist/validator/engine.js.map +1 -1
  116. package/dist/validator/index.d.ts +8 -4
  117. package/dist/validator/index.d.ts.map +1 -1
  118. package/dist/validator/index.js +4 -1
  119. package/dist/validator/index.js.map +1 -1
  120. package/dist/validator/tex-types.d.ts +19 -4
  121. package/dist/validator/tex-types.d.ts.map +1 -1
  122. package/dist/validator/tex-types.js +102 -0
  123. package/dist/validator/tex-types.js.map +1 -1
  124. package/dist/validator/tex.d.ts +1 -1
  125. package/dist/validator/tex.d.ts.map +1 -1
  126. package/dist/validator/tex.js +3 -1
  127. package/dist/validator/tex.js.map +1 -1
  128. package/dist/validator/types.d.ts +1 -0
  129. package/dist/validator/types.d.ts.map +1 -1
  130. package/package.json +46 -14
  131. package/dist/docs/content/dataloader.mdx +0 -170
  132. package/dist/docs/reference/dataloader.mdx +0 -91
@@ -1,86 +1,175 @@
1
1
  ---
2
- title: "Swagger (exisjs/swagger)"
3
- description: "API Reference for ExisJS Swagger & OpenAPI 3.1 Documentation Subsystem"
2
+ title: "exisjs/swagger"
3
+ description: "API Reference for ExisJS OpenAPI 3.1 generation, Swagger UI, Scalar documentation, and API metadata decorators."
4
+ nextUrl: "/docs/reference/testing"
5
+ nextTitle: "Testing Reference"
4
6
  ---
5
7
 
6
- # Swagger Reference (`exisjs/swagger`)
8
+ # `exisjs/swagger`
7
9
 
8
- The `exisjs/swagger` module provides tools and decorators for auto-generating OpenAPI 3.1 specifications and serving interactive documentation UIs.
10
+ The `exisjs/swagger` module provides automated OpenAPI 3.1 specification generation, interactive UI rendering (Swagger UI and Scalar), schema introspection from `TexEngine` validators, and OpenAPI operation decorators.
11
+
12
+ ---
13
+
14
+ ## Module Exports
9
15
 
10
16
  ```typescript
11
17
  import {
12
18
  swagger,
19
+ docs,
13
20
  defineSwagger,
21
+ defineDocs,
14
22
  generateOpenApiSpec,
15
23
  renderDocumentationHtml,
16
24
  mountDocumentation,
25
+ normalizeOpenApiPath,
26
+ schemaToOpenApi,
17
27
  ApiTags,
28
+ Tags,
18
29
  ApiOperation,
30
+ Operation,
19
31
  ApiResponse,
20
32
  ApiBearerAuth,
33
+ BearerAuth,
21
34
  ApiSecurity,
22
35
  ApiExclude,
23
36
  ApiProperty,
24
37
  } from 'exisjs/swagger'
38
+
39
+ import type {
40
+ SwaggerConfig,
41
+ OpenApiSpec,
42
+ OpenApiInfo,
43
+ OpenApiServer,
44
+ OpenApiTag,
45
+ OpenApiOperation,
46
+ OpenApiParameter,
47
+ OpenApiRequestBody,
48
+ OpenApiResponse,
49
+ SecuritySchemeObject,
50
+ RouteDocMetadata,
51
+ } from 'exisjs/swagger'
25
52
  ```
26
53
 
27
54
  ---
28
55
 
29
- ## Configuration (`SwaggerConfig`)
30
-
31
- | Property | Type | Default | Description |
32
- |---|---|---|---|
33
- | `enabled` | `boolean` | `false` | Whether to enable documentation routes |
34
- | `path` | `string` | `'/docs'` | URL path for the interactive HTML UI |
35
- | `specPath` | `string` | `'/docs/json'` | URL path for OpenAPI 3.1 JSON specification |
36
- | `title` | `string` | `'ExisJS API Documentation'` | API Title displayed in documentation |
37
- | `version` | `string` | `'1.0.0'` | API Version string |
38
- | `description` | `string` | `undefined` | Overview markdown or description |
39
- | `ui` | `'swagger-ui' \| 'scalar'` | `'swagger-ui'` | Documentation UI renderer |
40
- | `servers` | `OpenApiServer[]` | `[{ url: '/' }]` | Target server list |
41
- | `tags` | `OpenApiTag[]` | `[]` | Group tags with descriptions |
42
- | `security` | `Record<string, string[]>[]` | `[]` | Global security requirements |
43
- | `securitySchemes` | `Record<string, SecurityScheme>` | `{}` | Reusable security scheme definitions |
44
- | `customCss` | `string` | `undefined` | Custom CSS injected into the UI |
45
- | `customFavicon` | `string` | `undefined` | Custom favicon image URL |
46
- | `transformSpec` | `(spec: OpenApiSpec) => OpenApiSpec` | `undefined` | Hook to mutate OpenAPI spec before serving |
56
+ ## 1. Configuration Interface (`SwaggerConfig`)
57
+
58
+ Configuration options passed to `swagger(config)` or configured under `exis.config.ts`:
59
+
60
+ | Option | Type | Default | Description |
61
+ | :--- | :--- | :--- | :--- |
62
+ | `enabled` | `boolean` | `false` | Enables or disables OpenAPI specification generation and documentation endpoints. |
63
+ | `path` | `string` | `'/docs'` | Base URL path where the interactive documentation UI is mounted. |
64
+ | `specPath` | `string` | `'/docs/json'` | URL path where the raw OpenAPI 3.1.0 JSON specification is served. |
65
+ | `title` | `string` | `'ExisJS API Documentation'` | API Title displayed in documentation headers and page metadata. |
66
+ | `version` | `string` | `'1.0.0'` | Semantic version string of the API. |
67
+ | `description` | `string` | `undefined` | High-level API summary or Markdown description rendered in the UI header. |
68
+ | `termsOfService` | `string` | `undefined` | URL pointing to the API Terms of Service. |
69
+ | `contact` | `OpenApiInfo['contact']` | `undefined` | Contact metadata (`name`, `url`, `email`). |
70
+ | `license` | `OpenApiInfo['license']` | `undefined` | License descriptor (`name`, `url`). |
71
+ | `ui` | `'swagger-ui' \| 'scalar'` | `'swagger-ui'` | Interactive documentation UI renderer. |
72
+ | `servers` | `OpenApiServer[]` | `[{ url: '/' }]` | Array of server environment definitions (`url`, `description`, `variables`). |
73
+ | `tags` | `OpenApiTag[]` | `[]` | Global tag descriptors for grouping endpoints (`name`, `description`, `externalDocs`). |
74
+ | `security` | `Record<string, string[]>[]` | `[]` | Global security requirements applied to all operations unless overridden. |
75
+ | `securitySchemes` | `Record<string, SecuritySchemeObject>` | `{}` | Reusable authentication schemes (`apiKey`, `http` Bearer, `oauth2`, `openIdConnect`). |
76
+ | `customCss` | `string` | `undefined` | Custom CSS stylesheet injected into the documentation HTML. |
77
+ | `customFavicon` | `string` | `undefined` | Custom favicon image URL. |
78
+ | `transformSpec` | `(spec: OpenApiSpec) => OpenApiSpec \| void` | `undefined` | Hook to mutate or extend the generated specification before serving. |
47
79
 
48
80
  ---
49
81
 
50
- ## Decorators
82
+ ## 2. Mounting Documentation
83
+
84
+ ### `swagger(config?)` / `docs(config?)`
85
+
86
+ Mounts documentation routes onto an ExisJS `App` instance during startup:
87
+
88
+ ```typescript
89
+ function swagger(config?: SwaggerConfig): (app: App) => void
90
+ ```
91
+
92
+ #### Example
93
+
94
+ ```typescript filename="src/http/server.ts"
95
+ import { exis } from 'exisjs'
96
+ import { swagger } from 'exisjs/swagger'
97
+
98
+ export default exis({
99
+ onStart(app) {
100
+ swagger({
101
+ title: 'E-Commerce Platform API',
102
+ version: '2.4.0',
103
+ path: '/docs',
104
+ specPath: '/docs/openapi.json',
105
+ ui: 'scalar',
106
+ securitySchemes: {
107
+ bearerAuth: {
108
+ type: 'http',
109
+ scheme: 'bearer',
110
+ bearerFormat: 'JWT',
111
+ },
112
+ },
113
+ })(app)
114
+ },
115
+ })
116
+ ```
117
+
118
+ ---
119
+
120
+ ## 3. OpenAPI Decorators (`exisjs/swagger`)
121
+
122
+ Decorators attach metadata to class controllers and method handlers for OpenAPI specification generation.
51
123
 
52
- ### `@ApiTags(...tags: string[])`
53
- Assigns one or more tags to a controller class or method handler.
54
- *(Alias: `@Tags()`)*
124
+ ### `@ApiTags(...tags: string[])` / `@Tags(...)`
55
125
 
56
- ```typescript filename="src/http/users/route.ts"
126
+ Assigns one or more operational tags to a controller class or individual route method.
127
+
128
+ ```typescript
129
+ function ApiTags(...tags: string[]): ClassDecorator & MethodDecorator
130
+ ```
131
+
132
+ ```typescript filename="src/http/users/users.controller.ts"
57
133
  import { Controller, Get } from 'exisjs/decorators'
58
134
  import { ApiTags } from 'exisjs/swagger'
59
135
 
60
- @ApiTags('Users', 'Authentication')
61
- @Controller()
62
- export default class UserController {
136
+ @ApiTags('Users', 'Administration')
137
+ @Controller('/users')
138
+ export default class UsersController {
63
139
  @Get('/')
64
- findAll() {
140
+ listUsers() {
65
141
  return []
66
142
  }
67
143
  }
68
144
  ```
69
145
 
70
- ### `@ApiOperation(options)`
71
- Attaches summary, description, operationId, and deprecated status to a route method.
72
- *(Alias: `@Operation()`)*
146
+ ---
147
+
148
+ ### `@ApiOperation(options)` / `@Operation(...)`
149
+
150
+ Attaches summary, detailed description, operation ID, and deprecation flags to an endpoint.
73
151
 
74
- ```typescript filename="src/http/users/route.ts"
152
+ ```typescript
153
+ function ApiOperation(options: {
154
+ summary?: string
155
+ description?: string
156
+ operationId?: string
157
+ deprecated?: boolean
158
+ externalDocs?: { url: string; description?: string }
159
+ }): MethodDecorator
160
+ ```
161
+
162
+ ```typescript filename="src/http/users/users.controller.ts"
75
163
  import { Controller, Get, Param } from 'exisjs/decorators'
76
164
  import { ApiOperation } from 'exisjs/swagger'
77
165
 
78
- @Controller()
79
- export default class UserController {
166
+ @Controller('/users')
167
+ export default class UsersController {
80
168
  @Get('/:id')
81
169
  @ApiOperation({
82
- summary: 'Get user by UUID',
83
- description: 'Fetches user details from database',
170
+ summary: 'Retrieve User by ID',
171
+ description: 'Fetches complete user profile metadata from the database.',
172
+ operationId: 'getUserById',
84
173
  deprecated: false,
85
174
  })
86
175
  getUser(@Param('id') id: string) {
@@ -89,138 +178,229 @@ export default class UserController {
89
178
  }
90
179
  ```
91
180
 
181
+ ---
182
+
92
183
  ### `@ApiResponse(options)`
93
- Defines an expected HTTP response status code and optional schema.
94
184
 
95
- ```typescript filename="src/http/users/route.ts"
185
+ Documents expected response HTTP status codes, descriptions, and response body schemas.
186
+
187
+ ```typescript
188
+ function ApiResponse(options: {
189
+ status: number | string
190
+ description?: string
191
+ schema?: any
192
+ }): MethodDecorator
193
+ ```
194
+
195
+ ```typescript filename="src/http/users/users.controller.ts"
96
196
  import { Controller, Get, Param } from 'exisjs/decorators'
97
- import { ApiOperation, ApiResponse } from 'exisjs/swagger'
197
+ import { ApiResponse } from 'exisjs/swagger'
98
198
  import { tex } from 'exisjs/validator'
99
199
 
100
- const UserSchema = tex.object({
200
+ const UserResponseSchema = tex.object({
101
201
  id: tex.uuid(),
102
202
  name: tex.string(),
203
+ email: tex.email(),
103
204
  })
104
205
 
105
- @Controller()
106
- export default class UserController {
206
+ @Controller('/users')
207
+ export default class UsersController {
107
208
  @Get('/:id')
108
209
  @ApiResponse({
109
210
  status: 200,
110
- description: 'User details found',
111
- schema: UserSchema,
211
+ description: 'User successfully retrieved.',
212
+ schema: UserResponseSchema,
213
+ })
214
+ @ApiResponse({
215
+ status: 404,
216
+ description: 'User not found for given ID.',
112
217
  })
113
- @ApiResponse({ status: 404, description: 'User not found' })
114
218
  getUser(@Param('id') id: string) {
115
- return { id, name: 'Alice' }
219
+ return { id, name: 'Alice', email: 'alice@example.com' }
116
220
  }
117
221
  }
118
222
  ```
119
223
 
120
- ### `@ApiBearerAuth(name?: string)`
121
- Requires Bearer JWT authentication for this endpoint or controller.
122
- *(Alias: `@BearerAuth()`)*
224
+ ---
225
+
226
+ ### `@ApiBearerAuth(name?)` / `@BearerAuth(...)`
227
+
228
+ Enforces Bearer JWT authentication requirement on an entire controller or specific endpoint in OpenAPI.
229
+
230
+ ```typescript
231
+ function ApiBearerAuth(name = 'bearerAuth'): ClassDecorator & MethodDecorator
232
+ ```
123
233
 
124
- ```typescript filename="src/http/users/route.ts"
234
+ ```typescript filename="src/http/account/account.controller.ts"
125
235
  import { Controller, Get } from 'exisjs/decorators'
126
236
  import { ApiBearerAuth } from 'exisjs/swagger'
127
237
 
128
238
  @ApiBearerAuth()
129
- @Controller()
130
- export default class UserController {
131
- @Get('/me')
132
- getMe() {
133
- return { id: 'user-123', role: 'admin' }
239
+ @Controller('/account')
240
+ export default class AccountController {
241
+ @Get('/profile')
242
+ getProfile() {
243
+ return { status: 'authenticated' }
134
244
  }
135
245
  }
136
246
  ```
137
247
 
138
- ### `@ApiSecurity(name: string, scopes?: string[])`
139
- Requires custom security scheme authentication for this endpoint or controller.
248
+ ---
249
+
250
+ ### `@ApiSecurity(name, scopes?)`
140
251
 
141
- ```typescript filename="src/http/metrics/route.ts"
252
+ Enforces custom security requirements on an endpoint or controller.
253
+
254
+ ```typescript
255
+ function ApiSecurity(name: string, scopes?: string[]): ClassDecorator & MethodDecorator
256
+ ```
257
+
258
+ ```typescript filename="src/http/admin/admin.controller.ts"
142
259
  import { Controller, Get } from 'exisjs/decorators'
143
260
  import { ApiSecurity } from 'exisjs/swagger'
144
261
 
145
- @Controller()
146
- export default class MetricsController {
147
- @Get('/')
148
- @ApiSecurity('apiKeyAuth')
262
+ @Controller('/admin')
263
+ export default class AdminController {
264
+ @Get('/metrics')
265
+ @ApiSecurity('apiKeyAuth', ['read:admin'])
149
266
  getMetrics() {
150
- return { uptime: process.uptime() }
267
+ return { memory: process.memoryUsage() }
151
268
  }
152
269
  }
153
270
  ```
154
271
 
272
+ ---
273
+
155
274
  ### `@ApiExclude()`
156
- Excludes an endpoint or controller class from OpenAPI and Swagger generation.
157
275
 
158
- ```typescript filename="src/http/internal/route.ts"
276
+ Excludes an endpoint or entire controller class from OpenAPI generation and documentation UIs.
277
+
278
+ ```typescript
279
+ function ApiExclude(): ClassDecorator & MethodDecorator
280
+ ```
281
+
282
+ ```typescript filename="src/http/internal/internal.controller.ts"
159
283
  import { Controller, Get } from 'exisjs/decorators'
160
284
  import { ApiExclude } from 'exisjs/swagger'
161
285
 
162
- @Controller()
286
+ @Controller('/internal')
163
287
  export default class InternalController {
164
- @Get('/health')
288
+ @Get('/healthcheck')
165
289
  @ApiExclude()
166
- getHealth() {
167
- return { status: 'healthy' }
290
+ healthCheck() {
291
+ return { ok: true }
168
292
  }
169
293
  }
170
294
  ```
171
295
 
172
- ### `@ApiProperty(options?: { description?: string; example?: any; required?: boolean })`
173
- Annotates a class property with metadata for OpenAPI schema models.
296
+ ---
297
+
298
+ ### `@ApiProperty(options?)`
299
+
300
+ Annotates class properties with metadata for OpenAPI schema extraction.
301
+
302
+ ```typescript
303
+ function ApiProperty(options?: {
304
+ description?: string
305
+ example?: any
306
+ required?: boolean
307
+ type?: any
308
+ enum?: any[]
309
+ }): PropertyDecorator
310
+ ```
174
311
 
175
- ```typescript filename="src/http/users/dto.ts"
312
+ ```typescript filename="src/http/users/dto/create-user.dto.ts"
176
313
  import { ApiProperty } from 'exisjs/swagger'
177
314
 
178
315
  export class CreateUserDto {
179
- @ApiProperty({ description: 'Full name of the user', example: 'Alice Johnson', required: true })
180
- name!: string
181
-
182
- @ApiProperty({ description: 'Work email address', example: 'alice@example.com', required: true })
316
+ @ApiProperty({
317
+ description: 'Unique email address of the account owner',
318
+ example: 'user@example.com',
319
+ required: true,
320
+ })
183
321
  email!: string
322
+
323
+ @ApiProperty({
324
+ description: 'Account display name',
325
+ example: 'Jane Doe',
326
+ required: false,
327
+ })
328
+ name?: string
184
329
  }
185
330
  ```
186
331
 
187
332
  ---
188
333
 
189
- ## Functions
334
+ ## 4. Programmatic Generation Utilities
190
335
 
191
- ### `swagger(config?: SwaggerConfig)`
192
- Convenience helper to mount Swagger/OpenAPI documentation on an ExisJS App instance (typically inside `onStart` or custom server setups).
336
+ ### `generateOpenApiSpec(routesOrApp, config?)`
193
337
 
194
- ```typescript filename="src/http/server.ts"
195
- import { exis } from 'exisjs'
196
- import { swagger } from 'exisjs/swagger'
338
+ Pure generator function that scans routes, URL parameters, `TexEngine` validation schemas, and reflection metadata, producing a compliant OpenAPI 3.1.0 specification object.
197
339
 
198
- export default exis({
199
- onStart(app) {
200
- swagger({ title: 'My API', path: '/docs' })(app)
201
- },
202
- })
340
+ ```typescript
341
+ function generateOpenApiSpec(
342
+ routesOrApp: Route[] | App,
343
+ config?: SwaggerConfig
344
+ ): OpenApiSpec
203
345
  ```
204
346
 
205
- ### `generateOpenApiSpec(routesOrApp, config)`
206
- Pure generator function that introspects routes, parameters, and `TexEngine`/Zod schemas and returns a complete `OpenApiSpec` object.
347
+ #### Example
207
348
 
208
349
  ```typescript
209
350
  import { generateOpenApiSpec } from 'exisjs/swagger'
351
+ import { getActiveApp } from 'exisjs'
210
352
 
211
- const spec = generateOpenApiSpec(app, { title: 'My API', version: '1.0.0' })
353
+ const app = getActiveApp()
354
+ const spec = generateOpenApiSpec(app, {
355
+ title: 'Exported OpenAPI Spec',
356
+ version: '1.0.0',
357
+ })
212
358
  ```
213
359
 
360
+ ---
361
+
214
362
  ### `renderDocumentationHtml(config)`
215
- Renders standalone HTML markup for Swagger UI or Scalar API reference.
363
+
364
+ Generates standalone HTML markup embedding Swagger UI or Scalar API client scripts.
216
365
 
217
366
  ```typescript
218
- import { renderDocumentationHtml } from 'exisjs/swagger'
367
+ function renderDocumentationHtml(config: SwaggerConfig): string
368
+ ```
219
369
 
220
- const html = renderDocumentationHtml({
221
- title: 'My API',
222
- specPath: '/docs/json',
223
- ui: 'scalar',
224
- })
370
+ #### Parameters
371
+
372
+ | Property | Type | Description |
373
+ | :--- | :--- | :--- |
374
+ | `config.ui` | `'swagger-ui' \| 'scalar'` | The chosen UI documentation theme. |
375
+ | `config.specPath` | `string` | Target URL path where the UI fetches the OpenAPI JSON specification. |
376
+ | `config.title` | `string` | Document `<title>` tag content. |
377
+ | `config.customCss` | `string` | Injected stylesheet string. |
378
+ | `config.customFavicon` | `string` | Injected favicon link. |
379
+
380
+ ---
381
+
382
+ ### `schemaToOpenApi(validator)`
383
+
384
+ Converts any schema descriptor (`TexEngine`, `TexType`, `TexDiscriminatedUnionEngine`, Zod object/primitive, or raw property descriptor map) into an OpenAPI 3.1 compatible JSON Schema definition.
385
+
386
+ ```typescript
387
+ function schemaToOpenApi(validator: any): Record<string, any>
225
388
  ```
226
389
 
390
+ #### Example
391
+
392
+ ```typescript
393
+ import { schemaToOpenApi } from 'exisjs/swagger'
394
+ import { tex } from 'exisjs/validator'
395
+ import { z } from 'zod'
396
+
397
+ // Translates native TexEngine
398
+ const texJsonSchema = schemaToOpenApi(
399
+ tex.object({ id: tex.uuid(), count: tex.number({ min: 1 }) })
400
+ )
401
+
402
+ // Translates Zod schemas via duck typing
403
+ const zodJsonSchema = schemaToOpenApi(
404
+ z.object({ email: z.string().email(), role: z.enum(['admin', 'user']) })
405
+ )
406
+ ```