@noego/stitch 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README-schema.md +139 -0
  2. package/bin/stitch.js +156 -0
  3. package/dist/browser/index.d.ts +4 -0
  4. package/dist/browser/index.d.ts.map +1 -0
  5. package/dist/cli/StitchCLI.d.ts +12 -0
  6. package/dist/cli/StitchCLI.d.ts.map +1 -0
  7. package/dist/client.cjs +2 -0
  8. package/dist/client.cjs.map +1 -0
  9. package/dist/client.mjs +83 -0
  10. package/dist/client.mjs.map +1 -0
  11. package/dist/core/ConfigParser.d.ts +16 -0
  12. package/dist/core/ConfigParser.d.ts.map +1 -0
  13. package/dist/core/StitchEngine.d.ts +31 -0
  14. package/dist/core/StitchEngine.d.ts.map +1 -0
  15. package/dist/core/Validator.d.ts +18 -0
  16. package/dist/core/Validator.d.ts.map +1 -0
  17. package/dist/core/ViteHelper.d.ts +33 -0
  18. package/dist/core/ViteHelper.d.ts.map +1 -0
  19. package/dist/core/YamlMerger.d.ts +29 -0
  20. package/dist/core/YamlMerger.d.ts.map +1 -0
  21. package/dist/core/YamlMergerBrowser.d.ts +18 -0
  22. package/dist/core/YamlMergerBrowser.d.ts.map +1 -0
  23. package/dist/index.d.ts +15 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/types/StitchTypes.d.ts +38 -0
  26. package/dist/types/StitchTypes.d.ts.map +1 -0
  27. package/dist-ssr/browser/index.d.ts +4 -0
  28. package/dist-ssr/browser/index.d.ts.map +1 -0
  29. package/dist-ssr/cli/StitchCLI.d.ts +12 -0
  30. package/dist-ssr/cli/StitchCLI.d.ts.map +1 -0
  31. package/dist-ssr/core/ConfigParser.d.ts +16 -0
  32. package/dist-ssr/core/ConfigParser.d.ts.map +1 -0
  33. package/dist-ssr/core/StitchEngine.d.ts +31 -0
  34. package/dist-ssr/core/StitchEngine.d.ts.map +1 -0
  35. package/dist-ssr/core/Validator.d.ts +18 -0
  36. package/dist-ssr/core/Validator.d.ts.map +1 -0
  37. package/dist-ssr/core/ViteHelper.d.ts +33 -0
  38. package/dist-ssr/core/ViteHelper.d.ts.map +1 -0
  39. package/dist-ssr/core/YamlMerger.d.ts +29 -0
  40. package/dist-ssr/core/YamlMerger.d.ts.map +1 -0
  41. package/dist-ssr/core/YamlMergerBrowser.d.ts +18 -0
  42. package/dist-ssr/core/YamlMergerBrowser.d.ts.map +1 -0
  43. package/dist-ssr/index.d.ts +15 -0
  44. package/dist-ssr/index.d.ts.map +1 -0
  45. package/dist-ssr/server.cjs +574 -0
  46. package/dist-ssr/server.cjs.map +1 -0
  47. package/dist-ssr/server.d.ts +2 -0
  48. package/dist-ssr/server.js +554 -0
  49. package/dist-ssr/server.js.map +1 -0
  50. package/dist-ssr/types/StitchTypes.d.ts +38 -0
  51. package/dist-ssr/types/StitchTypes.d.ts.map +1 -0
  52. package/docs/advanced_validation.md +188 -0
  53. package/docs/middleware.md +507 -0
  54. package/docs/modules.md +175 -0
  55. package/docs/project.md +856 -0
  56. package/docs/validation.md +77 -0
  57. package/package.json +67 -0
  58. package/readme.md +159 -0
  59. package/schemas/schema.json +360 -0
  60. package/schemas/stitch-schema.json +38 -0
