fragment-ts 1.0.33 → 1.0.35

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 (88) hide show
  1. package/API.md +248 -38
  2. package/DOCS.md +327 -63
  3. package/NewCLIGENERATECOMMANDS.txt +5 -0
  4. package/README.md +168 -3
  5. package/USAGE.md +395 -2
  6. package/dist/cli/commands/build.command.d.ts.map +1 -1
  7. package/dist/cli/commands/build.command.js +20 -8
  8. package/dist/cli/commands/build.command.js.map +1 -1
  9. package/dist/cli/commands/diagnostics.command.d.ts +1 -2
  10. package/dist/cli/commands/diagnostics.command.d.ts.map +1 -1
  11. package/dist/cli/commands/diagnostics.command.js +37 -23
  12. package/dist/cli/commands/diagnostics.command.js.map +1 -1
  13. package/dist/cli/commands/generate.command.d.ts +5 -1
  14. package/dist/cli/commands/generate.command.d.ts.map +1 -1
  15. package/dist/cli/commands/generate.command.js +171 -39
  16. package/dist/cli/commands/generate.command.js.map +1 -1
  17. package/dist/cli/commands/init.command.d.ts.map +1 -1
  18. package/dist/cli/commands/init.command.js +98 -28
  19. package/dist/cli/commands/init.command.js.map +1 -1
  20. package/dist/cli/commands/migrate.command.d.ts +10 -17
  21. package/dist/cli/commands/migrate.command.d.ts.map +1 -1
  22. package/dist/cli/commands/migrate.command.js +133 -170
  23. package/dist/cli/commands/migrate.command.js.map +1 -1
  24. package/dist/cli/commands/serve.command.d.ts.map +1 -1
  25. package/dist/cli/commands/serve.command.js +9 -4
  26. package/dist/cli/commands/serve.command.js.map +1 -1
  27. package/dist/cli/commands/test.command.d.ts.map +1 -1
  28. package/dist/cli/commands/test.command.js +24 -6
  29. package/dist/cli/commands/test.command.js.map +1 -1
  30. package/dist/core/decorators/exception-filter.decorator.d.ts.map +1 -1
  31. package/dist/core/decorators/exception-filter.decorator.js +11 -4
  32. package/dist/core/decorators/exception-filter.decorator.js.map +1 -1
  33. package/dist/core/decorators/guard.decorator.d.ts.map +1 -1
  34. package/dist/core/decorators/guard.decorator.js +11 -4
  35. package/dist/core/decorators/guard.decorator.js.map +1 -1
  36. package/dist/core/decorators/interceptor.decorator.d.ts.map +1 -1
  37. package/dist/core/decorators/interceptor.decorator.js +10 -4
  38. package/dist/core/decorators/interceptor.decorator.js.map +1 -1
  39. package/dist/core/decorators/middleware.decorator.d.ts.map +1 -1
  40. package/dist/core/decorators/middleware.decorator.js +8 -4
  41. package/dist/core/decorators/middleware.decorator.js.map +1 -1
  42. package/dist/core/scanner/component-scanner.d.ts +12 -0
  43. package/dist/core/scanner/component-scanner.d.ts.map +1 -1
  44. package/dist/core/scanner/component-scanner.js +72 -14
  45. package/dist/core/scanner/component-scanner.js.map +1 -1
  46. package/dist/shared/config.utils.d.ts +58 -0
  47. package/dist/shared/config.utils.d.ts.map +1 -0
  48. package/dist/shared/config.utils.js +137 -0
  49. package/dist/shared/config.utils.js.map +1 -0
  50. package/dist/shared/env.utils.d.ts +27 -0
  51. package/dist/shared/env.utils.d.ts.map +1 -0
  52. package/dist/shared/env.utils.js +68 -0
  53. package/dist/shared/env.utils.js.map +1 -0
  54. package/dist/shared/tsconfig.utils.d.ts +122 -0
  55. package/dist/shared/tsconfig.utils.d.ts.map +1 -0
  56. package/dist/shared/tsconfig.utils.js +305 -0
  57. package/dist/shared/tsconfig.utils.js.map +1 -0
  58. package/dist/testing/runner.d.ts +9 -1
  59. package/dist/testing/runner.d.ts.map +1 -1
  60. package/dist/testing/runner.js +50 -10
  61. package/dist/testing/runner.js.map +1 -1
  62. package/dist/typeorm/typeorm-module.d.ts +1 -0
  63. package/dist/typeorm/typeorm-module.d.ts.map +1 -1
  64. package/dist/typeorm/typeorm-module.js +193 -85
  65. package/dist/typeorm/typeorm-module.js.map +1 -1
  66. package/dist/web/application.d.ts +0 -1
  67. package/dist/web/application.d.ts.map +1 -1
  68. package/dist/web/application.js +4 -26
  69. package/dist/web/application.js.map +1 -1
  70. package/package.json +1 -1
  71. package/src/cli/commands/build.command.ts +24 -9
  72. package/src/cli/commands/diagnostics.command.ts +42 -30
  73. package/src/cli/commands/generate.command.ts +212 -52
  74. package/src/cli/commands/init.command.ts +100 -29
  75. package/src/cli/commands/migrate.command.ts +145 -198
  76. package/src/cli/commands/serve.command.ts +181 -170
  77. package/src/cli/commands/test.command.ts +25 -11
  78. package/src/core/decorators/exception-filter.decorator.ts +29 -6
  79. package/src/core/decorators/guard.decorator.ts +28 -5
  80. package/src/core/decorators/interceptor.decorator.ts +32 -6
  81. package/src/core/decorators/middleware.decorator.ts +30 -6
  82. package/src/core/scanner/component-scanner.ts +100 -18
  83. package/src/shared/config.utils.ts +148 -0
  84. package/src/shared/env.utils.ts +72 -0
  85. package/src/shared/tsconfig.utils.ts +360 -0
  86. package/src/testing/runner.ts +62 -14
  87. package/src/typeorm/typeorm-module.ts +209 -86
  88. package/src/web/application.ts +4 -33
