@venizia/ignis-docs 0.0.5 → 0.0.6-0

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 (98) hide show
  1. package/package.json +1 -1
  2. package/wiki/best-practices/architecture-decisions.md +0 -8
  3. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  4. package/wiki/best-practices/performance-optimization.md +3 -3
  5. package/wiki/best-practices/security-guidelines.md +2 -2
  6. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  7. package/wiki/guides/core-concepts/components-guide.md +1 -1
  8. package/wiki/guides/core-concepts/components.md +2 -2
  9. package/wiki/guides/core-concepts/dependency-injection.md +1 -1
  10. package/wiki/guides/core-concepts/services.md +1 -1
  11. package/wiki/guides/tutorials/building-a-crud-api.md +1 -1
  12. package/wiki/guides/tutorials/ecommerce-api.md +2 -2
  13. package/wiki/guides/tutorials/realtime-chat.md +6 -6
  14. package/wiki/guides/tutorials/testing.md +1 -1
  15. package/wiki/references/base/bootstrapping.md +0 -2
  16. package/wiki/references/base/components.md +2 -2
  17. package/wiki/references/base/controllers.md +0 -1
  18. package/wiki/references/base/datasources.md +1 -1
  19. package/wiki/references/base/dependency-injection.md +1 -1
  20. package/wiki/references/base/filter-system/quick-reference.md +0 -14
  21. package/wiki/references/base/middlewares.md +0 -8
  22. package/wiki/references/base/providers.md +0 -9
  23. package/wiki/references/base/services.md +0 -1
  24. package/wiki/references/components/authentication/api.md +444 -0
  25. package/wiki/references/components/authentication/errors.md +177 -0
  26. package/wiki/references/components/authentication/index.md +571 -0
  27. package/wiki/references/components/authentication/usage.md +781 -0
  28. package/wiki/references/components/health-check.md +292 -103
  29. package/wiki/references/components/index.md +14 -12
  30. package/wiki/references/components/mail/api.md +505 -0
  31. package/wiki/references/components/mail/errors.md +176 -0
  32. package/wiki/references/components/mail/index.md +535 -0
  33. package/wiki/references/components/mail/usage.md +404 -0
  34. package/wiki/references/components/request-tracker.md +229 -25
  35. package/wiki/references/components/socket-io/api.md +1051 -0
  36. package/wiki/references/components/socket-io/errors.md +119 -0
  37. package/wiki/references/components/socket-io/index.md +410 -0
  38. package/wiki/references/components/socket-io/usage.md +322 -0
  39. package/wiki/references/components/static-asset/api.md +261 -0
  40. package/wiki/references/components/static-asset/errors.md +89 -0
  41. package/wiki/references/components/static-asset/index.md +617 -0
  42. package/wiki/references/components/static-asset/usage.md +364 -0
  43. package/wiki/references/components/swagger.md +390 -110
  44. package/wiki/references/components/template/api-page.md +125 -0
  45. package/wiki/references/components/template/errors-page.md +100 -0
  46. package/wiki/references/components/template/index.md +104 -0
  47. package/wiki/references/components/template/setup-page.md +134 -0
  48. package/wiki/references/components/template/single-page.md +132 -0
  49. package/wiki/references/components/template/usage-page.md +127 -0
  50. package/wiki/references/components/websocket/api.md +508 -0
  51. package/wiki/references/components/websocket/errors.md +123 -0
  52. package/wiki/references/components/websocket/index.md +453 -0
  53. package/wiki/references/components/websocket/usage.md +475 -0
  54. package/wiki/references/helpers/cron/index.md +224 -0
  55. package/wiki/references/helpers/crypto/index.md +537 -0
  56. package/wiki/references/helpers/env/index.md +214 -0
  57. package/wiki/references/helpers/error/index.md +232 -0
  58. package/wiki/references/helpers/index.md +16 -15
  59. package/wiki/references/helpers/inversion/index.md +608 -0
  60. package/wiki/references/helpers/logger/index.md +600 -0
  61. package/wiki/references/helpers/network/api.md +986 -0
  62. package/wiki/references/helpers/network/index.md +620 -0
  63. package/wiki/references/helpers/queue/index.md +589 -0
  64. package/wiki/references/helpers/redis/index.md +495 -0
  65. package/wiki/references/helpers/socket-io/api.md +497 -0
  66. package/wiki/references/helpers/socket-io/index.md +513 -0
  67. package/wiki/references/helpers/storage/api.md +705 -0
  68. package/wiki/references/helpers/storage/index.md +583 -0
  69. package/wiki/references/helpers/template/index.md +66 -0
  70. package/wiki/references/helpers/template/single-page.md +126 -0
  71. package/wiki/references/helpers/testing/index.md +510 -0
  72. package/wiki/references/helpers/types/index.md +512 -0
  73. package/wiki/references/helpers/uid/index.md +272 -0
  74. package/wiki/references/helpers/websocket/api.md +736 -0
  75. package/wiki/references/helpers/websocket/index.md +574 -0
  76. package/wiki/references/helpers/worker-thread/index.md +470 -0
  77. package/wiki/references/quick-reference.md +3 -18
  78. package/wiki/references/utilities/jsx.md +1 -8
  79. package/wiki/references/utilities/statuses.md +0 -7
  80. package/wiki/references/components/authentication.md +0 -476
  81. package/wiki/references/components/mail.md +0 -687
  82. package/wiki/references/components/socket-io.md +0 -562
  83. package/wiki/references/components/static-asset.md +0 -1277
  84. package/wiki/references/helpers/cron.md +0 -108
  85. package/wiki/references/helpers/crypto.md +0 -132
  86. package/wiki/references/helpers/env.md +0 -83
  87. package/wiki/references/helpers/error.md +0 -97
  88. package/wiki/references/helpers/inversion.md +0 -176
  89. package/wiki/references/helpers/logger.md +0 -296
  90. package/wiki/references/helpers/network.md +0 -396
  91. package/wiki/references/helpers/queue.md +0 -150
  92. package/wiki/references/helpers/redis.md +0 -142
  93. package/wiki/references/helpers/socket-io.md +0 -932
  94. package/wiki/references/helpers/storage.md +0 -665
  95. package/wiki/references/helpers/testing.md +0 -133
  96. package/wiki/references/helpers/types.md +0 -167
  97. package/wiki/references/helpers/uid.md +0 -167
  98. package/wiki/references/helpers/worker-thread.md +0 -178
