exisjs 0.7.11 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -39
- package/dist/cli/commands/dev.d.ts +4 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +136 -32
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/run.d.ts +7 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +99 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/index.js +29 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/manifest.d.ts.map +1 -1
- package/dist/cli/manifest.js +18 -3
- package/dist/cli/manifest.js.map +1 -1
- package/dist/cli/routes.d.ts +6 -0
- package/dist/cli/routes.d.ts.map +1 -1
- package/dist/cli/routes.js +224 -135
- package/dist/cli/routes.js.map +1 -1
- package/dist/config/config.d.ts +2 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +30 -9
- package/dist/config/types.d.ts.map +1 -1
- package/dist/database/lifecycle.d.ts +6 -1
- package/dist/database/lifecycle.d.ts.map +1 -1
- package/dist/database/lifecycle.js +15 -4
- package/dist/database/lifecycle.js.map +1 -1
- package/dist/decorators/params.d.ts +21 -0
- package/dist/decorators/params.d.ts.map +1 -1
- package/dist/decorators/params.js +21 -1
- package/dist/decorators/params.js.map +1 -1
- package/dist/di/container.d.ts +15 -6
- package/dist/di/container.d.ts.map +1 -1
- package/dist/di/container.js +26 -3
- package/dist/di/container.js.map +1 -1
- package/dist/di/index.d.ts +1 -1
- package/dist/di/index.d.ts.map +1 -1
- package/dist/di/index.js.map +1 -1
- package/dist/di/inject.d.ts +2 -1
- package/dist/di/inject.d.ts.map +1 -1
- package/dist/di/inject.js +2 -1
- package/dist/di/inject.js.map +1 -1
- package/dist/docs/BENCHMARKS.md +4 -4
- package/dist/docs/content/README.md +43 -44
- package/dist/docs/content/boundaries.mdx +141 -48
- package/dist/docs/content/cli/commands.mdx +161 -107
- package/dist/docs/content/cli/overview.mdx +61 -46
- package/dist/docs/content/cli/usage.mdx +107 -30
- package/dist/docs/content/config.mdx +145 -147
- package/dist/docs/content/controllers.mdx +193 -464
- package/dist/docs/content/cron.mdx +183 -69
- package/dist/docs/content/decorators.mdx +449 -154
- package/dist/docs/content/errors.mdx +202 -305
- package/dist/docs/content/exisjs-mcp.mdx +59 -49
- package/dist/docs/content/installation.mdx +243 -157
- package/dist/docs/content/introduction.mdx +220 -48
- package/dist/docs/content/middleware.mdx +171 -497
- package/dist/docs/content/modules.mdx +141 -83
- package/dist/docs/content/providers.mdx +216 -180
- package/dist/docs/content/requests.mdx +168 -488
- package/dist/docs/content/responses.mdx +200 -533
- package/dist/docs/content/routing.mdx +239 -558
- package/dist/docs/content/security.mdx +233 -57
- package/dist/docs/content/structure.mdx +151 -240
- package/dist/docs/content/swagger.mdx +192 -91
- package/dist/docs/content/testing.mdx +205 -74
- package/dist/docs/content/validation.mdx +479 -341
- package/dist/docs/reference/README.md +34 -2
- package/dist/docs/reference/config.mdx +277 -73
- package/dist/docs/reference/context.mdx +197 -106
- package/dist/docs/reference/cron.mdx +266 -152
- package/dist/docs/reference/database.mdx +135 -53
- package/dist/docs/reference/decorators.mdx +234 -116
- package/dist/docs/reference/di.mdx +146 -112
- package/dist/docs/reference/error.mdx +155 -178
- package/dist/docs/reference/exis.mdx +141 -70
- package/dist/docs/reference/logger.mdx +110 -126
- package/dist/docs/reference/middleware.mdx +235 -158
- package/dist/docs/reference/plugin.mdx +136 -64
- package/dist/docs/reference/router.mdx +277 -251
- package/dist/docs/reference/sanitize.mdx +91 -87
- package/dist/docs/reference/swagger.mdx +280 -100
- package/dist/docs/reference/testing.mdx +223 -89
- package/dist/docs/reference/validator.mdx +194 -206
- package/dist/lib/inspect-routes.d.ts +2 -0
- package/dist/lib/inspect-routes.d.ts.map +1 -0
- package/dist/lib/inspect-routes.js +148 -0
- package/dist/lib/inspect-routes.js.map +1 -0
- package/dist/lib/start-server.js +13 -8
- package/dist/lib/start-server.js.map +1 -1
- package/dist/module/module.d.ts +6 -3
- package/dist/module/module.d.ts.map +1 -1
- package/dist/module/module.js +17 -3
- package/dist/module/module.js.map +1 -1
- package/dist/router/controller-registrar.d.ts.map +1 -1
- package/dist/router/controller-registrar.js +26 -4
- package/dist/router/controller-registrar.js.map +1 -1
- package/dist/router/scanner/cron-mounter.d.ts.map +1 -1
- package/dist/router/scanner/cron-mounter.js +9 -2
- package/dist/router/scanner/cron-mounter.js.map +1 -1
- package/dist/server/app.d.ts +3 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +29 -8
- package/dist/server/app.js.map +1 -1
- package/dist/server/define.d.ts.map +1 -1
- package/dist/server/define.js +5 -0
- package/dist/server/define.js.map +1 -1
- package/dist/server/request.d.ts +2 -0
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/request.js +11 -0
- package/dist/server/request.js.map +1 -1
- package/dist/swagger/generator.d.ts.map +1 -1
- package/dist/swagger/generator.js +130 -10
- package/dist/swagger/generator.js.map +1 -1
- package/dist/telemetry/index.d.ts +12 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +121 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/testing/client.d.ts +1 -0
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +4 -1
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +20 -4
- package/dist/testing/index.js.map +1 -1
- package/dist/validator/builder.d.ts +26 -1
- package/dist/validator/builder.d.ts.map +1 -1
- package/dist/validator/builder.js +31 -0
- package/dist/validator/builder.js.map +1 -1
- package/dist/validator/engine.d.ts +23 -0
- package/dist/validator/engine.d.ts.map +1 -1
- package/dist/validator/engine.js +228 -31
- package/dist/validator/engine.js.map +1 -1
- package/dist/validator/index.d.ts +8 -4
- package/dist/validator/index.d.ts.map +1 -1
- package/dist/validator/index.js +4 -1
- package/dist/validator/index.js.map +1 -1
- package/dist/validator/tex-types.d.ts +15 -0
- package/dist/validator/tex-types.d.ts.map +1 -1
- package/dist/validator/tex-types.js +102 -0
- package/dist/validator/tex-types.js.map +1 -1
- package/dist/validator/tex.d.ts +1 -1
- package/dist/validator/tex.d.ts.map +1 -1
- package/dist/validator/tex.js +3 -1
- package/dist/validator/tex.js.map +1 -1
- package/dist/validator/types.d.ts +1 -0
- package/dist/validator/types.d.ts.map +1 -1
- package/package.json +47 -14
- package/dist/docs/content/dataloader.mdx +0 -170
- package/dist/docs/reference/dataloader.mdx +0 -91
|
@@ -1,241 +1,318 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
3
|
-
description: "API Reference for ExisJS built-in
|
|
2
|
+
title: "exisjs/middleware"
|
|
3
|
+
description: "API Reference for ExisJS built-in middleware: Helmet, CORS, Rate Limiting, File Uploads, Idempotency, CIDR IP Filtering, Compression, and Security Controls."
|
|
4
|
+
nextUrl: "/docs/reference/context"
|
|
5
|
+
nextTitle: "Context Reference"
|
|
4
6
|
---
|
|
5
7
|
|
|
6
|
-
#
|
|
8
|
+
# `exisjs/middleware`
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
The `exisjs/middleware` module provides the built-in HTTP middleware pipeline for ExisJS. It includes native Rust-accelerated traffic controls, multipart upload handlers, security header suites, and request context enhancers.
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Module Exports
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import {
|
|
18
|
+
// Core & Security
|
|
19
|
+
cors,
|
|
20
|
+
helmet,
|
|
21
|
+
csrf,
|
|
22
|
+
hpp,
|
|
23
|
+
mongoSanitize,
|
|
24
|
+
blockSuspiciousProbes,
|
|
25
|
+
timingSafeEqual,
|
|
26
|
+
timeout,
|
|
27
|
+
routeTimeout,
|
|
28
|
+
|
|
29
|
+
// Traffic & Reliability
|
|
30
|
+
rateLimit,
|
|
31
|
+
idempotent,
|
|
32
|
+
dedupe,
|
|
33
|
+
ipFilter,
|
|
34
|
+
backpressure,
|
|
35
|
+
compression,
|
|
36
|
+
|
|
37
|
+
// Multipart File Uploads
|
|
38
|
+
fileUpload,
|
|
39
|
+
fromExpress,
|
|
40
|
+
|
|
41
|
+
// Utilities & Observability
|
|
42
|
+
requestId,
|
|
43
|
+
requestLogger,
|
|
44
|
+
serveStatic,
|
|
45
|
+
validate,
|
|
46
|
+
conditionalGet,
|
|
47
|
+
} from 'exisjs/middleware'
|
|
48
|
+
|
|
49
|
+
import type {
|
|
50
|
+
CorsConfig,
|
|
51
|
+
RateLimitOptions,
|
|
52
|
+
IdempotencyOptions,
|
|
53
|
+
IpFilterOptions,
|
|
54
|
+
FileUploadOptions,
|
|
55
|
+
FileUploadLimits,
|
|
56
|
+
UploadedFile,
|
|
57
|
+
BlockProbesOptions,
|
|
58
|
+
TimeoutOptions,
|
|
59
|
+
CompressionOptions,
|
|
60
|
+
} from 'exisjs/middleware'
|
|
61
|
+
```
|
|
11
62
|
|
|
12
63
|
---
|
|
13
64
|
|
|
14
|
-
##
|
|
65
|
+
## 1. Security & Header Middlewares
|
|
15
66
|
|
|
16
|
-
|
|
67
|
+
### `helmet(options?)`
|
|
17
68
|
|
|
18
|
-
|
|
19
|
-
```typescript filename="src/http/users/route.ts"
|
|
20
|
-
import { Controller, Get, Use } from 'exisjs/decorators'
|
|
21
|
-
import { ipFilter } from 'exisjs/middleware'
|
|
69
|
+
Sets standard HTTP response headers for protection against XSS, clickjacking, MIME sniffing, and protocol downgrades.
|
|
22
70
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export default class UserController {
|
|
26
|
-
@Get('/stats')
|
|
27
|
-
getStats() {
|
|
28
|
-
return { users: 100 }
|
|
29
|
-
}
|
|
30
|
-
}
|
|
71
|
+
```typescript
|
|
72
|
+
function helmet(options?: HelmetOptions): Handler
|
|
31
73
|
```
|
|
32
74
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
75
|
+
| Option | Type | Default | Description |
|
|
76
|
+
| :--- | :--- | :--- | :--- |
|
|
77
|
+
| `contentSecurityPolicy` | `boolean \| object` | `false` | Configures Content Security Policy (`Content-Security-Policy`). |
|
|
78
|
+
| `xFrameOptions` | `'DENY' \| 'SAMEORIGIN'` | `'SAMEORIGIN'` | Protects against clickjacking. |
|
|
79
|
+
| `hsts` | `boolean \| HstsOptions` | `true` (in prod) | Strict Transport Security configuration. |
|
|
80
|
+
| `noSniff` | `boolean` | `true` | Sets `X-Content-Type-Options: nosniff`. |
|
|
81
|
+
| `xssFilter` | `boolean` | `true` | Sets `X-XSS-Protection: 1; mode=block`. |
|
|
37
82
|
|
|
38
|
-
|
|
39
|
-
middleware: [ipFilter({ allow: ['192.168.1.0/24'] })],
|
|
83
|
+
---
|
|
40
84
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
85
|
+
### `cors(config?)`
|
|
86
|
+
|
|
87
|
+
Manages Cross-Origin Resource Sharing headers, preflight `OPTIONS` responses, and allowed credentials.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
function cors(config?: CorsConfig): Handler
|
|
47
91
|
```
|
|
48
92
|
|
|
49
|
-
|
|
93
|
+
| Option | Type | Default | Description |
|
|
94
|
+
| :--- | :--- | :--- | :--- |
|
|
95
|
+
| `origin` | `string \| RegExp \| string[] \| boolean \| CorsOriginFn` | `'*'` | Allowed origin(s) or dynamic resolver function. |
|
|
96
|
+
| `methods` | `string[]` | `['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD']` | Allowed HTTP methods. |
|
|
97
|
+
| `allowedHeaders` | `string[]` | `['Content-Type', 'Authorization', 'Accept', 'Origin', ...]` | Allowed request headers. |
|
|
98
|
+
| `exposedHeaders` | `string[]` | `[]` | Headers exposed to client scripts. |
|
|
99
|
+
| `credentials` | `boolean` | `false` | Sets `Access-Control-Allow-Credentials: true`. |
|
|
100
|
+
| `maxAge` | `number` | `86400` | Preflight cache lifetime in seconds. |
|
|
50
101
|
|
|
51
|
-
|
|
102
|
+
---
|
|
52
103
|
|
|
53
|
-
### `
|
|
104
|
+
### `csrf(options?)`
|
|
54
105
|
|
|
55
|
-
|
|
106
|
+
Enforces Cross-Site Request Forgery protection using the Signed Double-Submit Cookie pattern.
|
|
56
107
|
|
|
57
108
|
```typescript
|
|
58
|
-
|
|
109
|
+
function csrf(options?: CsrfOptions): Handler
|
|
110
|
+
```
|
|
59
111
|
|
|
60
|
-
|
|
61
|
-
user: { id: string; role: 'admin' | 'user'; email: string }
|
|
62
|
-
}
|
|
112
|
+
---
|
|
63
113
|
|
|
64
|
-
|
|
65
|
-
req.user = { id: 'u1', role: 'admin', email: 'alex@example.com' }
|
|
66
|
-
next()
|
|
67
|
-
})
|
|
114
|
+
### `blockSuspiciousProbes(options?)`
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// req.user has full autocomplete and strict typing:
|
|
74
|
-
return res.json({ id: req.user.id, role: req.user.role })
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
})
|
|
116
|
+
Detects and drops malicious vulnerability scanners probing for sensitive assets (`.env`, `.git`, `wp-login.php`) before they hit route logic or flood log streams.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
function blockSuspiciousProbes(options?: BlockProbesOptions): Handler
|
|
78
120
|
```
|
|
79
121
|
|
|
80
122
|
---
|
|
81
123
|
|
|
82
|
-
|
|
124
|
+
### `hpp(options?)`
|
|
83
125
|
|
|
84
|
-
|
|
85
|
-
Sets 14+ strict security headers (HSTS, CSP, XSS Protection, No Sniff, Frameguard) to protect your application.
|
|
126
|
+
Protects against HTTP Parameter Pollution by normalizing repeated query parameters.
|
|
86
127
|
|
|
87
128
|
```typescript
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
app.use(helmet())
|
|
129
|
+
function hpp(options?: HppOptions): Handler
|
|
91
130
|
```
|
|
92
131
|
|
|
93
|
-
|
|
94
|
-
Implements the Signed Double Submit Cookie pattern for Cross-Site Request Forgery (CSRF) protection.
|
|
132
|
+
---
|
|
95
133
|
|
|
96
|
-
### `
|
|
97
|
-
Automatically times out requests that exceed the specified duration, returning a `503 Service Unavailable` response (or custom status code).
|
|
134
|
+
### `mongoSanitize(options?)`
|
|
98
135
|
|
|
99
|
-
|
|
100
|
-
- **Options**:
|
|
101
|
-
- `ms` (`number`): Timeout duration in milliseconds.
|
|
102
|
-
- `statusCode` (`number`): Status code to respond with (default: `503`).
|
|
103
|
-
- `message` (`string`): Error message returned to the client.
|
|
104
|
-
- `exclude` (`(string | RegExp)[]`): Array of route paths or regex patterns to exempt from timeout checks.
|
|
136
|
+
Strips `$` and `.` prefixes from request parameters and body fields to mitigate NoSQL injection vectors.
|
|
105
137
|
|
|
106
138
|
```typescript
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
app.use(timeout({
|
|
110
|
-
ms: 60000,
|
|
111
|
-
exclude: ['/webhooks/*', '/ai/stream'],
|
|
112
|
-
}))
|
|
139
|
+
function mongoSanitize(options?: MongoSanitizeOptions): Handler
|
|
113
140
|
```
|
|
114
141
|
|
|
115
|
-
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 2. Traffic, Rate Limiting & Reliability
|
|
116
145
|
|
|
117
|
-
### `
|
|
118
|
-
First-party multipart form data parsing and file upload middleware.
|
|
146
|
+
### `rateLimit(options?)`
|
|
119
147
|
|
|
120
|
-
-
|
|
121
|
-
- `fileUpload.single(fieldName, options?)`: Parses a single file into `req.file`.
|
|
122
|
-
- `fileUpload.array(fieldName, maxCount?, options?)`: Parses multiple files with the same field into `req.files` (`UploadedFile[]`).
|
|
123
|
-
- `fileUpload.fields([{ name, maxCount }])`: Parses multiple distinct fields into `req.files` (`Record<string, UploadedFile[]>`).
|
|
124
|
-
- `fileUpload.any(options?)`: Accepts any uploaded files.
|
|
125
|
-
- `fileUpload.none(options?)`: Accepts only text fields; rejects file uploads.
|
|
126
|
-
- **Options**:
|
|
127
|
-
- `dest` (`string`): Directory path to save uploaded files to disk automatically.
|
|
128
|
-
- `maxBytes` (`number`): Maximum file size in bytes (shorthand for `limits.fileSize`).
|
|
129
|
-
- `mimeTypes` (`string[]`): Array of permitted MIME types (e.g. `['image/png', 'image/jpeg']`).
|
|
130
|
-
- `limits` (`{ fileSize?: number; files?: number }`): Detailed size and count limits.
|
|
148
|
+
In-memory off-heap rate limiter backed by native Rust acceleration (`NativeRateLimiter`).
|
|
131
149
|
|
|
132
150
|
```typescript
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
app.post('/avatar', fileUpload.single('avatar', {
|
|
136
|
-
maxBytes: 5 * 1024 * 1024,
|
|
137
|
-
mimeTypes: ['image/*'],
|
|
138
|
-
}), (req, res) => {
|
|
139
|
-
const file = req.file // UploadedFile { filename, originalname, mimetype, size, buffer }
|
|
140
|
-
res.json({ success: true, filename: file.filename })
|
|
141
|
-
})
|
|
151
|
+
function rateLimit(options?: RateLimitOptions): Handler
|
|
142
152
|
```
|
|
143
153
|
|
|
144
|
-
|
|
145
|
-
|
|
154
|
+
| Option | Type | Default | Description |
|
|
155
|
+
| :--- | :--- | :--- | :--- |
|
|
156
|
+
| `windowMs` | `number` | `60000` (1 min) | Time window in milliseconds. |
|
|
157
|
+
| `max` | `number` | `100` | Maximum allowed requests within the time window. |
|
|
158
|
+
| `keyGenerator` | `(req: Request) => string` | `req => req.ip` | Custom partition key generator. |
|
|
159
|
+
| `message` | `string \| object` | `'Too many requests'` | Response payload on rate limit breach. |
|
|
160
|
+
| `statusCode` | `number` | `429` | HTTP status code for throttled requests. |
|
|
146
161
|
|
|
147
|
-
|
|
148
|
-
import { fromExpress } from 'exisjs/middleware'
|
|
149
|
-
import multer from 'multer'
|
|
162
|
+
---
|
|
150
163
|
|
|
151
|
-
|
|
164
|
+
### `timeout(options?)` & `routeTimeout(msOrOptions)`
|
|
152
165
|
|
|
153
|
-
|
|
154
|
-
res.json({ file: (req.raw as any).file })
|
|
155
|
-
})
|
|
156
|
-
```
|
|
166
|
+
Terminates long-running requests that exceed the specified threshold, returning `503 Service Unavailable`.
|
|
157
167
|
|
|
158
|
-
|
|
159
|
-
|
|
168
|
+
```typescript
|
|
169
|
+
function timeout(options?: TimeoutOptions): Handler
|
|
170
|
+
function routeTimeout(msOrOptions: number | TimeoutOptions): Handler
|
|
171
|
+
```
|
|
160
172
|
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
| Option | Type | Default | Description |
|
|
174
|
+
| :--- | :--- | :--- | :--- |
|
|
175
|
+
| `ms` | `number` | `60000` | Timeout threshold in milliseconds. |
|
|
176
|
+
| `statusCode` | `number` | `503` | Response status code upon timeout. |
|
|
177
|
+
| `message` | `string` | `'Service Unavailable'` | Error message sent to client. |
|
|
178
|
+
| `exclude` | `(string \| RegExp)[]` | `[]` | Path patterns exempt from timeout rules. |
|
|
163
179
|
|
|
164
180
|
---
|
|
165
181
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
### `rateLimit(options?)`
|
|
169
|
-
High-performance rate limiter running in-memory and off-heap via Rust native bindings (`NativeRateLimiter`).
|
|
182
|
+
### `idempotent(options?)`
|
|
170
183
|
|
|
171
|
-
|
|
172
|
-
> Core rate limiting is scoped to in-memory native execution. Distributed multi-instance Redis rate limiting moves to `@exisjs/cache`.
|
|
184
|
+
Caches responses against the `Idempotency-Key` HTTP header in off-heap native memory to prevent duplicate mutations.
|
|
173
185
|
|
|
174
186
|
```typescript
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
app.use(rateLimit({
|
|
178
|
-
windowMs: 60000,
|
|
179
|
-
max: 100
|
|
180
|
-
}))
|
|
187
|
+
function idempotent(options?: IdempotencyOptions): Handler
|
|
181
188
|
```
|
|
182
189
|
|
|
183
|
-
|
|
184
|
-
|
|
190
|
+
| Option | Type | Default | Description |
|
|
191
|
+
| :--- | :--- | :--- | :--- |
|
|
192
|
+
| `ttlMs` | `number` | `86400000` (24h) | Cache entry time-to-live in milliseconds. |
|
|
193
|
+
| `header` | `string` | `'idempotency-key'` | Target HTTP request header name. |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### `dedupe(options?)`
|
|
198
|
+
|
|
199
|
+
Prevents identical concurrent in-flight requests from being computed more than once simultaneously.
|
|
185
200
|
|
|
186
201
|
```typescript
|
|
187
|
-
|
|
202
|
+
function dedupe(options?: DedupeOptions): Handler
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
188
206
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
207
|
+
### `ipFilter(options)`
|
|
208
|
+
|
|
209
|
+
Applies CIDR-compatible IP allow-lists or deny-lists to restrict access to trusted networks.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
function ipFilter(options: IpFilterOptions): Handler
|
|
195
213
|
```
|
|
196
214
|
|
|
197
|
-
|
|
198
|
-
|
|
215
|
+
| Option | Type | Description |
|
|
216
|
+
| :--- | :--- | :--- |
|
|
217
|
+
| `allow` | `string[]` | Array of permitted IP addresses or CIDR blocks (e.g. `['10.0.0.0/8', '192.168.1.5']`). |
|
|
218
|
+
| `deny` | `string[]` | Array of blocked IP addresses or CIDR blocks. |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### `backpressure(options?)`
|
|
223
|
+
|
|
224
|
+
Monitors Node.js Event Loop lag in real-time, returning `503` when lag exceeds safe thresholds.
|
|
199
225
|
|
|
200
226
|
```typescript
|
|
201
|
-
|
|
227
|
+
function backpressure(options?: BackpressureOptions): Handler
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
202
231
|
|
|
203
|
-
|
|
232
|
+
### `compression(options?)`
|
|
233
|
+
|
|
234
|
+
Applies Gzip, Deflate, or Brotli compression to response streams when requested by the client `Accept-Encoding` header.
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
function compression(options?: CompressionOptions): Handler
|
|
204
238
|
```
|
|
205
239
|
|
|
206
|
-
|
|
207
|
-
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 3. Multipart File Uploads
|
|
243
|
+
|
|
244
|
+
### `fileUpload`
|
|
245
|
+
|
|
246
|
+
Streaming multipart/form-data upload middleware providing single, array, and field configurations.
|
|
208
247
|
|
|
209
248
|
```typescript
|
|
210
|
-
|
|
249
|
+
// Single file upload
|
|
250
|
+
fileUpload.single(fieldName: string, options?: FileUploadOptions): Handler
|
|
251
|
+
|
|
252
|
+
// Multiple files under the same field name
|
|
253
|
+
fileUpload.array(fieldName: string, maxCount?: number, options?: FileUploadOptions): Handler
|
|
211
254
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
255
|
+
// Multiple distinct fields
|
|
256
|
+
fileUpload.fields(fields: { name: string; maxCount?: number }[], options?: FileUploadOptions): Handler
|
|
257
|
+
|
|
258
|
+
// Any files accepted
|
|
259
|
+
fileUpload.any(options?: FileUploadOptions): Handler
|
|
260
|
+
|
|
261
|
+
// Text fields only
|
|
262
|
+
fileUpload.none(options?: FileUploadOptions): Handler
|
|
216
263
|
```
|
|
217
264
|
|
|
218
|
-
|
|
219
|
-
Prevents duplicate identical in-flight requests from being computed simultaneously.
|
|
265
|
+
#### `FileUploadOptions`
|
|
220
266
|
|
|
221
|
-
|
|
222
|
-
|
|
267
|
+
| Option | Type | Description |
|
|
268
|
+
| :--- | :--- | :--- |
|
|
269
|
+
| `dest` | `string` | Target directory on disk to stream uploaded files to. |
|
|
270
|
+
| `maxBytes` | `number` | Maximum allowed individual file size in bytes. |
|
|
271
|
+
| `mimeTypes` | `string[]` | Permitted MIME types (e.g. `['image/png', 'image/jpeg']`). |
|
|
272
|
+
| `limits` | `FileUploadLimits` | Detailed limits (`fileSize`, `files`, `fieldSize`, `fields`). |
|
|
223
273
|
|
|
224
|
-
|
|
225
|
-
|
|
274
|
+
#### Example
|
|
275
|
+
|
|
276
|
+
```typescript filename="src/http/users/route.ts"
|
|
277
|
+
import { controller, route } from 'exisjs/router'
|
|
278
|
+
import { fileUpload } from 'exisjs/middleware'
|
|
279
|
+
|
|
280
|
+
export default controller({
|
|
281
|
+
uploadAvatar: route.post('/avatar', {
|
|
282
|
+
middleware: [fileUpload.single('avatar', {
|
|
283
|
+
maxBytes: 5 * 1024 * 1024,
|
|
284
|
+
mimeTypes: ['image/png', 'image/jpeg'],
|
|
285
|
+
})],
|
|
286
|
+
async handle({ req }) {
|
|
287
|
+
const file = req.file // UploadedFile { filename, originalname, mimetype, size, buffer }
|
|
288
|
+
return { success: true, filename: file.filename }
|
|
289
|
+
},
|
|
290
|
+
}),
|
|
291
|
+
})
|
|
292
|
+
```
|
|
226
293
|
|
|
227
294
|
---
|
|
228
295
|
|
|
229
|
-
|
|
296
|
+
### `fromExpress(middleware)`
|
|
297
|
+
|
|
298
|
+
Adapts standard Express/Connect middleware to run within the ExisJS pipeline.
|
|
230
299
|
|
|
231
|
-
|
|
232
|
-
|
|
300
|
+
```typescript
|
|
301
|
+
import { fromExpress } from 'exisjs/middleware'
|
|
302
|
+
import morgan from 'morgan'
|
|
303
|
+
|
|
304
|
+
app.use(fromExpress(morgan('combined')))
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
233
308
|
|
|
234
|
-
|
|
235
|
-
Injects a unique `X-Request-Id` into every incoming request and outgoing response header.
|
|
309
|
+
## 4. Utility Middlewares
|
|
236
310
|
|
|
237
|
-
|
|
238
|
-
|
|
311
|
+
| Middleware | Signature | Description |
|
|
312
|
+
| :--- | :--- | :--- |
|
|
313
|
+
| `requestId()` | `() => Handler` | Injects a unique `X-Request-Id` into request and response headers. |
|
|
314
|
+
| `requestLogger(options?)` | `(options?: LoggerConfig) => Handler` | Formats and logs request completion timings and status codes. |
|
|
315
|
+
| `serveStatic(root, options?)` | `(root: string, options?: StaticOptions) => Handler` | Serves static assets from disk with caching headers and streaming backpressure. |
|
|
316
|
+
| `conditionalGet()` | `() => Handler` | Enables ETag validation and `304 Not Modified` responses. |
|
|
317
|
+
| `validate(schema)` | `(schema: ValidateSchema) => Handler` | Validates request parameters against a `TexEngine` schema. |
|
|
239
318
|
|
|
240
|
-
### `serveStatic(root, options?)`
|
|
241
|
-
Static file server supporting streaming and caching headers.
|