@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
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VersioningType = void 0;
4
+ exports.Version = Version;
5
+ exports.getVersionMetadata = getVersionMetadata;
6
+ exports.matchVersion = matchVersion;
7
+ exports.extractVersion = extractVersion;
8
+ require("reflect-metadata");
9
+ /**
10
+ * Version types
11
+ */
12
+ var VersioningType;
13
+ (function (VersioningType) {
14
+ VersioningType["URI"] = "uri";
15
+ VersioningType["HEADER"] = "header";
16
+ VersioningType["MEDIA_TYPE"] = "media-type";
17
+ VersioningType["CUSTOM"] = "custom";
18
+ })(VersioningType || (exports.VersioningType = VersioningType = {}));
19
+ /**
20
+ * Version decorator for controllers and routes
21
+ */
22
+ function Version(version) {
23
+ const decorator = (target, propertyKey, descriptor) => {
24
+ const versions = Array.isArray(version) ? version : [version];
25
+ if (propertyKey && descriptor) {
26
+ // Method decorator
27
+ Reflect.defineMetadata('hazel:version', versions, target, propertyKey);
28
+ return descriptor;
29
+ }
30
+ else {
31
+ // Class decorator
32
+ Reflect.defineMetadata('hazel:version', versions, target);
33
+ }
34
+ };
35
+ return decorator;
36
+ }
37
+ /**
38
+ * Get version metadata from a class or method
39
+ */
40
+ function getVersionMetadata(target, propertyKey) {
41
+ if (propertyKey) {
42
+ return Reflect.getMetadata('hazel:version', target, propertyKey);
43
+ }
44
+ return Reflect.getMetadata('hazel:version', target);
45
+ }
46
+ /**
47
+ * Check if a version matches the requested version
48
+ */
49
+ function matchVersion(routeVersions, requestedVersion, _options) {
50
+ // If no version specified on route, it matches all versions
51
+ if (!routeVersions || routeVersions.length === 0) {
52
+ return true;
53
+ }
54
+ // If no version requested, don't match versioned routes
55
+ if (!requestedVersion) {
56
+ return false;
57
+ }
58
+ // Check if requested version is in route versions
59
+ return routeVersions.includes(requestedVersion);
60
+ }
61
+ /**
62
+ * Extract version from request based on versioning type
63
+ */
64
+ function extractVersion(request, options) {
65
+ const req = request;
66
+ switch (options.type) {
67
+ case VersioningType.URI: {
68
+ // Extract from URL path (e.g., /v1/users)
69
+ const match = req.url?.match(/\/v(\d+)\//);
70
+ return match ? match[1] : undefined;
71
+ }
72
+ case VersioningType.HEADER: {
73
+ // Extract from custom header
74
+ const headerName = options.header || 'X-API-Version';
75
+ return req.headers?.[headerName.toLowerCase()];
76
+ }
77
+ case VersioningType.MEDIA_TYPE: {
78
+ // Extract from Accept header (e.g., application/vnd.api.v1+json)
79
+ const accept = req.headers?.['accept'];
80
+ const mediaMatch = accept?.match(/\.v(\d+)\+/);
81
+ return mediaMatch ? mediaMatch[1] : undefined;
82
+ }
83
+ case VersioningType.CUSTOM:
84
+ // Use custom extractor
85
+ return options.extractor?.(req);
86
+ default:
87
+ return undefined;
88
+ }
89
+ }
@@ -0,0 +1,9 @@
1
+ export declare abstract class BaseService {
2
+ protected constructor();
3
+ protected logError(method: string, error: Error & {
4
+ stack?: string;
5
+ }): void;
6
+ protected logInfo(method: string, message: string): void;
7
+ protected logDebug(method: string, message: string, data?: unknown): void;
8
+ }
9
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAGA,8BACsB,WAAW;IAC/B,SAAS;IAIT,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAO3E,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIxD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;CAG1E"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.BaseService = void 0;
16
+ const decorators_1 = require("./decorators");
17
+ const logger_1 = __importDefault(require("./logger"));
18
+ let BaseService = class BaseService {
19
+ constructor() {
20
+ logger_1.default.info(`Initializing service: ${this.constructor.name}`);
21
+ }
22
+ logError(method, error) {
23
+ logger_1.default.error(`[${this.constructor.name}.${method}] Error: ${error.message}`);
24
+ if (process.env.NODE_ENV === 'development' && error.stack) {
25
+ logger_1.default.debug(error.stack);
26
+ }
27
+ }
28
+ logInfo(method, message) {
29
+ logger_1.default.info(`[${this.constructor.name}.${method}] ${message}`);
30
+ }
31
+ logDebug(method, message, data) {
32
+ logger_1.default.debug(`[${this.constructor.name}.${method}] ${message}`, data);
33
+ }
34
+ };
35
+ exports.BaseService = BaseService;
36
+ exports.BaseService = BaseService = __decorate([
37
+ (0, decorators_1.Injectable)(),
38
+ __metadata("design:paramtypes", [])
39
+ ], BaseService);
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Graceful Shutdown Manager
3
+ * Handles SIGTERM, SIGINT signals and ensures clean shutdown
4
+ */
5
+ export interface ShutdownHandler {
6
+ name: string;
7
+ handler: () => Promise<void>;
8
+ timeout?: number;
9
+ }
10
+ export declare class ShutdownManager {
11
+ private handlers;
12
+ private isShuttingDown;
13
+ private shutdownTimeout;
14
+ constructor(timeout?: number);
15
+ /**
16
+ * Register a shutdown handler
17
+ */
18
+ registerHandler(handler: ShutdownHandler): void;
19
+ /**
20
+ * Setup signal handlers for graceful shutdown
21
+ */
22
+ setupSignalHandlers(): void;
23
+ /**
24
+ * Perform graceful shutdown
25
+ */
26
+ shutdown(_signal: string): Promise<void>;
27
+ /**
28
+ * Get shutdown status
29
+ */
30
+ isShutdown(): boolean;
31
+ }
32
+ //# sourceMappingURL=shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,CAAC,EAAE,MAAM;IAM5B;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAI/C;;OAEG;IACH,mBAAmB,IAAI,IAAI;IA+B3B;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+C9C;;OAEG;IACH,UAAU,IAAI,OAAO;CAGtB"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * Graceful Shutdown Manager
4
+ * Handles SIGTERM, SIGINT signals and ensures clean shutdown
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ShutdownManager = void 0;
11
+ const logger_1 = __importDefault(require("./logger"));
12
+ class ShutdownManager {
13
+ constructor(timeout) {
14
+ this.handlers = [];
15
+ this.isShuttingDown = false;
16
+ this.shutdownTimeout = 30000; // 30 seconds default
17
+ if (timeout) {
18
+ this.shutdownTimeout = timeout;
19
+ }
20
+ }
21
+ /**
22
+ * Register a shutdown handler
23
+ */
24
+ registerHandler(handler) {
25
+ this.handlers.push(handler);
26
+ }
27
+ /**
28
+ * Setup signal handlers for graceful shutdown
29
+ */
30
+ setupSignalHandlers() {
31
+ const signals = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
32
+ signals.forEach((signal) => {
33
+ process.on(signal, async () => {
34
+ logger_1.default.info(`Received ${signal} signal, starting graceful shutdown...`);
35
+ await this.shutdown(signal);
36
+ });
37
+ });
38
+ // Handle uncaught exceptions
39
+ process.on('uncaughtException', async (error) => {
40
+ logger_1.default.error('Uncaught Exception:', {
41
+ error: error.message,
42
+ stack: error.stack,
43
+ });
44
+ await this.shutdown('UNCAUGHT_EXCEPTION');
45
+ process.exit(1);
46
+ });
47
+ // Handle unhandled promise rejections
48
+ process.on('unhandledRejection', async (reason, promise) => {
49
+ logger_1.default.error('Unhandled Rejection:', {
50
+ reason,
51
+ promise,
52
+ });
53
+ await this.shutdown('UNHANDLED_REJECTION');
54
+ process.exit(1);
55
+ });
56
+ }
57
+ /**
58
+ * Perform graceful shutdown
59
+ */
60
+ async shutdown(_signal) {
61
+ if (this.isShuttingDown) {
62
+ logger_1.default.warn('Shutdown already in progress, ignoring signal');
63
+ return;
64
+ }
65
+ this.isShuttingDown = true;
66
+ logger_1.default.info('Starting graceful shutdown...');
67
+ // Set a timeout to force shutdown if handlers take too long
68
+ const forceShutdownTimer = setTimeout(() => {
69
+ logger_1.default.error(`Shutdown timeout (${this.shutdownTimeout}ms) exceeded, forcing exit`);
70
+ process.exit(1);
71
+ }, this.shutdownTimeout);
72
+ try {
73
+ // Execute all shutdown handlers
74
+ for (const { name, handler, timeout } of this.handlers) {
75
+ logger_1.default.info(`Executing shutdown handler: ${name}`);
76
+ try {
77
+ if (timeout) {
78
+ await Promise.race([
79
+ handler(),
80
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Handler ${name} timeout`)), timeout)),
81
+ ]);
82
+ }
83
+ else {
84
+ await handler();
85
+ }
86
+ logger_1.default.info(`Shutdown handler completed: ${name}`);
87
+ }
88
+ catch (error) {
89
+ logger_1.default.error(`Error in shutdown handler ${name}:`, error);
90
+ }
91
+ }
92
+ logger_1.default.info('Graceful shutdown completed successfully');
93
+ clearTimeout(forceShutdownTimer);
94
+ process.exit(0);
95
+ }
96
+ catch (error) {
97
+ logger_1.default.error('Error during shutdown:', error);
98
+ clearTimeout(forceShutdownTimer);
99
+ process.exit(1);
100
+ }
101
+ }
102
+ /**
103
+ * Get shutdown status
104
+ */
105
+ isShutdown() {
106
+ return this.isShuttingDown;
107
+ }
108
+ }
109
+ exports.ShutdownManager = ShutdownManager;
@@ -0,0 +1,83 @@
1
+ import { Type } from '../types';
2
+ import { Container, Provider, InjectionToken } from '../container';
3
+ /**
4
+ * Testing module builder
5
+ */
6
+ export declare class TestingModuleBuilder {
7
+ private controllers;
8
+ private providers;
9
+ private imports;
10
+ /**
11
+ * Create a testing module
12
+ */
13
+ static createTestingModule(metadata: TestingModuleMetadata): TestingModuleBuilder;
14
+ /**
15
+ * Override a provider for testing
16
+ */
17
+ overrideProvider<T>(token: InjectionToken<T>): OverrideByBuilder<T>;
18
+ /**
19
+ * Compile the testing module
20
+ */
21
+ compile(): Promise<TestingModule>;
22
+ /**
23
+ * Internal method to replace a provider
24
+ */
25
+ replaceProvider<T>(token: InjectionToken<T>, provider: Provider<T>): void;
26
+ }
27
+ /**
28
+ * Override builder for fluent API
29
+ */
30
+ export declare class OverrideByBuilder<T> {
31
+ private readonly builder;
32
+ private readonly token;
33
+ constructor(builder: TestingModuleBuilder, token: InjectionToken<T>);
34
+ /**
35
+ * Override with a value
36
+ */
37
+ useValue(value: T): TestingModuleBuilder;
38
+ /**
39
+ * Override with a class
40
+ */
41
+ useClass(useClass: Type<T>): TestingModuleBuilder;
42
+ /**
43
+ * Override with a factory
44
+ */
45
+ useFactory(factory: (...args: unknown[]) => T, inject?: InjectionToken[]): TestingModuleBuilder;
46
+ }
47
+ /**
48
+ * Compiled testing module
49
+ */
50
+ export declare class TestingModule {
51
+ private readonly container;
52
+ constructor(container: Container);
53
+ /**
54
+ * Get an instance from the container
55
+ */
56
+ get<T>(token: InjectionToken<T>): T;
57
+ /**
58
+ * Select a specific module context
59
+ */
60
+ select(_module: Type<unknown>): TestingModule;
61
+ /**
62
+ * Close the testing module and cleanup
63
+ */
64
+ close(): Promise<void>;
65
+ }
66
+ /**
67
+ * Testing module metadata
68
+ */
69
+ export interface TestingModuleMetadata {
70
+ controllers?: Type<unknown>[];
71
+ providers?: Array<Type<unknown> | Provider>;
72
+ imports?: Type<unknown>[];
73
+ }
74
+ /**
75
+ * Test utility class
76
+ */
77
+ export declare class Test {
78
+ /**
79
+ * Create a testing module builder
80
+ */
81
+ static createTestingModule(metadata: TestingModuleMetadata): TestingModuleBuilder;
82
+ }
83
+ //# sourceMappingURL=testing.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.module.d.ts","sourceRoot":"","sources":["../../src/testing/testing.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnE;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,OAAO,CAAuB;IAEtC;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,oBAAoB;IAkBjF;;OAEG;IACH,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAInE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IAwBvC;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI;CAc1E;AAED;;GAEG;AACH,qBAAa,iBAAiB,CAAC,CAAC;IAE5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,OAAO,EAAE,oBAAoB,EAC7B,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAG3C;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,oBAAoB;IAQxC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,oBAAoB;IAQjD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,cAAc,EAAE,GAAG,oBAAoB;CAQhG;AAED;;GAEG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;IAInC;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,aAAa;IAM7C;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,IAAI;IACf;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB,GAAG,oBAAoB;CAGlF"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Test = exports.TestingModule = exports.OverrideByBuilder = exports.TestingModuleBuilder = void 0;
7
+ const container_1 = require("../container");
8
+ const logger_1 = __importDefault(require("../logger"));
9
+ /**
10
+ * Testing module builder
11
+ */
12
+ class TestingModuleBuilder {
13
+ constructor() {
14
+ this.controllers = [];
15
+ this.providers = [];
16
+ this.imports = [];
17
+ }
18
+ /**
19
+ * Create a testing module
20
+ */
21
+ static createTestingModule(metadata) {
22
+ const builder = new TestingModuleBuilder();
23
+ if (metadata.controllers) {
24
+ builder.controllers = metadata.controllers;
25
+ }
26
+ if (metadata.providers) {
27
+ builder.providers = metadata.providers;
28
+ }
29
+ if (metadata.imports) {
30
+ builder.imports = metadata.imports;
31
+ }
32
+ return builder;
33
+ }
34
+ /**
35
+ * Override a provider for testing
36
+ */
37
+ overrideProvider(token) {
38
+ return new OverrideByBuilder(this, token);
39
+ }
40
+ /**
41
+ * Compile the testing module
42
+ */
43
+ async compile() {
44
+ logger_1.default.info('Compiling testing module');
45
+ const container = container_1.Container.createTestInstance();
46
+ // Register providers
47
+ for (const provider of this.providers) {
48
+ if (typeof provider === 'function') {
49
+ const instance = container.resolve(provider);
50
+ container.register(provider, instance);
51
+ }
52
+ else {
53
+ container.registerProvider(provider);
54
+ }
55
+ }
56
+ // Register controllers
57
+ for (const controller of this.controllers) {
58
+ const instance = container.resolve(controller);
59
+ container.register(controller, instance);
60
+ }
61
+ return new TestingModule(container);
62
+ }
63
+ /**
64
+ * Internal method to replace a provider
65
+ */
66
+ replaceProvider(token, provider) {
67
+ const index = this.providers.findIndex((p) => {
68
+ if (typeof p === 'function') {
69
+ return p === token;
70
+ }
71
+ return p.token === token;
72
+ });
73
+ if (index !== -1) {
74
+ this.providers[index] = provider;
75
+ }
76
+ else {
77
+ this.providers.push(provider);
78
+ }
79
+ }
80
+ }
81
+ exports.TestingModuleBuilder = TestingModuleBuilder;
82
+ /**
83
+ * Override builder for fluent API
84
+ */
85
+ class OverrideByBuilder {
86
+ constructor(builder, token) {
87
+ this.builder = builder;
88
+ this.token = token;
89
+ }
90
+ /**
91
+ * Override with a value
92
+ */
93
+ useValue(value) {
94
+ this.builder.replaceProvider(this.token, {
95
+ token: this.token,
96
+ useValue: value,
97
+ });
98
+ return this.builder;
99
+ }
100
+ /**
101
+ * Override with a class
102
+ */
103
+ useClass(useClass) {
104
+ this.builder.replaceProvider(this.token, {
105
+ token: this.token,
106
+ useClass,
107
+ });
108
+ return this.builder;
109
+ }
110
+ /**
111
+ * Override with a factory
112
+ */
113
+ useFactory(factory, inject) {
114
+ this.builder.replaceProvider(this.token, {
115
+ token: this.token,
116
+ useFactory: factory,
117
+ inject,
118
+ });
119
+ return this.builder;
120
+ }
121
+ }
122
+ exports.OverrideByBuilder = OverrideByBuilder;
123
+ /**
124
+ * Compiled testing module
125
+ */
126
+ class TestingModule {
127
+ constructor(container) {
128
+ this.container = container;
129
+ }
130
+ /**
131
+ * Get an instance from the container
132
+ */
133
+ get(token) {
134
+ return this.container.resolve(token);
135
+ }
136
+ /**
137
+ * Select a specific module context
138
+ */
139
+ select(_module) {
140
+ // For now, return the same module
141
+ // In a full implementation, this would handle module isolation
142
+ return this;
143
+ }
144
+ /**
145
+ * Close the testing module and cleanup
146
+ */
147
+ async close() {
148
+ this.container.clear();
149
+ logger_1.default.info('Testing module closed');
150
+ }
151
+ }
152
+ exports.TestingModule = TestingModule;
153
+ /**
154
+ * Test utility class
155
+ */
156
+ class Test {
157
+ /**
158
+ * Create a testing module builder
159
+ */
160
+ static createTestingModule(metadata) {
161
+ return TestingModuleBuilder.createTestingModule(metadata);
162
+ }
163
+ }
164
+ exports.Test = Test;
@@ -0,0 +1,76 @@
1
+ export type Type<T = unknown> = new (...args: any[]) => T;
2
+ export interface ModuleMetadata {
3
+ imports?: Type<unknown>[];
4
+ controllers: Type<unknown>[];
5
+ providers: Type<unknown>[];
6
+ exports?: Type<unknown>[];
7
+ middlewares?: Type<unknown>[];
8
+ }
9
+ export interface ControllerMetadata {
10
+ path: string;
11
+ middlewares?: Type<unknown>[];
12
+ }
13
+ export interface InjectableMetadata {
14
+ scope?: 'singleton' | 'transient';
15
+ }
16
+ export interface RouteMetadata {
17
+ path: string;
18
+ method: string;
19
+ handler: string | symbol;
20
+ middlewares?: Type<unknown>[];
21
+ }
22
+ export interface ProviderMetadata {
23
+ token: string | symbol | Type<unknown>;
24
+ useValue?: unknown;
25
+ useClass?: Type<unknown>;
26
+ useFactory?: (...args: unknown[]) => unknown;
27
+ deps?: Type<unknown>[];
28
+ }
29
+ export type Request = {
30
+ body?: unknown;
31
+ params?: Record<string, string>;
32
+ query?: Record<string, string>;
33
+ method?: string;
34
+ url?: string;
35
+ headers?: Record<string, string>;
36
+ };
37
+ export type Response = {
38
+ status: (code: number) => Response;
39
+ json: (data: unknown) => void;
40
+ send: (data: string) => void;
41
+ setHeader: (name: string, value: string) => void;
42
+ end: () => void;
43
+ };
44
+ export interface RequestContext {
45
+ method: string;
46
+ url: string;
47
+ headers: Record<string, string>;
48
+ params: Record<string, string>;
49
+ query: Record<string, string>;
50
+ body: unknown;
51
+ dtoType?: Type<unknown>;
52
+ user?: {
53
+ id: string | number;
54
+ username?: string;
55
+ role: string;
56
+ [key: string]: unknown;
57
+ };
58
+ req?: Request;
59
+ }
60
+ export interface ValidationRule {
61
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
62
+ required?: boolean;
63
+ min?: number;
64
+ max?: number;
65
+ pattern?: RegExp;
66
+ properties?: ValidationSchema;
67
+ items?: ValidationRule;
68
+ }
69
+ export interface ValidationSchema {
70
+ [key: string]: ValidationRule;
71
+ }
72
+ export interface ValidationError {
73
+ field: string;
74
+ message: string;
75
+ }
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });