exisjs 0.7.12 → 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.
Files changed (116) hide show
  1. package/README.md +195 -39
  2. package/dist/config/types.d.ts +2 -2
  3. package/dist/config/types.d.ts.map +1 -1
  4. package/dist/decorators/params.d.ts +21 -0
  5. package/dist/decorators/params.d.ts.map +1 -1
  6. package/dist/decorators/params.js +21 -1
  7. package/dist/decorators/params.js.map +1 -1
  8. package/dist/di/container.d.ts +15 -6
  9. package/dist/di/container.d.ts.map +1 -1
  10. package/dist/di/container.js +26 -3
  11. package/dist/di/container.js.map +1 -1
  12. package/dist/di/index.d.ts +1 -1
  13. package/dist/di/index.d.ts.map +1 -1
  14. package/dist/di/index.js.map +1 -1
  15. package/dist/di/inject.d.ts +2 -1
  16. package/dist/di/inject.d.ts.map +1 -1
  17. package/dist/di/inject.js +2 -1
  18. package/dist/di/inject.js.map +1 -1
  19. package/dist/docs/BENCHMARKS.md +4 -4
  20. package/dist/docs/content/README.md +43 -44
  21. package/dist/docs/content/boundaries.mdx +138 -61
  22. package/dist/docs/content/cli/commands.mdx +151 -128
  23. package/dist/docs/content/cli/overview.mdx +61 -47
  24. package/dist/docs/content/cli/usage.mdx +107 -30
  25. package/dist/docs/content/config.mdx +145 -158
  26. package/dist/docs/content/controllers.mdx +193 -464
  27. package/dist/docs/content/cron.mdx +183 -69
  28. package/dist/docs/content/decorators.mdx +449 -154
  29. package/dist/docs/content/errors.mdx +202 -305
  30. package/dist/docs/content/exisjs-mcp.mdx +59 -49
  31. package/dist/docs/content/installation.mdx +243 -157
  32. package/dist/docs/content/introduction.mdx +220 -48
  33. package/dist/docs/content/middleware.mdx +171 -497
  34. package/dist/docs/content/modules.mdx +141 -83
  35. package/dist/docs/content/providers.mdx +216 -180
  36. package/dist/docs/content/requests.mdx +168 -488
  37. package/dist/docs/content/responses.mdx +200 -533
  38. package/dist/docs/content/routing.mdx +235 -598
  39. package/dist/docs/content/security.mdx +233 -57
  40. package/dist/docs/content/structure.mdx +151 -240
  41. package/dist/docs/content/swagger.mdx +192 -91
  42. package/dist/docs/content/testing.mdx +205 -74
  43. package/dist/docs/content/validation.mdx +479 -341
  44. package/dist/docs/reference/README.md +34 -2
  45. package/dist/docs/reference/config.mdx +277 -75
  46. package/dist/docs/reference/context.mdx +197 -106
  47. package/dist/docs/reference/cron.mdx +266 -152
  48. package/dist/docs/reference/database.mdx +135 -53
  49. package/dist/docs/reference/decorators.mdx +234 -116
  50. package/dist/docs/reference/di.mdx +146 -112
  51. package/dist/docs/reference/error.mdx +155 -178
  52. package/dist/docs/reference/exis.mdx +141 -70
  53. package/dist/docs/reference/logger.mdx +110 -126
  54. package/dist/docs/reference/middleware.mdx +235 -158
  55. package/dist/docs/reference/plugin.mdx +136 -64
  56. package/dist/docs/reference/router.mdx +275 -293
  57. package/dist/docs/reference/sanitize.mdx +91 -87
  58. package/dist/docs/reference/swagger.mdx +280 -100
  59. package/dist/docs/reference/testing.mdx +223 -89
  60. package/dist/docs/reference/validator.mdx +194 -206
  61. package/dist/lib/start-server.js +3 -8
  62. package/dist/lib/start-server.js.map +1 -1
  63. package/dist/module/module.d.ts +6 -3
  64. package/dist/module/module.d.ts.map +1 -1
  65. package/dist/module/module.js +17 -3
  66. package/dist/module/module.js.map +1 -1
  67. package/dist/router/controller-registrar.d.ts.map +1 -1
  68. package/dist/router/controller-registrar.js +26 -4
  69. package/dist/router/controller-registrar.js.map +1 -1
  70. package/dist/server/app.d.ts +3 -1
  71. package/dist/server/app.d.ts.map +1 -1
  72. package/dist/server/app.js +24 -8
  73. package/dist/server/app.js.map +1 -1
  74. package/dist/server/request.d.ts +2 -0
  75. package/dist/server/request.d.ts.map +1 -1
  76. package/dist/server/request.js +11 -0
  77. package/dist/server/request.js.map +1 -1
  78. package/dist/swagger/generator.d.ts.map +1 -1
  79. package/dist/swagger/generator.js +130 -10
  80. package/dist/swagger/generator.js.map +1 -1
  81. package/dist/telemetry/index.d.ts +12 -0
  82. package/dist/telemetry/index.d.ts.map +1 -0
  83. package/dist/telemetry/index.js +121 -0
  84. package/dist/telemetry/index.js.map +1 -0
  85. package/dist/testing/client.d.ts +1 -0
  86. package/dist/testing/client.d.ts.map +1 -1
  87. package/dist/testing/client.js +4 -1
  88. package/dist/testing/client.js.map +1 -1
  89. package/dist/testing/index.d.ts.map +1 -1
  90. package/dist/testing/index.js +11 -4
  91. package/dist/testing/index.js.map +1 -1
  92. package/dist/validator/builder.d.ts +26 -1
  93. package/dist/validator/builder.d.ts.map +1 -1
  94. package/dist/validator/builder.js +31 -0
  95. package/dist/validator/builder.js.map +1 -1
  96. package/dist/validator/engine.d.ts +23 -0
  97. package/dist/validator/engine.d.ts.map +1 -1
  98. package/dist/validator/engine.js +228 -31
  99. package/dist/validator/engine.js.map +1 -1
  100. package/dist/validator/index.d.ts +8 -4
  101. package/dist/validator/index.d.ts.map +1 -1
  102. package/dist/validator/index.js +4 -1
  103. package/dist/validator/index.js.map +1 -1
  104. package/dist/validator/tex-types.d.ts +15 -0
  105. package/dist/validator/tex-types.d.ts.map +1 -1
  106. package/dist/validator/tex-types.js +102 -0
  107. package/dist/validator/tex-types.js.map +1 -1
  108. package/dist/validator/tex.d.ts +1 -1
  109. package/dist/validator/tex.d.ts.map +1 -1
  110. package/dist/validator/tex.js +3 -1
  111. package/dist/validator/tex.js.map +1 -1
  112. package/dist/validator/types.d.ts +1 -0
  113. package/dist/validator/types.d.ts.map +1 -1
  114. package/package.json +46 -14
  115. package/dist/docs/content/dataloader.mdx +0 -170
  116. package/dist/docs/reference/dataloader.mdx +0 -91
