ai.matey.http.core 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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/auth.js +173 -0
  3. package/dist/cjs/auth.js.map +1 -0
  4. package/dist/cjs/cors.js +140 -0
  5. package/dist/cjs/cors.js.map +1 -0
  6. package/dist/cjs/error-handler.js +147 -0
  7. package/dist/cjs/error-handler.js.map +1 -0
  8. package/dist/cjs/handler.js +335 -0
  9. package/dist/cjs/handler.js.map +1 -0
  10. package/dist/cjs/health.js +218 -0
  11. package/dist/cjs/health.js.map +1 -0
  12. package/dist/cjs/index.js +83 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/rate-limiter.js +163 -0
  15. package/dist/cjs/rate-limiter.js.map +1 -0
  16. package/dist/cjs/request-parser.js +141 -0
  17. package/dist/cjs/request-parser.js.map +1 -0
  18. package/dist/cjs/response-formatter.js +218 -0
  19. package/dist/cjs/response-formatter.js.map +1 -0
  20. package/dist/cjs/route-matcher.js +178 -0
  21. package/dist/cjs/route-matcher.js.map +1 -0
  22. package/dist/cjs/streaming-handler.js +120 -0
  23. package/dist/cjs/streaming-handler.js.map +1 -0
  24. package/dist/cjs/types.js +11 -0
  25. package/dist/cjs/types.js.map +1 -0
  26. package/dist/esm/auth.js +163 -0
  27. package/dist/esm/auth.js.map +1 -0
  28. package/dist/esm/cors.js +134 -0
  29. package/dist/esm/cors.js.map +1 -0
  30. package/dist/esm/error-handler.js +137 -0
  31. package/dist/esm/error-handler.js.map +1 -0
  32. package/dist/esm/handler.js +331 -0
  33. package/dist/esm/handler.js.map +1 -0
  34. package/dist/esm/health.js +210 -0
  35. package/dist/esm/health.js.map +1 -0
  36. package/dist/esm/index.js +30 -0
  37. package/dist/esm/index.js.map +1 -0
  38. package/dist/esm/rate-limiter.js +156 -0
  39. package/dist/esm/rate-limiter.js.map +1 -0
  40. package/dist/esm/request-parser.js +136 -0
  41. package/dist/esm/request-parser.js.map +1 -0
  42. package/dist/esm/response-formatter.js +206 -0
  43. package/dist/esm/response-formatter.js.map +1 -0
  44. package/dist/esm/route-matcher.js +171 -0
  45. package/dist/esm/route-matcher.js.map +1 -0
  46. package/dist/esm/streaming-handler.js +112 -0
  47. package/dist/esm/streaming-handler.js.map +1 -0
  48. package/dist/esm/types.js +10 -0
  49. package/dist/esm/types.js.map +1 -0
  50. package/dist/types/auth.d.ts +37 -0
  51. package/dist/types/auth.d.ts.map +1 -0
  52. package/dist/types/cors.d.ts +26 -0
  53. package/dist/types/cors.d.ts.map +1 -0
  54. package/dist/types/error-handler.d.ts +38 -0
  55. package/dist/types/error-handler.d.ts.map +1 -0
  56. package/dist/types/handler.d.ts +45 -0
  57. package/dist/types/handler.d.ts.map +1 -0
  58. package/dist/types/health.d.ts +164 -0
  59. package/dist/types/health.d.ts.map +1 -0
  60. package/dist/types/index.d.ts +21 -0
  61. package/dist/types/index.d.ts.map +1 -0
  62. package/dist/types/rate-limiter.d.ts +56 -0
  63. package/dist/types/rate-limiter.d.ts.map +1 -0
  64. package/dist/types/request-parser.d.ts +22 -0
  65. package/dist/types/request-parser.d.ts.map +1 -0
  66. package/dist/types/response-formatter.d.ts +49 -0
  67. package/dist/types/response-formatter.d.ts.map +1 -0
  68. package/dist/types/route-matcher.d.ts +45 -0
  69. package/dist/types/route-matcher.d.ts.map +1 -0
  70. package/dist/types/streaming-handler.d.ts +40 -0
  71. package/dist/types/streaming-handler.d.ts.map +1 -0
  72. package/dist/types/types.d.ts +398 -0
  73. package/dist/types/types.d.ts.map +1 -0
  74. package/package.json +73 -0
  75. package/readme.md +60 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,eAAe;AACf,2CAA+C;AAAtC,6GAAA,eAAe,OAAA;AA2BxB,kBAAkB;AAClB,yDAAoF;AAA3E,iHAAA,YAAY,OAAA;AAAE,uHAAA,kBAAkB,OAAA;AAAE,gHAAA,WAAW,OAAA;AAEtD,sBAAsB;AACtB,iEAWiC;AAV/B,iHAAA,QAAQ,OAAA;AACR,kHAAA,SAAS,OAAA;AACT,uHAAA,cAAc,OAAA;AACd,qHAAA,YAAY,OAAA;AACZ,qHAAA,YAAY,OAAA;AACZ,oHAAA,WAAW,OAAA;AACX,qHAAA,YAAY,OAAA;AACZ,iHAAA,QAAQ,OAAA;AACR,sHAAA,aAAa,OAAA;AACb,6HAAA,oBAAoB,OAAA;AAGtB,OAAO;AACP,qCAA2F;AAAlF,+GAAA,oBAAoB,OAAA;AAAE,qGAAA,UAAU,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,sGAAA,WAAW,OAAA;AAEvE,iBAAiB;AACjB,qCAQmB;AAPjB,+GAAA,oBAAoB,OAAA;AACpB,qHAAA,0BAA0B,OAAA;AAC1B,gHAAA,qBAAqB,OAAA;AACrB,mHAAA,wBAAwB,OAAA;AACxB,gHAAA,qBAAqB,OAAA;AACrB,yGAAA,cAAc,OAAA;AACd,2GAAA,gBAAgB,OAAA;AAGlB,gBAAgB;AAChB,qDAK2B;AAJzB,8GAAA,WAAW,OAAA;AACX,qHAAA,kBAAkB,OAAA;AAClB,oHAAA,iBAAiB,OAAA;AACjB,uHAAA,oBAAoB,OAAA;AAGtB,iBAAiB;AACjB,uDAQ4B;AAP1B,uHAAA,mBAAmB,OAAA;AACnB,6HAAA,yBAAyB,OAAA;AACzB,+HAAA,2BAA2B,OAAA;AAC3B,oHAAA,gBAAgB,OAAA;AAChB,oHAAA,gBAAgB,OAAA;AAChB,iHAAA,aAAa,OAAA;AACb,iHAAA,aAAa,OAAA;AAGf,YAAY;AACZ,+DAMgC;AAL9B,8HAAA,sBAAsB,OAAA;AACtB,oHAAA,YAAY,OAAA;AACZ,0HAAA,kBAAkB,OAAA;AAClB,yHAAA,iBAAiB,OAAA;AACjB,6HAAA,qBAAqB,OAAA;AAGvB,UAAU;AACV,uDAK4B;AAJ1B,gHAAA,YAAY,OAAA;AACZ,uHAAA,mBAAmB,OAAA;AACnB,iHAAA,aAAa,OAAA;AACb,mHAAA,eAAe,OAAA;AAGjB,gBAAgB;AAChB,yCAUqB;AATnB,wGAAA,WAAW,OAAA;AACX,8GAAA,iBAAiB,OAAA;AACjB,wHAAA,2BAA2B,OAAA;AAC3B,iHAAA,oBAAoB,OAAA;AACpB,gHAAA,mBAAmB,OAAA"}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ /**
