@venizia/ignis-docs 0.0.3 → 0.0.4-1

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 (131) hide show
  1. package/README.md +1 -1
  2. package/package.json +4 -2
  3. package/wiki/best-practices/api-usage-examples.md +591 -0
  4. package/wiki/best-practices/architectural-patterns.md +415 -0
  5. package/wiki/best-practices/architecture-decisions.md +488 -0
  6. package/wiki/{get-started/best-practices → best-practices}/code-style-standards.md +406 -17
  7. package/wiki/{get-started/best-practices → best-practices}/common-pitfalls.md +109 -4
  8. package/wiki/{get-started/best-practices → best-practices}/contribution-workflow.md +34 -7
  9. package/wiki/best-practices/data-modeling.md +376 -0
  10. package/wiki/best-practices/deployment-strategies.md +698 -0
  11. package/wiki/best-practices/index.md +27 -0
  12. package/wiki/best-practices/performance-optimization.md +196 -0
  13. package/wiki/best-practices/security-guidelines.md +218 -0
  14. package/wiki/{get-started/best-practices → best-practices}/troubleshooting-tips.md +97 -1
  15. package/wiki/changelogs/2025-12-16-initial-architecture.md +1 -1
  16. package/wiki/changelogs/2025-12-16-model-repo-datasource-refactor.md +1 -1
  17. package/wiki/changelogs/2025-12-17-refactor.md +1 -1
  18. package/wiki/changelogs/2025-12-18-performance-optimizations.md +5 -5
  19. package/wiki/changelogs/2025-12-18-repository-validation-security.md +13 -7
  20. package/wiki/changelogs/2025-12-26-nested-relations-and-generics.md +2 -2
  21. package/wiki/changelogs/2025-12-29-dynamic-binding-registration.md +104 -0
  22. package/wiki/changelogs/2025-12-29-snowflake-uid-helper.md +100 -0
  23. package/wiki/changelogs/2025-12-30-repository-enhancements.md +214 -0
  24. package/wiki/changelogs/2025-12-31-json-path-filtering-array-operators.md +214 -0
  25. package/wiki/changelogs/2025-12-31-string-id-custom-generator.md +137 -0
  26. package/wiki/changelogs/2026-01-02-default-filter-and-repository-mixins.md +418 -0
  27. package/wiki/changelogs/index.md +6 -0
  28. package/wiki/changelogs/planned-schema-migrator.md +0 -8
  29. package/wiki/{get-started/core-concepts → guides/core-concepts/application}/bootstrapping.md +18 -5
  30. package/wiki/{get-started/core-concepts/application.md → guides/core-concepts/application/index.md} +47 -104
  31. package/wiki/guides/core-concepts/components-guide.md +509 -0
  32. package/wiki/{get-started → guides}/core-concepts/components.md +24 -17
  33. package/wiki/{get-started → guides}/core-concepts/controllers.md +30 -13
  34. package/wiki/{get-started → guides}/core-concepts/dependency-injection.md +97 -0
  35. package/wiki/guides/core-concepts/persistent/datasources.md +179 -0
  36. package/wiki/guides/core-concepts/persistent/index.md +119 -0
  37. package/wiki/guides/core-concepts/persistent/models.md +241 -0
  38. package/wiki/guides/core-concepts/persistent/repositories.md +219 -0
  39. package/wiki/guides/core-concepts/persistent/transactions.md +170 -0
  40. package/wiki/{get-started → guides}/core-concepts/services.md +26 -3
  41. package/wiki/{get-started → guides/get-started}/5-minute-quickstart.md +59 -14
  42. package/wiki/guides/get-started/philosophy.md +682 -0
  43. package/wiki/guides/get-started/setup.md +157 -0
  44. package/wiki/guides/index.md +89 -0
  45. package/wiki/guides/reference/glossary.md +243 -0
  46. package/wiki/{get-started → guides/reference}/mcp-docs-server.md +0 -10
  47. package/wiki/{get-started → guides/tutorials}/building-a-crud-api.md +134 -132
  48. package/wiki/{get-started/quickstart.md → guides/tutorials/complete-installation.md} +107 -71
  49. package/wiki/guides/tutorials/ecommerce-api.md +1399 -0
  50. package/wiki/guides/tutorials/realtime-chat.md +1261 -0
  51. package/wiki/guides/tutorials/testing.md +723 -0
  52. package/wiki/index.md +176 -37
  53. package/wiki/references/base/application.md +27 -0
  54. package/wiki/references/base/bootstrapping.md +31 -26
  55. package/wiki/references/base/components.md +24 -7
  56. package/wiki/references/base/controllers.md +50 -20
  57. package/wiki/references/base/datasources.md +30 -0
  58. package/wiki/references/base/dependency-injection.md +39 -3
  59. package/wiki/references/base/filter-system/application-usage.md +224 -0
  60. package/wiki/references/base/filter-system/array-operators.md +132 -0
  61. package/wiki/references/base/filter-system/comparison-operators.md +109 -0
  62. package/wiki/references/base/filter-system/default-filter.md +428 -0
  63. package/wiki/references/base/filter-system/fields-order-pagination.md +155 -0
  64. package/wiki/references/base/filter-system/index.md +127 -0
  65. package/wiki/references/base/filter-system/json-filtering.md +197 -0
  66. package/wiki/references/base/filter-system/list-operators.md +71 -0
  67. package/wiki/references/base/filter-system/logical-operators.md +156 -0
  68. package/wiki/references/base/filter-system/null-operators.md +58 -0
  69. package/wiki/references/base/filter-system/pattern-matching.md +108 -0
  70. package/wiki/references/base/filter-system/quick-reference.md +431 -0
  71. package/wiki/references/base/filter-system/range-operators.md +63 -0
  72. package/wiki/references/base/filter-system/tips.md +190 -0
  73. package/wiki/references/base/filter-system/use-cases.md +452 -0
  74. package/wiki/references/base/index.md +90 -0
  75. package/wiki/references/base/middlewares.md +604 -0
  76. package/wiki/references/base/models.md +215 -23
  77. package/wiki/references/base/providers.md +731 -0
  78. package/wiki/references/base/repositories/advanced.md +555 -0
  79. package/wiki/references/base/repositories/index.md +228 -0
  80. package/wiki/references/base/repositories/mixins.md +331 -0
  81. package/wiki/references/base/repositories/relations.md +486 -0
  82. package/wiki/references/base/repositories.md +40 -635
  83. package/wiki/references/base/services.md +28 -4
  84. package/wiki/references/components/authentication.md +22 -2
  85. package/wiki/references/components/health-check.md +12 -0
  86. package/wiki/references/components/index.md +23 -0
  87. package/wiki/references/components/mail.md +687 -0
  88. package/wiki/references/components/request-tracker.md +16 -0
  89. package/wiki/references/components/socket-io.md +18 -0
  90. package/wiki/references/components/static-asset.md +14 -26
  91. package/wiki/references/components/swagger.md +17 -0
  92. package/wiki/references/configuration/environment-variables.md +427 -0
  93. package/wiki/references/configuration/index.md +73 -0
  94. package/wiki/references/helpers/cron.md +14 -0
  95. package/wiki/references/helpers/crypto.md +15 -0
  96. package/wiki/references/helpers/env.md +16 -0
  97. package/wiki/references/helpers/error.md +17 -0
  98. package/wiki/references/helpers/index.md +14 -0
  99. package/wiki/references/helpers/inversion.md +24 -4
  100. package/wiki/references/helpers/logger.md +19 -0
  101. package/wiki/references/helpers/network.md +11 -0
  102. package/wiki/references/helpers/queue.md +19 -0
  103. package/wiki/references/helpers/redis.md +21 -0
  104. package/wiki/references/helpers/socket-io.md +24 -5
  105. package/wiki/references/helpers/storage.md +18 -10
  106. package/wiki/references/helpers/testing.md +18 -0
  107. package/wiki/references/helpers/types.md +16 -0
  108. package/wiki/references/helpers/uid.md +167 -0
  109. package/wiki/references/helpers/worker-thread.md +16 -0
  110. package/wiki/references/index.md +177 -0
  111. package/wiki/references/quick-reference.md +634 -0
  112. package/wiki/references/src-details/boot.md +3 -3
  113. package/wiki/references/src-details/dev-configs.md +0 -4
  114. package/wiki/references/src-details/docs.md +2 -2
  115. package/wiki/references/src-details/index.md +86 -0
  116. package/wiki/references/src-details/inversion.md +1 -6
  117. package/wiki/references/src-details/mcp-server.md +3 -15
  118. package/wiki/references/utilities/index.md +86 -10
  119. package/wiki/references/utilities/jsx.md +577 -0
  120. package/wiki/references/utilities/request.md +0 -2
  121. package/wiki/references/utilities/statuses.md +740 -0
  122. package/wiki/get-started/best-practices/api-usage-examples.md +0 -266
  123. package/wiki/get-started/best-practices/architectural-patterns.md +0 -170
  124. package/wiki/get-started/best-practices/data-modeling.md +0 -177
  125. package/wiki/get-started/best-practices/deployment-strategies.md +0 -121
  126. package/wiki/get-started/best-practices/performance-optimization.md +0 -97
  127. package/wiki/get-started/best-practices/security-guidelines.md +0 -99
  128. package/wiki/get-started/core-concepts/persistent.md +0 -539
  129. package/wiki/get-started/index.md +0 -65
  130. package/wiki/get-started/philosophy.md +0 -296
  131. package/wiki/get-started/prerequisites.md +0 -113