@@ -1,44 +1,43 @@
1
- # ExisJS Documentation Blueprint
2
-
3
- This directory contains the core documentation for ExisJS. This `README.md` acts as a **blueprint** and index to help you navigate the features and understand what each markdown file contains.
4
-
5
- ## 🚀 Getting Started
6
- * **`introduction.mdx`**: High-level overview of ExisJS, its philosophy, and why it exists.
7
- * **`installation.mdx`**: How to create a new project using `create-exis` and basic setup.
8
- * **`structure.mdx`**: Explains the recommended folder structure (e.g., `src/http`, `src/jobs`, `src/services`).
9
- * **`cli.mdx`**: Documentation for the Exis CLI (`exis dev`, `exis build`), including Esbuild integration and Smart Port Detection.
10
- * **`config.mdx`**: How to configure the framework using `exis.config.ts`.
11
-
12
- ## 🧠 Core Routing & HTTP
13
- * **`routing.mdx`**: Covers File-System Routing, exact matches, parameters, and wildcards using the Radix Tree.
14
- * **`controllers.mdx`**: Using OOP class-based controllers (`@Controller`) and Functional controllers.
15
- * **`gateways.mdx`**: Explains Topological folder-based middleware (e.g., `_gateway.ts`) that runs before routes in a directory.
16
- * **`middleware.mdx`**: Global and route-level middleware, CORS, and `req.log` interception.
17
- * **`requests.mdx`**: How to read query params, body data, headers, and use the global `req` object.
18
- * **`responses.mdx`**: Sending JSON, streams, raw data, and manipulating HTTP status codes.
19
-
20
- ## 🏗️ Architecture & DI
21
- * **`modules.mdx`**: Grouping controllers and providers into modular chunks.
22
- * **`providers.mdx`**: Dependency Injection (DI) system, singletons, and injecting services.
23
- * **`decorators.mdx`**: Overview of all decorators available for OOP paradigms (e.g., `@Get`, `@Inject`).
24
-
25
- ## 🛡️ Data & Validation
26
- * **`validation.mdx`**: The Zod-like type-safe validation engine (`v`), strict parsing, and the standalone `sanitize` utilities.
27
- * **`dataloader.mdx`**: Solving the N+1 database problem automatically using integrated data loaders.
28
- * **`cache.mdx`**: Application-level caching, response caching, and invalidation strategies.
29
-
30
- ## ⚡ Advanced Capabilities
31
- * **`websockets.mdx`**: Real-time bidirectional communication using the native uWebSockets integration.
32
- * **`sse.mdx`**: Server-Sent Events for one-way streaming (useful for AI text generation).
33
- * **`queues.mdx`**: Background job processing, workers, and Redis-backed queues.
34
- * **`cron.mdx`**: Scheduling recurring tasks effortlessly using `cron` syntax.
35
- * **`rpc.mdx`**: End-to-end type safety connecting the ExisJS backend with an `@exisjs/client` frontend.
36
-
37
- ## 🔒 Security & Reliability
38
- * **`security.mdx`**: Helmet integration, Rate Limiting, CORS configuration, and best practices.
39
- * **`errors.mdx`**: Global error handling, custom `HttpException` classes, and safe error masking in production.
40
- * **`circuit-breaker.mdx`**: Preventing cascading failures when external APIs or databases go down.
41
- * **`testing.mdx`**: Using the integrated, native `node:test` runner to test your endpoints without Jest.
42
-
43
- ## 🔌 Ecosystem
44
- * **`adapters.mdx`**: How to run ExisJS inside serverless environments or mount it seamlessly alongside Next.js.
1
+ # ExisJS Documentation Content Directory
2
+
3
+ This directory contains the user guides, conceptual explanations, and how-to manuals for ExisJS.
4
+
5
+ Documentation follows the [Diátaxis Framework](https://diataxis.fr/), separating conceptual overviews, procedural how-to guides, and reference materials.
6
+
7
+ ---
8
+
9
+ ## Content Index
10
+
11
+ ### 1. Getting Started & Architecture
12
+ - [`introduction.mdx`](./introduction.mdx): Overview of framework architecture, design decisions, and supported paradigms.
13
+ - [`installation.mdx`](./installation.mdx): Prerequisites, project scaffolding (`npm create exisjs@latest`), and manual setup.
14
+ - [`structure.mdx`](./structure.mdx): Standardized directory layout (`src/http/`, `src/database/`, `src/common/`, `src/config/`, `src/cron/`).
15
+
16
+ ### 2. HTTP Routing & Request Pipeline
17
+ - [`routing.mdx`](./routing.mdx): File-system routing conventions (`route.ts`), path parameters, route groups, and handlers.
18
+ - [`controllers.mdx`](./controllers.mdx): Class-based routing, `@Controller` decorators, and parameter mappings.
19
+ - [`decorators.mdx`](./decorators.mdx): Reference guide for all decorators across routing, parameters, pipes, middlewares, security, and lifecycle.
20
+ - [`requests.mdx`](./requests.mdx): Request anatomy (`ExisRequest`), query strings, headers, cookies, and context augmentation.
21
+ - [`responses.mdx`](./responses.mdx): Response helpers, JSON output, HTTP status codes, SSE, and stream handling.
22
+ - [`boundaries.mdx`](./boundaries.mdx): Directory-scoped middleware cascading, hierarchical CORS inheritance, and boundary isolation.
23
+
24
+ ### 3. Validation, Dependency Injection & Data
25
+ - [`validation.mdx`](./validation.mdx): Schema validation engine (`tex.*`), parameter coercion, custom validators, and sanitization.
26
+ - [`providers.mdx`](./providers.mdx): Dependency injection, constructor injection, `@Injectable()`, `@Inject()`, and `forwardRef()`.
27
+ - [`modules.mdx`](./modules.mdx): Module encapsulation, `@Module()`, dynamic module registration, and `@Global()` scopes.
28
+
29
+ ### 4. Middleware, Security & Operations
30
+ - [`middleware.mdx`](./middleware.mdx): Global, boundary, and route-level middlewares, Express bridge, and execution order.
31
+ - [`security.mdx`](./security.mdx): Security headers (Helmet), CSRF tokens, CIDR IP filtering, parameter pollution, and probe blocking.
32
+ - [`errors.mdx`](./errors.mdx): HTTP exception classes, JSON error payloads, and custom error boundaries.
33
+ - [`cron.mdx`](./cron.mdx): Background task scheduling (`cron()` and `@Cron()`) with drift correction and overlap protection.
34
+ - [`swagger.mdx`](./swagger.mdx): Automatic OpenAPI 3.1 schema extraction, Swagger UI (`/docs`), and JSON documentation endpoints.
35
+ - [`testing.mdx`](./testing.mdx): Test harness (`createTestContext`, `createTestApp`), mocking utilities (`ex`), and CLI test runner.
36
+ - [`config.mdx`](./config.mdx): Global configuration options in `exis.config.ts`, lifecycle phases, clustering, and file watcher settings.
37
+ - [`exisjs-mcp.mdx`](./exisjs-mcp.mdx): Model Context Protocol (MCP) server integration for IDE AI assistants.
38
+
39
+ ### 5. CLI Tooling (`cli/`)
40
+ - [`cli/overview.mdx`](./cli/overview.mdx): CLI architecture and runtime execution.
41
+ - [`cli/usage.mdx`](./cli/usage.mdx): Basic usage and script execution.
42
+ - [`cli/commands.mdx`](./cli/commands.mdx): Reference for all CLI commands (`dev`, `build`, `start`, `routes`, `test`, `doctor`, `init`).
43
+
@@ -1,86 +1,88 @@
1
1
  ---
2
- nextUrl: "/docs/validation"
3
- nextTitle: "Validation"
2
+ title: 'Boundaries & Middleware Cascading'
3
+ description: 'Folder-scoped middleware cascading, security guards, CORS inheritance hierarchy, exclusion rules, and error handling with boundary.ts.'
4
+ nextUrl: '/docs/validation'
5
+ nextTitle: 'Validation & Schemas'
4
6
  ---
5
7
 
6
- # Boundaries (Config & Request Pipeline)
8
+ # Boundaries & Middleware Cascading (`boundary.ts`)
7
9
 
8
- A `boundary.ts` acts as a folder-scoped configuration and request pipeline in your file-system routing architecture.
10
+ A `boundary.ts` (or `<name>.boundary.ts`) file defines a folder-scoped request pipeline and configuration module in the ExisJS file-system routing hierarchy.
9
11
 
10
- Any `boundary.ts` applies to every route in its folder and all subfolders recursively. Instead of manually registering middleware chains or route guards, placing a `boundary.ts` configures **CORS**, **Headers**, **Excluded Paths**, **Dependency Injection**, and an **auto-detected request pipeline** cleanly scoped to that sub-tree.
12
+ Any `boundary.ts` automatically applies to every route within its directory and all descendant subdirectories recursively, providing scoped **CORS policies**, **custom headers**, **security guards**, **lifecycle hooks**, **route exclusions**, and **dependency injection scoping**.
11
13
 
12
14
  ---
13
15
 
14
16
  ## Anatomy of a Boundary
15
17
 
16
- A `boundary.ts` has two distinct, independent parts:
18
+ A `boundary.ts` consists of two distinct components:
17
19
 
18
- 1. **Config** — pure data, declared via `defineBoundary()` (functional) or the `@Boundary()` class decorator (OOP). It configures CORS, headers, DI providers, timeout, and exclusion rules.
19
- 2. **Pipeline** — real code, auto-detected by function signature. No manual pipeline registration is needed.
20
+ 1. **Configuration**: Pure declarative options declared via `defineBoundary()` (functional) or `@Boundary()` (OOP). It sets CORS, response headers, timeout limits, exclusion patterns, probe blackholing, and DI providers.
21
+ 2. **Pipeline Handlers**: Functions and lifecycle hooks that run before, during, or after request execution:
20
22
 
21
- | Signature | Detected as | Execution timing |
22
- |---|---|---|
23
- | `(req, res, next)` | Chain Step | Runs in file/declaration order, before the route |
24
- | `beforeHandle(req, res)` | Boundary Guard Hook | Immediately before the route handler. Short-circuits on `false` or when sending headers |
25
- | `afterHandle(req, res, data)` | Response Hook | Immediately after the route handler. Mutates returned payload or logs audit data |
26
- | `(ctx, next)` — default export (functional) or class method `handle(ctx, next)` (OOP) | Request Wrapper | Wraps around all chain steps and the nested route/boundary |
23
+ | Handler Type | Signature | Description |
24
+ | :--- | :--- | :--- |
25
+ | **Chain Step** | `(req, res, next)` | Standard middleware step running in declaration order before route handlers |
26
+ | **Guard Hook** | `beforeHandle(req, res)` | Runs immediately before route handler execution; aborts if returning `false` |
27
+ | **Audit Hook** | `afterHandle(req, res, data)` | Runs immediately after route handler returns; can transform response data |
28
+ | **Pipeline Wrapper** | `(ctx, next)` / `handle(ctx, next)` | Onion-style wrapper around all steps and downstream routes in the boundary |
27
29
 
28
30
  ---
29
31
 
30
32
  ## 1. Functional Paradigm
31
33
 
32
- In functional style, export `config = defineBoundary(...)`, export named middleware functions `(req, res, next)` for chain steps, and optionally provide a `default export` function `(ctx, next)` as an onion-style wrapper. You can also configure `beforeHandle` and `afterHandle` hooks directly inside `defineBoundary({ ... })`.
34
+ Export `config = defineBoundary(...)`, named middleware functions `(req, res, next)`, and optionally a default export `(ctx, next)` as a request wrapper:
33
35
 
34
36
  ```typescript filename="src/http/admin/boundary.ts"
35
37
  import { defineBoundary } from 'exisjs/router'
36
38
  import type { Request, Response, Next, BoundaryContext } from 'exisjs/router'
37
39
  import { UnauthorizedError } from 'exisjs/error'
38
40
 
39
- // 1. Configuration (CORS, Headers, Exclusions, Hooks, DI Providers)
41
+ // 1. Declarative Boundary Configuration
40
42
  export const config = defineBoundary({
41
43
  cors: {
42
- origin: ['https://admin.yourdomain.com'],
44
+ origin: ['https://admin.example.com'],
43
45
  credentials: true,
44
46
  },
45
47
  headers: {
46
- 'X-Admin-Api-Version': '2.0',
48
+ 'X-Admin-Scope': 'active',
47
49
  },
48
50
  exclude: [
49
51
  '/admin/health',
50
- { path: '/admin/public/*', method: 'GET' }
52
+ { path: '/admin/public/*', method: 'GET' },
51
53
  ],
52
54
 
53
- // Pre-handler hook: Return false to reject with 403, or send custom response
55
+ // Pre-handler guard hook
54
56
  beforeHandle(req, res) {
55
57
  if (!req.headers['x-admin-token']) {
56
58
  res.status(401).json({ error: 'Missing admin access token' })
57
- return false
59
+ return false // Aborts downstream execution
58
60
  }
59
61
  },
60
62
 
61
- // Post-handler hook: Transform outgoing response payload or perform async audit
63
+ // Post-handler response transformation hook
62
64
  afterHandle(req, res, data) {
63
- res.setHeader('X-Audited', 'true')
64
- return { ...data, auditedAt: Date.now() }
65
+ res.setHeader('X-Audited-At', new Date().toISOString())
66
+ return { ...data, audited: true }
65
67
  },
66
68
  })
67
69
 
68
- // 2. Chain Step (auto-detected by (req, res, next) signature)
69
- export function requireAuth(req: Request, res: Response, next: Next) {
70
+ // 2. Named Chain Step Middleware
71
+ export function verifyApiKey(req: Request, res: Response, next: Next) {
70
72
  if (!req.headers['x-api-key']) {
71
- throw new UnauthorizedError('Missing API key')
73
+ throw new UnauthorizedError('Missing required API key')
72
74
  }
73
75
  next()
74
76
  }
75
77
 
76
- // 3. Wrapper (auto-detected as default export with (ctx, next) signature)
78
+ // 3. Pipeline Wrapper (Default Export)
77
79
  export default async function (ctx: BoundaryContext, next: Next) {
78
80
  const start = Date.now()
79
81
  try {
80
82
  const result = await next()
81
83
  const duration = Date.now() - start
82
84
  ctx.res.setHeader('X-Response-Time', `${duration}ms`)
83
- return { success: true, data: result }
85
+ return result
84
86
  } catch (err: any) {
85
87
  return {
86
88
  success: false,
@@ -94,7 +96,7 @@ export default async function (ctx: BoundaryContext, next: Next) {
94
96
 
95
97
  ## 2. Class-Based (OOP) Paradigm
96
98
 
97
- In OOP style, decorate a class with `@Boundary(...)`. Named methods taking `(req, res, next)` are auto-detected as chain steps, `beforeHandle(req, res)` and `afterHandle(req, res, data)` act as lifecycle hooks, and a method named `handle(ctx, next)` serves as the request wrapper.
99
+ Decorate a class with `@Boundary(...)`. Class methods taking `(req, res, next)` become chain steps, `beforeHandle` / `afterHandle` serve as lifecycle hooks, and a method named `handle(ctx, next)` acts as the pipeline wrapper:
98
100
 
99
101
  ```typescript filename="src/http/admin/boundary.ts"
100
102
  import { Boundary } from 'exisjs/decorators'
@@ -103,11 +105,11 @@ import { UnauthorizedError } from 'exisjs/error'
103
105
 
104
106
  @Boundary({
105
107
  cors: {
106
- origin: ['https://admin.yourdomain.com'],
108
+ origin: ['https://admin.example.com'],
107
109
  credentials: true,
108
110
  },
109
111
  headers: {
110
- 'X-Admin-Api-Version': '2.0',
112
+ 'X-Admin-Scope': 'active',
111
113
  },
112
114
  exclude: ['/admin/health'],
113
115
  })
@@ -122,19 +124,19 @@ export default class AdminBoundary {
122
124
 
123
125
  // Post-handler hook
124
126
  afterHandle(req: Request, res: Response, data: any) {
125
- res.setHeader('X-Audited', 'true')
126
- return { ...data, auditedAt: Date.now() }
127
+ res.setHeader('X-Audited-At', new Date().toISOString())
128
+ return { ...data, audited: true }
127
129
  }
128
130
 
129
- // Chain step
130
- requireAuth(req: Request, res: Response, next: Next) {
131
+ // Named chain step
132
+ verifyApiKey(req: Request, res: Response, next: Next) {
131
133
  if (!req.headers['x-api-key']) {
132
- throw new UnauthorizedError('Missing API key')
134
+ throw new UnauthorizedError('Missing required API key')
133
135
  }
134
136
  next()
135
137
  }
136
138
 
137
- // Wrapper
139
+ // Pipeline wrapper
138
140
  async handle(ctx: BoundaryContext, next: Next) {
139
141
  const start = Date.now()
140
142
  const result = await next()
@@ -146,44 +148,110 @@ export default class AdminBoundary {
146
148
 
147
149
  ---
148
150
 
149
- ## Cascading & Inheritance
151
+ ## Boundary Cascading & Execution Order
150
152
 
151
- Boundaries cascade down the directory tree. For instance:
153
+ Boundaries cascade top-down through the folder structure:
152
154
 
153
155
  ```text
154
156
  src/http/
155
- ├── boundary.ts # Root Boundary (applies to /api/*)
157
+ ├── boundary.ts # Root Boundary (applies to all routes)
156
158
  └── admin/
157
- ├── boundary.ts # Admin Boundary (applies to /api/admin/*)
159
+ ├── boundary.ts # Admin Boundary (applies to /admin/*)
158
160
  └── users/
159
- └── route.ts # Handled by both Root Boundary and Admin Boundary
161
+ └── route.ts # Handled by both Root Boundary and Admin Boundary
160
162
  ```
161
163
 
162
- 1. **Wrappers & Chain Steps**: Outer boundaries execute first. Root wrappers wrap nested wrappers, and root chain steps run before nested chain steps top-down.
163
- 2. **CORS Precedence & Inheritance**:
164
- - **Innermost Boundary Wins**: If a nested boundary specifies `cors`, it overrides any CORS configuration set in parent boundaries or `exis.config.ts`.
165
- - **Inheritance**: If a sub-boundary omits `cors`, it seamlessly inherits the parent boundary's CORS configuration (or global config).
166
- - **Per-Route Overrides**: A `route.ts` handler can define its own `cors` setting to override boundary settings for that single endpoint.
167
- - **Disabling CORS**: Setting `cors: false` on a boundary or route explicitly disables CORS headers and preflight handling for that sub-tree or route.
168
- 3. **Headers Merging**: Headers are deep-merged from root to child. Child headers override parent headers if keys collide.
169
- 4. **Exclusions**: When a route matches an exclusion pattern (e.g. `/admin/health` in `exclude`), that boundary's chain steps and wrappers are bypassed for the request.
164
+ ### Execution Order
165
+
166
+ 1. **Wrappers**: Outer wrappers wrap inner wrappers (onion architecture).
167
+ 2. **Chain Steps**: Root chain steps run before nested boundary chain steps.
168
+ 3. **Guard Hooks (`beforeHandle`)**: Run immediately before the route handler, evaluated from root boundary down to the innermost boundary.
169
+ 4. **Response Hooks (`afterHandle`)**: Run in reverse order (innermost boundary up to root boundary).
170
+
171
+ ---
172
+
173
+ ## CORS Inheritance & Precedence
174
+
175
+ CORS configuration follows a 4-tier hierarchy:
176
+
177
+ | Priority | Level | Where Defined | Description |
178
+ | :---: | :--- | :--- | :--- |
179
+ | 1 | **Route Override** | `route.get('/', { cors: ... })` or `@Cors(...)` | Specific to a single endpoint; overrides all boundaries and global configs |
180
+ | 2 | **Innermost Boundary** | `src/http/admin/boundary.ts` | Scoped to subfolder tree; overrides parent boundaries |
181
+ | 3 | **Parent / Root Boundary** | `src/http/boundary.ts` | Scoped to all routes in `src/http/`; overrides global defaults |
182
+ | 4 | **Global Configuration** | `exis.config.ts` (`cors`) | Fallback baseline for endpoints without boundary or route CORS |
183
+
184
+ > [!NOTE]
185
+ > If a sub-boundary omits `cors`, it inherits the CORS settings of the nearest ancestor boundary (or `exis.config.ts`). Setting `cors: false` on a boundary explicitly disables CORS for that entire subtree.
186
+
187
+ ---
188
+
189
+ ## Headers Merging
170
190
 
171
- ### CORS Resolution Hierarchy
191
+ Response headers defined across boundaries are deep-merged from root to child. If header keys conflict, the innermost boundary value takes precedence:
172
192
 
173
- ExisJS resolves CORS in a 3-tier precedence order:
193
+ ```typescript
194
+ // src/http/boundary.ts (Root)
195
+ export const config = defineBoundary({
196
+ headers: { 'X-Framework': 'ExisJS', 'X-Environment': 'production' },
197
+ })
198
+
199
+ // src/http/v2/boundary.ts (Nested)
200
+ export const config = defineBoundary({
201
+ headers: { 'X-Api-Version': 'v2', 'X-Environment': 'v2-canary' },
202
+ })
174
203
 
175
- | Level | Where to Define | Priority | Description |
176
- |---|---|---|---|
177
- | **Route** | `route.get('/', { cors: ... })` or `@Cors(...)` | 🥇 **Highest** | Specific to a single endpoint. Overrides boundary and global config. |
178
- | **Nested Boundary** | `src/http/admin/boundary.ts` | 🥈 **High** | Scoped to the subfolder tree. Overrides parent boundaries and global config. |
179
- | **Parent / Root Boundary** | `src/http/boundary.ts` | 🥉 **Medium** | Scoped to all API routes under the folder. Overrides global config. |
180
- | **Global Config** | `exis.config.ts` (`defineConfig({ cors })`) | **Base** | Fallback baseline for any route not covered by a boundary or route override. |
204
+ // Endpoints under /v2 receive:
205
+ // X-Framework: ExisJS
206
+ // X-Api-Version: v2
207
+ // X-Environment: v2-canary (overwritten by nested boundary)
208
+ ```
181
209
 
182
210
  ---
183
211
 
184
- ## Dependency Injection via Providers
212
+ ## Route Exclusion Rules
213
+
214
+ To bypass boundary middleware for specific routes (e.g. public webhooks or health checks), add rules to `exclude`:
215
+
216
+ ```typescript filename="src/http/boundary.ts"
217
+ import { defineBoundary } from 'exisjs/router'
218
+
219
+ export const config = defineBoundary({
220
+ exclude: [
221
+ // 1. Exact path string
222
+ '/health',
185
223
 
186
- Boundaries also act as IoC module scopes. You can scope providers to a directory tree using `providers`:
224
+ // 2. Wildcard pattern matching any HTTP method
225
+ '/public/*',
226
+
227
+ // 3. Path with specific HTTP method restriction
228
+ { path: '/webhooks/stripe', method: 'POST' },
229
+ { path: '/docs/*', methods: ['GET', 'HEAD'] },
230
+ ],
231
+ })
232
+ ```
233
+
234
+ When an incoming request matches an exclusion rule, the boundary's chain steps and `beforeHandle` hooks are bypassed.
235
+
236
+ ---
237
+
238
+ ## Noise Suppression & Exploit Probe Blackholing
239
+
240
+ ExisJS can automatically intercept and drop automated vulnerability scanner probes (e.g. `/.env`, `/.git`, `/.DS_Store`, `/wp-admin`) at the boundary level without flooding application logs:
241
+
242
+ ```typescript filename="src/http/boundary.ts"
243
+ import { defineBoundary } from 'exisjs/router'
244
+
245
+ export const config = defineBoundary({
246
+ blockSuspiciousProbes: true, // Blackholes malicious probe paths immediately
247
+ })
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Dependency Injection Scoping
253
+
254
+ Boundaries can register scoped providers into the IoC container for all routes within their sub-tree:
187
255
 
188
256
  ```typescript filename="src/http/users/boundary.ts"
189
257
  import { defineBoundary } from 'exisjs/router'
@@ -195,3 +263,12 @@ export const config = defineBoundary({
195
263
  ],
196
264
  })
197
265
  ```
266
+
267
+ ---
268
+
269
+ ## Next Steps
270
+
271
+ - **[Validation Guide](/docs/validation)**: Building request schemas with `tex`.
272
+ - **[Dependency Injection](/docs/providers)**: IoC containers, tokens, and provider lifecycles.
273
+ - **[Routing](/docs/routing)**: File-system route parameters and handler definitions.
274
+ - **[Controllers](/docs/controllers)**: Class-based routing and parameter decorators.