ai.matey.http 0.2.0

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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/deno/adapter.js +173 -0
  3. package/dist/cjs/deno/adapter.js.map +1 -0
  4. package/dist/cjs/deno/handler.js +78 -0
  5. package/dist/cjs/deno/handler.js.map +1 -0
  6. package/dist/cjs/deno/index.js +26 -0
  7. package/dist/cjs/deno/index.js.map +1 -0
  8. package/dist/cjs/express/adapter.js +150 -0
  9. package/dist/cjs/express/adapter.js.map +1 -0
  10. package/dist/cjs/express/index.js +26 -0
  11. package/dist/cjs/express/index.js.map +1 -0
  12. package/dist/cjs/express/middleware.js +63 -0
  13. package/dist/cjs/express/middleware.js.map +1 -0
  14. package/dist/cjs/fastify/adapter.js +149 -0
  15. package/dist/cjs/fastify/adapter.js.map +1 -0
  16. package/dist/cjs/fastify/handler.js +54 -0
  17. package/dist/cjs/fastify/handler.js.map +1 -0
  18. package/dist/cjs/fastify/index.js +26 -0
  19. package/dist/cjs/fastify/index.js.map +1 -0
  20. package/dist/cjs/hono/adapter.js +172 -0
  21. package/dist/cjs/hono/adapter.js.map +1 -0
  22. package/dist/cjs/hono/index.js +26 -0
  23. package/dist/cjs/hono/index.js.map +1 -0
  24. package/dist/cjs/hono/middleware.js +75 -0
  25. package/dist/cjs/hono/middleware.js.map +1 -0
  26. package/dist/cjs/index.js +37 -0
  27. package/dist/cjs/index.js.map +1 -0
  28. package/dist/cjs/koa/adapter.js +153 -0
  29. package/dist/cjs/koa/adapter.js.map +1 -0
  30. package/dist/cjs/koa/index.js +26 -0
  31. package/dist/cjs/koa/index.js.map +1 -0
  32. package/dist/cjs/koa/middleware.js +58 -0
  33. package/dist/cjs/koa/middleware.js.map +1 -0
  34. package/dist/cjs/node/adapter.js +170 -0
  35. package/dist/cjs/node/adapter.js.map +1 -0
  36. package/dist/cjs/node/index.js +26 -0
  37. package/dist/cjs/node/index.js.map +1 -0
  38. package/dist/cjs/node/listener.js +98 -0
  39. package/dist/cjs/node/listener.js.map +1 -0
  40. package/dist/esm/deno/adapter.js +168 -0
  41. package/dist/esm/deno/adapter.js.map +1 -0
  42. package/dist/esm/deno/handler.js +75 -0
  43. package/dist/esm/deno/handler.js.map +1 -0
  44. package/dist/esm/deno/index.js +10 -0
  45. package/dist/esm/deno/index.js.map +1 -0
  46. package/dist/esm/express/adapter.js +145 -0
  47. package/dist/esm/express/adapter.js.map +1 -0
  48. package/dist/esm/express/index.js +10 -0
  49. package/dist/esm/express/index.js.map +1 -0
  50. package/dist/esm/express/middleware.js +60 -0
  51. package/dist/esm/express/middleware.js.map +1 -0
  52. package/dist/esm/fastify/adapter.js +144 -0
  53. package/dist/esm/fastify/adapter.js.map +1 -0
  54. package/dist/esm/fastify/handler.js +51 -0
  55. package/dist/esm/fastify/handler.js.map +1 -0
  56. package/dist/esm/fastify/index.js +10 -0
  57. package/dist/esm/fastify/index.js.map +1 -0
  58. package/dist/esm/hono/adapter.js +167 -0
  59. package/dist/esm/hono/adapter.js.map +1 -0
  60. package/dist/esm/hono/index.js +10 -0
  61. package/dist/esm/hono/index.js.map +1 -0
  62. package/dist/esm/hono/middleware.js +72 -0
  63. package/dist/esm/hono/middleware.js.map +1 -0
  64. package/dist/esm/index.js +21 -0
  65. package/dist/esm/index.js.map +1 -0
  66. package/dist/esm/koa/adapter.js +148 -0
  67. package/dist/esm/koa/adapter.js.map +1 -0
  68. package/dist/esm/koa/index.js +10 -0
  69. package/dist/esm/koa/index.js.map +1 -0
  70. package/dist/esm/koa/middleware.js +55 -0
  71. package/dist/esm/koa/middleware.js.map +1 -0
  72. package/dist/esm/node/adapter.js +165 -0
  73. package/dist/esm/node/adapter.js.map +1 -0
  74. package/dist/esm/node/index.js +10 -0
  75. package/dist/esm/node/index.js.map +1 -0
  76. package/dist/esm/node/listener.js +92 -0
  77. package/dist/esm/node/listener.js.map +1 -0
  78. package/dist/types/deno/adapter.d.ts +56 -0
  79. package/dist/types/deno/adapter.d.ts.map +1 -0
  80. package/dist/types/deno/handler.d.ts +38 -0
  81. package/dist/types/deno/handler.d.ts.map +1 -0
  82. package/dist/types/deno/index.d.ts +10 -0
  83. package/dist/types/deno/index.d.ts.map +1 -0
  84. package/dist/types/express/adapter.d.ts +46 -0
  85. package/dist/types/express/adapter.d.ts.map +1 -0
  86. package/dist/types/express/index.d.ts +10 -0
  87. package/dist/types/express/index.d.ts.map +1 -0
  88. package/dist/types/express/middleware.d.ts +39 -0
  89. package/dist/types/express/middleware.d.ts.map +1 -0
  90. package/dist/types/fastify/adapter.d.ts +46 -0
  91. package/dist/types/fastify/adapter.d.ts.map +1 -0
  92. package/dist/types/fastify/handler.d.ts +36 -0
  93. package/dist/types/fastify/handler.d.ts.map +1 -0
  94. package/dist/types/fastify/index.d.ts +10 -0
  95. package/dist/types/fastify/index.d.ts.map +1 -0
  96. package/dist/types/hono/adapter.d.ts +47 -0
  97. package/dist/types/hono/adapter.d.ts.map +1 -0
  98. package/dist/types/hono/index.d.ts +10 -0
  99. package/dist/types/hono/index.d.ts.map +1 -0
  100. package/dist/types/hono/middleware.d.ts +36 -0
  101. package/dist/types/hono/middleware.d.ts.map +1 -0
  102. package/dist/types/index.d.ts +15 -0
  103. package/dist/types/index.d.ts.map +1 -0
  104. package/dist/types/koa/adapter.d.ts +46 -0
  105. package/dist/types/koa/adapter.d.ts.map +1 -0
  106. package/dist/types/koa/index.d.ts +10 -0
  107. package/dist/types/koa/index.d.ts.map +1 -0
  108. package/dist/types/koa/middleware.d.ts +40 -0
  109. package/dist/types/koa/middleware.d.ts.map +1 -0
  110. package/dist/types/node/adapter.d.ts +57 -0
  111. package/dist/types/node/adapter.d.ts.map +1 -0
  112. package/dist/types/node/index.d.ts +10 -0
  113. package/dist/types/node/index.d.ts.map +1 -0
  114. package/dist/types/node/listener.d.ts +51 -0
  115. package/dist/types/node/listener.d.ts.map +1 -0
  116. package/package.json +160 -0
  117. package/readme.md +93 -0
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ /**
3
+ * Koa HTTP Adapter
4
+ *
5
+ * Converts Koa Context to GenericRequest/GenericResponse
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.KoaResponseAdapter = exports.KoaRequestAdapter = void 0;
11
+ const ai_matey_http_core_1 = require("ai.matey.http.core");
12
+ /**
13
+ * Adapter that converts Koa Context to GenericRequest
14
+ */
15
+ class KoaRequestAdapter {
16
+ ctx;
17
+ constructor(ctx) {
18
+ this.ctx = ctx;
19
+ }
20
+ get method() {
21
+ return this.ctx.method || 'GET';
22
+ }
23
+ get url() {
24
+ return this.ctx.originalUrl || this.ctx.url || '/';
25
+ }
26
+ get headers() {
27
+ const headers = {};
28
+ for (const [key, value] of Object.entries(this.ctx.headers)) {
29
+ if (typeof value === 'string') {
30
+ headers[key.toLowerCase()] = value;
31
+ }
32
+ else if (Array.isArray(value)) {
33
+ headers[key.toLowerCase()] = value.join(', ');
34
+ }
35
+ }
36
+ return headers;
37
+ }
38
+ get body() {
39
+ // Koa body is already parsed if koa-bodyparser middleware is used
40
+ return this.ctx.request.body ?? null;
41
+ }
42
+ get params() {
43
+ // Koa router stores params in ctx.params
44
+ return this.ctx.params;
45
+ }
46
+ get query() {
47
+ // Koa query is available as ctx.query
48
+ const query = {};
49
+ for (const [key, value] of Object.entries(this.ctx.query)) {
50
+ if (typeof value === 'string') {
51
+ query[key] = value;
52
+ }
53
+ else if (Array.isArray(value)) {
54
+ query[key] = value.join(',');
55
+ }
56
+ else if (value !== undefined) {
57
+ query[key] = String(value);
58
+ }
59
+ }
60
+ return Object.keys(query).length > 0 ? query : undefined;
61
+ }
62
+ get ip() {
63
+ // Koa provides IP through ctx.ip
64
+ return this.ctx.ip || this.ctx.request.socket?.remoteAddress;
65
+ }
66
+ /**
67
+ * Get the underlying Koa context object
68
+ */
69
+ get raw() {
70
+ return this.ctx;
71
+ }
72
+ }
73
+ exports.KoaRequestAdapter = KoaRequestAdapter;
74
+ /**
75
+ * Adapter that converts GenericResponse methods to Koa Context
76
+ */
77
+ class KoaResponseAdapter {
78
+ ctx;
79
+ _statusCode = 200;
80
+ _headersSent = false;
81
+ constructor(ctx) {
82
+ this.ctx = ctx;
83
+ }
84
+ status(code) {
85
+ this._statusCode = code;
86
+ if (!this._headersSent) {
87
+ this.ctx.status = code;
88
+ }
89
+ }
90
+ header(name, value) {
91
+ if (!this._headersSent) {
92
+ this.ctx.set(name, value);
93
+ }
94
+ }
95
+ send(data) {
96
+ if (!this.isWritable()) {
97
+ return;
98
+ }
99
+ this._headersSent = true;
100
+ // Handle empty string (e.g., for CORS preflight 204 responses)
101
+ if (data === '') {
102
+ this.ctx.body = '';
103
+ return;
104
+ }
105
+ // Koa automatically JSON-stringifies objects
106
+ this.ctx.status = this._statusCode;
107
+ this.ctx.body = data;
108
+ }
109
+ async stream(generator) {
110
+ if (!this.isWritable()) {
111
+ return;
112
+ }
113
+ this._headersSent = true;
114
+ // Get the underlying Node.js response for SSE
115
+ const nodeRes = this.ctx.res;
116
+ // Set SSE headers
117
+ (0, ai_matey_http_core_1.sendSSEHeaders)(nodeRes, {});
118
+ // Set Koa to not handle the response
119
+ this.ctx.respond = false;
120
+ try {
121
+ // Stream chunks
122
+ for await (const chunk of generator) {
123
+ if (!this.isWritable()) {
124
+ break;
125
+ }
126
+ (0, ai_matey_http_core_1.sendSSEChunk)(nodeRes, chunk);
127
+ }
128
+ // Send done marker
129
+ if (this.isWritable()) {
130
+ (0, ai_matey_http_core_1.sendSSEDone)(nodeRes);
131
+ }
132
+ }
133
+ catch (error) {
134
+ // If error occurs during streaming, we can't change status code
135
+ // Just log and close
136
+ console.error('Streaming error:', error);
137
+ if (this.isWritable()) {
138
+ nodeRes.end();
139
+ }
140
+ }
141
+ }
142
+ isWritable() {
143
+ return !this.ctx.response.headerSent && this.ctx.writable;
144
+ }
145
+ /**
146
+ * Get the underlying Koa context object
147
+ */
148
+ get raw() {
149
+ return this.ctx;
150
+ }
151
+ }
152
+ exports.KoaResponseAdapter = KoaResponseAdapter;
153
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/koa/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * Koa HTTP Adapter
4
+ *
5
+ * HTTP adapter for Koa
6
+ *
7
+ * @module
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ __exportStar(require("./adapter.js"), exports);
25
+ __exportStar(require("./middleware.js"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/koa/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;AAEH,+CAA6B;AAC7B,kDAAgC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * Koa Middleware
4
+ *
5
+ * HTTP request middleware for Koa that uses the core handler.
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.KoaMiddleware = KoaMiddleware;
11
+ const ai_matey_http_core_1 = require("ai.matey.http.core");
12
+ const adapter_js_1 = require("./adapter.js");
13
+ /**
14
+ * Create Koa middleware for handling AI chat requests
15
+ *
16
+ * @param bridge - Bridge instance
17
+ * @param options - HTTP listener options
18
+ * @returns Koa middleware function
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import Koa from 'koa';
23
+ * import bodyParser from 'koa-bodyparser';
24
+ * import { KoaMiddleware } from 'ai.matey.http/koa';
25
+ *
26
+ * const app = new Koa();
27
+ * const bridge = new Bridge(frontend, backend);
28
+ *
29
+ * // Use body parser middleware first
30
+ * app.use(bodyParser());
31
+ *
32
+ * // Add AI chat middleware
33
+ * app.use(KoaMiddleware(bridge, {
34
+ * cors: true,
35
+ * streaming: true,
36
+ * }));
37
+ *
38
+ * app.listen(3000);
39
+ * ```
40
+ */
41
+ function KoaMiddleware(bridge, options = {}) {
42
+ // Create core handler with all business logic
43
+ const { cors, ...restOptions } = options;
44
+ const coreHandler = new ai_matey_http_core_1.CoreHTTPHandler({
45
+ bridge,
46
+ cors: cors === false || cors === undefined ? undefined : cors === true ? {} : cors,
47
+ ...restOptions, // HTTPListenerOptions types are compatible with CoreHandlerOptions at runtime
48
+ });
49
+ // Return Koa middleware
50
+ return async (ctx, _next) => {
51
+ // Create adapters
52
+ const genericReq = new adapter_js_1.KoaRequestAdapter(ctx);
53
+ const genericRes = new adapter_js_1.KoaResponseAdapter(ctx);
54
+ // Handle request through core handler
55
+ await coreHandler.handle(genericReq, genericRes);
56
+ };
57
+ }
58
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/koa/middleware.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAoCH,sCAsBC;AArDD,2DAAqD;AACrD,6CAAqE;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,aAAa,CAC3B,MAAc,EACd,UAA+B,EAAE;IAEjC,8CAA8C;IAC9C,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;IAEzC,MAAM,WAAW,GAAG,IAAI,oCAAe,CAAC;QACtC,MAAM;QACN,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;QAClF,GAAI,WAAmB,EAAE,8EAA8E;KACxG,CAAC,CAAC;IAEH,wBAAwB;IACxB,OAAO,KAAK,EAAE,GAAY,EAAE,KAAW,EAAiB,EAAE;QACxD,kBAAkB;QAClB,MAAM,UAAU,GAAG,IAAI,8BAAiB,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,IAAI,+BAAkB,CAAC,GAAG,CAAC,CAAC;QAE/C,sCAAsC;QACtC,MAAM,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ /**
3
+ * Node.js HTTP Adapter
4
+ *
5
+ * Converts Node.js IncomingMessage/ServerResponse to GenericRequest/GenericResponse
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.NodeResponseAdapter = exports.NodeRequestAdapter = void 0;
11
+ const ai_matey_http_core_1 = require("ai.matey.http.core");
12
+ /**
13
+ * Adapter that converts Node.js IncomingMessage to GenericRequest
14
+ */
15
+ class NodeRequestAdapter {
16
+ req;
17
+ maxBodySize;
18
+ _parsed = null;
19
+ _parsePromise = null;
20
+ constructor(req, maxBodySize = 10 * 1024 * 1024) {
21
+ this.req = req;
22
+ this.maxBodySize = maxBodySize;
23
+ }
24
+ /**
25
+ * Parse the request body if not already parsed
26
+ */
27
+ async ensureParsed() {
28
+ if (this._parsed) {
29
+ return;
30
+ }
31
+ // Avoid multiple simultaneous parse calls
32
+ if (this._parsePromise) {
33
+ await this._parsePromise;
34
+ return;
35
+ }
36
+ this._parsePromise = (async () => {
37
+ this._parsed = await (0, ai_matey_http_core_1.parseRequest)(this.req, this.maxBodySize);
38
+ })();
39
+ await this._parsePromise;
40
+ }
41
+ get method() {
42
+ return this.req.method || 'GET';
43
+ }
44
+ get url() {
45
+ return this.req.url || '/';
46
+ }
47
+ get headers() {
48
+ const headers = {};
49
+ for (const [key, value] of Object.entries(this.req.headers)) {
50
+ if (typeof value === 'string') {
51
+ headers[key.toLowerCase()] = value;
52
+ }
53
+ else if (Array.isArray(value)) {
54
+ headers[key.toLowerCase()] = value.join(', ');
55
+ }
56
+ }
57
+ return headers;
58
+ }
59
+ get body() {
60
+ // Return parsed body if available, null otherwise
61
+ return this._parsed?.body ?? null;
62
+ }
63
+ get params() {
64
+ // ParsedRequest doesn't have params, so return undefined
65
+ return undefined;
66
+ }
67
+ get query() {
68
+ return this._parsed?.query;
69
+ }
70
+ get ip() {
71
+ // Try various sources for IP address
72
+ const forwarded = this.req.headers['x-forwarded-for'];
73
+ if (typeof forwarded === 'string') {
74
+ return forwarded.split(',')[0]?.trim();
75
+ }
76
+ const realIp = this.req.headers['x-real-ip'];
77
+ if (typeof realIp === 'string') {
78
+ return realIp;
79
+ }
80
+ const socket = this.req.socket;
81
+ return socket?.remoteAddress;
82
+ }
83
+ /**
84
+ * Get the underlying Node.js request object
85
+ */
86
+ get raw() {
87
+ return this.req;
88
+ }
89
+ /**
90
+ * Parse the request body (called by core handler before accessing body)
91
+ */
92
+ async parse() {
93
+ await this.ensureParsed();
94
+ }
95
+ }
96
+ exports.NodeRequestAdapter = NodeRequestAdapter;
97
+ /**
98
+ * Adapter that converts GenericResponse methods to Node.js ServerResponse
99
+ */
100
+ class NodeResponseAdapter {
101
+ res;
102
+ _statusCode = 200;
103
+ _headersSent = false;
104
+ constructor(res) {
105
+ this.res = res;
106
+ }
107
+ status(code) {
108
+ this._statusCode = code;
109
+ if (!this._headersSent) {
110
+ this.res.statusCode = code;
111
+ }
112
+ }
113
+ header(name, value) {
114
+ if (!this._headersSent) {
115
+ this.res.setHeader(name, value);
116
+ }
117
+ }
118
+ send(data) {
119
+ if (!this.isWritable()) {
120
+ return;
121
+ }
122
+ this._headersSent = true;
123
+ // Handle empty string (e.g., for CORS preflight 204 responses)
124
+ if (data === '') {
125
+ this.res.end();
126
+ return;
127
+ }
128
+ (0, ai_matey_http_core_1.sendJSON)(this.res, data, this._statusCode);
129
+ }
130
+ async stream(generator) {
131
+ if (!this.isWritable()) {
132
+ return;
133
+ }
134
+ this._headersSent = true;
135
+ // Set SSE headers
136
+ (0, ai_matey_http_core_1.sendSSEHeaders)(this.res, {});
137
+ try {
138
+ // Stream chunks
139
+ for await (const chunk of generator) {
140
+ if (!this.isWritable()) {
141
+ break;
142
+ }
143
+ (0, ai_matey_http_core_1.sendSSEChunk)(this.res, chunk);
144
+ }
145
+ // Send done marker
146
+ if (this.isWritable()) {
147
+ (0, ai_matey_http_core_1.sendSSEDone)(this.res);
148
+ }
149
+ }
150
+ catch (error) {
151
+ // If error occurs during streaming, we can't change status code
152
+ // Just log and close
153
+ console.error('Streaming error:', error);
154
+ if (this.isWritable()) {
155
+ this.res.end();
156
+ }
157
+ }
158
+ }
159
+ isWritable() {
160
+ return this.res.writable && !this.res.headersSent;
161
+ }
162
+ /**
163
+ * Get the underlying Node.js response object
164
+ */
165
+ get raw() {
166
+ return this.res;
167
+ }
168
+ }
169
+ exports.NodeResponseAdapter = NodeResponseAdapter;
170
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/node/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * Node.js HTTP Adapter
4
+ *
5
+ * HTTP adapter for Node.js http.Server
6
+ *
7
+ * @module
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ __exportStar(require("./adapter.js"), exports);
25
+ __exportStar(require("./listener.js"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/node/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;AAEH,+CAA6B;AAC7B,gDAA8B"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ /**
3
+ * Node.js HTTP Listener
4
+ *
5
+ * HTTP request handler for Node.js http.Server that uses the core handler.
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.NodeHTTPListener = NodeHTTPListener;
11
+ exports.createSimpleListener = createSimpleListener;
12
+ exports.createLoggingListener = createLoggingListener;
13
+ exports.createSecureListener = createSecureListener;
14
+ const ai_matey_http_core_1 = require("ai.matey.http.core");
15
+ const adapter_js_1 = require("./adapter.js");
16
+ /**
17
+ * Create Node.js HTTP request handler
18
+ *
19
+ * @param bridge - Bridge instance
20
+ * @param options - HTTP listener options
21
+ * @returns HTTP request handler function
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { createServer } from 'http';
26
+ * import { NodeHTTPListener } from 'ai.matey.http/node';
27
+ *
28
+ * const bridge = new Bridge(frontend, backend);
29
+ *
30
+ * const server = createServer(
31
+ * NodeHTTPListener(bridge, {
32
+ * cors: true,
33
+ * streaming: true,
34
+ * })
35
+ * );
36
+ *
37
+ * server.listen(3000);
38
+ * ```
39
+ */
40
+ function NodeHTTPListener(bridge, options = {}) {
41
+ // Create core handler with all business logic
42
+ // Extract cors option to normalize it
43
+ const { cors, ...restOptions } = options;
44
+ const coreHandler = new ai_matey_http_core_1.CoreHTTPHandler({
45
+ bridge,
46
+ cors: cors === false || cors === undefined ? undefined : cors === true ? {} : cors,
47
+ ...restOptions, // HTTPListenerOptions types are compatible with CoreHandlerOptions at runtime
48
+ });
49
+ // Get max body size for adapter
50
+ const maxBodySize = options.maxBodySize ?? 10 * 1024 * 1024;
51
+ // Return Node.js request handler
52
+ return async (req, res) => {
53
+ // Set timeout if configured
54
+ const timeout = options.timeout ?? 30000;
55
+ req.setTimeout?.(timeout);
56
+ res.setTimeout?.(timeout);
57
+ // Create adapters
58
+ const genericReq = new adapter_js_1.NodeRequestAdapter(req, maxBodySize);
59
+ const genericRes = new adapter_js_1.NodeResponseAdapter(res);
60
+ // Parse request body before passing to core handler
61
+ await genericReq.parse();
62
+ // Handle request through core handler
63
+ await coreHandler.handle(genericReq, genericRes);
64
+ };
65
+ }
66
+ /**
67
+ * Create simple HTTP listener without advanced features
68
+ */
69
+ function createSimpleListener(bridge) {
70
+ return NodeHTTPListener(bridge, {
71
+ cors: true,
72
+ streaming: true,
73
+ logging: false,
74
+ });
75
+ }
76
+ /**
77
+ * Create HTTP listener with logging enabled
78
+ */
79
+ function createLoggingListener(bridge, log) {
80
+ return NodeHTTPListener(bridge, {
81
+ cors: true,
82
+ streaming: true,
83
+ logging: true,
84
+ log,
85
+ });
86
+ }
87
+ /**
88
+ * Create HTTP listener with auth and rate limiting
89
+ */
90
+ function createSecureListener(bridge, options) {
91
+ return NodeHTTPListener(bridge, {
92
+ validateAuth: options.validateAuth,
93
+ rateLimit: options.rateLimit,
94
+ cors: options.cors ?? true,
95
+ streaming: true,
96
+ });
97
+ }
98
+ //# sourceMappingURL=listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listener.js","sourceRoot":"","sources":["../../../src/node/listener.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAgCH,4CAkCC;AAKD,oDAMC;AAKD,sDAUC;AAKD,oDAcC;AA1GD,2DAAqD;AACrD,6CAAuE;AAEvE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,gBAAgB,CAC9B,MAAc,EACd,UAA+B,EAAE;IAEjC,8CAA8C;IAC9C,sCAAsC;IACtC,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;IAEzC,MAAM,WAAW,GAAG,IAAI,oCAAe,CAAC;QACtC,MAAM;QACN,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;QAClF,GAAI,WAAmB,EAAE,8EAA8E;KACxG,CAAC,CAAC;IAEH,gCAAgC;IAChC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;IAE5D,iCAAiC;IACjC,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,4BAA4B;QAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;QACzC,GAAG,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC;QAC1B,GAAG,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC;QAE1B,kBAAkB;QAClB,MAAM,UAAU,GAAG,IAAI,+BAAkB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,gCAAmB,CAAC,GAAG,CAAC,CAAC;QAEhD,oDAAoD;QACpD,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;QAEzB,sCAAsC;QACtC,MAAM,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,MAAc;IACjD,OAAO,gBAAgB,CAAC,MAAM,EAAE;QAC9B,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CACnC,MAAc,EACd,GAA+C;IAE/C,OAAO,gBAAgB,CAAC,MAAM,EAAE;QAC9B,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,IAAI;QACb,GAAG;KACJ,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,MAAc,EACd,OAIC;IAED,OAAO,gBAAgB,CAAC,MAAM,EAAE;QAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;QAC1B,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC"}