@@ -1,138 +1,68 @@
1
- # Swagger/OpenAPI Component
1
+ # Swagger/OpenAPI
2
2
 
3
- Automatic interactive API documentation generation using OpenAPI specifications.
3
+ Automatic interactive API documentation generation using OpenAPI specifications, powered by Scalar or Swagger UI.
4
4
 
5
5
  ## Quick Reference
6
6
 
7
- | Component | Purpose |
8
- |-----------|---------|
9
- | **SwaggerComponent** | Configures documentation UI and routes |
10
- | **UIProviderFactory** | Manages UI providers (Swagger UI, Scalar) |
11
- | **Default UI** | Scalar (can be changed to Swagger UI) |
12
-
13
- ### Default Endpoints
14
-
15
- | Path | Description |
16
- |------|-------------|
17
- | `/doc/explorer` | Documentation UI (Scalar by default) |
18
- | `/doc/openapi.json` | Raw OpenAPI specification |
19
-
20
- ### UI Provider Types
7
+ | Item | Value |
8
+ |------|-------|
9
+ | **Package** | `@venizia/ignis` |
10
+ | **Class** | `SwaggerComponent` |
11
+ | **UI Factory** | `UIProviderFactory` |
12
+ | **Runtimes** | Both |
21
13
 
22
14
  | Provider | Value | When to Use |
23
15
  |----------|-------|-------------|
24
16
  | **Scalar** | `'scalar'` | Modern, clean UI (default) |
25
17
  | **Swagger UI** | `'swagger'` | Classic Swagger interface |
26
18
 
27
- ## Architecture Components
28
-
29
- - **`SwaggerComponent`**: Configures documentation UI and registers routes
30
- - **`UIProviderFactory`**: Manages different UI providers
31
- - **`@hono/zod-openapi`**: Powers OpenAPI generation from Zod schemas
32
- - **Integration**: Works with controller `defineRoute` methods using Zod schemas
33
-
34
- ## Implementation Details
35
-
36
- ### Tech Stack
37
-
38
- - **Hono**
39
- - **`@hono/zod-openapi`**
40
- - **`@hono/swagger-ui`** (for Swagger UI)
41
- - **`@scalar/hono-api-reference`** (for Scalar UI)
42
- - **`zod`**
43
-
44
- ### Configuration
45
-
46
- The Swagger component can be configured via the `ISwaggerOptions` binding. You can customize the documentation path, OpenAPI version, and the UI provider type.
47
-
48
- **`ISwaggerOptions` Interface:**
49
-
19
+ #### Import Paths
50
20
  ```typescript
51
- export interface ISwaggerOptions {
52
- restOptions: {
53
- base: { path: string }; // Base path for all documentation routes
54
- doc: { path: string }; // Path to the raw openapi.json file
55
- ui: {
56
- path: string; // Path to the documentation UI
57
- type: 'swagger' | 'scalar'; // Type of UI to render
58
- };
59
- };
60
- explorer: {
61
- openapi: string;
62
- info?: { /* ... */ };
63
- servers?: Array<{ url: string; description?: string; }>;
64
- };
65
- uiConfig?: Record<string, any>; // Custom config for the UI provider
66
- }
21
+ import { SwaggerComponent, SwaggerBindingKeys, UIProviderFactory } from '@venizia/ignis';
22
+ import type { ISwaggerOptions, IUIProvider, IUIConfig, IGetProviderParams } from '@venizia/ignis';
67
23
  ```
