@venizia/ignis-docs 0.2.0 → 0.2.1-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.
- package/README.md +14 -14
- package/content/best-practices/api-usage-examples.md +39 -19
- package/content/best-practices/architectural-patterns.md +24 -13
- package/content/best-practices/architecture-decisions.md +29 -16
- package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
- package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
- package/content/best-practices/code-style-standards/control-flow.md +33 -1
- package/content/best-practices/code-style-standards/documentation.md +28 -8
- package/content/best-practices/code-style-standards/function-patterns.md +15 -4
- package/content/best-practices/code-style-standards/index.md +7 -2
- package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
- package/content/best-practices/code-style-standards/route-definitions.md +9 -5
- package/content/best-practices/code-style-standards/tooling.md +14 -1
- package/content/best-practices/code-style-standards/type-safety.md +39 -6
- package/content/best-practices/common-pitfalls.md +59 -35
- package/content/best-practices/contribution-workflow.md +8 -4
- package/content/best-practices/data-modeling.md +78 -62
- package/content/best-practices/deployment-strategies.md +56 -19
- package/content/best-practices/error-handling.md +247 -153
- package/content/best-practices/index.md +6 -0
- package/content/best-practices/performance-optimization.md +26 -13
- package/content/best-practices/security-guidelines.md +35 -9
- package/content/best-practices/testing-strategies.md +7 -2
- package/content/best-practices/troubleshooting-tips.md +27 -17
- package/content/extensions/components/api-reference.md +109 -323
- package/content/extensions/components/authentication/api.md +489 -602
- package/content/extensions/components/authentication/errors.md +135 -498
- package/content/extensions/components/authentication/index.md +89 -801
- package/content/extensions/components/authentication/usage.md +231 -955
- package/content/extensions/components/authorization/api.md +991 -644
- package/content/extensions/components/authorization/errors.md +204 -208
- package/content/extensions/components/authorization/getting-started.md +227 -0
- package/content/extensions/components/authorization/index.md +88 -795
- package/content/extensions/components/authorization/usage.md +219 -528
- package/content/extensions/components/health-check.md +77 -243
- package/content/extensions/components/index.md +24 -90
- package/content/extensions/components/mail/api.md +553 -285
- package/content/extensions/components/mail/errors.md +76 -62
- package/content/extensions/components/mail/index.md +111 -463
- package/content/extensions/components/mail/usage.md +139 -173
- package/content/extensions/components/request-tracker.md +70 -173
- package/content/extensions/components/socket-io/api.md +462 -785
- package/content/extensions/components/socket-io/errors.md +49 -51
- package/content/extensions/components/socket-io/index.md +69 -372
- package/content/extensions/components/socket-io/usage.md +212 -105
- package/content/extensions/components/static-asset/api.md +461 -141
- package/content/extensions/components/static-asset/errors.md +121 -53
- package/content/extensions/components/static-asset/index.md +84 -606
- package/content/extensions/components/static-asset/usage.md +184 -299
- package/content/extensions/components/template/index.md +3 -3
- package/content/extensions/components/websocket/api.md +311 -404
- package/content/extensions/components/websocket/errors.md +47 -56
- package/content/extensions/components/websocket/index.md +75 -407
- package/content/extensions/components/websocket/usage.md +120 -338
- package/content/extensions/helpers/cron/index.md +52 -160
- package/content/extensions/helpers/crypto/index.md +67 -480
- package/content/extensions/helpers/crypto/reference.md +528 -0
- package/content/extensions/helpers/env/index.md +64 -178
- package/content/extensions/helpers/error/index.md +286 -196
- package/content/extensions/helpers/index.md +61 -47
- package/content/extensions/helpers/inversion/index.md +76 -550
- package/content/extensions/helpers/inversion/reference.md +530 -0
- package/content/extensions/helpers/kafka/admin.md +23 -3
- package/content/extensions/helpers/kafka/compile-binary.md +83 -52
- package/content/extensions/helpers/kafka/consumer.md +65 -28
- package/content/extensions/helpers/kafka/examples.md +46 -253
- package/content/extensions/helpers/kafka/index.md +55 -617
- package/content/extensions/helpers/kafka/producer.md +156 -22
- package/content/extensions/helpers/kafka/schema-registry.md +59 -79
- package/content/extensions/helpers/logger/hf-logger.md +220 -0
- package/content/extensions/helpers/logger/index.md +78 -552
- package/content/extensions/helpers/logger/pino.md +105 -0
- package/content/extensions/helpers/logger/reference.md +937 -0
- package/content/extensions/helpers/network/api.md +276 -195
- package/content/extensions/helpers/network/index.md +87 -524
- package/content/extensions/helpers/queue/index.md +80 -897
- package/content/extensions/helpers/queue/reference.md +494 -0
- package/content/extensions/helpers/redis/index.md +86 -640
- package/content/extensions/helpers/redis/reference.md +784 -0
- package/content/extensions/helpers/secrets/index.md +136 -0
- package/content/extensions/helpers/socket-io/api.md +325 -204
- package/content/extensions/helpers/socket-io/index.md +79 -429
- package/content/extensions/helpers/storage/api.md +584 -464
- package/content/extensions/helpers/storage/index.md +80 -573
- package/content/extensions/helpers/types/index.md +75 -495
- package/content/extensions/helpers/types/reference.md +689 -0
- package/content/extensions/helpers/uid/index.md +176 -189
- package/content/extensions/helpers/websocket/api.md +366 -214
- package/content/extensions/helpers/websocket/index.md +68 -503
- package/content/extensions/helpers/worker-thread/index.md +62 -396
- package/content/extensions/helpers/worker-thread/reference.md +428 -0
- package/content/extensions/index.md +38 -39
- package/content/extensions/src-details/mcp-server.md +96 -548
- package/content/guides/core-concepts/persistent/datasources.md +2 -2
- package/content/guides/core-concepts/persistent/index.md +5 -1
- package/content/guides/core-concepts/persistent/models.md +1 -1
- package/content/guides/core-concepts/persistent/pglite.md +218 -0
- package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
- package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
- package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
- package/content/guides/core-concepts/persistent/sqlite.md +296 -0
- package/content/guides/core-concepts/persistent/transactions.md +12 -11
- package/content/guides/core-concepts/secrets-vault.md +177 -0
- package/content/guides/core-concepts/services.md +1 -1
- package/content/guides/get-started/5-minute-quickstart.md +59 -206
- package/content/guides/get-started/philosophy.md +135 -670
- package/content/guides/get-started/setup.md +53 -74
- package/content/guides/migrations/redis-helpers-migration.md +5 -4
- package/content/guides/migrations/scoped-rbac-migration.md +5 -5
- package/content/guides/migrations/unified-connectors-migration.md +8 -7
- package/content/guides/tutorials/ecommerce-api.md +3 -8
- package/content/guides/tutorials/realtime-chat.md +1 -1
- package/content/references/base/application.md +64 -22
- package/content/references/base/components.md +3 -3
- package/content/references/base/connectors.md +79 -136
- package/content/references/base/controllers.md +12 -12
- package/content/references/base/datasources-reference.md +600 -0
- package/content/references/base/datasources.md +84 -444
- package/content/references/base/dependency-injection.md +25 -46
- package/content/references/base/filter-system/application-usage.md +95 -123
- package/content/references/base/filter-system/array-operators.md +33 -43
- package/content/references/base/filter-system/comparison-operators.md +55 -63
- package/content/references/base/filter-system/default-filter.md +144 -350
- package/content/references/base/filter-system/fields-order-pagination.md +116 -148
- package/content/references/base/filter-system/index.md +114 -253
- package/content/references/base/filter-system/json-filtering.md +52 -181
- package/content/references/base/filter-system/list-operators.md +28 -44
- package/content/references/base/filter-system/logical-operators.md +69 -114
- package/content/references/base/filter-system/null-operators.md +41 -98
- package/content/references/base/filter-system/pattern-matching.md +48 -51
- package/content/references/base/filter-system/quick-reference.md +93 -196
- package/content/references/base/filter-system/range-operators.md +22 -38
- package/content/references/base/filter-system/tips.md +70 -133
- package/content/references/base/filter-system/use-cases.md +173 -232
- package/content/references/base/grpc-controllers.md +53 -17
- package/content/references/base/index.md +5 -3
- package/content/references/base/middlewares.md +43 -28
- package/content/references/base/models-reference.md +886 -0
- package/content/references/base/models.md +81 -1452
- package/content/references/base/providers.md +8 -8
- package/content/references/base/repositories/advanced.md +281 -419
- package/content/references/base/repositories/index.md +84 -644
- package/content/references/base/repositories/mixins.md +25 -21
- package/content/references/base/repositories/relations.md +194 -375
- package/content/references/base/repositories/soft-deletable.md +67 -55
- package/content/references/base/secrets.md +267 -0
- package/content/references/base/services.md +8 -6
- package/content/references/configuration/environment-variables.md +73 -21
- package/content/references/configuration/index.md +51 -31
- package/content/references/index.md +1 -1
- package/content/references/quick-reference.md +3 -16
- package/content/references/utilities/crypto.md +35 -76
- package/content/references/utilities/date.md +33 -73
- package/content/references/utilities/duration.md +85 -0
- package/content/references/utilities/index.md +6 -2
- package/content/references/utilities/jsx-reference.md +298 -0
- package/content/references/utilities/jsx.md +82 -525
- package/content/references/utilities/module.md +81 -61
- package/content/references/utilities/parse.md +34 -64
- package/content/references/utilities/performance.md +33 -58
- package/content/references/utilities/promise.md +28 -62
- package/content/references/utilities/request.md +58 -218
- package/content/references/utilities/retry.md +139 -0
- package/content/references/utilities/schema.md +43 -137
- package/content/references/utilities/statuses-reference.md +361 -0
- package/content/references/utilities/statuses.md +63 -667
- package/dist/mcp-server/index.js +0 -0
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
- package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
- package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
- package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
- package/package.json +24 -23
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Request Tracker
|
|
2
2
|
|
|
3
|
-
Automatic request logging middleware
|
|
3
|
+
Automatic request logging middleware that assigns a UUID request ID to every request. It logs method, path, client IP, and timing on the way in and out.
|
|
4
4
|
|
|
5
5
|
> [!IMPORTANT]
|
|
6
6
|
> This component is **auto-registered** by `BaseApplication` during `initialize()`. No manual registration is needed.
|
|
@@ -12,7 +12,7 @@ Automatic request logging middleware with unique request IDs, client IP detectio
|
|
|
12
12
|
| **Package** | `@venizia/ignis` |
|
|
13
13
|
| **Component** | `RequestTrackerComponent` |
|
|
14
14
|
| **Middleware** | `RequestSpyMiddleware` |
|
|
15
|
-
| **Utility** | `getIncomingIp()` |
|
|
15
|
+
| **Utility** | `NetworkUtility.getIncomingIp()` |
|
|
16
16
|
| **Runtimes** | Both (Bun and Node.js) |
|
|
17
17
|
|
|
18
18
|
#### Import Paths
|
|
@@ -20,225 +20,116 @@ Automatic request logging middleware with unique request IDs, client IP detectio
|
|
|
20
20
|
import { RequestTrackerComponent } from '@venizia/ignis';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
##
|
|
23
|
+
## In one example
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
No configuration binding is required. The component has no user-facing configuration options.
|
|
28
|
-
|
|
29
|
-
### Step 2: Register Component
|
|
30
|
-
|
|
31
|
-
This happens automatically inside `BaseApplication.initialize()`:
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
// Internal to BaseApplication -- shown for reference only
|
|
35
|
-
this.component(RequestTrackerComponent);
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
The component registers two Hono middlewares on the application server during its `binding()` phase:
|
|
39
|
-
1. `requestId()` from `hono/request-id` -- generates a UUID and stores it on the Hono context under the key `'requestId'`
|
|
40
|
-
2. `RequestSpyMiddleware` -- logs request start/end with IP, method, path, query, body, and timing
|
|
41
|
-
|
|
42
|
-
### Step 3: Use
|
|
43
|
-
|
|
44
|
-
No injection or manual usage is needed. Once the application starts, every incoming request is automatically logged with a unique request ID.
|
|
45
|
-
|
|
46
|
-
A sample log output in **non-production** mode looks like this:
|
|
25
|
+
Nothing to configure - once the application starts, every request is logged automatically.
|
|
47
26
|
|
|
48
27
|
```
|
|
49
28
|
[SpyMW] [<request-id>][127.0.0.1][=>] GET /hello | query: {} | body: null
|
|
50
29
|
[SpyMW] [<request-id>][127.0.0.1][<=] GET /hello | Took: 1.23 (ms)
|
|
51
30
|
```
|
|
52
31
|
|
|
53
|
-
|
|
32
|
+
Bodies are logged only in a development environment. Everywhere else - including when `NODE_ENV` is
|
|
33
|
+
unset - the body is omitted and query is still logged:
|
|
54
34
|
|
|
55
35
|
```
|
|
56
36
|
[SpyMW] [<request-id>][127.0.0.1][=>] GET /hello | query: {}
|
|
57
37
|
[SpyMW] [<request-id>][127.0.0.1][<=] GET /hello | Took: 1.23 (ms)
|
|
58
38
|
```
|
|
59
39
|
|
|
60
|
-
The log format follows this structure:
|
|
61
|
-
|
|
62
40
|
| Direction | Format |
|
|
63
41
|
|-----------|--------|
|
|
64
42
|
| Incoming (`=>`) | `[requestId][clientIp][=>] METHOD path \| query: {...} \| body: {...}` |
|
|
65
43
|
| Outgoing (`<=`) | `[requestId][clientIp][<=] METHOD path \| Took: X.XX (ms)` |
|
|
66
44
|
|
|
67
|
-
The HTTP method is padded to 8 characters for consistent alignment
|
|
68
|
-
|
|
69
|
-
> [!TIP]
|
|
70
|
-
> The request ID is also available in the framework's error handlers (`notFoundHandler`, `appErrorHandler`), making it easy to correlate error logs with the original request.
|
|
71
|
-
|
|
72
|
-
## Configuration
|
|
73
|
-
|
|
74
|
-
The Request Tracker component has no user-configurable options. Its behavior is fully automatic.
|
|
45
|
+
The HTTP method is padded to 8 characters for consistent alignment.
|
|
75
46
|
|
|
76
|
-
|
|
77
|
-
|----------|-------------|
|
|
78
|
-
| **Request ID** | Generated automatically via `hono/request-id` middleware (UUID), stored on context as `'requestId'` |
|
|
79
|
-
| **IP Detection** | Priority: (1) connection info via `getIncomingIp()`, (2) `x-real-ip` header, (3) `x-forwarded-for` header |
|
|
80
|
-
| **Body Logging** | Logs request body in non-production environments only. Query is always logged |
|
|
81
|
-
| **Timing** | Measures and logs request duration in milliseconds (2 decimal places) via `performance.now()` |
|
|
82
|
-
| **Scope** | Registered as a singleton provider |
|
|
47
|
+
## How it works
|
|
83
48
|
|
|
84
|
-
|
|
85
|
-
|
|
49
|
+
- **One middleware, and an ID it does not install.** `requestId()` comes from `RestApplication.registerDefaultMiddlewares()`, which runs before any component, so it is already in place when `binding()` resolves `RequestSpyMiddleware` from the DI container and registers it. The generator is IGNIS's `RequestIdGenerator`, not hono's `crypto.randomUUID` default - that keeps a server and a browser-Worker BFF stamping the same format.
|
|
50
|
+
- **IP resolution is best-effort, never fatal.** The middleware falls through several sources before giving up - see the resolution order below. An unresolved IP never fails the request; this middleware observes traffic, it does not gate it.
|
|
51
|
+
- **Body logging is environment-gated, and it fails closed.** `RequestSpyMiddleware` reads `NODE_ENV` once in its constructor and logs the body only when the value is one of `local`, `debug`, `development`, `dev`, `sit`. Anything else - `staging`, `uat`, `production`, or `NODE_ENV` unset entirely - logs query only. Query is always logged in every environment.
|
|
86
52
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
The component class extends `BaseComponent`. It receives `BaseApplication` via `@inject({ key: CoreBindings.APPLICATION_INSTANCE })` in its constructor.
|
|
92
|
-
|
|
93
|
-
During construction, it creates a singleton binding for the middleware:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
Binding.bind({ key: RequestTrackerComponent.REQUEST_TRACKER_MW_BINDING_KEY })
|
|
97
|
-
.toProvider(RequestSpyMiddleware)
|
|
98
|
-
.setScope(BindingScopes.SINGLETON)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
The binding key is constructed as `BindingNamespaces.MIDDLEWARE + '.' + RequestSpyMiddleware.name`, which resolves to `'middlewares.RequestSpyMiddleware'`.
|
|
102
|
-
|
|
103
|
-
#### Component Lifecycle
|
|
104
|
-
|
|
105
|
-
1. **`constructor()`** -- Receives `BaseApplication` via DI. Defines the middleware binding as a singleton provider.
|
|
106
|
-
2. **`binding()`** -- Registers `requestId()` middleware on the server. Resolves the `RequestSpyMiddleware` binding from the DI container. Throws if the middleware cannot be resolved. Registers the resolved middleware on the server.
|
|
107
|
-
|
|
108
|
-
### RequestSpyMiddleware
|
|
109
|
-
|
|
110
|
-
The middleware class extends `BaseHelper` with scope `'SpyMW'` and implements `IProvider<MiddlewareHandler>`.
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
class RequestSpyMiddleware extends BaseHelper implements IProvider<MiddlewareHandler> {
|
|
114
|
-
static readonly REQUEST_ID_KEY = 'requestId';
|
|
115
|
-
private isDebugMode: boolean;
|
|
116
|
-
// ...
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
#### IProvider Pattern
|
|
121
|
-
|
|
122
|
-
`RequestSpyMiddleware` implements the `IProvider<T>` interface from `@venizia/ignis-inversion`. This interface requires a single method:
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
interface IProvider<T> {
|
|
126
|
-
value(container: Container): T;
|
|
127
|
-
}
|
|
128
|
-
```
|
|
53
|
+
> [!WARNING]
|
|
54
|
+
> This rule used to be "anything that is not `production`", which logged full request bodies in `staging`, `uat` and with `NODE_ENV` unset. If you relied on bodies appearing outside a development environment, set `NODE_ENV` to one of the five values above.
|
|
55
|
+
- **Body parsing follows Content-Type.** See the outcomes table below for what each Content-Type resolves to. A parse failure throws `'Malformed Body Payload'` (HTTP 400).
|
|
56
|
+
- **The middleware is an `IProvider`, not a plain function.** `RequestSpyMiddleware` implements `IProvider<MiddlewareHandler>` from `@venizia/ignis-inversion`. The container instantiates the class, so it can hold `isDebugMode` state as an instance field. It then calls `.value()` to obtain the actual Hono handler.
|
|
129
57
|
|
|
130
|
-
|
|
58
|
+
> [!TIP]
|
|
59
|
+
> The request ID is also available in the framework's error handlers (`notFoundHandler`, `AppErrorMiddleware`) - the same ID correlates error logs with the original request.
|
|
131
60
|
|
|
132
|
-
|
|
61
|
+
## Common tasks
|
|
133
62
|
|
|
134
|
-
|
|
63
|
+
### Correlate logs with a request
|
|
64
|
+
Read the `requestId` context value inside your own handlers or middleware - the same ID appears in every `[SpyMW]` log line for that request.
|
|
135
65
|
|
|
136
66
|
```typescript
|
|
137
|
-
|
|
138
|
-
super({ scope: 'SpyMW' });
|
|
139
|
-
const env = process.env.NODE_ENV?.toLowerCase();
|
|
140
|
-
this.isDebugMode = env !== Environment.PRODUCTION;
|
|
141
|
-
}
|
|
67
|
+
const requestId = context.get('requestId');
|
|
142
68
|
```
|
|
143
69
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
#### value() -- Middleware Handler
|
|
147
|
-
|
|
148
|
-
The `value()` method returns a Hono middleware created via `createMiddleware()` from `hono/factory`. The middleware performs the following steps:
|
|
149
|
-
|
|
150
|
-
1. Starts a performance timer via `performance.now()`
|
|
151
|
-
2. Extracts the request ID from the Hono context (set by `requestId()` middleware)
|
|
152
|
-
3. Resolves the client IP using the priority chain (see IP Detection below)
|
|
153
|
-
4. Throws `'Malformed Connection Info'` (400) if both `incomingIp` and `forwardedIp` are `null`
|
|
154
|
-
5. Extracts method, path, and query from the request
|
|
155
|
-
6. Parses the request body via `parseBody()`
|
|
156
|
-
7. Logs the incoming request with `[=>]` direction marker
|
|
157
|
-
8. Calls `await next()` to proceed to the next middleware/handler
|
|
158
|
-
9. Calculates duration and logs the outgoing response with `[<=]` direction marker
|
|
159
|
-
|
|
160
|
-
#### parseBody()
|
|
161
|
-
|
|
162
|
-
A public method that parses the request body based on `Content-Type` and `Content-Length` headers.
|
|
70
|
+
### Reuse `parseBody` for your own middleware
|
|
71
|
+
`parseBody` is a public method - reuse it wherever you need the same Content-Type-aware parsing.
|
|
163
72
|
|
|
164
73
|
```typescript
|
|
165
74
|
async parseBody(opts: { req: TContext['req'] }): Promise<unknown>
|
|
166
75
|
```
|
|
167
76
|
|
|
168
|
-
|
|
77
|
+
### Understand the client IP resolution order
|
|
78
|
+
| Priority | Source | Notes |
|
|
79
|
+
|----------|--------|-------|
|
|
80
|
+
| 1 | `NetworkUtility.getIncomingIp(context)` | Native connection info - `hono/bun` on Bun, `@hono/node-server/conninfo` on Node.js |
|
|
81
|
+
| 2 | `x-real-ip` header | Set by reverse proxies (e.g., Nginx `proxy_set_header X-Real-IP`) |
|
|
82
|
+
| 3 | `x-forwarded-for` header | Standard proxy header |
|
|
83
|
+
| 4 | `'unknown'` | Logged when none of the above resolve - the request still proceeds |
|
|
169
84
|
|
|
85
|
+
### Understand body-parsing outcomes
|
|
170
86
|
| Condition | Result |
|
|
171
87
|
|-----------|--------|
|
|
172
|
-
| No `Content-Type` header |
|
|
173
|
-
|
|
|
174
|
-
| `Content-Type` includes `application/json` |
|
|
175
|
-
| `Content-Type` includes `multipart/form-data` |
|
|
176
|
-
| `Content-Type`
|
|
177
|
-
| Any other `Content-Type` (text, html, xml, etc.) |
|
|
178
|
-
| Parsing
|
|
179
|
-
|
|
180
|
-
### getIncomingIp() Utility
|
|
181
|
-
|
|
182
|
-
A utility function that attempts to extract the client IP address from the Hono context using runtime-specific connection info.
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
const getIncomingIp = (context: Context): string | null
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
**Runtime detection:**
|
|
189
|
-
- Uses `RuntimeModules.isBun()` from `@venizia/ignis-helpers` to detect the runtime
|
|
190
|
-
- On **Bun**: imports `getConnInfo` from `hono/bun`
|
|
191
|
-
- On **Node.js**: imports `getConnInfo` from `@hono/node-server/conninfo`
|
|
192
|
-
- Returns `connInfo.remote.address` if available, `null` otherwise
|
|
193
|
-
- Returns `null` if `getConnInfo` is unavailable or throws
|
|
194
|
-
|
|
195
|
-
#### IP Detection Priority
|
|
196
|
-
|
|
197
|
-
The middleware resolves the client IP using a three-step fallback chain:
|
|
198
|
-
|
|
199
|
-
| Priority | Source | Description |
|
|
200
|
-
|----------|--------|-------------|
|
|
201
|
-
| 1 | `getIncomingIp(context)` | Direct connection info from the runtime (Bun or Node.js) |
|
|
202
|
-
| 2 | `x-real-ip` header | Set by reverse proxies (e.g., Nginx `proxy_set_header X-Real-IP`) |
|
|
203
|
-
| 3 | `x-forwarded-for` header | Standard proxy header with original client IP |
|
|
88
|
+
| No `Content-Type` header | `null` |
|
|
89
|
+
| `Content-Length` is `'0'`, or no body stream present | `null` |
|
|
90
|
+
| `Content-Type` includes `application/json` | `req.json()` |
|
|
91
|
+
| `Content-Type` includes `multipart/form-data` or `application/x-www-form-urlencoded` | `req.parseBody()` |
|
|
92
|
+
| `Content-Type` is `application/octet-stream` | Raw body stream |
|
|
93
|
+
| Any other `Content-Type` (text, html, xml, etc.) | `req.text()` |
|
|
94
|
+
| Parsing throws for any content type | `'Malformed Body Payload'` (HTTP 400) |
|
|
204
95
|
|
|
205
|
-
|
|
96
|
+
## Reference
|
|
206
97
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
## Binding Keys
|
|
98
|
+
### Configuration
|
|
99
|
+
No user-configurable options - behavior is fully automatic.
|
|
210
100
|
|
|
101
|
+
### Binding keys
|
|
211
102
|
| Key | Constant | Type | Required | Default |
|
|
212
103
|
|-----|----------|------|----------|---------|
|
|
213
|
-
| `middlewares.RequestSpyMiddleware` | `RequestTrackerComponent.REQUEST_TRACKER_MW_BINDING_KEY` | `MiddlewareHandler` | Auto |
|
|
214
|
-
|
|
215
|
-
The key is constructed from `BindingNamespaces.MIDDLEWARE` (`'middlewares'`) + `RequestSpyMiddleware.name` (`'RequestSpyMiddleware'`). The component binds `RequestSpyMiddleware` as a singleton provider at this key during construction.
|
|
216
|
-
|
|
217
|
-
## Troubleshooting
|
|
218
|
-
|
|
219
|
-
### "Invalid middleware to init request tracker | Please check again binding value"
|
|
104
|
+
| `middlewares.RequestSpyMiddleware` | `RequestTrackerComponent.REQUEST_TRACKER_MW_BINDING_KEY` | `MiddlewareHandler` | Auto | Singleton provider, registered by the constructor |
|
|
220
105
|
|
|
221
|
-
|
|
106
|
+
The key is built as `BindingNamespaces.MIDDLEWARE` (`'middlewares'`) + `.` + `RequestSpyMiddleware.name`.
|
|
222
107
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
108
|
+
### RequestSpyMiddleware
|
|
109
|
+
```typescript
|
|
110
|
+
class RequestSpyMiddleware extends BaseHelper implements IProvider<MiddlewareHandler> {
|
|
111
|
+
static readonly REQUEST_ID_KEY = 'requestId';
|
|
112
|
+
private isDebugMode: boolean;
|
|
113
|
+
// ...
|
|
114
|
+
}
|
|
115
|
+
```
|
|
230
116
|
|
|
231
|
-
|
|
117
|
+
- Extends `BaseHelper` with scope `'SpyMW'`
|
|
118
|
+
- Constructor sets `isDebugMode = process.env.NODE_ENV?.toLowerCase() !== Environment.PRODUCTION`
|
|
119
|
+
- `value()` returns a Hono middleware built via `createMiddleware()` from `hono/factory`
|
|
232
120
|
|
|
233
|
-
|
|
121
|
+
### Component lifecycle
|
|
122
|
+
1. **`constructor()`** - Receives `BaseApplication` via DI. Defines the middleware binding as a singleton provider.
|
|
123
|
+
2. **`binding()`** - Resolves the `RequestSpyMiddleware` binding, throwing if it cannot be resolved. Registers the resolved middleware on the server. The request ID is already installed by the application's default stack.
|
|
234
124
|
|
|
235
|
-
|
|
236
|
-
- `x-real-ip`
|
|
237
|
-
- `x-forwarded-for`
|
|
125
|
+
## Troubleshooting
|
|
238
126
|
|
|
239
|
-
|
|
127
|
+
| Symptom | Cause | Fix |
|
|
128
|
+
|---------|-------|-----|
|
|
129
|
+
| `Invalid middleware to init request tracker \| Please check again binding value` | `RequestSpyMiddleware` binding was unbound or overwritten before `binding()` ran | Don't unbind or replace `middlewares.RequestSpyMiddleware`; extend the component instead of removing its binding |
|
|
130
|
+
| `Malformed Body Payload` (400) | Body content didn't match its declared `Content-Type` (e.g., invalid JSON with `application/json`) | Ensure clients send body content that matches the `Content-Type` header |
|
|
240
131
|
|
|
241
|
-
## See
|
|
132
|
+
## See also
|
|
242
133
|
|
|
243
134
|
- **Guides:**
|
|
244
135
|
- [Components Overview](/guides/core-concepts/components) - Component system basics
|
|
@@ -253,3 +144,9 @@ If running without a proxy, ensure the runtime provides connection info (Bun doe
|
|
|
253
144
|
- **Best Practices:**
|
|
254
145
|
- [Troubleshooting Tips](/best-practices/troubleshooting-tips) - Debugging with request IDs
|
|
255
146
|
- [Deployment Strategies](/best-practices/deployment-strategies) - Production logging
|
|
147
|
+
|
|
148
|
+
**Files:**
|
|
149
|
+
|
|
150
|
+
- [`packages/core-server/src/components/request-tracker/component.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/components/request-tracker/component.ts) - `RequestTrackerComponent`
|
|
151
|
+
- [`packages/core-server/src/base/middlewares/request-spy/request-spy.middleware.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/base/middlewares/request-spy/request-spy.middleware.ts) - `RequestSpyMiddleware`
|
|
152
|
+
- [`packages/core-server/src/utilities/network.utility.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/core-server/src/utilities/network.utility.ts) - `NetworkUtility.getIncomingIp()`
|