@hazeljs/core 0.3.1 → 0.4.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.
package/dist/index.js CHANGED
@@ -7,9 +7,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  return (mod && mod.__esModule) ? mod : { "default": mod };
8
8
  };
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.HttpError = exports.Scope = exports.Container = exports.CUSTOM_METADATA_PREFIX = exports.createParamDecorator = exports.getMetadata = exports.SetMetadata = exports.ApiOperation = exports.ApiTags = exports.Retry = exports.Session = exports.Optional = exports.Timeout = exports.AITask = exports.SkipAuth = exports.Public = exports.UseGuards = exports.UseInterceptors = exports.UsePipes = exports.Inject = exports.Redirect = exports.Header = exports.HttpCode = exports.Headers = exports.Host = exports.Ip = exports.Res = exports.Req = exports.Query = exports.Param = exports.Body = exports.Patch = exports.Delete = exports.Put = exports.Post = exports.Get = exports.Service = exports.Injectable = exports.Controller = exports.TimeoutMiddleware = exports.BuiltInHealthChecks = exports.HealthCheckManager = exports.ShutdownManager = exports.collectControllersFromModule = exports.collectModulesFromModule = exports.getModuleMetadata = exports.HazelModuleInstance = exports.Module = exports.HazelModule = exports.HazelApp = void 0;
11
- exports.sanitizeSql = exports.sanitizeEmail = exports.sanitizeUrl = exports.sanitizeString = exports.sanitizeHtml = exports.RequestParser = exports.Router = exports.Validator = exports.default = exports.logger = exports.UploadedFiles = exports.UploadedFile = exports.FileUploadInterceptor = exports.CsrfMiddleware = exports.RateLimitMiddleware = exports.SecurityHeadersMiddleware = exports.LoggerMiddleware = exports.CorsMiddleware = exports.GlobalMiddlewareManager = exports.extractVersion = exports.matchVersion = exports.getVersionMetadata = exports.VersioningType = exports.Version = exports.RouteMatcher = exports.TestingModuleBuilder = exports.TestingModule = exports.Test = exports.HttpExceptionFilter = exports.getFilterExceptions = exports.Catch = exports.ArgumentsHostImpl = exports.RetryInterceptor = exports.ValidationPipe = exports.ParseIntPipe = exports.ValidationError = exports.RequestTimeoutError = exports.InternalServerErrorException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.HttpException = exports.InternalServerError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = void 0;
12
- exports.escapeHtml = exports.sanitizeObject = void 0;
10
+ exports.Scope = exports.Container = exports.CUSTOM_METADATA_PREFIX = exports.Lazy = exports.createParamDecorator = exports.getMetadata = exports.SetMetadata = exports.ApiOperation = exports.ApiTags = exports.Retry = exports.Session = exports.Optional = exports.Timeout = exports.AITask = exports.SkipAuth = exports.Public = exports.UseGuards = exports.UseInterceptors = exports.UsePipes = exports.Inject = exports.Redirect = exports.Header = exports.HttpCode = exports.Headers = exports.Host = exports.Ip = exports.Res = exports.Req = exports.Query = exports.Param = exports.Body = exports.Patch = exports.Delete = exports.Put = exports.Post = exports.Get = exports.Service = exports.Injectable = exports.Controller = exports.TimeoutMiddleware = exports.BuiltInHealthChecks = exports.HealthCheckManager = exports.ShutdownManager = exports.collectControllersFromModule = exports.collectModulesFromModule = exports.getModuleMetadata = exports.HazelModuleInstance = exports.Module = exports.HazelModule = exports.HazelApp = void 0;
11
+ exports.sanitizeEmail = exports.sanitizeUrl = exports.sanitizeString = exports.sanitizeHtml = exports.RequestParser = exports.Router = exports.Validator = exports.default = exports.logger = exports.UploadedFiles = exports.UploadedFile = exports.FileUploadInterceptor = exports.CsrfMiddleware = exports.RateLimitMiddleware = exports.SecurityHeadersMiddleware = exports.LoggerMiddleware = exports.CorsMiddleware = exports.GlobalMiddlewareManager = exports.extractVersion = exports.matchVersion = exports.getVersionMetadata = exports.VersioningType = exports.Version = exports.RouteMatcher = exports.TestingModuleBuilder = exports.TestingModule = exports.Test = exports.HttpExceptionFilter = exports.getFilterExceptions = exports.Catch = exports.ArgumentsHostImpl = exports.RetryInterceptor = exports.ValidationPipe = exports.ParseIntPipe = exports.ValidationError = exports.RequestTimeoutError = exports.InternalServerErrorException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.HttpException = exports.InternalServerError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = exports.HttpError = void 0;
12
+ exports.EnhancedErrors = exports.createEnhancedError = exports.ErrorHandler = exports.BuiltinPerformanceHooks = exports.PerformanceMonitor = exports.escapeHtml = exports.sanitizeObject = exports.sanitizeSql = void 0;
13
13
  // Import reflect-metadata to enable decorator metadata