package/DOCS.md CHANGED
@@ -1,3 +1,4 @@
1
+ ---
1
2
 
2
3
  # In-Depth Documentation
3
4
 
@@ -9,6 +10,7 @@ Fragment TS follows a component-based architecture with dependency injection at
9
10
  2. **Separation of Concerns**: Clear separation between controllers, services, and repositories
10
11
  3. **Convention over Configuration**: Automatic component scanning and registration
11
12
  4. **Type Safety**: Leveraging TypeScript's type system for compile-time validation
13
+ 5. **Enhancement Pipeline**: Modular request/response processing through middleware, guards, interceptors, and exception filters
12
14
 
13
15
  ![Architecture Diagram](https://example.com/fragment-architecture.png)
14
16
 
@@ -19,6 +21,7 @@ Fragment TS follows a component-based architecture with dependency injection at
19
21
  3. **Component Scanner**: Discovers and registers components automatically
20
22
  4. **Web Application**: Configures and starts the Express server
21
23
  5. **TypeORM Module**: Integrates TypeORM for database operations
24
+ 6. **Enhancement Pipeline**: Processes requests through middleware → guards → interceptors → handlers → exception filters
22
25
 
23
26
  ## Dependency Injection System
24
27
 
@@ -30,11 +33,13 @@ The dependency injection system in Fragment TS works through a combination of de
30
33
  - Class decorators (`@Service()`, `@Controller()`, etc.) register components with the metadata storage
31
34
  - Property decorators (`@Autowired()`, `@InjectRepository()`, etc.) store metadata about dependencies
32
35
  - Method and parameter decorators store route and handler information
36
+ - **Enhancement decorators** (`@FragmentMiddleware`, `@FragmentGuard`, etc.) store pipeline metadata
33
37
 
34
38
  2. **Component Registration**:
35
39
  - During application bootstrap, the component scanner loads all relevant files
36
40
  - The metadata storage is populated with component definitions
37
41
  - Components are registered with the DI container
42
+ - Enhancement components are resolved through the same DI container
38
43
 
39
44
  3. **Dependency Resolution**:
40
45
  - When a component is requested, the container creates an instance
@@ -51,13 +56,13 @@ Fragment TS supports three scopes for components:
51
56
  3. **Transient**: New instance every time it's requested
52
57
 
53
58
  ```typescript
54
- @Injectable('singleton')
59
+ @Injectable("singleton")
55
60
  class DatabaseConnection {}
56
61
 
57
- @Injectable('request')
62
+ @Injectable("request")
58
63
  class RequestContext {}
59
64
 
60
- @Injectable('transient')
65
+ @Injectable("transient")
61
66
  class RandomGenerator {}
62
67
  ```
63
68
 
@@ -94,17 +99,17 @@ Fragment TS components follow a well-defined lifecycle:
94
99
  @Service()
95
100
  class LifecycleService {
96
101
  constructor() {
97
- console.log('Constructor called');
102
+ console.log("Constructor called");
98
103
  }
99
-
104
+
100
105
  @PostConstruct()
101
106
  init() {
102
- console.log('Post-construct called - dependencies are available');
107
+ console.log("Post-construct called - dependencies are available");
103
108
  }
104
-
109
+
105
110
  @PreDestroy()
106
111
  cleanup() {
107
- console.log('Pre-destroy called - cleanup resources');
112
+ console.log("Pre-destroy called - cleanup resources");
108
113
  }
109
114
  }
110
115
  ```
@@ -113,20 +118,171 @@ class LifecycleService {
113
118
 
114
119
  ### Request Processing Pipeline
115
120
 
121
+ Fragment TS implements a sophisticated request processing pipeline that executes enhancements in a specific order:
122
+
116
123
  1. **Route Registration**:
117
124
  - Controllers and routes are registered during application bootstrap
118
125
  - Route metadata is stored in the metadata storage
126
+ - Enhancement metadata (middleware, guards, interceptors, filters) is collected
127
+
128
+ 2. **Request Handling Pipeline**:
129
+ - **Express Middleware**: Standard Express middleware runs first
130
+ - **Fragment Middleware**: `@FragmentMiddleware` components execute (class-level then method-level)
131
+ - **Guards**: `@FragmentGuard` components validate access (class-level then method-level)
132
+ - **Parameter Resolution**: Route parameters are resolved and injected
133
+ - **Handler Execution**: Controller method is invoked
134
+ - **Interceptors**: `@FragmentInterceptor` components transform the result (class-level then method-level)
135
+ - **Response**: Final result is sent as JSON
136
+
137
+ 3. **Error Handling Pipeline**:
138
+ - If any step throws an error, **Exception Filters** are executed
139
+ - `@FragmentExceptionFilter` components handle errors (method-level then class-level)
140
+ - If no filter handles the error, it falls back to Express error handling
141
+
142
+ ### Enhancement Decorators
143
+
144
+ #### Middleware (`@FragmentMiddleware`)
145
+
146
+ Middleware components implement the `Middleware` interface and can modify the request/response cycle or terminate it early.
147
+
148
+ ```typescript
149
+ // Middleware interface
150
+ interface Middleware {
151
+ use(req: Request, res: Response, next: NextFunction): void | Promise<void>;
152
+ }
153
+
154
+ // Implementation
155
+ @Injectable()
156
+ class LoggingMiddleware implements Middleware {
157
+ use(req: Request, res: Response, next: NextFunction): void {
158
+ console.log(`📥 ${req.method} ${req.path}`);
159
+ next();
160
+ }
161
+ }
162
+
163
+ // Usage
164
+ @FragmentMiddleware(LoggingMiddleware)
165
+ @Controller("/api")
166
+ class ApiController {}
167
+ ```
168
+
169
+ #### Guards (`@FragmentGuard`)
170
+
171
+ Guard components implement the `Guard` interface and control whether a route handler should be executed.
119
172
 
120
- 2. **Request Handling**:
121
- - Express middleware processes the incoming request
122
- - Route handler is matched based on path and HTTP method
123
- - Controller instance is retrieved from the container
124
- - Route parameters are resolved and injected
125
- - Handler method is invoked
173
+ ```typescript
174
+ // Guard interface
175
+ interface Guard {
176
+ canActivate(req: Request): boolean | Promise<boolean>;
177
+ }
126
178
 
127
- 3. **Response Processing**:
128
- - Return value is automatically converted to JSON
129
- - Error handling middleware processes any exceptions
179
+ // Implementation
180
+ @Injectable()
181
+ class AuthGuard implements Guard {
182
+ canActivate(req: Request): boolean {
183
+ const token = req.headers.authorization;
184
+ return token === "Bearer valid-token";
185
+ }
186
+ }
187
+
188
+ // Usage
189
+ @FragmentGuard(AuthGuard)
190
+ @Controller("/secure")
191
+ class SecureController {}
192
+ ```
193
+
194
+ #### Interceptors (`@FragmentInterceptor`)
195
+
196
+ Interceptor components implement the `Interceptor` interface and can transform the handler's result before it's sent to the client.
197
+
198
+ ```typescript
199
+ // Interceptor interface
200
+ interface Interceptor {
201
+ intercept(req: Request, res: Response, result: any): any | Promise<any>;
202
+ }
203
+
204
+ // Implementation
205
+ @Injectable()
206
+ class TransformInterceptor implements Interceptor {
207
+ intercept(req: Request, res: Response, result: any): any {
208
+ return {
209
+ success: true,
210
+ data: result,
211
+ timestamp: new Date().toISOString(),
212
+ };
213
+ }
214
+ }
215
+
216
+ // Usage
217
+ @FragmentInterceptor(TransformInterceptor)
218
+ @Controller("/api")
219
+ class DataController {}
220
+ ```
221
+
222
+ #### Exception Filters (`@FragmentExceptionFilter`)
223
+
224
+ Exception filter components implement the `ExceptionFilter` interface and handle errors thrown during request processing.
225
+
226
+ ```typescript
227
+ // ExceptionFilter interface
228
+ interface ExceptionFilter {
229
+ catch(exception: Error, req: Request, res: Response): void;
230
+ }
231
+
232
+ // Implementation
233
+ @Injectable()
234
+ class HttpExceptionFilter implements ExceptionFilter {
235
+ catch(exception: Error, req: Request, res: Response): void {
236
+ if (exception.name === "ValidationError") {
237
+ res
238
+ .status(400)
239
+ .json({ error: "Validation failed", message: exception.message });
240
+ } else if (exception.name === "NotFoundError") {
241
+ res.status(404).json({ error: "Not found", message: exception.message });
242
+ } else {
243
+ res.status(500).json({ error: "Internal server error" });
244
+ }
245
+ }
246
+ }
247
+
248
+ // Usage
249
+ @FragmentExceptionFilter(HttpExceptionFilter)
250
+ @FragmentApplication()
251
+ class Application {}
252
+ ```
253
+
254
+ ### Enhancement Composition
255
+
256
+ All enhancement decorators can be combined and applied at both class and method levels:
257
+
258
+ ```typescript
259
+ @FragmentMiddleware(LoggingMiddleware)
260
+ @FragmentGuard(AuthGuard)
261
+ @FragmentInterceptor(TransformInterceptor)
262
+ @FragmentExceptionFilter(HttpExceptionFilter)
263
+ @Controller("/api")
264
+ class ComplexController {
265
+ @Get("/public")
266
+ @FragmentGuard(PublicGuard) // Overrides class-level guard for this method
267
+ publicData() {
268
+ return { message: "Public data" };
269
+ }
270
+
271
+ @Post("/admin")
272
+ @FragmentGuard(AdminGuard) // Additional guard
273
+ @FragmentInterceptor(CacheInterceptor) // Additional interceptor
274
+ createAdminData(@Body() data: any) {
275
+ return { created: true, data };
276
+ }
277
+ }
278
+ ```
279
+
280
+ The execution order is:
281
+
282
+ 1. **Middleware**: Class → Method
283
+ 2. **Guards**: Class → Method (all must pass)
284
+ 3. **Interceptors**: Class → Method (applied in reverse order on result)
285
+ 4. **Exception Filters**: Method → Class (first one to handle stops propagation)
130
286
 
131
287
  ### Middleware Integration
132
288
 
@@ -136,8 +292,8 @@ Fragment TS integrates with Express middleware through the underlying Express ap
136
292
  const app = new FragmentWebApplication();
137
293
  const expressApp = app.getExpressApp();
138
294
 
139
- // Add custom middleware
140
- expressApp.use('/api', apiMiddleware);
295
+ // Add custom Express middleware
296
+ expressApp.use("/api", apiMiddleware);
141
297
  expressApp.use(errorHandler);
142
298
  ```
143
299
 
@@ -171,10 +327,10 @@ Fragment TS encourages the repository pattern for data access:
171
327
  export class User {
172
328
  @PrimaryGeneratedColumn()
173
329
  id: number;
174
-
330
+
175
331
  @Column()
176
332
  name: string;
177
-
333
+
178
334
  @Column()
179
335
  email: string;
180
336
  }
@@ -191,15 +347,15 @@ export interface UserRepository {
191
347
  export class TypeOrmUserRepository implements UserRepository {
192
348
  @InjectRepository(User)
193
349
  private repo!: Repository<User>;
194
-
350
+
195
351
  async findAll(): Promise<User[]> {
196
352
  return this.repo.find();
197
353
  }
198
-
354
+
199
355
  async findById(id: number): Promise<User | null> {
200
356
  return this.repo.findOneBy({ id });
201
357
  }
202
-
358
+
203
359
  async save(user: User): Promise<User> {
204
360
  return this.repo.save(user);
205
361
  }
@@ -225,7 +381,7 @@ class DefaultLoggerService implements LoggerService {}
225
381
 
226
382
  // Only register if environment variable is set
227
383
  @Service()
228
- @ConditionalOnProperty('ENABLE_CACHE', 'true')
384
+ @ConditionalOnProperty("ENABLE_CACHE", "true")
229
385
  class CacheService {}
230
386
  ```
231
387
 
@@ -236,13 +392,13 @@ Application configuration can be injected from environment variables or config f
236
392
  ```typescript
237
393
  @Service()
238
394
  class AppConfig {
239
- @Value('${PORT:3000}')
395
+ @Value("${PORT:3000}")
240
396
  port!: number;
241
-
242
- @Value('${DATABASE_URL}')
397
+
398
+ @Value("${DATABASE_URL}")
243
399
  databaseUrl!: string;
244
-
245
- @Value('${FEATURE_FLAG_NEW_UI:false}')
400
+
401
+ @Value("${FEATURE_FLAG_NEW_UI:false}")
246
402
  featureFlagNewUi!: boolean;
247
403
  }
248
404
  ```
@@ -253,32 +409,51 @@ Fragment TS is designed for testability with minimal dependencies on framework i
253
409
 
254
410
  ```typescript
255
411
  // Unit test example
256
- describe('UserService', () => {
412
+ describe("UserService", () => {
257
413
  let userService: UserService;
258
414
  let mockUserRepository: jest.Mocked<UserRepository>;
259
-
415
+
260
416
  beforeEach(() => {
261
417
  mockUserRepository = {
262
418
  findAll: jest.fn(),
263
- findById: jest.fn()
419
+ findById: jest.fn(),
264
420
  } as any;
265
-
421
+
266
422
  userService = new UserService();
267
- Object.defineProperty(userService, 'userRepository', {
268
- value: mockUserRepository
423
+ Object.defineProperty(userService, "userRepository", {
424
+ value: mockUserRepository,
269
425
  });
270
426
  });
271
-
272
- it('should return all users', async () => {
273
- const mockUsers = [{ id: 1, name: 'John' }];
427
+
428
+ it("should return all users", async () => {
429
+ const mockUsers = [{ id: 1, name: "John" }];
274
430
  mockUserRepository.findAll.mockResolvedValue(mockUsers);
275
-
431
+
276
432
  const result = await userService.findAll();
277
-
433
+
278
434
  expect(result).toEqual(mockUsers);
279
435
  expect(mockUserRepository.findAll).toHaveBeenCalled();
280
436
  });
281
437
  });
438
+
439
+ // Testing guards
440
+ describe("AuthGuard", () => {
441
+ let guard: AuthGuard;
442
+
443
+ beforeEach(() => {
444
+ guard = new AuthGuard();
445
+ });
446
+
447
+ it("should allow valid tokens", () => {
448
+ const mockReq = { headers: { authorization: "Bearer valid-token" } } as any;
449
+ expect(guard.canActivate(mockReq)).toBe(true);
450
+ });
451
+
452
+ it("should reject invalid tokens", () => {
453
+ const mockReq = { headers: { authorization: "Bearer invalid" } } as any;
454
+ expect(guard.canActivate(mockReq)).toBe(false);
455
+ });
456
+ });
282
457
  ```
283
458
 
284
459
  ## Performance Considerations
@@ -297,9 +472,17 @@ Component scanning and dependency resolution happen during application startup.
297
472
  - Request-scoped components are created per request and should be lightweight
298
473
  - Transient components are created on-demand and not cached
299
474
 
475
+ ### Enhancement Performance
476
+
477
+ - **Middleware**: Should be fast and non-blocking; avoid heavy async operations
478
+ - **Guards**: Should be lightweight validation; avoid database calls when possible
479
+ - **Interceptors**: Can be more expensive since they run after handler execution
480
+ - **Exception Filters**: Should handle errors quickly without additional async operations
481
+
300
482
  ### Optimization Techniques
301
483
 
302
484
  1. **Lazy Loading**:
485
+
303
486
  ```typescript
304
487
  @Service()
305
488
  class HeavyService {
@@ -310,9 +493,10 @@ class HeavyService {
310
493
  ```
311
494
 
312
495
  2. **Selective Component Scanning**:
496
+
313
497
  ```typescript
314
498
  @FragmentApplication({
315
- autoScan: false // Disable automatic scanning
499
+ autoScan: false, // Disable automatic scanning
316
500
  })
317
501
  class Application {}
318
502
 
@@ -323,6 +507,7 @@ container.register(UserController);
323
507
  ```
324
508
 
325
509
  3. **Production Build**:
510
+
326
511
  - Always use compiled JavaScript in production
327
512
  - Enable tree-shaking and minification
328
513
  - Use environment variables for configuration instead of config files when possible
@@ -341,13 +526,16 @@ class CustomErrorHandler {
341
526
  @PostConstruct()
342
527
  register() {
343
528
  const expressApp = app.getExpressApp();
344
- expressApp.use((err: Error, req: Request, res: Response, next: NextFunction) => {
345
- console.error('Global error:', err);
346
- res.status(500).json({
347
- error: 'Internal Server Error',
348
- message: process.env.NODE_ENV === 'development' ? err.message : undefined
349
- });
350
- });
529
+ expressApp.use(
530
+ (err: Error, req: Request, res: Response, next: NextFunction) => {
531
+ console.error("Global error:", err);
532
+ res.status(500).json({
533
+ error: "Internal Server Error",
534
+ message:
535
+ process.env.NODE_ENV === "development" ? err.message : undefined,
536
+ });
537
+ },
538
+ );
351
539
  }
352
540
  }
353
541
  ```
@@ -360,18 +548,29 @@ Define custom error types for better error handling:
360
548
  export class NotFoundError extends Error {
361
549
  constructor(message: string) {
362
550
  super(message);
363
- this.name = 'NotFoundError';
551
+ this.name = "NotFoundError";
364
552
  }
365
553
  }
366
554
 
367
555
  export class ValidationError extends Error {
368
556
  constructor(public errors: any[]) {
369
- super('Validation failed');
370
- this.name = 'ValidationError';
557
+ super("Validation failed");
558
+ this.name = "ValidationError";
371
559
  }
372
560
  }
373
561
  ```
374
562
 
563
+ ### Exception Filter Hierarchy
564
+
565
+ Exception filters follow a specific hierarchy for error handling:
566
+
567
+ 1. **Method-level filters** are checked first
568
+ 2. **Controller-level filters** are checked next
569
+ 3. **Application-level filters** (on `@FragmentApplication` class) are checked last
570
+ 4. **Global Express error handler** is the final fallback
571
+
572
+ This allows for fine-grained error handling at different levels of your application.
573
+
375
574
  ## Extensibility
376
575
 
377
576
  ### Custom Decorators
@@ -380,7 +579,11 @@ Create custom decorators by leveraging the metadata storage:
380
579
 
381
580
  ```typescript
382
581
  function CustomDecorator(metadata: any): MethodDecorator {
383
- return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
582
+ return (
583
+ target: any,
584
+ propertyKey: string | symbol,
585
+ descriptor: PropertyDescriptor,
586
+ ) => {
384
587
  const storage = MetadataStorage.getInstance();
385
588
  storage.addCustomMetadata(target.constructor, propertyKey, metadata);
386
589
  };
@@ -388,11 +591,19 @@ function CustomDecorator(metadata: any): MethodDecorator {
388
591
 
389
592
  // Usage
390
593
  class MyController {
391
- @CustomDecorator({ role: 'admin' })
594
+ @CustomDecorator({ role: "admin" })
392
595
  adminMethod() {}
393
596
  }
394
597
  ```
395
598
 
599
+ ### Custom Enhancement Types
600
+
601
+ You can extend the enhancement pipeline with custom types by:
602
+
603
+ 1. Adding new metadata keys to `METADATA_KEYS`
604
+ 2. Creating new decorators that store metadata
605
+ 3. Updating the route registration logic to process your custom enhancements
606
+
396
607
  ### Custom Modules
397
608
 
398
609
  Extend the framework with custom modules:
@@ -401,9 +612,9 @@ Extend the framework with custom modules:
401
612
  class CustomModule {
402
613
  static async initialize() {
403
614
  // Custom initialization logic
404
- console.log('Custom module initialized');
615
+ console.log("Custom module initialized");
405
616
  }
406
-
617
+
407
618
  static getDependency() {
408
619
  // Return dependency for injection
409
620
  return new CustomDependency();
@@ -426,10 +637,19 @@ class Application {
426
637
  1. **Single Responsibility**: Each component should have one clear responsibility
427
638
  2. **Loose Coupling**: Depend on abstractions (interfaces) rather than concrete implementations
428
639
  3. **High Cohesion**: Related functionality should be grouped together
640
+ 4. **Enhancement Separation**: Keep middleware, guards, interceptors, and filters focused on their specific concerns
641
+
642
+ ### Enhancement Patterns
643
+
644
+ 1. **Middleware**: Use for cross-cutting concerns like logging, authentication headers, request ID generation
645
+ 2. **Guards**: Use for authorization, rate limiting, feature flags
646
+ 3. **Interceptors**: Use for response transformation, caching, metrics collection
647
+ 4. **Exception Filters**: Use for standardized error responses, logging, alerting
429
648
 
430
649
  ### Code Organization
431
650
 
432
651
  1. **Feature-based Structure**:
652
+
433
653
  ```
434
654
  src/
435
655
  ├── features/
@@ -442,16 +662,26 @@ src/
442
662
  │ └── product/
443
663
  │ ├── product.controller.ts
444
664
  │ └── ...
665
+ ├── enhancements/
666
+ │ ├── middleware/
667
+ │ ├── guards/
668
+ │ ├── interceptors/
669
+ │ └── filters/
445
670
  ```
446
671
 
447
672
  2. **Layer-based Structure**:
673
+
448
674
  ```
449
675
  src/
450
676
  ├── controllers/
451
677
  ├── services/
452
678
  ├── repositories/
453
679
  ├── entities/
454
- └── dtos/
680
+ ├── dtos/
681
+ ├── middleware/
682
+ ├── guards/
683
+ ├── interceptors/
684
+ └── filters/
455
685
  ```
456
686
 
457
687
  ### Testing Strategy
@@ -459,26 +689,29 @@ src/
459
689
  1. **Unit Tests**: Test individual components in isolation
460
690
  2. **Integration Tests**: Test component interactions
461
691
  3. **End-to-End Tests**: Test full request/response cycle
692
+ 4. **Enhancement Tests**: Specifically test middleware, guards, interceptors, and filters in isolation
462
693
 
463
694
  ## Migration Guide
464
695
 
465
696
  ### From Express
466
697
 
467
698
  1. Create a Fragment application class:
699
+
468
700
  ```typescript
469
701
  @FragmentApplication()
470
702
  class Application {}
471
703
  ```
472
704
 
473
705
  2. Convert Express routes to controllers:
706
+
474
707
  ```typescript
475
708
  // Before (Express)
476
- app.get('/users', (req, res) => {
709
+ app.get("/users", (req, res) => {
477
710
  // handler
478
711
  });
479
712
 
480
713
  // After (Fragment)
481
- @Controller('/users')
714
+ @Controller("/users")
482
715
  class UserController {
483
716
  @Get()
484
717
  findAll() {
@@ -488,9 +721,10 @@ class UserController {
488
721
  ```
489
722
 
490
723
  3. Extract business logic to services:
724
+
491
725
  ```typescript
492
726
  // Before
493
- app.post('/users', async (req, res) => {
727
+ app.post("/users", async (req, res) => {
494
728
  const user = await db.users.create(req.body);
495
729
  res.json(user);
496
730
  });
@@ -500,17 +734,17 @@ app.post('/users', async (req, res) => {
500
734
  class UserService {
501
735
  @Autowired()
502
736
  private userRepository!: UserRepository;
503
-
737
+
504
738
  async create(userData: any) {
505
739
  return this.userRepository.save(userData);
506
740
  }
507
741
  }
508
742
 
509
- @Controller('/users')
743
+ @Controller("/users")
510
744
  class UserController {
511
745
  @Autowired()
512
746
  private userService!: UserService;
513
-
747
+
514
748
  @Post()
515
749
  async create(@Body() userData: any) {
516
750
  return this.userService.create(userData);
@@ -518,6 +752,31 @@ class UserController {
518
752
  }
519
753
  ```
520
754
 
755
+ 4. Convert Express middleware to Fragment middleware:
756
+
757
+ ```typescript
758
+ // Before
759
+ app.use("/api", (req, res, next) => {
760
+ console.log("API request");
761
+ next();
762
+ });
763
+
764
+ // After
765
+ @Injectable()
766
+ class ApiLoggingMiddleware implements Middleware {
767
+ use(req: Request, res: Response, next: NextFunction) {
768
+ if (req.path.startsWith("/api")) {
769
+ console.log("API request");
770
+ }
771
+ next();
772
+ }
773
+ }
774
+
775
+ @FragmentMiddleware(ApiLoggingMiddleware)
776
+ @Controller("/api")
777
+ class ApiController {}
778
+ ```
779
+
521
780
  ### From NestJS
522
781
 
523
782
  Fragment TS shares many concepts with NestJS:
@@ -525,11 +784,14 @@ Fragment TS shares many concepts with NestJS:
525
784
  1. **Dependency Injection**: Similar `@Injectable()`, `@Autowired()` patterns
526
785
  2. **Controllers and Services**: Nearly identical structure
527
786
  3. **TypeORM Integration**: Similar repository patterns
787
+ 4. **Enhancement Pipeline**: Similar to NestJS interceptors, guards, and filters
528
788
 
529
789
  Key differences:
790
+
530
791
  - Fragment TS uses property injection by default instead of constructor injection
531
792
  - Simpler configuration with less boilerplate
532
793
  - More lightweight with fewer dependencies
794
+ - Enhancement decorators work at both class and method levels with intuitive composition
533
795
 
534
796
  ## Roadmap
535
797
 
@@ -540,6 +802,8 @@ Key differences:
540
802
  3. **Swagger Integration**: Automatic API documentation
541
803
  4. **WebSockets Support**: Real-time communication capabilities
542
804
  5. **CLI Tooling**: Project generation and management commands
805
+ 6. **Async Local Storage**: Better request context propagation
806
+ 7. **Performance Monitoring**: Built-in metrics and tracing
543
807
 
544
808
  ### Community Contributions
545
809
 
@@ -0,0 +1,5 @@
1
+ # Generate enhancement components
2
+ fragment generate middleware logging
3
+ fragment generate guard auth
4
+ fragment generate interceptor transform
5
+ fragment generate filter http-exception