@hazeljs/core 0.2.2 → 0.2.4

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.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const hazel_response_1 = require("../hazel-response");
4
- describe('HazelExpressResponse', () => {
4
+ describe('HazelHttpResponse', () => {
5
5
  let mockRes;
6
6
  let hazelResponse;
7
7
  beforeEach(() => {
@@ -12,7 +12,7 @@ describe('HazelExpressResponse', () => {
12
12
  send: jest.fn(),
13
13
  end: jest.fn(),
14
14
  };
15
- hazelResponse = new hazel_response_1.HazelExpressResponse(mockRes);
15
+ hazelResponse = new hazel_response_1.HazelHttpResponse(mockRes);
16
16
  });
17
17
  describe('setHeader', () => {
18
18
  it('should set header when headers not sent', () => {
@@ -35,7 +35,7 @@ describe('HazelExpressResponse', () => {
35
35
  });
36
36
  it('should return this for chaining', () => {
37
37
  const result = hazelResponse.status(200);
38
- expect(result).toBeInstanceOf(hazel_response_1.HazelExpressResponse);
38
+ expect(result).toBeInstanceOf(hazel_response_1.HazelHttpResponse);
39
39
  });
40
40
  it('should not set status after headers are sent', () => {
41
41
  hazelResponse.write('test');
@@ -104,11 +104,11 @@ describe('HazelExpressResponse', () => {
104
104
  hazelResponse.json('string value');
105
105
  expect(mockRes.json).toHaveBeenCalledWith('string value');
106
106
  jest.clearAllMocks();
107
- hazelResponse = new hazel_response_1.HazelExpressResponse(mockRes);
107
+ hazelResponse = new hazel_response_1.HazelHttpResponse(mockRes);
108
108
  hazelResponse.json(123);
109
109
  expect(mockRes.json).toHaveBeenCalledWith(123);
110
110
  jest.clearAllMocks();
111
- hazelResponse = new hazel_response_1.HazelExpressResponse(mockRes);
111
+ hazelResponse = new hazel_response_1.HazelHttpResponse(mockRes);
112
112
  hazelResponse.json(true);
113
113
  expect(mockRes.json).toHaveBeenCalledWith(true);
114
114
  });
@@ -116,7 +116,7 @@ describe('HazelExpressResponse', () => {
116
116
  hazelResponse.json(null);
117
117
  expect(mockRes.json).toHaveBeenCalledWith(null);
118
118
  jest.clearAllMocks();
119
- hazelResponse = new hazel_response_1.HazelExpressResponse(mockRes);
119
+ hazelResponse = new hazel_response_1.HazelHttpResponse(mockRes);
120
120
  hazelResponse.json(undefined);
121
121
  expect(mockRes.json).toHaveBeenCalledWith(undefined);
122
122
  });
@@ -22,6 +22,7 @@ export declare class HazelApp {
22
22
  private shutdownManager;
23
23
  private healthManager;
24
24
  private requestTimeout;
25
+ private globalPrefix;
25
26
  private corsEnabled;
26
27
  private corsOptions?;
27
28
  private timeoutMiddleware?;
@@ -69,6 +70,11 @@ export declare class HazelApp {
69
70
  * Set request timeout
70
71
  */
71
72
  setRequestTimeout(timeout: number, options?: TimeoutOptions): void;
73
+ /**
74
+ * Set a global prefix for all routes (e.g. '/api/v1').
75
+ * Requests that don't match the prefix will receive a 404.
76
+ */
77
+ setGlobalPrefix(prefix: string): void;
72
78
  /**
73
79
  * Enable CORS
74
80
  */
@@ -1 +1 @@
1
- {"version":3,"file":"hazel-app.d.ts","sourceRoot":"","sources":["../src/hazel-app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hazel-app.d.ts","sourceRoot":"","sources":["../src/hazel-app.ts"],"names":[],"mappings":"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"}
package/dist/hazel-app.js CHANGED
@@ -61,12 +61,32 @@ class HttpResponse {
61
61
  this.res.writeHead(statusCode, { ...this.headers, Location: url });
62
62
  this.res.end();
63
63
  }
64
+ sse() {
65
+ if (!this.headersSent) {
66
+ this.headersSent = true;
67
+ this.res.writeHead(this.statusCode, {
68
+ 'Content-Type': 'text/event-stream',
69
+ 'Cache-Control': 'no-cache',
70
+ 'Connection': 'keep-alive',
71
+ 'Access-Control-Allow-Origin': '*',
72
+ });
73
+ }
74
+ return {
75
+ write: (data) => {
76
+ this.res.write(data);
77
+ },
78
+ end: () => {
79
+ this.res.end();
80
+ },
81
+ };
82
+ }
64
83
  }
65
84
  class HazelApp {
66
85
  constructor(moduleType) {
67
86
  this.moduleType = moduleType;
68
87
  this.server = null;
69
88
  this.requestTimeout = 30000; // 30 seconds default
89
+ this.globalPrefix = '';
70
90
  this.corsEnabled = false;
71
91
  this.earlyHandlers = [];
72
92
  this.proxyHandlers = [];
@@ -275,6 +295,19 @@ class HazelApp {
275
295
  }
276
296
  throw error;
277
297
  }
298
+ // Strip global prefix from URL before routing
299
+ if (this.globalPrefix && req.url) {
300
+ const urlPath = req.url.split('?')[0];
301
+ if (urlPath === this.globalPrefix || urlPath.startsWith(this.globalPrefix + '/')) {
302
+ req.url = req.url.slice(this.globalPrefix.length) || '/';
303
+ }
304
+ else {
305
+ // URL doesn't match the global prefix → 404
306
+ res.writeHead(404, { 'Content-Type': 'application/json' });
307
+ res.end(JSON.stringify({ statusCode: 404, message: 'Not Found' }));
308
+ return;
309
+ }
310
+ }
278
311
  // Proxy handlers (e.g. API gateway) - run before router
279
312
  const pathname = (req.url || '/').split('?')[0];
280
313
  for (const { pathPrefix, handler } of this.proxyHandlers) {
@@ -456,6 +489,18 @@ class HazelApp {
456
489
  this.timeoutMiddleware = new timeout_middleware_1.TimeoutMiddleware({ ...options, timeout });
457
490
  logger_1.default.debug(`Request timeout set to ${timeout}ms`);
458
491
  }
492
+ /**
493
+ * Set a global prefix for all routes (e.g. '/api/v1').
494
+ * Requests that don't match the prefix will receive a 404.
495
+ */
496
+ setGlobalPrefix(prefix) {
497
+ // Normalize: ensure leading slash, no trailing slash
498
+ this.globalPrefix = prefix.startsWith('/') ? prefix : `/${prefix}`;
499
+ if (this.globalPrefix.endsWith('/')) {
500
+ this.globalPrefix = this.globalPrefix.slice(0, -1);
501
+ }
502
+ logger_1.default.debug(`Global prefix set to "${this.globalPrefix}"`);
503
+ }
459
504
  /**
460
505
  * Enable CORS
461
506
  */
@@ -9,10 +9,11 @@ export interface HazelResponse {
9
9
  /** Send a Buffer as binary (e.g. audio, PDF). Sets Content-Type if provided. */
10
10
  sendBuffer?(buffer: Buffer, contentType?: string): void;
11
11
  }
12
- export declare class HazelExpressResponse implements HazelResponse {
12
+ export declare class HazelHttpResponse implements HazelResponse {
13
13
  private res;
14
14
  private isStreaming;
15
15
  private headersSent;
16
+ private customHeaders;
16
17
  constructor(res: Response);
17
18
  setHeader(name: string, value: string): void;
18
19
  write(chunk: string): void;
@@ -21,5 +22,9 @@ export declare class HazelExpressResponse implements HazelResponse {
21
22
  redirect(url: string, statusCode?: number): void;
22
23
  sendBuffer(buffer: Buffer, contentType?: string): void;
23
24
  json(data: unknown): void;
25
+ sse(): {
26
+ write: (data: string) => void;
27
+ end: () => void;
28
+ };
24
29
  }
25
30
  //# sourceMappingURL=hazel-response.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hazel-response.d.ts","sourceRoot":"","sources":["../src/hazel-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC;IACZ,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,gFAAgF;IAChF,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzD;AAED,qBAAa,oBAAqB,YAAW,aAAa;IAI5C,OAAO,CAAC,GAAG;IAHvB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAAkB;gBAEjB,GAAG,EAAE,QAAQ;IAEjC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM5C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAY1B,GAAG,IAAI,IAAI;IAMX,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IAOnC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,GAAG,IAAI;IAWrD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAWtD,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CA+B1B"}
1
+ {"version":3,"file":"hazel-response.d.ts","sourceRoot":"","sources":["../src/hazel-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC;IACZ,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,gFAAgF;IAChF,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzD;AAED,qBAAa,iBAAkB,YAAW,aAAa;IAKzC,OAAO,CAAC,GAAG;IAJvB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAA8B;gBAE/B,GAAG,EAAE,QAAQ;IAEjC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAO5C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAe1B,GAAG,IAAI,IAAI;IAMX,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IAOnC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,GAAG,IAAI;IAWrD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAWtD,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAgCzB,GAAG,IAAI;QAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,IAAI,CAAA;KAAE;CAkB1D"}
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HazelExpressResponse = void 0;
4
- class HazelExpressResponse {
3
+ exports.HazelHttpResponse = void 0;
4
+ class HazelHttpResponse {
5
5
  constructor(res) {
6
6
  this.res = res;
7
7
  this.isStreaming = false;
8
8
  this.headersSent = false;
9
+ this.customHeaders = {};
9
10
  }
10
11
  setHeader(name, value) {
11
12
  if (!this.headersSent) {
13
+ this.customHeaders[name] = value;
12
14
  this.res.setHeader(name, value);
13
15
  }
14
16
  }
@@ -16,7 +18,10 @@ class HazelExpressResponse {
16
18
  if (!this.isStreaming) {
17
19
  this.isStreaming = true;
18
20
  this.headersSent = true;
19
- this.res.setHeader('Content-Type', 'text/plain');
21
+ // Only set Content-Type if not already set
22
+ if (!this.customHeaders['Content-Type']) {
23
+ this.res.setHeader('Content-Type', 'text/plain');
24
+ }
20
25
  this.res.setHeader('Transfer-Encoding', 'chunked');
21
26
  this.res.send(chunk);
22
27
  }
@@ -85,5 +90,22 @@ class HazelExpressResponse {
85
90
  this.res.json({ error: 'Failed to serialize response' });
86
91
  }
87
92
  }
93
+ sse() {
94
+ if (!this.headersSent) {
95
+ this.headersSent = true;
96
+ this.isStreaming = true;
97
+ this.res.setHeader('Content-Type', 'text/event-stream');
98
+ this.res.setHeader('Cache-Control', 'no-cache');
99
+ this.res.setHeader('Connection', 'keep-alive');
100
+ }
101
+ return {
102
+ write: (data) => {
103
+ this.res.send(data);
104
+ },
105
+ end: () => {
106
+ this.res.end();
107
+ },
108
+ };
109
+ }
88
110
  }
89
- exports.HazelExpressResponse = HazelExpressResponse;
111
+ exports.HazelHttpResponse = HazelHttpResponse;
package/dist/router.js CHANGED
@@ -205,7 +205,7 @@ class Router {
205
205
  }
206
206
  else if (injection.type === 'response') {
207
207
  // Handle @Res decorator
208
- args[i] = new hazel_response_1.HazelExpressResponse(res);
208
+ args[i] = new hazel_response_1.HazelHttpResponse(res);
209
209
  }
210
210
  else if (injection.type === 'body') {
211
211
  // Handle @Body decorator with DTO type
package/dist/types.d.ts CHANGED
@@ -40,6 +40,11 @@ export type Response = {
40
40
  send: (data: string) => void;
41
41
  setHeader: (name: string, value: string) => void;
42
42
  end: () => void;
43
+ /** Start SSE streaming - sets headers and returns write function */
44
+ sse: () => {
45
+ write: (data: string) => void;
46
+ end: () => void;
47
+ };
43
48
  };
44
49
  export interface RequestContext {
45
50
  method: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1B,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7B,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzB,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC7C,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAC;IACnC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,yEAAyE;IACzE,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAA;KAAE,CAAC;CACrF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/core",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
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": "b43901feaa561a191242c34acabefa531dd1d21d"
66
+ "gitHead": "e0c2d21ace726f2a0bf20c5baefad02e1e681ba9"
67
67
  }