14
14
  // Users don't need to import this manually
15
15
  require("reflect-metadata");
@@ -69,6 +69,7 @@ Object.defineProperty(exports, "ApiOperation", { enumerable: true, get: function
69
69
  Object.defineProperty(exports, "SetMetadata", { enumerable: true, get: function () { return decorators_1.SetMetadata; } });
70
70
  Object.defineProperty(exports, "getMetadata", { enumerable: true, get: function () { return decorators_1.getMetadata; } });
71
71
  Object.defineProperty(exports, "createParamDecorator", { enumerable: true, get: function () { return decorators_1.createParamDecorator; } });
72
+ Object.defineProperty(exports, "Lazy", { enumerable: true, get: function () { return decorators_1.Lazy; } });
72
73
  Object.defineProperty(exports, "CUSTOM_METADATA_PREFIX", { enumerable: true, get: function () { return decorators_1.CUSTOM_METADATA_PREFIX; } });
73
74
  // Container & DI
74
75
  var container_1 = require("./container");
@@ -160,3 +161,12 @@ Object.defineProperty(exports, "sanitizeEmail", { enumerable: true, get: functio
160
161
  Object.defineProperty(exports, "sanitizeSql", { enumerable: true, get: function () { return sanitize_1.sanitizeSql; } });
161
162
  Object.defineProperty(exports, "sanitizeObject", { enumerable: true, get: function () { return sanitize_1.sanitizeObject; } });
162
163
  Object.defineProperty(exports, "escapeHtml", { enumerable: true, get: function () { return sanitize_1.escapeHtml; } });
164
+ // Performance monitoring
165
+ var performance_1 = require("./performance");
166
+ Object.defineProperty(exports, "PerformanceMonitor", { enumerable: true, get: function () { return performance_1.PerformanceMonitor; } });
167
+ Object.defineProperty(exports, "BuiltinPerformanceHooks", { enumerable: true, get: function () { return performance_1.BuiltinPerformanceHooks; } });
168
+ // Enhanced error handling
169
+ var enhanced_errors_1 = require("./enhanced-errors");
170
+ Object.defineProperty(exports, "ErrorHandler", { enumerable: true, get: function () { return enhanced_errors_1.ErrorHandler; } });
171
+ Object.defineProperty(exports, "createEnhancedError", { enumerable: true, get: function () { return enhanced_errors_1.createEnhancedError; } });
172
+ Object.defineProperty(exports, "EnhancedErrors", { enumerable: true, get: function () { return enhanced_errors_1.EnhancedErrors; } });
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAwQvD,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,MAAM,MAAM,IAAI,KACf,IAyBF,CAAC;AAQF,QAAA,MAAM,cAAc;0BALO,OAAO;CAOhC,CAAC;AAGH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAoSvD,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,MAAM,MAAM,IAAI,KACf,IAyBF,CAAC;AAQF,QAAA,MAAM,cAAc;0BALO,OAAO;CAOhC,CAAC;AAGH,eAAe,cAAc,CAAC"}
package/dist/logger.js CHANGED
@@ -178,10 +178,24 @@ if (logEnabled) {
178
178
  const { level, message, timestamp, ...metadata } = info;
179
179
  let msg = `${timestamp} [${String(level).toUpperCase()}] ${message}`;
180
180
  if (Object.keys(metadata).length > 0) {
181
+ // Use the same comprehensive circular reference handling as console logger
182
+ const seen = new WeakSet();
181
183
  msg += ` | ${JSON.stringify(metadata, (key, val) => {
184
+ // Skip known circular references
182
185
  if (key === 'socket' || key === 'parser' || key === 'res' || key === 'req') {
183
186
  return '[Circular]';
184
187
  }
188
+ // Skip Node.js internal objects
189
+ if (key === '_idlePrev' || key === '_idleNext' || key === 'cleanupInterval') {
190
+ return '[Internal]';
191
+ }
192
+ // Handle circular references
193
+ if (typeof val === 'object' && val !== null) {
194
+ if (seen.has(val)) {
195
+ return '[Circular]';
196
+ }
197
+ seen.add(val);
198
+ }
185
199
  return val;
186
200
  })}`;
187
201
  }
@@ -194,10 +208,24 @@ if (logEnabled) {
194
208
  const { level, message, timestamp, ...metadata } = info;
195
209
  let msg = `${timestamp} [${String(level).toUpperCase()}] ${message}`;
196
210
  if (Object.keys(metadata).length > 0) {
211
+ // Use the same comprehensive circular reference handling as console logger
212
+ const seen = new WeakSet();
197
213
  msg += ` | ${JSON.stringify(metadata, (key, val) => {
214
+ // Skip known circular references
198
215
  if (key === 'socket' || key === 'parser' || key === 'res' || key === 'req') {
199
216
  return '[Circular]';
200
217
  }
218
+ // Skip Node.js internal objects
219
+ if (key === '_idlePrev' || key === '_idleNext' || key === 'cleanupInterval') {
220
+ return '[Internal]';
221
+ }
222
+ // Handle circular references
223
+ if (typeof val === 'object' && val !== null) {
224
+ if (seen.has(val)) {
225
+ return '[Circular]';
226
+ }
227
+ seen.add(val);
228
+ }
201
229
  return val;
202
230
  })}`;
203
231
  }
@@ -0,0 +1,49 @@
1
+ import { Request } from './types';
2
+ export interface PerformanceMetrics {
3
+ requestId: string;
4
+ method: string;
5
+ path: string;
6
+ startTime: number;
7
+ endTime?: number;
8
+ duration?: number;
9
+ statusCode?: number;
10
+ memoryUsage?: NodeJS.MemoryUsage;
11
+ cpuUsage?: NodeJS.CpuUsage;
12
+ error?: Error;
13
+ }
14
+ export interface PerformanceHook {
15
+ name: string;
16
+ onRequest?: (metrics: PerformanceMetrics) => void | Promise<void>;
17
+ onResponse?: (metrics: PerformanceMetrics) => void | Promise<void>;
18
+ onError?: (metrics: PerformanceMetrics) => void | Promise<void>;
19
+ }
20
+ export interface PerformanceOptions {
21
+ enableMetrics?: boolean;
22
+ slowRequestThreshold?: number;
23
+ maxRequestsWindow?: number;
24
+ rateLimitWindow?: number;
25
+ }
26
+ export declare class PerformanceMonitor {
27
+ private hooks;
28
+ private activeRequests;
29
+ constructor();
30
+ addHook(hook: PerformanceHook): void;
31
+ removeHook(name: string): void;
32
+ startRequest(req: Request): string;
33
+ endRequest(requestId: string, statusCode: number, error?: Error): void;
34
+ getActiveRequests(): PerformanceMetrics[];
35
+ getMetrics(): {
36
+ activeRequests: number;
37
+ totalHooks: number;
38
+ averageResponseTime?: number;
39
+ };
40
+ private generateRequestId;
41
+ private executeHooks;
42
+ }
43
+ export declare const BuiltinPerformanceHooks: {
44
+ slowRequestLogger: (threshold?: number) => PerformanceHook;
45
+ memoryMonitor: () => PerformanceHook;
46
+ rateLimiter: (maxRequests?: number, windowMs?: number) => PerformanceHook;
47
+ metricsCollector: () => PerformanceHook;
48
+ };
49
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../src/performance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,cAAc,CAA8C;;IAMpE,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAKpC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK9B,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM;IAmBlC,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAmBtE,iBAAiB,IAAI,kBAAkB,EAAE;IAIzC,UAAU,IAAI;QACZ,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B;IAOD,OAAO,CAAC,iBAAiB;YAIX,YAAY;CAgB3B;AAGD,eAAO,MAAM,uBAAuB;oCAEH,MAAM,KAAU,eAAe;yBAY3C,eAAe;gCAaP,MAAM,aAAkB,MAAM,KAAW,eAAe;4BA0B7D,eAAe;CAwBtC,CAAC"}
@@ -0,0 +1,140 @@
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.BuiltinPerformanceHooks = exports.PerformanceMonitor = void 0;
7
+ const logger_1 = __importDefault(require("./logger"));
8
+ class PerformanceMonitor {
9
+ constructor() {
10
+ this.hooks = [];
11
+ this.activeRequests = new Map();
12
+ logger_1.default.debug('PerformanceMonitor initialized');
13
+ }
14
+ addHook(hook) {
15
+ this.hooks.push(hook);
16
+ logger_1.default.debug(`Added performance hook: ${hook.name}`);
17
+ }
18
+ removeHook(name) {
19
+ this.hooks = this.hooks.filter(hook => hook.name !== name);
20
+ logger_1.default.debug(`Removed performance hook: ${name}`);
21
+ }
22
+ startRequest(req) {
23
+ const requestId = this.generateRequestId();
24
+ const metrics = {
25
+ requestId,
26
+ method: req.method || 'GET',
27
+ path: req.url || '/',
28
+ startTime: Date.now(),
29
+ memoryUsage: process.memoryUsage(),
30
+ cpuUsage: process.cpuUsage(),
31
+ };
32
+ this.activeRequests.set(requestId, metrics);
33
+ // Execute request hooks
34
+ this.executeHooks('onRequest', metrics);
35
+ return requestId;
36
+ }
37
+ endRequest(requestId, statusCode, error) {
38
+ const metrics = this.activeRequests.get(requestId);
39
+ if (!metrics)
40
+ return;
41
+ metrics.endTime = Date.now();
42
+ metrics.duration = metrics.endTime - metrics.startTime;
43
+ metrics.statusCode = statusCode;
44
+ metrics.error = error;
45
+ // Execute response or error hooks
46
+ if (error) {
47
+ this.executeHooks('onError', metrics);
48
+ }
49
+ else {
50
+ this.executeHooks('onResponse', metrics);
51
+ }
52
+ this.activeRequests.delete(requestId);
53
+ }
54
+ getActiveRequests() {
55
+ return Array.from(this.activeRequests.values());
56
+ }
57
+ getMetrics() {
58
+ return {
59
+ activeRequests: this.activeRequests.size,
60
+ totalHooks: this.hooks.length,
61
+ };
62
+ }
63
+ generateRequestId() {
64
+ return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
65
+ }
66
+ async executeHooks(hookType, metrics) {
67
+ const promises = this.hooks
68
+ .filter(hook => hook[hookType])
69
+ .map(async (hook) => {
70
+ try {
71
+ await hook[hookType](metrics);
72
+ }
73
+ catch (error) {
74
+ logger_1.default.error(`Error in performance hook ${hook.name}:`, error);
75
+ }
76
+ });
77
+ await Promise.allSettled(promises);
78
+ }
79
+ }
80
+ exports.PerformanceMonitor = PerformanceMonitor;
81
+ // Built-in performance hooks
82
+ exports.BuiltinPerformanceHooks = {
83
+ // Log slow requests
84
+ slowRequestLogger: (threshold = 1000) => ({
85
+ name: 'slow-request-logger',
86
+ onResponse: (metrics) => {
87
+ if (metrics.duration && metrics.duration > threshold) {
88
+ logger_1.default.warn(`Slow request detected: ${metrics.method} ${metrics.path} took ${metrics.duration}ms`);
89
+ }
90
+ },
91
+ }),
92
+ // Memory usage monitoring
93
+ memoryMonitor: () => ({
94
+ name: 'memory-monitor',
95
+ onRequest: (metrics) => {
96
+ const memUsage = metrics.memoryUsage;
97
+ if (memUsage.heapUsed > 100 * 1024 * 1024) { // 100MB
98
+ logger_1.default.warn(`High memory usage during request ${metrics.requestId}: ${Math.round(memUsage.heapUsed / 1024 / 1024)}MB`);
99
+ }
100
+ },
101
+ }),
102
+ // Request rate limiting
103
+ rateLimiter: (maxRequests = 100, windowMs = 60000) => {
104
+ const requests = [];
105
+ return {
106
+ name: 'rate-limiter',
107
+ onRequest: (_metrics) => {
108
+ const now = Date.now();
109
+ const windowStart = now - windowMs;
110
+ // Remove old requests
111
+ while (requests.length > 0 && requests[0] < windowStart) {
112
+ requests.shift();
113
+ }
114
+ requests.push(now);
115
+ if (requests.length > maxRequests) {
116
+ logger_1.default.warn(`Rate limit exceeded: ${requests.length} requests in ${windowMs}ms`);
117
+ }
118
+ },
119
+ };
120
+ },
121
+ // Performance metrics collector
122
+ metricsCollector: () => {
123
+ const metrics = [];
124
+ return {
125
+ name: 'metrics-collector',
126
+ onResponse: (metricsData) => {
127
+ metrics.push(metricsData);
128
+ // Keep only last 1000 metrics
129
+ if (metrics.length > 1000) {
130
+ metrics.splice(0, 100);
131
+ }
132
+ // Calculate average response time
133
+ const avgTime = metrics.reduce((sum, m) => sum + (m.duration || 0), 0) / metrics.length;
134
+ if (metrics.length % 100 === 0) {
135
+ logger_1.default.debug(`Performance metrics - Avg response time: ${Math.round(avgTime)}ms, Requests: ${metrics.length}`);
136
+ }
137
+ },
138
+ };
139
+ },
140
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/core",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Core HazelJS framework - Dependency injection, routing, decorators, and base functionality",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -63,5 +63,5 @@
63
63
  "url": "https://github.com/hazeljs/hazel-js/issues"
64
64
  },
65
65
  "homepage": "https://hazeljs.ai",
66
- "gitHead": "db6df492988e5d7b03253a98977c71c7a4540e1c"
66
+ "gitHead": "151d5678aa2aeddd75fb75b1b5c55fabe8cb8050"
67
67
  }