68
24
 
69
- **Default Options:**
25
+ ## Setup
26
+
27
+ ### Step 1: Bind Configuration (Optional)
70
28
 
71
- The default UI provider is `scalar`.
29
+ Skip this step to use the defaults (Scalar UI at `/doc/explorer`). To customize:
72
30
 
73
31
  ```typescript
74
- const DEFAULT_SWAGGER_OPTIONS: ISwaggerOptions = {
32
+ // In your Application class's preConfigure method (src/application.ts)
33
+ import { SwaggerBindingKeys, ISwaggerOptions } from '@venizia/ignis';
34
+
35
+ this.bind<ISwaggerOptions>({
36
+ key: SwaggerBindingKeys.SWAGGER_OPTIONS,
37
+ }).toValue({
75
38
  restOptions: {
76
39
  base: { path: '/doc' },
77
40
  doc: { path: '/openapi.json' },
78
- ui: { path: '/explorer', type: 'scalar' },
41
+ ui: { path: '/explorer', type: 'swagger' }, // Use Swagger UI instead of Scalar
79
42
  },
80
- // ...
81
- };
43
+ explorer: {
44
+ openapi: '3.0.0',
45
+ },
46
+ });
82
47
  ```
83
48
 
84
- ### Code Samples
85
-
86
- #### 1. Registering the Swagger Component
87
-
88
- In your `src/application.ts`, register the `SwaggerComponent`.
49
+ ### Step 2: Register Component
89
50
 
90
51
  ```typescript
91
52
  // src/application.ts
92
53
  import { SwaggerComponent, BaseApplication, ValueOrPromise } from '@venizia/ignis';
93
54
 
94
55
  export class Application extends BaseApplication {
95
- // ...
96
- preConfigure(): ValueOrPromise<void> {
97
- // ...
98
- this.component(SwaggerComponent);
99
- // ...
100
- }
101
- // ...
102
- }
103
- ```
104
-
105
- #### 2. Customizing the UI Provider
106
-
107
- To change the UI provider to Swagger UI, you can bind custom options in your application's `preConfigure` method.
108
-
109
- ```typescript
110
- import { SwaggerComponent, SwaggerBindingKeys, ISwaggerOptions } from '@venizia/ignis';
111
-
112
- // ... in your Application class's preConfigure method
113
56
  preConfigure(): ValueOrPromise<void> {
114
57
  // ...
115
- this.bind<ISwaggerOptions>({
116
- key: SwaggerBindingKeys.SWAGGER_OPTIONS,
117
- }).toValue({
118
- restOptions: {
119
- base: { path: '/doc' },
120
- doc: { path: '/openapi.json' },
121
- ui: { path: '/explorer', type: 'swagger' }, // Use Swagger UI
122
- },
123
- explorer: {
124
- openapi: '3.0.0',
125
- },
126
- });
127
-
128
58
  this.component(SwaggerComponent);
129
- // ...
130
59
  }
60
+ }
131
61
  ```
132
62
 
133
- #### 3. Defining Routes with Zod Schemas
63
+ ### Step 3: Define Routes with Zod Schemas
134
64
 
135
- To get the most out of the documentation, define your routes with `zod` schemas.
65
+ To get the most out of the documentation, define your routes with `zod` schemas:
136
66
 
137
67
  ```typescript
138
68
  // src/controllers/hello.controller.ts
@@ -165,28 +95,378 @@ export class HelloController extends BaseController {
165
95
  }
166
96
  ```
167
97
 