@@ -0,0 +1,90 @@
1
+ # Base Abstractions
2
+
3
+ Core classes that power every Ignis application - from the Application entry point to Repositories for data access.
4
+
5
+ ## Quick Reference
6
+
7
+ | Class | Purpose | Extends |
8
+ |-------|---------|---------|
9
+ | `BaseApplication` | Application entry point, DI container | `AbstractApplication` |
10
+ | `BaseController` | HTTP route handlers | - |
11
+ | `BaseService` | Business logic layer | - |
12
+ | `BaseProvider` | Factory pattern for runtime instantiation | `BaseHelper` |
13
+ | `BaseComponent` | Pluggable feature modules | - |
14
+ | `BaseDataSource` | Database connections | - |
15
+ | `BaseEntity` | Model definitions | - |
16
+ | `DefaultCRUDRepository` | Full CRUD operations | `PersistableRepository` |
17
+ | `ReadableRepository` | Read-only operations | `AbstractRepository` |
18
+
19
+ ## Architecture
20
+
21
+ ```
22
+ ┌─────────────────────────────────────────────────────────────┐
23
+ │ BaseApplication │
24
+ │ (DI Container + Lifecycle + Server Management) │
25
+ ├─────────────────────────────────────────────────────────────┤
26
+ │ │
27
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
28
+ │ │ BaseController│ │ BaseService │ │BaseComponent │ │
29
+ │ │ (HTTP Layer) │ │(Business Logic)│ │ (Plugins) │ │
30
+ │ └──────┬───────┘ └──────┬───────┘ └──────────────┘ │
31
+ │ │ │ │
32
+ │ └────────┬─────────┘ │
33
+ │ ▼ │
34
+ │ ┌──────────────────┐ │
35
+ │ │DefaultCRUDRepository│ │
36
+ │ │ (Data Access) │ │
37
+ │ └────────┬──────────┘ │
38
+ │ │ │
39
+ │ ┌────────┴────────┐ │
40
+ │ ▼ ▼ │
41
+ │ ┌────────────┐ ┌────────────┐ │
42
+ │ │BaseDataSource│ │ BaseEntity │ │
43
+ │ │(Connection) │ │ (Schema) │ │
44
+ │ └─────────────┘ └────────────┘ │
45
+ │ │
46
+ └──────────────────────────────────────────────────────────────┘
47
+ ```
48
+
49
+ ## What's in This Section
50
+
51
+ ### Core Application
52
+ - [Application](./application.md) - `BaseApplication` class, resource registration, lifecycle hooks
53
+ - [Bootstrapping](./bootstrapping.md) - Startup sequence, `initialize()` flow
54
+
55
+ ### HTTP Layer
56
+ - [Controllers](./controllers.md) - Route handlers, decorators, request/response handling
57
+ - [Middlewares](./middlewares.md) - Built-in middlewares for error handling, logging, and request processing
58
+ - [Services](./services.md) - Business logic, injectable services
59
+
60
+ ### Dependency Injection
61
+ - [Dependency Injection](./dependency-injection.md) - Container, bindings, `@inject` patterns
62
+ - [Providers](./providers.md) - Factory pattern for configuration-driven instantiation
63
+ - [Components](./components.md) - Pluggable modules, component lifecycle
64
+
65
+ ### Data Layer
66
+ - [Models & Enrichers](./models.md) - `BaseEntity`, schema definitions, enrichers
67
+ - [DataSources](./datasources.md) - Database connections, auto-discovery
68
+ - [Repositories](./repositories/) - CRUD operations, filtering, relations
69
+ - [Filter System](./filter-system/) - Query filter types and operators
70
+
71
+ ## Class Hierarchy
72
+
73
+ ```
74
+ AbstractApplication
75
+ └── BaseApplication ──────► Your Application
76
+
77
+ AbstractRepository
78
+ ├── ReadableRepository
79
+ │ └── PersistableRepository
80
+ │ └── DefaultCRUDRepository ──────► Your Repository
81
+
82
+ BaseController ──────► Your Controller
83
+ BaseService ──────► Your Service
84
+ BaseProvider ──────► Your Provider
85
+ BaseComponent ──────► Your Component
86
+ BaseDataSource ──────► Your DataSource
87
+ BaseEntity ──────► Your Model
88
+ ```
89
+
90
+ > **Related:** [Core Concepts Guide](../../guides/core-concepts/application/) | [Persistent Layer Guide](../../guides/core-concepts/persistent/)
@@ -0,0 +1,604 @@
1
+ ---
2
+ title: Middlewares Reference
3
+ description: Technical reference for IGNIS built-in middlewares
4
+ difficulty: intermediate
5
+ lastUpdated: 2026-01-03
6
+ ---
7
+
8
+ # Middlewares Reference
9
+
10
+ IGNIS provides a collection of built-in middlewares for common application needs including error handling, request logging, request normalization, and favicon serving.
11
+
12
+ **Files:**
13
+ - `packages/core/src/base/middlewares/*.ts`
14
+
15
+ ## Prerequisites
16
+
17
+ - [Hono Middleware basics](https://hono.dev/docs/guides/middleware)
18
+ - [IGNIS Application basics](./application.md)
19
+ - Basic understanding of HTTP request/response lifecycle
20
+
21
+ ## Quick Reference
22
+
23
+ | Middleware | Purpose | Key Options |
24
+ |------------|---------|-------------|
25
+ | `appErrorHandler` | Catches and formats application errors | `logger` |
26
+ | `notFoundHandler` | Handles 404 Not Found responses | `logger` |
27
+ | `requestNormalize` | Pre-parses JSON request bodies | None |
28
+ | `RequestSpyMiddleware` | Logs request lifecycle and timing | None |
29
+ | `emojiFavicon` | Serves an emoji as favicon | `icon` |
30
+
31
+ ## Table of Contents
32
+
33
+ - [Error Handler (`appErrorHandler`)](#error-handler-apporerrorhandler)
34
+ - [Not Found Handler (`notFoundHandler`)](#not-found-handler-notfoundhandler)
35
+ - [Request Normalizer (`requestNormalize`)](#request-normalizer-requestnormalize)
36
+ - [Request Spy (Debug)](#request-spy-debug)
37
+ - [Emoji Favicon](#emoji-favicon)
38
+ - [Creating Custom Middleware](#creating-custom-middleware)
39
+ - [Middleware Order & Priority](#middleware-order--priority)
40
+ - [See Also](#see-also)
41
+
42
+ ## Built-in Middlewares
43
+
44
+ ### Error Handler (`appErrorHandler`)
45
+
46
+ The error handler middleware catches all unhandled errors in your application and formats them into consistent JSON responses.
47
+
48
+ **File:** `packages/core/src/base/middlewares/app-error.middleware.ts`
49
+
50
+ #### Features
51
+
52
+ - **Automatic Error Formatting**: Converts all errors to structured JSON responses
53
+ - **ZodError Support**: Special handling for Zod validation errors with detailed field-level messages
54
+ - **Environment-Aware**: Hides stack traces and error causes in production
55
+ - **Request Tracking**: Includes `requestId` for debugging and tracing
56
+ - **Status Code Detection**: Automatically extracts HTTP status codes from errors
57
+
58
+ #### Usage
59
+
60
+ ```typescript
61
+ import { appErrorHandler } from '@venizia/ignis';
62
+
63
+ const app = new IgnisApplication({
64
+ // ...
65
+ });
66
+
67
+ // Register error handler
68
+ app.onError(appErrorHandler({
69
+ logger: app.logger
70
+ }));
71
+ ```
72
+
73
+ #### Error Response Format
74
+
75
+ **Standard Error:**
76
+ ```json
77
+ {
78
+ "message": "Something went wrong",
79
+ "statusCode": 500,
80
+ "requestId": "abc123",
81
+ "details": {
82
+ "url": "http://localhost:3000/api/users",
83
+ "path": "/api/users",
84
+ "stack": "Error: Something went wrong\n at ...", // development only
85
+ "cause": { ... } // development only
86
+ }
87
+ }
88
+ ```
89
+
90
+ **Validation Error (ZodError):**
91
+ ```json
92
+ {
93
+ "message": "ValidationError",
94
+ "statusCode": 422,
95
+ "requestId": "abc123",
96
+ "details": {
97
+ "url": "http://localhost:3000/api/users",
98
+ "path": "/api/users",
99
+ "stack": "...", // development only
100
+ "cause": [
101
+ {
102
+ "path": "email",
103
+ "message": "Invalid email address",
104
+ "code": "invalid_string",
105
+ "expected": "string",
106
+ "received": "undefined"
107
+ }
108
+ ]
109
+ }
110
+ }
111
+ ```
112
+
113
+ #### API Reference
114
+
115
+ ##### `appErrorHandler(options)`
116
+
117
+ **Parameters:**
118
+ | Option | Type | Required | Description |
119
+ |--------|------|----------|-------------|
120
+ | `logger` | `ApplicationLogger` | Yes | Logger instance for error logging |
121
+
122
+ **Returns:** `ErrorHandler` - Hono error handler function
123
+
124
+ #### Common Patterns
125
+
126
+ ```typescript
127
+ // Custom error with status code
128
+ class NotFoundError extends Error {
129
+ statusCode = 404;
130
+
131
+ constructor(message: string) {
132
+ super(message);
133
+ this.name = 'NotFoundError';
134
+ }
135
+ }
136
+
137
+ // Throw in controller
138
+ const GetUserConfig = {
139
+ method: HTTP.Methods.GET,
140
+ path: '/users/:id',
141
+ request: {
142
+ params: z.object({ id: z.string() }),
143
+ },
144
+ responses: jsonResponse({
145
+ schema: z.object({ id: z.string(), name: z.string() }),
146
+ }),
147
+ } as const;
148
+
149
+ @get({ configs: GetUserConfig })
150
+ async getUser(c: TRouteContext<typeof GetUserConfig>) {
151
+ const { id } = c.req.valid('param');
152
+ const user = await this.userRepository.findById(id);
153
+ if (!user) {
154
+ throw new NotFoundError(`User ${id} not found`);
155
+ }
156
+ return c.json(user, HTTP.ResultCodes.RS_2.Ok);
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ### Not Found Handler (`notFoundHandler`)
163
+
164
+ Handles requests to routes that don't exist, returning a standardized 404 response.
165
+
166
+ **File:** `packages/core/src/base/middlewares/not-found.middleware.ts`
167
+
168
+ #### Usage
169
+
170
+ ```typescript
171
+ import { notFoundHandler } from '@venizia/ignis';
172
+
173
+ const app = new IgnisApplication({
174
+ // ...
175
+ });
176
+
177
+ // Register 404 handler
178
+ app.notFound(notFoundHandler({
179
+ logger: app.logger
180
+ }));
181
+ ```
182
+
183
+ #### Response Format
184
+
185
+ ```json
186
+ {
187
+ "message": "URL NOT FOUND",
188
+ "path": "/api/nonexistent",
189
+ "url": "http://localhost:3000/api/nonexistent"
190
+ }
191
+ ```
192
+
193
+ **Status Code:** `404 Not Found`
194
+
195
+ #### API Reference
196
+
197
+ ##### `notFoundHandler(options)`
198
+
199
+ **Parameters:**
200
+ | Option | Type | Required | Default | Description |
201
+ |--------|------|----------|---------|-------------|
202
+ | `logger` | `ApplicationLogger` | No | `console` | Logger instance for logging 404s |
203
+
204
+ **Returns:** `NotFoundHandler` - Hono not found handler function
205
+
206
+ ---
207
+
208
+ ### Request Normalizer (`requestNormalize`)
209
+
210
+ Pre-parses JSON request bodies to ensure consistent request handling and prevent common parsing issues.
211
+
212
+ **File:** `packages/core/src/base/middlewares/request-normalize.middleware.ts`
213
+
214
+ #### How It Works
215
+
216
+ 1. **Skip for GET/OPTIONS**: No normalization for read-only requests
217
+ 2. **Check Content-Length**: Skip if no body is present (`Content-Length: 0`)
218
+ 3. **Check Content-Type**: Only process `application/json` requests
219
+ 4. **Pre-parse JSON**: Calls `context.req.json()` to cache the parsed body
220
+
221
+ #### Benefits
222
+
223
+ - Prevents multiple body parsing attempts
224
+ - Ensures body is available for all subsequent middleware/handlers
225
+ - Catches JSON parsing errors early in the request lifecycle
226
+
227
+ #### Usage
228
+
229
+ ```typescript
230
+ import { requestNormalize } from '@venizia/ignis';
231
+
232
+ const app = new IgnisApplication({
233
+ // ...
234
+ });
235
+
236
+ // Register as early middleware
237
+ app.use(requestNormalize());
238
+ ```
239
+
240
+ :::tip Why Pre-parse?
241
+ Hono's request body can only be read once. This middleware ensures the body is parsed and cached early, making it available to all downstream handlers.
242
+ :::
243
+
244
+ #### API Reference
245
+
246
+ ##### `requestNormalize()`
247
+
248
+ **Parameters:** None
249
+
250
+ **Returns:** `MiddlewareHandler` - Hono middleware function
251
+
252
+ ---
253
+
254
+ ### Request Spy (Debug)
255
+
256
+ Logs detailed information about each request including timing, IP address, method, path, and query parameters.
257
+
258
+ **File:** `packages/core/src/base/middlewares/request-spy.middleware.ts`
259
+
260
+ #### Features
261
+
262
+ - Request lifecycle logging (START/DONE)
263
+ - Performance timing tracking
264
+ - IP address extraction (supports `x-real-ip` and `x-forwarded-for` headers)
265
+ - Request ID tracking
266
+ - Query and body parameter logging
267
+
268
+ #### Usage
269
+
270
+ ```typescript
271
+ import { RequestSpyMiddleware } from '@venizia/ignis';
272
+
273
+ const app = new IgnisApplication({
274
+ // ...
275
+ });
276
+
277
+ // Create and register spy middleware
278
+ const requestSpy = new RequestSpyMiddleware();
279
+ app.use(requestSpy.value());
280
+ ```
281
+
282
+ #### Log Output
283
+
284
+ **Request Start:**
285
+ ```
286
+ [spy][abc123] START | Handling Request | forwardedIp: 192.168.1.1 | path: /api/users | method: GET
287
+ ```
288
+
289
+ **Request Complete:**
290
+ ```
291
+ [spy][abc123] DONE | Handling Request | forwardedIp: 192.168.1.1 | path: /api/users | method: GET | Took: 45.23 (ms)
292
+ ```
293
+
294
+ #### API Reference
295
+
296
+ ##### `RequestSpyMiddleware`
297
+
298
+ **Class Methods:**
299
+ | Method | Returns | Description |
300
+ |--------|---------|-------------|
301
+ | `value()` | `MiddlewareHandler` | Returns the middleware handler |
302
+
303
+ **Static Properties:**
304
+ | Property | Type | Value | Description |
305
+ |----------|------|-------|-------------|
306
+ | `REQUEST_ID_KEY` | `string` | `'requestId'` | Context key for request ID |
307
+
308
+ #### Accessing Request ID
309
+
310
+ ```typescript
311
+ import { RequestSpyMiddleware, get, HTTP, jsonResponse, TRouteContext, z } from '@venizia/ignis';
312
+
313
+ const ExampleConfig = {
314
+ method: HTTP.Methods.GET,
315
+ path: '/example',
316
+ responses: jsonResponse({
317
+ schema: z.object({ requestId: z.string() }),
318
+ }),
319
+ } as const;
320
+
321
+ // In a controller
322
+ @get({ configs: ExampleConfig })
323
+ async example(c: TRouteContext<typeof ExampleConfig>) {
324
+ const requestId = c.get(RequestSpyMiddleware.REQUEST_ID_KEY);
325
+ console.log('Request ID:', requestId);
326
+ return c.json({ requestId }, HTTP.ResultCodes.RS_2.Ok);
327
+ }
328
+ ```
329
+
330
+ :::warning Performance Impact
331
+ Request spy logs every request detail. Consider disabling or reducing verbosity in production environments with high traffic.
332
+ :::
333
+
334
+ ---
335
+
336
+ ### Emoji Favicon
337
+
338
+ Serves an SVG emoji as the application's favicon, providing a lightweight alternative to traditional favicon files.
339
+
340
+ **File:** `packages/core/src/base/middlewares/emoji-favicon.middleware.ts`
341
+
342
+ #### Usage
343
+
344
+ ```typescript
345
+ import { emojiFavicon } from '@venizia/ignis';
346
+
347
+ const app = new IgnisApplication({
348
+ // ...
349
+ });
350
+
351
+ // Serve a rocket emoji as favicon
352
+ app.use(emojiFavicon({ icon: '🚀' }));
353
+ ```
354
+
355
+ #### How It Works
356
+
357
+ 1. Intercepts requests to `/favicon.ico`
358
+ 2. Returns an inline SVG with the specified emoji
359
+ 3. Sets `Content-Type: image/svg+xml`
360
+ 4. All other requests pass through unchanged
361
+
362
+ #### API Reference
363
+
364
+ ##### `emojiFavicon(options)`
365
+
366
+ **Parameters:**
367
+ | Option | Type | Required | Description |
368
+ |--------|------|----------|-------------|
369
+ | `icon` | `string` | Yes | Emoji character to use as favicon |
370
+
371
+ **Returns:** `MiddlewareHandler` - Hono middleware function
372
+
373
+ #### Examples
374
+
375
+ ```typescript
376
+ // Different emoji icons
377
+ app.use(emojiFavicon({ icon: '🔥' })); // Fire
378
+ app.use(emojiFavicon({ icon: '⚡' })); // Lightning
379
+ app.use(emojiFavicon({ icon: '🎯' })); // Target
380
+ app.use(emojiFavicon({ icon: '🌟' })); // Star
381
+ ```
382
+
383
+ :::tip Browser Support
384
+ SVG favicons are supported in all modern browsers. Fallback to a traditional `.ico` file if you need to support legacy browsers.
385
+ :::
386
+
387
+ ---
388
+
389
+ ## Creating Custom Middleware
390
+
391
+ IGNIS uses Hono's middleware system. Create custom middleware using the `createMiddleware` factory:
392
+
393
+ ### Basic Middleware
394
+
395
+ ```typescript
396
+ import { createMiddleware } from 'hono/factory';
397
+ import type { MiddlewareHandler } from 'hono';
398
+
399
+ export const myMiddleware = (): MiddlewareHandler => {
400
+ return createMiddleware(async (context, next) => {
401
+ // Before request handling
402
+ console.log('Before:', context.req.path);
403
+
404
+ await next();
405
+
406
+ // After request handling
407
+ console.log('After:', context.req.path);
408
+ });
409
+ };
410
+ ```
411
+
412
+ ### Middleware with Options
413
+
414
+ ```typescript
415
+ interface MyMiddlewareOptions {
416
+ enabled: boolean;
417
+ prefix?: string;
418
+ }
419
+
420
+ export const myMiddleware = (opts: MyMiddlewareOptions): MiddlewareHandler => {
421
+ const { enabled, prefix = 'LOG' } = opts;
422
+
423
+ return createMiddleware(async (context, next) => {
424
+ if (enabled) {
425
+ console.log(`[${prefix}]`, context.req.path);
426
+ }
427
+ await next();
428
+ });
429
+ };
430
+
431
+ // Usage
432
+ app.use(myMiddleware({ enabled: true, prefix: 'API' }));
433
+ ```
434
+
435
+ ### Provider-Based Middleware
436
+
437
+ For middleware requiring dependency injection:
438
+
439
+ ```typescript
440
+ import { BaseHelper } from '@venizia/ignis-helpers';
441
+ import { IProvider } from '@venizia/ignis-inversion';
442
+ import { injectable } from '@venizia/ignis-inversion';
443
+ import { createMiddleware } from 'hono/factory';
444
+ import type { MiddlewareHandler } from 'hono';
445
+
446
+ @injectable()
447
+ export class MyMiddleware extends BaseHelper implements IProvider<MiddlewareHandler> {
448
+ constructor() {
449
+ super({ scope: MyMiddleware.name });
450
+ }
451
+
452
+ value(): MiddlewareHandler {
453
+ return createMiddleware(async (context, next) => {
454
+ this.logger.info('Processing request:', context.req.path);
455
+ await next();
456
+ });
457
+ }
458
+ }
459
+
460
+ // Usage
461
+ const myMiddleware = app.get(MyMiddleware);
462
+ app.use(myMiddleware.value());
463
+ ```
464
+
465
+ ---
466
+
467
+ ## Middleware Order & Priority
468
+
469
+ Middleware execution order matters. Follow these guidelines:
470
+
471
+ ### Recommended Order
472
+
473
+ ```typescript
474
+ const app = new IgnisApplication({ /* ... */ });
475
+
476
+ // 1. CORS (if needed)
477
+ app.use(cors());
478
+
479
+ // 2. Request ID generation
480
+ app.use(requestId());
481
+
482
+ // 3. Request spy/logging
483
+ const requestSpy = new RequestSpyMiddleware();
484
+ app.use(requestSpy.value());
485
+
486
+ // 4. Request normalization
487
+ app.use(requestNormalize());
488
+
489
+ // 5. Security middleware (helmet, etc.)
490
+ app.use(helmet());
491
+
492
+ // 6. Rate limiting
493
+ app.use(rateLimit());
494
+
495
+ // 7. Authentication
496
+ app.use('/api/*', authenticate());
497
+
498
+ // 8. Favicon (can be early or late)
499
+ app.use(emojiFavicon({ icon: '🚀' }));
500
+
501
+ // 9. Application routes
502
+ app.mountControllers();
503
+
504
+ // 10. Error handler (LAST in chain)
505
+ app.onError(appErrorHandler({ logger: app.logger }));
506
+
507
+ // 11. Not found handler (AFTER error handler)
508
+ app.notFound(notFoundHandler({ logger: app.logger }));
509
+ ```
510
+
511
+ ### Key Principles
512
+
513
+ 1. **Request ID First**: Generate request ID before logging
514
+ 2. **Logging Early**: Log requests before normalization/parsing
515
+ 3. **Normalization Before Business Logic**: Parse bodies before they're needed
516
+ 4. **Security Middleware Before Routes**: Protect routes with security checks
517
+ 5. **Error Handler Last**: Catch all errors from previous middleware
518
+ 6. **404 Handler After Error Handler**: Ensure unhandled routes return 404
519
+
520
+ :::warning Order Matters
521
+ Placing error handler before routes will prevent it from catching route errors. Always register error handlers last.
522
+ :::
523
+
524
+ ---
525
+
526
+ ## Common Patterns
527
+
528
+ ### Conditional Middleware
529
+
530
+ ```typescript
531
+ const app = new IgnisApplication({ /* ... */ });
532
+
533
+ // Enable request spy only in development
534
+ if (process.env.NODE_ENV === 'development') {
535
+ const requestSpy = new RequestSpyMiddleware();
536
+ app.use(requestSpy.value());
537
+ }
538
+ ```
539
+
540
+ ### Route-Specific Middleware
541
+
542
+ ```typescript
543
+ // Apply middleware to specific routes
544
+ app.use('/api/admin/*', adminAuthMiddleware());
545
+ app.use('/api/public/*', rateLimitMiddleware());
546
+ ```
547
+
548
+ ### Middleware Composition
549
+
550
+ ```typescript
551
+ // Combine multiple middleware
552
+ const apiMiddleware = (): MiddlewareHandler => {
553
+ return createMiddleware(async (context, next) => {
554
+ // Run multiple middleware in sequence
555
+ await requestNormalize()(context, async () => {
556
+ await authenticate()(context, next);
557
+ });
558
+ });
559
+ };
560
+ ```
561
+
562
+ ---
563
+
564
+ ## Performance Considerations
565
+
566
+ ### Request Spy in Production
567
+
568
+ Request spy logs detailed information for every request. In high-traffic production environments:
569
+
570
+ ```typescript
571
+ // Conditional request spy
572
+ const isDevelopment = process.env.NODE_ENV === 'development';
573
+
574
+ if (isDevelopment) {
575
+ const requestSpy = new RequestSpyMiddleware();
576
+ app.use(requestSpy.value());
577
+ }
578
+ ```
579
+
580
+ ### Error Logging Volume
581
+
582
+ Error handlers log every error. For high error rates, consider:
583
+ - Sampling (log 1 in N errors)
584
+ - Error aggregation services (Sentry, Rollbar)
585
+ - Rate-limited logging
586
+
587
+ ---
588
+
589
+ ## See Also
590
+
591
+ - **Related References:**
592
+ - [Application](./application.md) - Application setup and configuration
593
+ - [Controllers](./controllers.md) - HTTP routing and request handling
594
+ - [Dependency Injection](./dependency-injection.md) - DI container and providers
595
+
596
+ - **Guides:**
597
+ - [Building a CRUD API](/guides/tutorials/building-a-crud-api)
598
+
599
+ - **Best Practices:**
600
+ - [Troubleshooting Tips](/best-practices/troubleshooting-tips)
601
+
602
+ - **External Resources:**
603
+ - [Hono Middleware Documentation](https://hono.dev/docs/guides/middleware)
604
+ - [HTTP Status Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)