@hazeljs/core 0.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +522 -0
  2. package/dist/__tests__/container.test.d.ts +2 -0
  3. package/dist/__tests__/container.test.d.ts.map +1 -0
  4. package/dist/__tests__/container.test.js +454 -0
  5. package/dist/__tests__/decorators.test.d.ts +2 -0
  6. package/dist/__tests__/decorators.test.d.ts.map +1 -0
  7. package/dist/__tests__/decorators.test.js +693 -0
  8. package/dist/__tests__/errors/http.error.test.d.ts +2 -0
  9. package/dist/__tests__/errors/http.error.test.d.ts.map +1 -0
  10. package/dist/__tests__/errors/http.error.test.js +117 -0
  11. package/dist/__tests__/filters/exception-filter.test.d.ts +2 -0
  12. package/dist/__tests__/filters/exception-filter.test.d.ts.map +1 -0
  13. package/dist/__tests__/filters/exception-filter.test.js +135 -0
  14. package/dist/__tests__/filters/http-exception.filter.test.d.ts +2 -0
  15. package/dist/__tests__/filters/http-exception.filter.test.d.ts.map +1 -0
  16. package/dist/__tests__/filters/http-exception.filter.test.js +119 -0
  17. package/dist/__tests__/hazel-app.test.d.ts +2 -0
  18. package/dist/__tests__/hazel-app.test.d.ts.map +1 -0
  19. package/dist/__tests__/hazel-app.test.js +682 -0
  20. package/dist/__tests__/hazel-module.test.d.ts +2 -0
  21. package/dist/__tests__/hazel-module.test.d.ts.map +1 -0
  22. package/dist/__tests__/hazel-module.test.js +408 -0
  23. package/dist/__tests__/hazel-response.test.d.ts +2 -0
  24. package/dist/__tests__/hazel-response.test.d.ts.map +1 -0
  25. package/dist/__tests__/hazel-response.test.js +138 -0
  26. package/dist/__tests__/health.test.d.ts +2 -0
  27. package/dist/__tests__/health.test.d.ts.map +1 -0
  28. package/dist/__tests__/health.test.js +147 -0
  29. package/dist/__tests__/index.test.d.ts +2 -0
  30. package/dist/__tests__/index.test.d.ts.map +1 -0
  31. package/dist/__tests__/index.test.js +239 -0
  32. package/dist/__tests__/interceptors/interceptor.test.d.ts +2 -0
  33. package/dist/__tests__/interceptors/interceptor.test.d.ts.map +1 -0
  34. package/dist/__tests__/interceptors/interceptor.test.js +166 -0
  35. package/dist/__tests__/logger.test.d.ts +2 -0
  36. package/dist/__tests__/logger.test.d.ts.map +1 -0
  37. package/dist/__tests__/logger.test.js +141 -0
  38. package/dist/__tests__/middleware/cors.test.d.ts +2 -0
  39. package/dist/__tests__/middleware/cors.test.d.ts.map +1 -0
  40. package/dist/__tests__/middleware/cors.test.js +129 -0
  41. package/dist/__tests__/middleware/csrf.test.d.ts +2 -0
  42. package/dist/__tests__/middleware/csrf.test.d.ts.map +1 -0
  43. package/dist/__tests__/middleware/csrf.test.js +247 -0
  44. package/dist/__tests__/middleware/global-middleware.test.d.ts +2 -0
  45. package/dist/__tests__/middleware/global-middleware.test.d.ts.map +1 -0
  46. package/dist/__tests__/middleware/global-middleware.test.js +259 -0
  47. package/dist/__tests__/middleware/rate-limit.test.d.ts +2 -0
  48. package/dist/__tests__/middleware/rate-limit.test.d.ts.map +1 -0
  49. package/dist/__tests__/middleware/rate-limit.test.js +264 -0
  50. package/dist/__tests__/middleware/security-headers.test.d.ts +2 -0
  51. package/dist/__tests__/middleware/security-headers.test.d.ts.map +1 -0
  52. package/dist/__tests__/middleware/security-headers.test.js +229 -0
  53. package/dist/__tests__/middleware/timeout.test.d.ts +2 -0
  54. package/dist/__tests__/middleware/timeout.test.d.ts.map +1 -0
  55. package/dist/__tests__/middleware/timeout.test.js +132 -0
  56. package/dist/__tests__/middleware.test.d.ts +2 -0
  57. package/dist/__tests__/middleware.test.d.ts.map +1 -0
  58. package/dist/__tests__/middleware.test.js +180 -0
  59. package/dist/__tests__/pipes/pipe.test.d.ts +2 -0
  60. package/dist/__tests__/pipes/pipe.test.d.ts.map +1 -0
  61. package/dist/__tests__/pipes/pipe.test.js +245 -0
  62. package/dist/__tests__/pipes/validation.pipe.test.d.ts +2 -0
  63. package/dist/__tests__/pipes/validation.pipe.test.d.ts.map +1 -0
  64. package/dist/__tests__/pipes/validation.pipe.test.js +297 -0
  65. package/dist/__tests__/request-parser.test.d.ts +2 -0
  66. package/dist/__tests__/request-parser.test.d.ts.map +1 -0
  67. package/dist/__tests__/request-parser.test.js +182 -0
  68. package/dist/__tests__/router.test.d.ts +2 -0
  69. package/dist/__tests__/router.test.d.ts.map +1 -0
  70. package/dist/__tests__/router.test.js +680 -0
  71. package/dist/__tests__/routing/route-matcher.test.d.ts +2 -0
  72. package/dist/__tests__/routing/route-matcher.test.d.ts.map +1 -0
  73. package/dist/__tests__/routing/route-matcher.test.js +219 -0
  74. package/dist/__tests__/routing/version.decorator.test.d.ts +2 -0
  75. package/dist/__tests__/routing/version.decorator.test.d.ts.map +1 -0
  76. package/dist/__tests__/routing/version.decorator.test.js +298 -0
  77. package/dist/__tests__/service.test.d.ts +2 -0
  78. package/dist/__tests__/service.test.d.ts.map +1 -0
  79. package/dist/__tests__/service.test.js +121 -0
  80. package/dist/__tests__/shutdown.test.d.ts +2 -0
  81. package/dist/__tests__/shutdown.test.d.ts.map +1 -0
  82. package/dist/__tests__/shutdown.test.js +250 -0
  83. package/dist/__tests__/testing/testing.module.test.d.ts +2 -0
  84. package/dist/__tests__/testing/testing.module.test.d.ts.map +1 -0
  85. package/dist/__tests__/testing/testing.module.test.js +370 -0
  86. package/dist/__tests__/upload/file-upload.test.d.ts +2 -0
  87. package/dist/__tests__/upload/file-upload.test.d.ts.map +1 -0
  88. package/dist/__tests__/upload/file-upload.test.js +498 -0
  89. package/dist/__tests__/utils/sanitize.test.d.ts +2 -0
  90. package/dist/__tests__/utils/sanitize.test.d.ts.map +1 -0
  91. package/dist/__tests__/utils/sanitize.test.js +291 -0
  92. package/dist/__tests__/validator.test.d.ts +2 -0
  93. package/dist/__tests__/validator.test.d.ts.map +1 -0
  94. package/dist/__tests__/validator.test.js +300 -0
  95. package/dist/container.d.ts +80 -0
  96. package/dist/container.d.ts.map +1 -0
  97. package/dist/container.js +271 -0
  98. package/dist/decorators.d.ts +92 -0
  99. package/dist/decorators.d.ts.map +1 -0
  100. package/dist/decorators.js +343 -0
  101. package/dist/errors/http.error.d.ts +31 -0
  102. package/dist/errors/http.error.d.ts.map +1 -0
  103. package/dist/errors/http.error.js +62 -0
  104. package/dist/filters/exception-filter.d.ts +39 -0
  105. package/dist/filters/exception-filter.d.ts.map +1 -0
  106. package/dist/filters/exception-filter.js +38 -0
  107. package/dist/filters/http-exception.filter.d.ts +9 -0
  108. package/dist/filters/http-exception.filter.d.ts.map +1 -0
  109. package/dist/filters/http-exception.filter.js +42 -0
  110. package/dist/hazel-app.d.ts +78 -0
  111. package/dist/hazel-app.d.ts.map +1 -0
  112. package/dist/hazel-app.js +453 -0
  113. package/dist/hazel-module.d.ts +20 -0
  114. package/dist/hazel-module.d.ts.map +1 -0
  115. package/dist/hazel-module.js +109 -0
  116. package/dist/hazel-response.d.ts +20 -0
  117. package/dist/hazel-response.d.ts.map +1 -0
  118. package/dist/hazel-response.js +68 -0
  119. package/dist/health.d.ts +73 -0
  120. package/dist/health.d.ts.map +1 -0
  121. package/dist/health.js +174 -0
  122. package/dist/index.d.ts +41 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +140 -0
  125. package/dist/interceptors/interceptor.d.ts +22 -0
  126. package/dist/interceptors/interceptor.d.ts.map +1 -0
  127. package/dist/interceptors/interceptor.js +46 -0
  128. package/dist/logger.d.ts +8 -0
  129. package/dist/logger.d.ts.map +1 -0
  130. package/dist/logger.js +238 -0
  131. package/dist/middleware/cors.middleware.d.ts +44 -0
  132. package/dist/middleware/cors.middleware.d.ts.map +1 -0
  133. package/dist/middleware/cors.middleware.js +118 -0
  134. package/dist/middleware/csrf.middleware.d.ts +82 -0
  135. package/dist/middleware/csrf.middleware.d.ts.map +1 -0
  136. package/dist/middleware/csrf.middleware.js +183 -0
  137. package/dist/middleware/global-middleware.d.ts +111 -0
  138. package/dist/middleware/global-middleware.d.ts.map +1 -0
  139. package/dist/middleware/global-middleware.js +179 -0
  140. package/dist/middleware/rate-limit.middleware.d.ts +73 -0
  141. package/dist/middleware/rate-limit.middleware.d.ts.map +1 -0
  142. package/dist/middleware/rate-limit.middleware.js +124 -0
  143. package/dist/middleware/security-headers.middleware.d.ts +76 -0
  144. package/dist/middleware/security-headers.middleware.d.ts.map +1 -0
  145. package/dist/middleware/security-headers.middleware.js +123 -0
  146. package/dist/middleware/timeout.middleware.d.ts +25 -0
  147. package/dist/middleware/timeout.middleware.d.ts.map +1 -0
  148. package/dist/middleware/timeout.middleware.js +74 -0
  149. package/dist/middleware.d.ts +13 -0
  150. package/dist/middleware.d.ts.map +1 -0
  151. package/dist/middleware.js +47 -0
  152. package/dist/pipes/pipe.d.ts +50 -0
  153. package/dist/pipes/pipe.d.ts.map +1 -0
  154. package/dist/pipes/pipe.js +96 -0
  155. package/dist/pipes/validation.pipe.d.ts +6 -0
  156. package/dist/pipes/validation.pipe.d.ts.map +1 -0
  157. package/dist/pipes/validation.pipe.js +61 -0
  158. package/dist/request-context.d.ts +17 -0
  159. package/dist/request-context.d.ts.map +1 -0
  160. package/dist/request-context.js +2 -0
  161. package/dist/request-parser.d.ts +7 -0
  162. package/dist/request-parser.d.ts.map +1 -0
  163. package/dist/request-parser.js +60 -0
  164. package/dist/router.d.ts +33 -0
  165. package/dist/router.d.ts.map +1 -0
  166. package/dist/router.js +426 -0
  167. package/dist/routing/route-matcher.d.ts +39 -0
  168. package/dist/routing/route-matcher.d.ts.map +1 -0
  169. package/dist/routing/route-matcher.js +93 -0
  170. package/dist/routing/version.decorator.d.ts +36 -0
  171. package/dist/routing/version.decorator.d.ts.map +1 -0
  172. package/dist/routing/version.decorator.js +89 -0
  173. package/dist/service.d.ts +9 -0
  174. package/dist/service.d.ts.map +1 -0
  175. package/dist/service.js +39 -0
  176. package/dist/shutdown.d.ts +32 -0
  177. package/dist/shutdown.d.ts.map +1 -0
  178. package/dist/shutdown.js +109 -0
  179. package/dist/testing/testing.module.d.ts +83 -0
  180. package/dist/testing/testing.module.d.ts.map +1 -0
  181. package/dist/testing/testing.module.js +164 -0
  182. package/dist/types.d.ts +76 -0
  183. package/dist/types.d.ts.map +1 -0
  184. package/dist/types.js +2 -0
  185. package/dist/upload/file-upload.d.ts +75 -0
  186. package/dist/upload/file-upload.d.ts.map +1 -0
  187. package/dist/upload/file-upload.js +261 -0
  188. package/dist/utils/sanitize.d.ts +45 -0
  189. package/dist/utils/sanitize.d.ts.map +1 -0
  190. package/dist/utils/sanitize.js +165 -0
  191. package/dist/validator.d.ts +7 -0
  192. package/dist/validator.d.ts.map +1 -0
  193. package/dist/validator.js +119 -0
  194. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,522 @@