168
- ## API or Interface Specifications
98
+ > [!TIP]
99
+ > Controllers using `defineRoute` with Zod schemas automatically generate OpenAPI specs. The Swagger component discovers all registered controller routes and renders them in the documentation UI.
100
+
101
+ ## Configuration
102
+
103
+ | Option | Type | Default | Description |
104
+ |--------|------|---------|-------------|
105
+ | `restOptions.base.path` | `string` | `'/doc'` | Base path for all documentation routes |
106
+ | `restOptions.doc.path` | `string` | `'/openapi.json'` | Path to the raw OpenAPI spec (relative to base) |
107
+ | `restOptions.ui.path` | `string` | `'/explorer'` | Path to the documentation UI (relative to base) |
108
+ | `restOptions.ui.type` | `'swagger' \| 'scalar'` | `'scalar'` | UI provider type |
109
+ | `explorer.openapi` | `string` | `'3.0.0'` | OpenAPI specification version |
110
+ | `uiConfig` | `Record<string, any>` | `undefined` | Custom config passed to the UI provider |
111
+
112
+ > [!IMPORTANT]
113
+ > The `explorer.info` field is **always overwritten** during the component's `binding()` phase. The component unconditionally reads your application's `package.json` via `application.getAppInfo()` and sets `explorer.info` to `{ title, version, description, contact }` from that data. Any user-provided `explorer.info` values are discarded. If you need to customize these fields, update your `package.json` instead.
114
+
115
+ > [!NOTE]
116
+ > The `explorer.servers` field is auto-populated only when empty. If you provide `explorer.servers` with at least one entry, the component preserves your values. When no servers are configured, it creates a default entry from `application.getServerAddress()` plus the application base path.
117
+
118
+ #### ISwaggerOptions -- Full Reference
119
+ ```typescript
120
+ export interface ISwaggerOptions {
121
+ restOptions: {
122
+ base: { path: string };
123
+ doc: { path: string };
124
+ ui: { path: string; type: TDocumentUIType };
125
+ };
126
+ explorer: {
127
+ openapi: string;
128
+ info?: {
129
+ title: string;
130
+ version: string;
131
+ description: string;
132
+ contact?: { name: string; email: string };
133
+ };
134
+ servers?: Array<{
135
+ url: string;
136
+ description?: string;
137
+ }>;
138
+ };
139
+ uiConfig?: Record<string, any>;
140
+ }
141
+ ```
142
+
143
+ | Option | Type | Default | Description |
144
+ |--------|------|---------|-------------|
145
+ | `restOptions.base.path` | `string` | `'/doc'` | Base path for all documentation routes |
146
+ | `restOptions.doc.path` | `string` | `'/openapi.json'` | Path to the raw OpenAPI spec (relative to base) |
147
+ | `restOptions.ui.path` | `string` | `'/explorer'` | Path to the documentation UI (relative to base) |
148
+ | `restOptions.ui.type` | `'swagger' \| 'scalar'` | `'scalar'` | UI provider type |
149
+ | `explorer.openapi` | `string` | `'3.0.0'` | OpenAPI specification version |
150
+ | `explorer.info.title` | `string` | Always from `package.json` `name` | API title (overwritten at runtime) |
151
+ | `explorer.info.version` | `string` | Always from `package.json` `version` | API version (overwritten at runtime) |
152
+ | `explorer.info.description` | `string` | Always from `package.json` `description` | API description (overwritten at runtime) |
153
+ | `explorer.info.contact` | `{ name, email }` | Always from `package.json` `author` | Contact information (overwritten at runtime) |
154
+ | `explorer.servers` | `Array<{ url, description? }>` | Auto-detected when empty | Server URLs |
155
+ | `uiConfig` | `Record<string, any>` | `undefined` | Custom config passed to the UI provider |
156
+
157
+ #### IGetProviderParams Interface
158
+
159
+ The `IGetProviderParams` interface is used by `UIProviderFactory.getProvider()` and `UIProviderFactory.register()`:
160
+
161
+ ```typescript
162
+ export interface IGetProviderParams {
163
+ type: string;
164
+ }
165
+ ```
166
+
167
+ This interface is exported for use when building custom tooling around the `UIProviderFactory` -- for example, programmatically querying which providers are available or registering providers in tests.
168
+
169
+ ### Tech Stack
170
+
171
+ | Library | Purpose |
172
+ |---------|---------|
173
+ | `@hono/zod-openapi` | OpenAPI generation from Zod schemas |
174
+ | `@hono/swagger-ui` | Swagger UI rendering |
175
+ | `@scalar/hono-api-reference` | Scalar UI rendering |
176
+ | `zod` | Schema validation and type generation |
177
+
178
+ > [!TIP]
179
+ > The component also auto-registers JWT (`bearer`) and Basic security schemes in the OpenAPI spec, so authenticated endpoints display the correct auth UI in the documentation.
180
+
181
+ ## Architecture
182
+
183
+ ### Component Lifecycle
184
+
185
+ The `SwaggerComponent` executes the following during `binding()`:
186
+
187
+ 1. **Resolve options** -- reads `SwaggerBindingKeys.SWAGGER_OPTIONS` from DI using `application.get()` with `isOptional: true`, falls back to `DEFAULT_SWAGGER_OPTIONS` via the `??` operator if no binding exists
188
+ 2. **Overwrite info** -- unconditionally reads `package.json` via `application.getAppInfo()` and overwrites `explorer.info` with `{ title: appInfo.name, version: appInfo.version, description: appInfo.description, contact: appInfo.author }`
189
+ 3. **Auto-detect servers** -- if `explorer.servers` is empty or unset, creates one entry from `http://` + `application.getServerAddress()` + `configs.path.base`
190
+ 4. **Normalize paths** -- all path segments (`base.path`, `doc.path`, `ui.path`) are normalized to ensure a leading `/` is present, handling both `/path` and `path` inputs
191
+ 5. **Register OpenAPI doc route** -- calls `rootRouter.doc(docPath, explorer)` to register the raw JSON endpoint
192
+ 6. **Resolve UI type with fallback** -- evaluates `restOptions.ui.type || DocumentUITypes.SWAGGER`. Note: this means a falsy value (empty string) falls back to `'swagger'`, not `'scalar'`
193
+ 7. **Validate UI type** -- checks the resolved type against `DocumentUITypes.SCHEME_SET`, throws if invalid
194
+ 8. **Register UI provider** -- calls `UIProviderFactory.register({ type })` to instantiate the UI renderer
195
+ 9. **Construct docUrl** -- builds the full documentation URL by joining `configs.path.base`, `configs.basePath`, and the computed `docPath`
196
+ 10. **Register UI route** -- creates `GET` handler at `uiPath` that calls `uiProvider.render()` with `{ title: appInfo.name, url: docUrl, ...uiConfig }`
197
+ 11. **Register security schemes** -- auto-registers JWT (bearer) and Basic security schemes in the OpenAPI registry
198
+
199
+ ### Architecture Components
200
+
201
+ | Component | Class | Role |
202
+ |-----------|-------|------|
203
+ | **SwaggerComponent** | `extends BaseComponent` | Orchestrates binding, overwrites OpenAPI metadata from `package.json` |
204
+ | **UIProviderFactory** | `extends MemoryStorageHelper` (singleton) | Registry for UI providers, validates and instantiates |
205
+ | **SwaggerUIProvider** | `implements IUIProvider` | Renders Swagger UI via `@hono/swagger-ui` |
206
+ | **ScalarUIProvider** | `implements IUIProvider` | Renders Scalar UI via `@scalar/hono-api-reference` |
207
+
208
+ #### UIProviderFactory and MemoryStorageHelper
209
+
210
+ `UIProviderFactory` extends `MemoryStorageHelper<{ [key: string | symbol]: IUIProvider }>`, which provides a simple in-memory key-value store with the following methods used internally:
211
+
212
+ - `isBound(key)` -- checks if a provider type is already registered
213
+ - `get(key)` -- retrieves a registered provider instance
214
+ - `set(key, value)` -- stores a provider instance
215
+ - `keys()` -- lists all registered provider type keys
216
+
217
+ This gives the factory a lightweight, type-safe storage backend without requiring the full DI container.
218
+
219
+ #### Lazy Dynamic Imports
220
+
221
+ Both `SwaggerUIProvider` and `ScalarUIProvider` use `await import()` inside their `render()` method to load the underlying UI library:
222
+
223
+ ```typescript
224
+ // SwaggerUIProvider
225
+ async render(context, config, next) {
226
+ const { swaggerUI } = await import('@hono/swagger-ui');
227
+ // ...
228
+ }
229
+
230
+ // ScalarUIProvider
231
+ async render(context, config, next) {
232
+ const { Scalar } = await import('@scalar/hono-api-reference');
233
+ // ...
234
+ }
235
+ ```
236
+
237
+ This means UI libraries are loaded on the **first HTTP request** to the documentation endpoint, not at application startup. This keeps startup time fast and avoids loading unused UI libraries (only the configured provider's library is ever imported).
238
+
239
+ #### ScalarUIProvider Title Mapping
240
+
241
+ The `ScalarUIProvider` maps the `title` field to `pageTitle` when calling the Scalar renderer:
242
+
243
+ ```typescript
244
+ const { title, url, ...customConfig } = config;
245
+ return Scalar({ url, pageTitle: title, ...customConfig })(context, next);
246
+ ```
247
+
248
+ This is a quirk to be aware of if you are inspecting the rendered output or writing custom UI providers -- Scalar uses `pageTitle` instead of `title`.
249
+
250
+ ### UIProviderFactory API
251
+
252
+ | Method | Signature | Description |
253
+ |--------|-----------|-------------|
254
+ | `getInstance()` | `static () => UIProviderFactory` | Returns singleton instance |
255
+ | `register()` | `(opts: { type: string }) => void` | Instantiates and registers a UI provider (idempotent) |
256
+ | `getProvider()` | `(opts: IGetProviderParams) => IUIProvider` | Returns registered provider or throws |
257
+ | `getRegisteredProviders()` | `() => string[]` | Lists all registered provider type keys |
258
+
259
+ #### register() Idempotency
260
+
261
+ The `register()` method is idempotent. If a provider of the given type is already registered, it logs a warning and returns without error:
262
+
263
+ ```typescript
264
+ register(opts: { type: string }): void {
265
+ if (this.isBound(opts.type)) {
266
+ this.logger
267
+ .for(this.register.name)
268
+ .warn('Skip registering BOUNDED Document UI | type: %s', opts.type);
269
+ return;
270
+ }
271
+ // ... instantiate and store the provider
272
+ }
273
+ ```
274
+
275
+ This means calling `register({ type: 'scalar' })` multiple times is safe and will not create duplicate provider instances.
276
+
277
+ ### IUIProvider Interface
278
+
279
+ ```typescript
280
+ interface IUIProvider {
281
+ render(context: Context, config: IUIConfig, next: Next): Promise<Response | void>;
282
+ }
283
+
284
+ interface IUIConfig {
285
+ title: string; // App name from package.json
286
+ url: string; // Full URL to OpenAPI JSON endpoint
287
+ [key: string]: any; // Additional config from uiConfig option
288
+ }
289
+ ```
290
+
291
+ ### Security Scheme Registration
292
+
293
+ The component auto-registers two OpenAPI security schemes:
294
+
295
+ ```typescript
296
+ // JWT Bearer
297
+ rootRouter.openAPIRegistry.registerComponent('securitySchemes', 'jwt', {
298
+ type: 'http',
299
+ scheme: 'bearer',
300
+ bearerFormat: 'JWT',
301
+ });
302
+
303
+ // Basic Auth
304
+ rootRouter.openAPIRegistry.registerComponent('securitySchemes', 'basic', {
305
+ type: 'http',
306
+ scheme: 'basic',
307
+ });
308
+ ```
309
+
310
+ This ensures routes using `authStrategies: ['jwt']` or `authStrategies: ['basic']` display the correct auth UI (lock icon + input fields) in the documentation.
311
+
312
+ ## Binding Keys
313
+
314
+ | Key | Constant | Type | Required | Default |
315
+ |-----|----------|------|----------|---------|
316
+ | `@app/swagger/options` | `SwaggerBindingKeys.SWAGGER_OPTIONS` | `ISwaggerOptions` | No | See below |
317
+
318
+ The `SwaggerComponent` constructor creates a default binding using the `Binding` fluent API:
319
+
320
+ ```typescript
321
+ this.bindings = {
322
+ [SwaggerBindingKeys.SWAGGER_OPTIONS]: Binding.bind<ISwaggerOptions>({
323
+ key: SwaggerBindingKeys.SWAGGER_OPTIONS,
324
+ }).toValue(DEFAULT_SWAGGER_OPTIONS),
325
+ };
326
+ ```
327
+
328
+ Note that unlike `HealthCheckComponent`, `SwaggerComponent` does not pass `initDefault: { enable: true, container: application }` to `BaseComponent`. The default bindings stored in `this.bindings` are not automatically registered into the DI container. Instead, the `binding()` method reads from the container with `isOptional: true` and falls back to `DEFAULT_SWAGGER_OPTIONS` via the `??` operator.
329
+
330
+ **Default value:**
331
+
332
+ ```typescript
333
+ const DEFAULT_SWAGGER_OPTIONS: ISwaggerOptions = {
334
+ restOptions: {
335
+ base: { path: '/doc' },
336
+ doc: { path: '/openapi.json' },
337
+ ui: { path: '/explorer', type: 'scalar' },
338
+ },
339
+ explorer: {
340
+ openapi: '3.0.0',
341
+ info: {
342
+ title: 'API Documentation',
343
+ version: '1.0.0',
344
+ description: 'API documentation for your service',
345
+ },
346
+ },
347
+ };
348
+ ```
349
+
350
+ > [!NOTE]
351
+ > The `explorer.info` values in `DEFAULT_SWAGGER_OPTIONS` are never used at runtime because `binding()` unconditionally overwrites `explorer.info` with data from `package.json`. They exist only as structural defaults.
352
+
353
+ ### Type Definitions
354
+
355
+ ```typescript
356
+ type TDocumentUIType = TConstValue<typeof DocumentUITypes>;
357
+
358
+ class DocumentUITypes {
359
+ static readonly SWAGGER = 'swagger';
360
+ static readonly SCALAR = 'scalar';
361
+ static readonly SCHEME_SET: Set<string>;
362
+ static isValid(input: string): boolean;
363
+ }
364
+ ```
365
+
366
+ `TDocumentUIType` is derived via `TConstValue`, which extracts the union of all `static readonly` string values from `DocumentUITypes`. This ensures the type stays in sync with the constants automatically.
367
+
368
+ ## API Endpoints
369
+
370
+ | Method | Path | Description |
371
+ |--------|------|-------------|
372
+ | `GET` | `/doc/explorer` | Documentation UI (Scalar by default) |
373
+ | `GET` | `/doc/openapi.json` | Raw OpenAPI specification |
374
+
375
+ > [!NOTE]
376
+ > These paths are based on the default configuration. If you customize `restOptions.base.path`, `restOptions.ui.path`, or `restOptions.doc.path`, the actual endpoints change accordingly.
377
+
378
+ ### Documentation UI Endpoint
379
+
380
+ **Default path:** `/doc/explorer`
381
+
382
+ Renders an interactive API documentation page using the configured UI provider (Scalar or Swagger UI). The UI fetches the OpenAPI spec from the JSON endpoint and renders it with full request/response exploration, authentication controls, and try-it-out functionality.
383
+
384
+ ### OpenAPI JSON Endpoint
385
+
386
+ **Default path:** `/doc/openapi.json`
387
+
388
+ Returns the raw OpenAPI JSON specification generated from all registered controller routes and their Zod schemas. This endpoint can be used by:
389
+ - External API testing tools (Postman, Insomnia)
390
+ - CI pipelines for API contract validation
391
+ - Client SDK generators (openapi-generator, orval)
392
+ - API gateway configuration
393
+
394
+ ## Troubleshooting
395
+
396
+ ### "Invalid document UI Type"
397
+
398
+ **Cause:** The `restOptions.ui.type` value is not `'swagger'` or `'scalar'`. The `UIProviderFactory` only recognizes these two built-in providers. Note that a falsy value (empty string, `undefined`) does not trigger this error -- it silently falls back to `'swagger'` due to the `||` operator, not to the default `'scalar'`.
399
+
400
+ **Fix:** Use a valid UI type:
401
+
402
+ ```typescript
403
+ this.bind<ISwaggerOptions>({
404
+ key: SwaggerBindingKeys.SWAGGER_OPTIONS,
405
+ }).toValue({
406
+ restOptions: {
407
+ base: { path: '/doc' },
408
+ doc: { path: '/openapi.json' },
409
+ ui: { path: '/explorer', type: 'scalar' }, // 'scalar' or 'swagger'
410
+ },
411
+ explorer: { openapi: '3.0.0' },
412
+ });
413
+ ```
414
+
415
+ ### Documentation UI shows no routes
416
+
417
+ **Cause:** Controllers are not defining routes with Zod schemas via `defineRoute` or `bindRoute`. Only routes registered through `@hono/zod-openapi` appear in the OpenAPI spec.
418
+
419
+ **Fix:** Use `defineRoute` with Zod response schemas in your controllers:
420
+
421
+ ```typescript
422
+ this.defineRoute({
423
+ configs: {
424
+ path: '/',
425
+ method: 'get',
426
+ responses: {
427
+ 200: jsonContent({
428
+ description: 'Success',
429
+ schema: z.object({ message: z.string() }),
430
+ }),
431
+ },
432
+ },
433
+ handler: (c) => c.json({ message: 'ok' }, 200),
434
+ });
435
+ ```
436
+
437
+ ### "Unknown UI Provider"
438
+
439
+ **Cause:** The `UIProviderFactory.getProvider()` was called with a type that has not been registered. This typically happens if the component binding phase failed silently.
440
+
441
+ **Fix:** Ensure the `SwaggerComponent` is registered in `preConfigure()` and that no errors occur during its `binding()` phase. Check the application logs for warnings from `UIProviderFactory`.
442
+
443
+ ### OpenAPI spec missing authentication schemes
444
+
445
+ **Cause:** The `SwaggerComponent` auto-registers JWT and Basic security schemes. If the `AuthenticationComponent` is not registered, authenticated routes will not show auth UI in the documentation.
446
+
447
+ **Fix:** Register `AuthenticationComponent` before `SwaggerComponent` in `preConfigure()` to ensure auth strategies are available when the Swagger component configures security schemes.
169
448
 
170
- By default, the documentation is available at the following endpoints:
449
+ ### explorer.info values not matching custom configuration
171
450
 
172
- - **/doc/explorer**: The documentation UI (`scalar` by default).
173
- - **/doc/openapi.json**: The raw OpenAPI specification.
451
+ **Cause:** The `SwaggerComponent` unconditionally overwrites `explorer.info` with values from `package.json` during its `binding()` phase. Any values you set in `explorer.info` via the DI binding are discarded.
174
452
 
175
- These paths can be configured by providing custom `ISwaggerOptions`. This feature provides a powerful and flexible way to document your APIs, making them easier to consume and understand.
453
+ **Fix:** Update your project's `package.json` fields (`name`, `version`, `description`, `author`) to control what appears in the API documentation info section. The component reads these via `application.getAppInfo()`.
176
454
 
177
455
  ## See Also
178
456
 
179
- - **Related Concepts:**
457
+ - **Guides:**
180
458
  - [Components Overview](/guides/core-concepts/components) - Component system basics
181
459
  - [Controllers](/guides/core-concepts/controllers) - Defining OpenAPI routes
182
460
 
183
- - **Other Components:**
184
- - [Components Index](./index) - All built-in components
461
+ - **Components:**
462
+ - [All Components](./index) - Built-in components list
463
+ - [Authentication](./authentication/) - JWT/Basic auth for secured endpoints
185
464
 
186
- - **References:**
465
+ - **Utilities:**
187
466
  - [Schema Utilities](/references/utilities/schema) - Response schema helpers
188
467
  - [JSX Utilities](/references/utilities/jsx) - HTML response schemas
189
468
 
190
469
  - **External Resources:**
191
470
  - [OpenAPI Specification](https://swagger.io/specification/) - OpenAPI standard
192
- - [Scalar Documentation](https://github.com/scalar/scalar) - API documentation UI
471
+ - [Scalar Documentation](https://github.com/scalar/scalar) - Scalar API documentation UI
472
+ - [@hono/zod-openapi](https://github.com/honojs/middleware/tree/main/packages/zod-openapi) - Hono OpenAPI integration
@@ -0,0 +1,125 @@
1
+ # API Reference Page Template (Tier 2 -- api.md)
2
+
3
+ The "understand it deeply" page. A developer reads this on Day 30 when they need to understand how the component works internally, debug edge cases, or extend behavior. Contains architecture diagrams, full method signatures, internal lifecycle, and type definitions.
4
+
5
+ Paired with [Setup](./setup-page), [Usage](./usage-page), and [Error Reference](./errors-page).
6
+
7
+ ## When to Use
8
+
9
+ Always created alongside the other 3 pages for Tier 2 components.
10
+
11
+ ## Page Structure
12
+
13
+ ```markdown
14
+ # {Component Name} -- API Reference
15
+
16
+ > Architecture, method signatures, and internals for the [{Component Name}](./) component.
17
+
18
+ ## Architecture
19
+
20
+ ` ``
21
+ ┌─────────────────┐
22
+ │ Application │
23
+ └────────┬────────┘
24
+ │ registers
25
+
26
+ ┌─────────────────┐ ┌──────────────┐
27
+ │ Component │────▶│ Helper │
28
+ └─────────────────┘ └──────────────┘
29
+ ` ``
30
+
31
+ ### {Flow Name} (e.g., "Authentication Flow", "Message Delivery Flow")
32
+
33
+ 1. Step-by-step explanation of the data flow
34
+ 2. What happens at each stage
35
+ 3. How components interact
36
+
37
+ ## {Public API Section} (e.g., "Server Helper API", "Strategy Registry")
38
+
39
+ ### `methodName()`
40
+
41
+ ` ``typescript
42
+ methodName(opts: { param: Type }): ReturnType
43
+ ` ``
44
+
45
+ | Parameter | Type | Description |
46
+ |-----------|------|-------------|
47
+ | `param` | `Type` | What it controls |
48
+
49
+ **Returns:** Description of return value.
50
+
51
+ ### `anotherMethod()`
52
+
53
+ ` ``typescript
54
+ anotherMethod(): void
55
+ ` ``
56
+
57
+ Description of what this method does.
58
+
59
+ ## Types Reference
60
+
61
+ ### `IInterfaceName`
62
+
63
+ ` ``typescript
64
+ interface IInterfaceName {
65
+ field: string;
66
+ optional?: number;
67
+ }
68
+ ` ``
69
+
70
+ | Field | Type | Description |
71
+ |-------|------|-------------|
72
+ | `field` | `string` | What it represents |
73
+ | `optional` | `number` | Optional description |
74
+
75
+ ## Internals
76
+
77
+ ### Component Lifecycle
78
+
79
+ How the component initializes during application startup:
80
+
81
+ 1. **`constructor()`** -- What happens at instantiation
82
+ 2. **`binding()`** -- What gets registered with the DI container
83
+ 3. **`resolveBindings()`** -- How bindings are resolved
84
+ 4. **Post-start hook** -- What runs after the server starts (if applicable)
85
+
86
+ ### {Internal Mechanism} (e.g., "Token Encryption", "Redis Channel Architecture")
87
+
88
+ Detailed explanation of a key internal mechanism.
89
+
90
+ ` ``typescript
91
+ // Key implementation code
92
+ ` ``
93
+
94
+ ### {Another Internal}
95
+
96
+ Description and code.
97
+
98
+ ## See Also
99
+
100
+ - [Setup & Configuration](./) -- Quick reference, setup steps, configuration options
101
+ - [Usage & Examples](./usage) -- Usage patterns, examples, API endpoints
102
+ - [Error Reference](./errors) -- Error tables and troubleshooting
103
+
104
+ - **Guides:**
105
+ - [Components](/guides/core-concepts/components) - Component system overview
106
+
107
+ - **Components:**
108
+ - [All Components](../index) - Built-in components list
109
+ ```
110
+
111
+ ## Rules
112
+
113
+ - **File name:** Always `api.md` inside the component directory
114
+ - **Focus:** How it works internally. Architecture, methods, types, lifecycle
115
+ - **Architecture section:** Required. Use ASCII art or Mermaid diagrams. Focus on data flow and component relationships
116
+ - **Method signatures:** Show full TypeScript signatures with parameter tables
117
+ - **Types Reference:** Include all public interfaces and types. Show the full interface definition plus a field description table
118
+ - **Internals:** Explain the component lifecycle and key internal mechanisms. Include relevant source code snippets
119
+ - **No setup steps** on this page -- those are in `index.md`
120
+ - **No usage examples** on this page -- those are in `usage.md`
121
+ - **No API endpoint specs** on this page -- those are in `usage.md`
122
+ - **No error tables** on this page -- those are in `errors.md`
123
+ - **No troubleshooting** on this page -- those are in `errors.md`
124
+ - **No collapsible sections** -- show all content directly using `####` sub-headings for source code, verbose explanations
125
+ - Use `> [!NOTE]`, `> [!TIP]`, `> [!WARNING]`, `> [!IMPORTANT]` callouts