3
+ * Rate Limiter
4
+ *
5
+ * Implements rate limiting for HTTP requests using a sliding window algorithm.
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.RateLimiter = void 0;
11
+ exports.userIDKeyGenerator = userIDKeyGenerator;
12
+ exports.tokenKeyGenerator = tokenKeyGenerator;
13
+ exports.combineKeyGenerators = combineKeyGenerators;
14
+ const request_parser_js_1 = require("./request-parser.js");
15
+ const response_formatter_js_1 = require("./response-formatter.js");
16
+ /**
17
+ * Rate limiter class
18
+ */
19
+ class RateLimiter {
20
+ options;
21
+ store;
22
+ cleanupIntervalId;
23
+ constructor(options) {
24
+ this.options = {
25
+ max: options.max,
26
+ windowMs: options.windowMs ?? 60000, // 1 minute default
27
+ keyGenerator: options.keyGenerator ?? defaultKeyGenerator,
28
+ handler: options.handler ?? defaultRateLimitHandler,
29
+ skip: options.skip ?? (() => false),
30
+ headers: options.headers ?? true,
31
+ };
32
+ this.store = new Map();
33
+ // Cleanup old entries periodically
34
+ this.cleanupIntervalId = setInterval(() => this.cleanup(), this.options.windowMs);
35
+ }
36
+ /**
37
+ * Dispose of the rate limiter and clean up resources.
38
+ * Call this when the rate limiter is no longer needed to prevent memory leaks.
39
+ */
40
+ dispose() {
41
+ if (this.cleanupIntervalId) {
42
+ clearInterval(this.cleanupIntervalId);
43
+ this.cleanupIntervalId = undefined;
44
+ }
45
+ this.store.clear();
46
+ }
47
+ /**
48
+ * Check if request should be rate limited
49
+ */
50
+ async check(req, res) {
51
+ // Check if rate limiting should be skipped
52
+ if (await this.options.skip(req)) {
53
+ return false;
54
+ }
55
+ const key = this.options.keyGenerator(req);
56
+ const now = Date.now();
57
+ // Get or create state for this key
58
+ let state = this.store.get(key);
59
+ if (!state || now >= state.resetTime) {
60
+ // Create new window
61
+ state = {
62
+ count: 0,
63
+ resetTime: now + this.options.windowMs,
64
+ };
65
+ this.store.set(key, state);
66
+ }
67
+ // Increment request count
68
+ state.count++;
69
+ // Add rate limit headers
70
+ if (this.options.headers) {
71
+ res.setHeader('X-RateLimit-Limit', String(this.options.max));
72
+ res.setHeader('X-RateLimit-Remaining', String(Math.max(0, this.options.max - state.count)));
73
+ res.setHeader('X-RateLimit-Reset', String(Math.ceil(state.resetTime / 1000)));
74
+ }
75
+ // Check if limit exceeded
76
+ if (state.count > this.options.max) {
77
+ const retryAfter = Math.ceil((state.resetTime - now) / 1000);
78
+ if (this.options.headers) {
79
+ res.setHeader('Retry-After', String(retryAfter));
80
+ }
81
+ // Call custom handler
82
+ await this.options.handler(req, res, retryAfter);
83
+ return true; // Rate limited
84
+ }
85
+ return false; // Not rate limited
86
+ }
87
+ /**
88
+ * Clean up expired entries
89
+ */
90
+ cleanup() {
91
+ const now = Date.now();
92
+ for (const [key, state] of this.store.entries()) {
93
+ if (now >= state.resetTime) {
94
+ this.store.delete(key);
95
+ }
96
+ }
97
+ }
98
+ /**
99
+ * Reset rate limit for a specific key
100
+ */
101
+ reset(key) {
102
+ this.store.delete(key);
103
+ }
104
+ /**
105
+ * Reset all rate limits
106
+ */
107
+ resetAll() {
108
+ this.store.clear();
109
+ }
110
+ /**
111
+ * Get current state for a key
112
+ */
113
+ getState(key) {
114
+ return this.store.get(key);
115
+ }
116
+ }
117
+ exports.RateLimiter = RateLimiter;
118
+ /**
119
+ * Default key generator (uses IP address)
120
+ */
121
+ function defaultKeyGenerator(req) {
122
+ return (0, request_parser_js_1.getClientIP)(req);
123
+ }
124
+ /**
125
+ * Default rate limit handler
126
+ */
127
+ function defaultRateLimitHandler(_req, res, retryAfter) {
128
+ (0, response_formatter_js_1.sendJSON)(res, {
129
+ error: {
130
+ message: 'Too many requests, please try again later.',
131
+ type: 'rate_limit_exceeded',
132
+ retryAfter,
133
+ },
134
+ }, 429);
135
+ }
136
+ /**
137
+ * Create key generator from user ID in request body
138
+ */
139
+ function userIDKeyGenerator(req) {
140
+ // This would need to be called after body parsing
141
+ // For now, fall back to IP
142
+ return (0, request_parser_js_1.getClientIP)(req);
143
+ }
144
+ /**
145
+ * Create key generator from authorization token
146
+ */
147
+ function tokenKeyGenerator(req) {
148
+ const auth = req.headers.authorization;
149
+ if (auth) {
150
+ return auth;
151
+ }
152
+ return (0, request_parser_js_1.getClientIP)(req);
153
+ }
154
+ /**
155
+ * Create key generator that combines multiple factors
156
+ */
157
+ function combineKeyGenerators(...generators) {
158
+ return (req) => {
159
+ const parts = generators.map((gen) => gen(req));
160
+ return parts.join(':');
161
+ };
162
+ }
163
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ /**
3
+ * HTTP Request Parser
4
+ *
5
+ * Parses incoming HTTP requests into a standardized format for processing.
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.parseRequest = parseRequest;
11
+ exports.extractBearerToken = extractBearerToken;
12
+ exports.getClientIP = getClientIP;
13
+ /**
14
+ * Parse incoming HTTP request
15
+ */
16
+ async function parseRequest(req, maxBodySize = 10 * 1024 * 1024 // 10MB default
17
+ ) {
18
+ // Parse URL
19
+ const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
20
+ const path = url.pathname;
21
+ const method = req.method?.toUpperCase() || 'GET';
22
+ // Parse query parameters
23
+ const query = {};
24
+ url.searchParams.forEach((value, key) => {
25
+ query[key] = value;
26
+ });
27
+ // Normalize headers
28
+ const headers = {};
29
+ for (const [key, value] of Object.entries(req.headers)) {
30
+ if (typeof value === 'string') {
31
+ headers[key.toLowerCase()] = value;
32
+ }
33
+ else if (Array.isArray(value)) {
34
+ headers[key.toLowerCase()] = value[0] || '';
35
+ }
36
+ }
37
+ // Parse body (if present)
38
+ let body = null;
39
+ if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
40
+ const rawBody = await readBody(req, maxBodySize);
41
+ if (rawBody) {
42
+ const contentType = headers['content-type'] || '';
43
+ if (contentType.includes('application/json')) {
44
+ try {
45
+ body = JSON.parse(rawBody);
46
+ }
47
+ catch (error) {
48
+ throw new Error(`Invalid JSON body: ${error instanceof Error ? error.message : String(error)}`);
49
+ }
50
+ }
51
+ else if (contentType.includes('application/x-www-form-urlencoded')) {
52
+ body = parseFormData(rawBody);
53
+ }
54
+ else {
55
+ // Unknown content type, try JSON anyway
56
+ try {
57
+ body = JSON.parse(rawBody);
58
+ }
59
+ catch {
60
+ body = rawBody;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ // Detect streaming request
66
+ const stream = body?.stream === true || headers['accept'] === 'text/event-stream';
67
+ return {
68
+ body,
69
+ headers,
70
+ path,
71
+ method,
72
+ query,
73
+ stream,
74
+ };
75
+ }
76
+ /**
77
+ * Read request body as string
78
+ */
79
+ function readBody(req, maxSize) {
80
+ return new Promise((resolve, reject) => {
81
+ const chunks = [];
82
+ let totalSize = 0;
83
+ req.on('data', (chunk) => {
84
+ totalSize += chunk.length;
85
+ if (totalSize > maxSize) {
86
+ // Destroy the stream to stop receiving data and free resources
87
+ req.destroy();
88
+ reject(new Error(`Request body too large (max ${maxSize} bytes)`));
89
+ return;
90
+ }
91
+ chunks.push(chunk);
92
+ });
93
+ req.on('end', () => {
94
+ const body = Buffer.concat(chunks).toString('utf-8');
95
+ resolve(body);
96
+ });
97
+ req.on('error', (error) => {
98
+ reject(error);
99
+ });
100
+ });
101
+ }
102
+ /**
103
+ * Parse form-encoded data
104
+ */
105
+ function parseFormData(data) {
106
+ const params = new URLSearchParams(data);
107
+ const result = {};
108
+ params.forEach((value, key) => {
109
+ result[key] = value;
110
+ });
111
+ return result;
112
+ }
113
+ /**
114
+ * Extract bearer token from Authorization header
115
+ */
116
+ function extractBearerToken(req) {
117
+ const auth = req.headers.authorization;
118
+ if (!auth) {
119
+ return null;
120
+ }
121
+ const match = auth.match(/^Bearer\s+(.+)$/i);
122
+ return match ? match[1] || null : null;
123
+ }
124
+ /**
125
+ * Get client IP address from request
126
+ */
127
+ function getClientIP(req) {
128
+ // Check common proxy headers
129
+ const forwarded = req.headers['x-forwarded-for'];
130
+ if (forwarded) {
131
+ const ips = typeof forwarded === 'string' ? forwarded.split(',') : forwarded;
132
+ return ips[0]?.trim() || 'unknown';
133
+ }
134
+ const realIP = req.headers['x-real-ip'];
135
+ if (realIP && typeof realIP === 'string') {
136
+ return realIP;
137
+ }
138
+ // Fallback to socket address
139
+ return req.socket.remoteAddress || 'unknown';
140
+ }
141
+ //# sourceMappingURL=request-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-parser.js","sourceRoot":"","sources":["../../src/request-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ /**
3
+ * HTTP Response Formatter
4
+ *
5
+ * Formats responses for HTTP responses with proper headers and status codes.
6
+ *
7
+ * @module
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.sendJSON = sendJSON;
11
+ exports.sendError = sendError;
12
+ exports.sendSSEHeaders = sendSSEHeaders;
13
+ exports.sendSSEChunk = sendSSEChunk;
14
+ exports.sendSSEEvent = sendSSEEvent;
15
+ exports.sendSSEDone = sendSSEDone;
16
+ exports.sendSSEError = sendSSEError;
17
+ exports.sendText = sendText;
18
+ exports.sendNoContent = sendNoContent;
19
+ exports.detectProviderFormat = detectProviderFormat;
20
+ /**
21
+ * Send JSON response
22
+ */
23
+ function sendJSON(res, data, statusCode = 200, headers = {}) {
24
+ res.statusCode = statusCode;
25
+ res.setHeader('Content-Type', 'application/json');
26
+ // Set custom headers
27
+ for (const [key, value] of Object.entries(headers)) {
28
+ res.setHeader(key, value);
29
+ }
30
+ const body = JSON.stringify(data);
31
+ res.end(body);
32
+ }
33
+ /**
34
+ * Send error response
35
+ */
36
+ function sendError(res, error, statusCode = 500, format = 'generic') {
37
+ let errorBody;
38
+ switch (format) {
39
+ case 'openai':
40
+ errorBody = formatOpenAIError(error, statusCode);
41
+ break;
42
+ case 'anthropic':
43
+ errorBody = formatAnthropicError(error, statusCode);
44
+ break;
45
+ default:
46
+ errorBody = formatGenericError(error, statusCode);
47
+ break;
48
+ }
49
+ sendJSON(res, errorBody, statusCode);
50
+ }
51
+ /**
52
+ * Format error in OpenAI style
53
+ */
54
+ function formatOpenAIError(error, statusCode) {
55
+ return {
56
+ error: {
57
+ message: error.message,
58
+ type: getOpenAIErrorType(statusCode),
59
+ code: statusCode === 429 ? 'rate_limit_exceeded' : null,
60
+ },
61
+ };
62
+ }
63
+ /**
64
+ * Format error in Anthropic style
65
+ */
66
+ function formatAnthropicError(error, statusCode) {
67
+ return {
68
+ type: 'error',
69
+ error: {
70
+ type: getAnthropicErrorType(statusCode),
71
+ message: error.message,
72
+ },
73
+ };
74
+ }
75
+ /**
76
+ * Format error in generic style
77
+ */
78
+ function formatGenericError(error, statusCode) {
79
+ return {
80
+ error: {
81
+ message: error.message,
82
+ status: statusCode,
83
+ },
84
+ };
85
+ }
86
+ /**
87
+ * Get OpenAI error type from status code
88
+ */
89
+ function getOpenAIErrorType(statusCode) {
90
+ switch (statusCode) {
91
+ case 400:
92
+ return 'invalid_request_error';
93
+ case 401:
94
+ return 'authentication_error';
95
+ case 403:
96
+ return 'permission_error';
97
+ case 404:
98
+ return 'not_found_error';
99
+ case 429:
100
+ return 'rate_limit_error';
101
+ case 500:
102
+ return 'server_error';
103
+ case 503:
104
+ return 'service_unavailable_error';
105
+ default:
106
+ return 'api_error';
107
+ }
108
+ }
109
+ /**
110
+ * Get Anthropic error type from status code
111
+ */
112
+ function getAnthropicErrorType(statusCode) {
113
+ switch (statusCode) {
114
+ case 400:
115
+ return 'invalid_request_error';
116
+ case 401:
117
+ return 'authentication_error';
118
+ case 403:
119
+ return 'permission_error';
120
+ case 404:
121
+ return 'not_found_error';
122
+ case 429:
123
+ return 'rate_limit_error';
124
+ case 500:
125
+ return 'api_error';
126
+ case 529:
127
+ return 'overloaded_error';
128
+ default:
129
+ return 'api_error';
130
+ }
131
+ }
132
+ /**
133
+ * Send Server-Sent Events (SSE) headers
134
+ */
135
+ function sendSSEHeaders(res, headers = {}) {
136
+ res.statusCode = 200;
137
+ res.setHeader('Content-Type', 'text/event-stream');
138
+ res.setHeader('Cache-Control', 'no-cache');
139
+ res.setHeader('Connection', 'keep-alive');
140
+ // Set custom headers
141
+ for (const [key, value] of Object.entries(headers)) {
142
+ res.setHeader(key, value);
143
+ }
144
+ // Write headers (flushes them to client)
145
+ res.flushHeaders?.();
146
+ }
147
+ /**
148
+ * Send SSE data chunk
149
+ */
150
+ function sendSSEChunk(res, data) {
151
+ const json = JSON.stringify(data);
152
+ res.write(`data: ${json}\n\n`);
153
+ }
154
+ /**
155
+ * Send SSE event with custom event type
156
+ */
157
+ function sendSSEEvent(res, event, data) {
158
+ const json = JSON.stringify(data);
159
+ res.write(`event: ${event}\ndata: ${json}\n\n`);
160
+ }
161
+ /**
162
+ * Send SSE done marker
163
+ */
164
+ function sendSSEDone(res) {
165
+ res.write('data: [DONE]\n\n');
166
+ res.end();
167
+ }
168
+ /**
169
+ * Send SSE error
170
+ */
171
+ function sendSSEError(res, error, format = 'generic') {
172
+ let errorData;
173
+ switch (format) {
174
+ case 'openai':
175
+ errorData = formatOpenAIError(error, 500);
176
+ break;
177
+ case 'anthropic':
178
+ errorData = formatAnthropicError(error, 500);
179
+ break;
180
+ default:
181
+ errorData = formatGenericError(error, 500);
182
+ break;
183
+ }
184
+ sendSSEChunk(res, errorData);
185
+ res.end();
186
+ }
187
+ /**
188
+ * Send plain text response
189
+ */
190
+ function sendText(res, text, statusCode = 200, headers = {}) {
191
+ res.statusCode = statusCode;
192
+ res.setHeader('Content-Type', 'text/plain');
193
+ // Set custom headers
194
+ for (const [key, value] of Object.entries(headers)) {
195
+ res.setHeader(key, value);
196
+ }
197
+ res.end(text);
198
+ }
199
+ /**
200
+ * Send 204 No Content response
201
+ */
202
+ function sendNoContent(res) {
203
+ res.statusCode = 204;
204
+ res.end();
205
+ }
206
+ /**
207
+ * Detect provider format from request path or headers
208
+ */
209
+ function detectProviderFormat(path) {
210
+ if (path.includes('/chat/completions')) {
211
+ return 'openai';
212
+ }
213
+ if (path.includes('/messages')) {
214
+ return 'anthropic';
215
+ }
216
+ return 'generic';
217
+ }
218
+ //# sourceMappingURL=response-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-formatter.js","sourceRoot":"","sources":["../../src/response-formatter.ts"],"names":[],"mappings":"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"}