1
+ # @hazeljs/core
2
+
3
+ **Core HazelJS Framework - Dependency Injection, Routing, Decorators, and Base Functionality**
4
+
5
+ The foundation of the HazelJS framework, providing enterprise-grade dependency injection, decorator-based routing, middleware support, and production-ready features.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@hazeljs/core.svg)](https://www.npmjs.com/package/@hazeljs/core)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ## Features
11
+
12
+ - 🎯 **Dependency Injection** - Advanced DI with Singleton, Transient, and Request scopes
13
+ - 🎨 **Decorator-Based API** - Clean, intuitive programming model
14
+ - 🛣️ **Routing** - Express-based routing with parameter extraction
15
+ - 🔌 **Middleware Support** - Global and route-level middleware
16
+ - 🛡️ **Guards & Interceptors** - Request validation and transformation
17
+ - 🔧 **Pipes** - Data transformation and validation
18
+ - 🏥 **Health Checks** - Built-in liveness, readiness, and startup probes
19
+ - 🛑 **Graceful Shutdown** - Proper cleanup and connection draining
20
+ - 📊 **Logging** - Winston-based structured logging
21
+ - ✅ **Validation** - Automatic request validation with class-validator
22
+ - 🧪 **Testing Utilities** - Full testing support with TestingModule
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install @hazeljs/core
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ### 1. Create a Controller
33
+
34
+ ```typescript
35
+ import { Controller, Get, Post, Body, Param } from '@hazeljs/core';
36
+
37
+ @Controller('/users')
38
+ export class UserController {
39
+ @Get()
40
+ findAll() {
41
+ return { users: [] };
42
+ }
43
+
44
+ @Get('/:id')
45
+ findOne(@Param('id') id: string) {
46
+ return { id, name: 'John Doe' };
47
+ }
48
+
49
+ @Post()
50
+ create(@Body() createUserDto: CreateUserDto) {
51
+ return { message: 'User created', data: createUserDto };
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### 2. Create a Service
57
+
58
+ ```typescript
59
+ import { Injectable } from '@hazeljs/core';
60
+
61
+ @Injectable()
62
+ export class UserService {
63
+ private users = [];
64
+
65
+ findAll() {
66
+ return this.users;
67
+ }
68
+
69
+ findOne(id: string) {
70
+ return this.users.find(user => user.id === id);
71
+ }
72
+
73
+ create(data: any) {
74
+ const user = { id: Date.now().toString(), ...data };
75
+ this.users.push(user);
76
+ return user;
77
+ }
78
+ }
79
+ ```
80
+
81
+ ### 3. Create a Module
82
+
83
+ ```typescript
84
+ import { HazelModule } from '@hazeljs/core';
85
+ import { UserController } from './user.controller';
86
+ import { UserService } from './user.service';
87
+
88
+ @HazelModule({
89
+ controllers: [UserController],
90
+ providers: [UserService],
91
+ })
92
+ export class AppModule {}
93
+ ```
94
+
95
+ ### 4. Bootstrap the Application
96
+
97
+ ```typescript
98
+ import { HazelApp, BuiltInHealthChecks } from '@hazeljs/core';
99
+ import { AppModule } from './app.module';
100
+
101
+ async function bootstrap() {
102
+ const app = await HazelApp.create(AppModule);
103
+
104
+ // Register health checks
105
+ app.registerHealthCheck(BuiltInHealthChecks.memoryCheck(500));
106
+ app.registerHealthCheck(BuiltInHealthChecks.eventLoopCheck(100));
107
+
108
+ // Register shutdown handlers
109
+ app.registerShutdownHandler({
110
+ name: 'cleanup',
111
+ handler: async () => {
112
+ console.log('Cleaning up resources...');
113
+ },
114
+ timeout: 5000,
115
+ });
116
+
117
+ await app.listen(3000);
118
+ }
119
+
120
+ bootstrap();
121
+ ```
122
+
123
+ ## Dependency Injection
124
+
125
+ ### Scopes
126
+
127
+ ```typescript
128
+ import { Injectable, Scope } from '@hazeljs/core';
129
+
130
+ // Singleton (default) - one instance for entire app
131
+ @Injectable()
132
+ export class SingletonService {}
133
+
134
+ // Transient - new instance every time
135
+ @Injectable({ scope: Scope.TRANSIENT })
136
+ export class TransientService {}
137
+
138
+ // Request - one instance per HTTP request
139
+ @Injectable({ scope: Scope.REQUEST })
140
+ export class RequestContextService {}
141
+ ```
142
+
143
+ ### Constructor Injection
144
+
145
+ ```typescript
146
+ @Injectable()
147
+ export class OrderService {
148
+ constructor(
149
+ private userService: UserService,
150
+ private paymentService: PaymentService
151
+ ) {}
152
+
153
+ async createOrder(userId: string) {
154
+ const user = await this.userService.findOne(userId);
155
+ const payment = await this.paymentService.process(user);
156
+ return { user, payment };
157
+ }
158
+ }
159
+ ```
160
+
161
+ ## Routing & Decorators
162
+
163
+ ### HTTP Methods
164
+
165
+ ```typescript
166
+ import { Controller, Get, Post, Put, Delete, Patch } from '@hazeljs/core';
167
+
168
+ @Controller('/api')
169
+ export class ApiController {
170
+ @Get('/items')
171
+ getItems() {}
172
+
173
+ @Post('/items')
174
+ createItem() {}
175
+
176
+ @Put('/items/:id')
177
+ updateItem() {}
178
+
179
+ @Patch('/items/:id')
180
+ patchItem() {}
181
+
182
+ @Delete('/items/:id')
183
+ deleteItem() {}
184
+ }
185
+ ```
186
+
187
+ ### Parameter Decorators
188
+
189
+ ```typescript
190
+ import { Controller, Get, Post, Param, Query, Body, Headers, Req, Res } from '@hazeljs/core';
191
+
192
+ @Controller('/users')
193
+ export class UserController {
194
+ @Get('/:id')
195
+ findOne(
196
+ @Param('id') id: string,
197
+ @Query('include') include?: string
198
+ ) {
199
+ return { id, include };
200
+ }
201
+
202
+ @Post()
203
+ create(
204
+ @Body() createUserDto: CreateUserDto,
205
+ @Headers('authorization') auth: string
206
+ ) {
207
+ return { data: createUserDto, auth };
208
+ }
209
+
210
+ @Get('/raw')
211
+ rawAccess(@Req() req: Request, @Res() res: Response) {
212
+ res.json({ message: 'Direct access to req/res' });
213
+ }
214
+ }
215
+ ```
216
+
217
+ ## Middleware
218
+
219
+ ### Global Middleware
220
+
221
+ ```typescript
222
+ import { Middleware, MiddlewareContext } from '@hazeljs/core';
223
+
224
+ @Injectable()
225
+ export class LoggerMiddleware implements Middleware {
226
+ async use(context: MiddlewareContext, next: () => Promise<void>) {
227
+ console.log(`${context.request.method} ${context.request.url}`);
228
+ await next();
229
+ }
230
+ }
231
+
232
+ // Register globally
233
+ const app = await HazelApp.create(AppModule);
234
+ app.useGlobalMiddleware(new LoggerMiddleware());
235
+ ```
236
+
237
+ ### Route-Level Middleware
238
+
239
+ ```typescript
240
+ import { Controller, Get, UseMiddleware } from '@hazeljs/core';
241
+
242
+ @Controller('/admin')
243
+ @UseMiddleware(AuthMiddleware)
244
+ export class AdminController {
245
+ @Get('/dashboard')
246
+ @UseMiddleware(RoleCheckMiddleware)
247
+ getDashboard() {
248
+ return { data: 'admin dashboard' };
249
+ }
250
+ }
251
+ ```
252
+
253
+ ## Guards
254
+
255
+ ```typescript
256
+ import { Guard, GuardContext } from '@hazeljs/core';
257
+
258
+ @Injectable()
259
+ export class AuthGuard implements Guard {
260
+ canActivate(context: GuardContext): boolean | Promise<boolean> {
261
+ const token = context.request.headers.authorization;
262
+ return this.validateToken(token);
263
+ }
264
+
265
+ private validateToken(token: string): boolean {
266
+ // Validate JWT token
267
+ return !!token;
268
+ }
269
+ }
270
+
271
+ // Use in controller
272
+ @Controller('/protected')
273
+ @UseGuard(AuthGuard)
274
+ export class ProtectedController {
275
+ @Get()
276
+ getData() {
277
+ return { message: 'Protected data' };
278
+ }
279
+ }
280
+ ```
281
+
282
+ ## Interceptors
283
+
284
+ ```typescript
285
+ import { Interceptor, InterceptorContext } from '@hazeljs/core';
286
+
287
+ @Injectable()
288
+ export class TransformInterceptor implements Interceptor {
289
+ async intercept(context: InterceptorContext, next: () => Promise<any>) {
290
+ const result = await next();
291
+
292
+ return {
293
+ data: result,
294
+ timestamp: new Date().toISOString(),
295
+ path: context.request.url,
296
+ };
297
+ }
298
+ }
299
+
300
+ // Use globally or per route
301
+ @Controller('/api')
302
+ @UseInterceptor(TransformInterceptor)
303
+ export class ApiController {}
304
+ ```
305
+
306
+ ## Pipes
307
+
308
+ ```typescript
309
+ import { Pipe, PipeContext } from '@hazeljs/core';
310
+
311
+ @Injectable()
312
+ export class ValidationPipe implements Pipe {
313
+ transform(value: any, context: PipeContext) {
314
+ if (!value) {
315
+ throw new Error('Value is required');
316
+ }
317
+ return value;
318
+ }
319
+ }
320
+
321
+ // Use in route
322
+ @Post()
323
+ create(@Body(ValidationPipe) createDto: CreateDto) {
324
+ return createDto;
325
+ }
326
+ ```
327
+
328
+ ## Validation
329
+
330
+ ```typescript
331
+ import { IsEmail, IsString, MinLength } from 'class-validator';
332
+
333
+ export class CreateUserDto {
334
+ @IsEmail()
335
+ email: string;
336
+
337
+ @IsString()
338
+ @MinLength(8)
339
+ password: string;
340
+
341
+ @IsString()
342
+ name: string;
343
+ }
344
+
345
+ @Controller('/users')
346
+ export class UserController {
347
+ @Post()
348
+ create(@Body() createUserDto: CreateUserDto) {
349
+ // Automatically validated before reaching here
350
+ return createUserDto;
351
+ }
352
+ }
353
+ ```
354
+
355
+ ## Health Checks
356
+
357
+ ```typescript
358
+ import { HazelApp, BuiltInHealthChecks } from '@hazeljs/core';
359
+
360
+ const app = await HazelApp.create(AppModule);
361
+
362
+ // Built-in checks
363
+ app.registerHealthCheck(BuiltInHealthChecks.memoryCheck(500)); // 500MB threshold
364
+ app.registerHealthCheck(BuiltInHealthChecks.eventLoopCheck(100)); // 100ms lag
365
+
366
+ // Custom health check
367
+ app.registerHealthCheck({
368
+ name: 'database',
369
+ check: async () => {
370
+ try {
371
+ await database.ping();
372
+ return { status: 'healthy' };
373
+ } catch (error) {
374
+ return {
375
+ status: 'unhealthy',
376
+ message: error.message
377
+ };
378
+ }
379
+ },
380
+ critical: true,
381
+ timeout: 3000,
382
+ });
383
+
384
+ // Endpoints available:
385
+ // GET /health - Liveness probe
386
+ // GET /ready - Readiness probe
387
+ // GET /startup - Startup probe
388
+ ```
389
+
390
+ ## Graceful Shutdown
391
+
392
+ ```typescript
393
+ const app = await HazelApp.create(AppModule);
394
+
395
+ app.registerShutdownHandler({
396
+ name: 'database',
397
+ handler: async () => {
398
+ await database.disconnect();
399
+ console.log('Database disconnected');
400
+ },
401
+ timeout: 5000,
402
+ });
403
+
404
+ app.registerShutdownHandler({
405
+ name: 'cache',
406
+ handler: async () => {
407
+ await redis.quit();
408
+ console.log('Redis connection closed');
409
+ },
410
+ timeout: 3000,
411
+ });
412
+
413
+ await app.listen(3000);
414
+
415
+ // On SIGTERM/SIGINT:
416
+ // 1. HTTP server stops accepting new connections
417
+ // 2. Existing requests complete (up to 10s)
418
+ // 3. Shutdown handlers execute in order
419
+ // 4. Process exits cleanly
420
+ ```
421
+
422
+ ## Exception Handling
423
+
424
+ ```typescript
425
+ import { ExceptionFilter, ExceptionContext } from '@hazeljs/core';
426
+
427
+ @Injectable()
428
+ export class HttpExceptionFilter implements ExceptionFilter {
429
+ catch(error: Error, context: ExceptionContext) {
430
+ const response = context.response;
431
+
432
+ response.status(500).json({
433
+ statusCode: 500,
434
+ message: error.message,
435
+ timestamp: new Date().toISOString(),
436
+ path: context.request.url,
437
+ });
438
+ }
439
+ }
440
+
441
+ // Use globally
442
+ app.useGlobalExceptionFilter(new HttpExceptionFilter());
443
+ ```
444
+
445
+ ## Testing
446
+
447
+ ```typescript
448
+ import { TestingModule } from '@hazeljs/core';
449
+ import { UserController } from './user.controller';
450
+ import { UserService } from './user.service';
451
+
452
+ describe('UserController', () => {
453
+ let module: TestingModule;
454
+ let controller: UserController;
455
+ let service: UserService;
456
+
457
+ beforeEach(async () => {
458
+ module = await TestingModule.create({
459
+ controllers: [UserController],
460
+ providers: [
461
+ {
462
+ provide: UserService,
463
+ useValue: {
464
+ findAll: jest.fn().mockResolvedValue([]),
465
+ },
466
+ },
467
+ ],
468
+ });
469
+
470
+ controller = module.get(UserController);
471
+ service = module.get(UserService);
472
+ });
473
+
474
+ afterEach(async () => {
475
+ await module.close();
476
+ });
477
+
478
+ it('should return all users', async () => {
479
+ const result = await controller.findAll();
480
+ expect(result).toEqual([]);
481
+ expect(service.findAll).toHaveBeenCalled();
482
+ });
483
+ });
484
+ ```
485
+
486
+ ## API Reference
487
+
488
+ ### Decorators
489
+
490
+ - `@HazelModule(options)` - Define a module
491
+ - `@Controller(path)` - Define a controller
492
+ - `@Injectable(options?)` - Mark class as injectable
493
+ - `@Get(path?)`, `@Post(path?)`, `@Put(path?)`, `@Delete(path?)`, `@Patch(path?)` - HTTP methods
494
+ - `@Param(name)`, `@Query(name)`, `@Body()`, `@Headers(name)` - Parameter extraction
495
+ - `@UseMiddleware(middleware)` - Apply middleware
496
+ - `@UseGuard(guard)` - Apply guard
497
+ - `@UseInterceptor(interceptor)` - Apply interceptor
498
+
499
+ ### Classes
500
+
501
+ - `HazelApp` - Main application class
502
+ - `TestingModule` - Testing utilities
503
+ - `Logger` - Logging service
504
+
505
+ ## Examples
506
+
507
+ See the [examples](../../example) directory for complete working examples.
508
+
509
+ ## Contributing
510
+
511
+ Contributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md) for details.
512
+
513
+ ## License
514
+
515
+ MIT © [HazelJS](https://hazeljs.com)
516
+
517
+ ## Links
518
+
519
+ - [Documentation](https://hazeljs.com/docs)
520
+ - [GitHub](https://github.com/hazel-js/hazeljs)
521
+ - [Issues](https://github.com/hazeljs/hazel-js/issues)
522
+ - [Discord](https://discord.gg/hazeljs)
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=container.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/container.test.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,CAAC"}