@@ -0,0 +1,188 @@
1
+ # OpenAPI Validation Cheatsheet
2
+
3
+ When defining endpoints in OpenAPI (using JSON Schema–style validation), you can constrain your data in **several** ways. This guide provides a quick overview of **common validation** approaches, such as **string constraints**, **patterns (regex)**, **numerical constraints**, and more.
4
+
5
+ ---
6
+
7
+ ## 1. String Constraints
8
+
9
+ **OpenAPI** leverages standard JSON Schema properties to validate strings.
10
+
11
+ ### Basic Example
12
+
13
+ ```yaml
14
+ components:
15
+ schemas:
16
+ UserName:
17
+ type: string
18
+ description: A simple username
19
+ minLength: 3
20
+ maxLength: 50
21
+ ```
22
+
23
+ - **`minLength`**: The string must be at least 3 characters.
24
+ - **`maxLength`**: The string must be at most 50 characters.
25
+
26
+ ### Format Examples
27
+
28
+ - **`format: email`**
29
+ Validates that a string is an email (e.g., `john@example.com`).
30
+ - **`format: uri`**
31
+ Validates that a string is a URI (e.g., `https://example.com`).
32
+ - **`format: date`** / **`format: date-time`**
33
+ Checks that a string is in a valid date/time format.
34
+
35
+ ```yaml
36
+ components:
37
+ schemas:
38
+ Profile:
39
+ type: object
40
+ properties:
41
+ email:
42
+ type: string
43
+ format: email
44
+ website:
45
+ type: string
46
+ format: uri
47
+ birthday:
48
+ type: string
49
+ format: date
50
+ required: [ email, website ]
51
+ ```
52
+
53
+ > Note: The `format` checks are not bulletproof but are a quick way to ensure a minimal level of validity.
54
+
55
+ ### Pattern (Regex)
56
+
57
+ For **custom rules**, add a `"pattern"` (regex). For example:
58
+
59
+ ```yaml
60
+ components:
61
+ schemas:
62
+ StrictUserId:
63
+ type: string
64
+ pattern: '^[A-Z0-9]{8}$'
65
+ description: Must be exactly 8 characters of uppercase letters or digits
66
+ ```
67
+ - The pattern `'^[A-Z0-9]{8}$'` enforces exactly 8 uppercase alpha-numerics.
68
+
69
+ ---
70
+
71
+ ## 2. Numeric Constraints
72
+
73
+ You can validate numbers by specifying **minimum**, **maximum**, and whether the number is an **integer**.
74
+
75
+ ```yaml
76
+ components:
77
+ schemas:
78
+ Product:
79
+ type: object
80
+ properties:
81
+ price:
82
+ type: number
83
+ minimum: 0.01
84
+ quantity:
85
+ type: integer
86
+ minimum: 1
87
+ maximum: 9999
88
+ required: [ price, quantity ]
89
+ ```
90
+
91
+ - **`type: number`** vs. **`type: integer`**
92
+ - `number` can have decimals; `integer` cannot.
93
+ - **`minimum`** / **`maximum`**
94
+ - Price must be ≥ 0.01.
95
+ - Quantity must be between 1 and 9999.
96
+
97
+ ---
98
+
99
+ ## 3. Array Constraints
100
+
101
+ For arrays, use keywords like **items**, **minItems**, and **maxItems**:
102
+
103
+ ```yaml
104
+ components:
105
+ schemas:
106
+ TagList:
107
+ type: array
108
+ minItems: 1
109
+ maxItems: 10
110
+ items:
111
+ type: string
112
+ maxLength: 20
113
+ ```
114
+
115
+ - **`items`**: schema each array element must follow.
116
+ - **`minItems`** / **`maxItems`**: ensures array length constraints.
117
+
118
+ ---
119
+
120
+ ## 4. Required Fields
121
+
122
+ If you have **object** properties that must be provided:
123
+
124
+ ```yaml
125
+ components:
126
+ schemas:
127
+ RegisterUser:
128
+ type: object
129
+ properties:
130
+ username:
131
+ type: string
132
+ password:
133
+ type: string
134
+ required: [ username, password ]
135
+ ```
136
+
137
+ Those fields become mandatory. Missing them triggers a **400 Bad Request** from the validator.
138
+
139
+ ---
140
+
141
+ ## 5. Combining Validation Approaches
142
+
143
+ You can combine multiple validations. For example, ensure a **username** is at least 3 chars and also matches a pattern:
144
+
145
+ ```yaml
146
+ components:
147
+ schemas:
148
+ StrictUsername:
149
+ type: string
150
+ minLength: 3
151
+ maxLength: 12
152
+ pattern: '^[a-zA-Z0-9._-]+$'
153
+ description: 3–12 characters, only letters, digits, '.', '_' or '-'
154
+ ```
155
+
156
+ ---
157
+
158
+ ## 6. How the Validation Happens
159
+
160
+ - **OpenAPI** spec includes your schemas.
161
+ - **Fastify** uses **Ajv** behind the scenes to auto-validate requests.
162
+ - If a request body (or query param, path param, etc.) fails to match the schema, a **400** is returned automatically.
163
+ - No manual coding needed to check lengths, patterns, or formats—**the schema does the job**.
164
+
165
+ ---
166
+
167
+ ## 7. Quick Tips
168
+
169
+ 1. **Start Simple**
170
+ Use `type`, `required`, and `format` if that’s all you need.
171
+
172
+ 2. **Regex for Power**
173
+ `"pattern"` is your friend for custom validations, from strict username rules to domain-specific checks.
174
+
175
+ 3. **Min/Max**
176
+ Avoid weird input by bounding string length, array length, or numeric ranges.
177
+
178
+ 4. **Keep Schemas Organized**
179
+ Put them in `components.schemas`. Reuse by referencing them across your OpenAPI spec.
180
+
181
+ ---
182
+
183
+ ## 8. Further Reading
184
+
185
+ - **Fastify** validation docs: <https://www.fastify.io/docs/latest/Reference/Validation-and-Serialization/>
186
+ - **Ajv** official docs: <https://ajv.js.org/>
187
+ - **OpenAPI** specification about schema: <https://swagger.io/docs/specification/data-models/data-types/>
188
+
@@ -0,0 +1,507 @@
1
+ # Middleware Documentation
2
+
3
+ ## Current Implementation
4
+
5
+ ### How Middleware Works
6
+
7
+ The framework implements route-specific middleware through OpenAPI configuration. Middleware executes sequentially before controller actions using dynamic imports and Promise-based execution.
8
+
9
+ **Current Architecture Issue**: Middleware logic is embedded directly in the ExpressServerImplementation class, making it tightly coupled and harder to maintain.
10
+
11
+ **Desired Architecture**: Separate middleware functionality into a dedicated `MiddlewareAdapter` class (see forge implementation: `express_server_adapter.ts:22`, `middleware_adapter.ts`).
12
+
13
+ ## Improved Architecture Pattern (From Forge)
14
+
15
+ ### Separation of Concerns
16
+
17
+ The forge implementation demonstrates proper separation:
18
+
19
+ ```typescript
20
+ // express_server_adapter.ts:22
21
+ export class ExpressServerAdapter extends ServerAdapter {
22
+ constructor(
23
+ private server: ReturnType<typeof express>,
24
+ private manager: ComponentManager,
25
+ private htmlRender: IHTMLRender,
26
+ private api_adapter: ApiAdapter,
27
+ private middleware_adapter: MiddlewareAdapter // Injected dependency
28
+ ) {
29
+ super()
30
+ }
31
+ ```
32
+
33
+ ### Middleware Adapter Interface
34
+
35
+ ```typescript
36
+ // middleware_adapter.ts:19
37
+ async handleMiddleware(req: any, reply: any, route: IRoute, request_data: RequestData, callback: Callback): Promise<any>
38
+ ```
39
+
40
+ ### Execution Flow in Server Adapter
41
+
42
+ ```typescript
43
+ // express_server_adapter.ts:107-118
44
+ try {
45
+ await new Promise((resolve: any, reject: any) => {
46
+ this.middleware_adapter.handleMiddleware(req, res, route, request_data, resolve).catch(reject)
47
+ })
48
+ } catch(e) {
49
+ console.log('Error in middleware', e)
50
+ res.status(500).send(`
51
+ <h1>500 Internal Server Error</h1>
52
+ <pre>${e}</pre>
53
+ `)
54
+ return
55
+ }
56
+ ```
57
+
58
+ ### Middleware Adapter Implementation Features
59
+
60
+ #### Component-Based Middleware (`middleware_adapter.ts:20-26`)
61
+ ```typescript
62
+ let components = await this.manager.getLayoutComponents(route)
63
+ let middleware_stack = await Promise.all(components.map(async (component) => {
64
+ const middleware = [ ...(component.middleware||[]), ...(component.middlewares||[]) ]
65
+ return middleware
66
+ }))
67
+ const layout_middlewares = middleware_stack.flat() || []
68
+ ```
69
+
70
+ #### Sequential Execution with Deduplication (`middleware_adapter.ts:52-76`)
71
+ ```typescript
72
+ private runMiddleware<K>(middleware: K[], req: any, reply: any, callback: Callback): void {
73
+ middleware = this.dedupe(middleware) // Remove duplicates
74
+ let index = 0;
75
+
76
+ let next = () => {
77
+ if (index >= middleware.length) {
78
+ callback()
79
+ return
80
+ }
81
+ const mw = middleware[index]
82
+ index++
83
+ if (typeof mw === 'function') {
84
+ if(!reply.sent)
85
+ mw(req, reply, next)
86
+ } else {
87
+ if (!reply.sent)
88
+ next()
89
+ }
90
+ }
91
+ next()
92
+ }
93
+ ```
94
+
95
+ #### Layout + View Middleware Support (`middleware_adapter.ts:38-47`)
96
+ - **Layout Middleware**: Executed first from layout components
97
+ - **View Middleware**: Executed second from view components
98
+ - Both support `middleware` and `middlewares` array properties
99
+
100
+ ---
101
+
102
+ ## Current Server Implementation (Needs Refactoring)
103
+
104
+ ### Configuration & Structure
105
+
106
+ #### Server Configuration
107
+ ```typescript
108
+ // ServerOptions interface
109
+ interface ServerOptions {
110
+ middleware_path?: string; // Optional absolute path to middleware directory
111
+ controllers_base_path: string; // Fallback path if middleware_path not set
112
+ }
113
+ ```
114
+
115
+ #### OpenAPI Route Configuration
116
+ ```yaml
117
+ # Middleware assigned per route using x-middleware array
118
+ /user/{id}:
119
+ get:
120
+ x-controller: controllers/user.controller
121
+ x-action: get
122
+ x-middleware:
123
+ - user/auth # Default export only
124
+ - auth:* # All exported functions
125
+ - auth:default,cookie,parsing # Specific functions
126
+ ```
127
+
128
+ #### Module-Level Middleware (Implementation Required First)
129
+
130
+ > **⚠️ Implementation Required**: Module support does not currently exist in this server implementation. The module system exists in the forge project but needs to be ported to support module-level middleware.
131
+
132
+ **Planned Module Configuration with Top-Level BasePath**
133
+ ```yaml
134
+ # This functionality requires implementing module support first
135
+ openapi: 3.0.0
136
+ info:
137
+ title: My API
138
+ version: 1.0.0
139
+
140
+ basePath: "/api" # Top-level basePath applied to ALL routes
141
+
142
+ module:
143
+ users:
144
+ basePath: "/users" # Module basePath (combined with top-level)
145
+ x-middleware: # Module-level middleware (NOT YET SUPPORTED)
146
+ - auth # Applied to all routes in this module
147
+ - logging:request # Applied to all routes in this module
148
+ paths:
149
+ "/": # Becomes /api/users/
150
+ get:
151
+ x-controller: controllers/user.controller
152
+ x-action: getAll
153
+ x-middleware: # Route-specific middleware
154
+ - validation:users # Combined with module middleware
155
+ "/{id}": # Becomes /api/users/{id}
156
+ get:
157
+ x-controller: controllers/user.controller
158
+ x-action: get
159
+ x-middleware:
160
+ - validation:user-id
161
+ posts:
162
+ basePath: "/posts" # Becomes /api/posts/*
163
+ paths:
164
+ "/":
165
+ get:
166
+ x-controller: controllers/post.controller
167
+ x-action: getAll
168
+
169
+ # Direct paths also get top-level basePath
170
+ paths:
171
+ "/health": # Becomes /api/health
172
+ get:
173
+ x-controller: controllers/health.controller
174
+ x-action: check
175
+ ```
176
+
177
+ **Implementation Requirements**:
178
+ 1. **Top-Level BasePath Support**: Add support for top-level `basePath` configuration
179
+ - Parse top-level `basePath` from OpenAPI config
180
+ - Apply to all routes (both direct paths and module-generated paths)
181
+ 2. **OpenAPI Parser Extension**: Add module parsing support (see `forge/src/parser/openapi.ts:19-61`)
182
+ - Parse module configurations with `basePath` and module-level `x-middleware`
183
+ - Inherit module middleware to all routes within the module
184
+ - Flatten modules into regular `paths` structure for easier processing
185
+ 3. **Route Normalization**: Implement module-to-paths normalization (`forge/src/parser/openapi.ts:94-123`)
186
+ - Combine top-level basePath + module basePath + route path
187
+ - Combine module routes with direct path routes
188
+ - Write all routes back to standard `config.paths[path][method]` structure
189
+ - Delete `config.modules` section after normalization
190
+ 4. **Middleware Inheritance**: During module parsing, prepend module middleware to route middleware
191
+ 5. **Flat Route Processing**: Current `ExpressServerImplementation` can remain unchanged since routes are flattened
192
+
193
+ **Module Normalization Example**:
194
+ ```yaml
195
+ # Input: Configuration with top-level basePath and modules
196
+ basePath: "/api" # Top-level basePath
197
+
198
+ module:
199
+ users:
200
+ basePath: "/users" # Module basePath
201
+ x-middleware: [auth, logging:request]
202
+ paths:
203
+ "/":
204
+ get:
205
+ x-controller: controllers/user.controller
206
+ x-action: getAll
207
+ x-middleware: [validation:users]
208
+ "/{id}":
209
+ get:
210
+ x-controller: controllers/user.controller
211
+ x-action: get
212
+
213
+ paths:
214
+ "/health": # Direct path
215
+ get:
216
+ x-controller: controllers/health.controller
217
+ x-action: check
218
+
219
+ # Output: Normalized to standard paths structure
220
+ paths:
221
+ "/api/users/": # top-level + module + route
222
+ get:
223
+ x-controller: controllers/user.controller
224
+ x-action: getAll
225
+ x-middleware: [auth, logging:request, validation:users] # Module middleware prepended
226
+ "/api/users/{id}": # top-level + module + route
227
+ get:
228
+ x-controller: controllers/user.controller
229
+ x-action: get
230
+ x-middleware: [auth, logging:request] # Module middleware inherited
231
+ "/api/health": # top-level + direct path
232
+ get:
233
+ x-controller: controllers/health.controller
234
+ x-action: check
235
+ ```
236
+
237
+ **Planned Module Middleware Features**:
238
+ - All routes within a module inherit the module's `x-middleware`
239
+ - Module middleware is prepended to route-specific middleware
240
+ - Module middleware applies to every path within that module
241
+ - Nested modules inherit parent module middleware (when supported)
242
+
243
+ #### Middleware Function Structure
244
+
245
+ **Default Export (Current Behavior)**
246
+ ```typescript
247
+ // auth.ts - uses default export only
248
+ export default function UserAuth(req: any, res: any, next: any) {
249
+ // Middleware logic here
250
+ next();
251
+ }
252
+ ```
253
+
254
+ **Multiple Function Exports (Extended Behavior)**
255
+ ```typescript
256
+ // auth.ts - multiple middleware functions
257
+ export default function UserAuth(req: any, res: any, next: any) {
258
+ // Default authentication
259
+ next();
260
+ }
261
+
262
+ export function cookie(req: any, res: any, next: any) {
263
+ // Cookie handling middleware
264
+ next();
265
+ }
266
+
267
+ export function parsing(req: any, res: any, next: any) {
268
+ // Request parsing middleware
269
+ next();
270
+ }
271
+ ```
272
+
273
+ #### Middleware Resolution Patterns
274
+
275
+ | Pattern | Behavior | Example |
276
+ |---------|----------|---------|
277
+ | `auth` | Load default export only | `middleware_module.default` |
278
+ | `auth:*` | Load all exported functions | `Object.values(middleware_module).filter(fn => typeof fn === 'function')` |
279
+ | `auth:default,cookie,parsing` | Load specific named functions | `[middleware_module.default, middleware_module.cookie, middleware_module.parsing]` |
280
+
281
+ #### Extended Middleware Examples
282
+
283
+ **Example 1: Using all functions from a middleware file**
284
+ ```yaml
285
+ x-middleware:
286
+ - auth:* # Executes all exported functions in order: default, cookie, parsing
287
+ ```
288
+
289
+ **Example 2: Selective function execution**
290
+ ```yaml
291
+ x-middleware:
292
+ - auth:cookie,parsing # Only executes cookie and parsing functions, skips default
293
+ ```
294
+
295
+ **Example 3: Mixed middleware patterns**
296
+ ```yaml
297
+ x-middleware:
298
+ - logging # Default export only
299
+ - auth:* # All functions from auth.ts
300
+ - validation:schema # Only schema function from validation.ts
301
+ - security:default,cors # Default and cors functions from security.ts
302
+ ```
303
+
304
+ **Execution Order**: Functions execute in the exact order specified:
305
+ 1. `logging.default`
306
+ 2. `auth.default`, `auth.cookie`, `auth.parsing` (in export order)
307
+ 3. `validation.schema`
308
+ 4. `security.default`, `security.cors`
309
+
310
+ ### Execution Flow
311
+
312
+ 1. **Route Matching**: Request matches OpenAPI route definition
313
+ 2. **Middleware Extraction**: Extract middleware from route configuration:
314
+ - **Current**: Only route-level `x-middleware` from OpenAPI route definition
315
+ - **Future**: Module middleware consolidation when module support is added
316
+ 3. **Middleware Resolution**: Each middleware in the array is resolved:
317
+ - **Path Parsing**: Split middleware string on `:` to separate file path from function selector
318
+ - **File Resolution**: `(middleware_path || controllers_base_path) + filePath`
319
+ - **Dynamic Import**: `await import(middleware_full_path)`
320
+ - **Function Extraction**: Based on pattern:
321
+ - `auth` → `[middleware_module.default]` (validate is function)
322
+ - `auth:*` → `Object.values(middleware_module).filter(fn => typeof fn === 'function')`
323
+ - `auth:default,cookie,parsing` → `[middleware_module.default, middleware_module.cookie, middleware_module.parsing]` (validate each is function)
324
+ 4. **Function Flattening**: All resolved functions are flattened into a single execution array
325
+ 5. **Sequential Execution**: For each middleware function:
326
+ - Wrapped in Promise for async handling
327
+ - Called with `(req, res, next)` parameters
328
+ - Must complete before next middleware executes
329
+ 6. **Error Handling**: Any middleware error halts execution with 500 response
330
+ - **File Not Found**: Middleware file doesn't exist at resolved path
331
+ - **Function Not Found**: Specified function doesn't exist in module
332
+ - **Runtime Errors**: Middleware throws exception or calls `next(error)`
333
+ 7. **Controller Execution**: After all middleware succeeds, controller action runs
334
+
335
+ ### Current Implementation Details
336
+
337
+ #### Path Resolution (`ExpressServerImplentation.ts:183-211`)
338
+ ```typescript
339
+ // Use middleware_path if provided, otherwise fall back to controller_base
340
+ const middleware_base = this.options.middleware_path || controller_base;
341
+ const middleware_full_path = path.resolve(process.cwd(), path.join(middleware_base, `${middlewarePath}`));
342
+ ```
343
+
344
+ #### Middleware Execution Loop (`ExpressServerImplentation.ts:183-211`)
345
+
346
+ The middleware execution follows this detailed process for each middleware in the `x-middleware` array:
347
+
348
+ ```typescript
349
+ for (const middlewarePath of middleware) {
350
+ try {
351
+ // 1. Path Resolution
352
+ // Use middleware_path if provided, otherwise fall back to controller_base
353
+ const middleware_base = this.options.middleware_path || controller_base;
354
+ const middleware_full_path = path.resolve(process.cwd(), path.join(middleware_base, `${middlewarePath}`));
355
+
356
+ // 2. Dynamic Module Import
357
+ const middleware_module = (await import(middleware_full_path));
358
+ const middleware_function = middleware_module.default;
359
+
360
+ // 3. Function Validation & Execution
361
+ if (middleware_function && typeof middleware_function === "function") {
362
+ await new Promise<void>((resolve, reject) => {
363
+ middleware_function(req, res, (error?: any) => {
364
+ if (error) {
365
+ reject(error);
366
+ } else {
367
+ resolve();
368
+ }
369
+ });
370
+ });
371
+ }
372
+ } catch (error) {
373
+ // 4. Error Handling
374
+ console.error(`Middleware execution failed for ${middlewarePath}:`, error);
375
+ res.status(500).send({
376
+ error: true,
377
+ message: `Middleware execution failed: ${middlewarePath}`,
378
+ statusCode: 500,
379
+ });
380
+ return // Stops execution immediately
381
+ }
382
+ }
383
+ ```
384
+
385
+ ##### Step-by-Step Breakdown:
386
+
387
+ **1. Path Resolution**
388
+ - Constructs absolute path using `middleware_path` option or falls back to `controller_base`
389
+ - Uses `path.resolve(process.cwd(), path.join(base, middlewarePath))`
390
+ - Example: `middlewarePath: "user/auth"` → `/absolute/path/to/middleware/user/auth`
391
+
392
+ **2. Dynamic Module Import**
393
+ - Uses ES6 dynamic import: `await import(middleware_full_path)`
394
+ - Automatically resolves file extensions (`.js`, `.ts`, etc.)
395
+ - Extracts default export: `middleware_module.default`
396
+
397
+ **3. Function Validation & Execution**
398
+ - Validates middleware is a function before execution
399
+ - Wraps execution in Promise for async control flow
400
+ - Provides Express-style callback: `(error?: any) => void`
401
+ - Middleware must call callback to continue: `next()` or `next(error)`
402
+
403
+ **4. Error Handling**
404
+ - **Import Errors**: Module not found, syntax errors, etc.
405
+ - **Runtime Errors**: Middleware throws exception or calls `next(error)`
406
+ - **Response**: Sets 500 status with structured error message
407
+ - **Flow Control**: `return` statement halts entire request processing
408
+
409
+ ##### Execution Characteristics:
410
+
411
+ - **Sequential**: Middleware executes one at a time, not in parallel
412
+ - **Blocking**: Each middleware must complete before next one starts
413
+ - **Fail-Fast**: First error stops all subsequent middleware and controller execution
414
+ - **No Caching**: Modules are imported fresh on every request
415
+ - **Stateless**: No shared state between middleware executions
416
+
417
+ #### Error Response Format
418
+ ```json
419
+ {
420
+ "error": true,
421
+ "message": "Middleware execution failed: user/auth",
422
+ "statusCode": 500
423
+ }
424
+ ```
425
+
426
+ #### Extended Error Handling
427
+
428
+ **File Not Found Errors**
429
+ ```json
430
+ {
431
+ "error": true,
432
+ "message": "Middleware file not found: auth.ts",
433
+ "statusCode": 500
434
+ }
435
+ ```
436
+
437
+ **Function Not Found Errors**
438
+ ```json
439
+ {
440
+ "error": true,
441
+ "message": "Middleware function 'cookie' not found in auth.ts",
442
+ "statusCode": 500
443
+ }
444
+ ```
445
+
446
+ **Multiple Function Errors**
447
+ ```json
448
+ {
449
+ "error": true,
450
+ "message": "Middleware functions 'cookie,parsing' not found in auth.ts",
451
+ "statusCode": 500
452
+ }
453
+ ```
454
+
455
+ **Non-Function Export Errors**
456
+ ```json
457
+ {
458
+ "error": true,
459
+ "message": "Middleware export 'cookie' in auth.ts is not a function",
460
+ "statusCode": 500
461
+ }
462
+ ```
463
+
464
+ **Multiple Non-Function Errors**
465
+ ```json
466
+ {
467
+ "error": true,
468
+ "message": "Middleware exports 'cookie,config' in auth.ts are not functions",
469
+ "statusCode": 500
470
+ }
471
+ ```
472
+
473
+ **Default Export Missing**
474
+ ```json
475
+ {
476
+ "error": true,
477
+ "message": "Middleware file auth.ts has no default export",
478
+ "statusCode": 500
479
+ }
480
+ ```
481
+
482
+ **Default Export Not Function**
483
+ ```json
484
+ {
485
+ "error": true,
486
+ "message": "Middleware default export in auth.ts is not a function",
487
+ "statusCode": 500
488
+ }
489
+ ```
490
+
491
+ **Validation Rules**
492
+ - **File Resolution**: Must throw error if middleware file doesn't exist at resolved path
493
+ - **Function Resolution**: Must throw error if any specified function doesn't exist in module
494
+ - **Function Type Validation**: Must throw error if any resolved export is not a function
495
+ - **Default Export Validation**:
496
+ - `auth` pattern must fail if module has no default export or if default export is not a function
497
+ - `auth:default` pattern must fail if module has no default export or if default export is not a function
498
+ - **Wildcard Validation**: `auth:*` should only fail if file doesn't exist, not if no functions found
499
+
500
+ ### Current Limitations
501
+
502
+ - **Route-Specific Only**: No global middleware support
503
+ - **Basic Error Handling**: Generic 500 responses for all middleware failures
504
+ - **No Dependency Injection**: Middleware cannot access IoC container
505
+ - **Simple Path Resolution**: No middleware aliases or advanced routing
506
+ - **No Caching**: Middleware modules imported on every request
507
+ - **Limited Context**: No framework context or shared state between middleware