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.
- package/LICENSE +21 -0
- package/dist/cjs/auth.js +173 -0
- package/dist/cjs/auth.js.map +1 -0
- package/dist/cjs/cors.js +140 -0
- package/dist/cjs/cors.js.map +1 -0
- package/dist/cjs/error-handler.js +147 -0
- package/dist/cjs/error-handler.js.map +1 -0
- package/dist/cjs/handler.js +335 -0
- package/dist/cjs/handler.js.map +1 -0
- package/dist/cjs/health.js +218 -0
- package/dist/cjs/health.js.map +1 -0
- package/dist/cjs/index.js +83 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/rate-limiter.js +163 -0
- package/dist/cjs/rate-limiter.js.map +1 -0
- package/dist/cjs/request-parser.js +141 -0
- package/dist/cjs/request-parser.js.map +1 -0
- package/dist/cjs/response-formatter.js +218 -0
- package/dist/cjs/response-formatter.js.map +1 -0
- package/dist/cjs/route-matcher.js +178 -0
- package/dist/cjs/route-matcher.js.map +1 -0
- package/dist/cjs/streaming-handler.js +120 -0
- package/dist/cjs/streaming-handler.js.map +1 -0
- package/dist/cjs/types.js +11 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/auth.js +163 -0
- package/dist/esm/auth.js.map +1 -0
- package/dist/esm/cors.js +134 -0
- package/dist/esm/cors.js.map +1 -0
- package/dist/esm/error-handler.js +137 -0
- package/dist/esm/error-handler.js.map +1 -0
- package/dist/esm/handler.js +331 -0
- package/dist/esm/handler.js.map +1 -0
- package/dist/esm/health.js +210 -0
- package/dist/esm/health.js.map +1 -0
- package/dist/esm/index.js +30 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/rate-limiter.js +156 -0
- package/dist/esm/rate-limiter.js.map +1 -0
- package/dist/esm/request-parser.js +136 -0
- package/dist/esm/request-parser.js.map +1 -0
- package/dist/esm/response-formatter.js +206 -0
- package/dist/esm/response-formatter.js.map +1 -0
- package/dist/esm/route-matcher.js +171 -0
- package/dist/esm/route-matcher.js.map +1 -0
- package/dist/esm/streaming-handler.js +112 -0
- package/dist/esm/streaming-handler.js.map +1 -0
- package/dist/esm/types.js +10 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/auth.d.ts +37 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/cors.d.ts +26 -0
- package/dist/types/cors.d.ts.map +1 -0
- package/dist/types/error-handler.d.ts +38 -0
- package/dist/types/error-handler.d.ts.map +1 -0
- package/dist/types/handler.d.ts +45 -0
- package/dist/types/handler.d.ts.map +1 -0
- package/dist/types/health.d.ts +164 -0
- package/dist/types/health.d.ts.map +1 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/rate-limiter.d.ts +56 -0
- package/dist/types/rate-limiter.d.ts.map +1 -0
- package/dist/types/request-parser.d.ts +22 -0
- package/dist/types/request-parser.d.ts.map +1 -0
- package/dist/types/response-formatter.d.ts +49 -0
- package/dist/types/response-formatter.d.ts.map +1 -0
- package/dist/types/route-matcher.d.ts +45 -0
- package/dist/types/route-matcher.d.ts.map +1 -0
- package/dist/types/streaming-handler.d.ts +40 -0
- package/dist/types/streaming-handler.d.ts.map +1 -0
- package/dist/types/types.d.ts +398 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +73 -0
- package/readme.md +60 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP Response Formatter
|
|
3
|
+
*
|
|
4
|
+
* Formats responses for HTTP responses with proper headers and status codes.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Send JSON response
|
|
10
|
+
*/
|
|
11
|
+
export function sendJSON(res, data, statusCode = 200, headers = {}) {
|
|
12
|
+
res.statusCode = statusCode;
|
|
13
|
+
res.setHeader('Content-Type', 'application/json');
|
|
14
|
+
// Set custom headers
|
|
15
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
16
|
+
res.setHeader(key, value);
|
|
17
|
+
}
|
|
18
|
+
const body = JSON.stringify(data);
|
|
19
|
+
res.end(body);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Send error response
|
|
23
|
+
*/
|
|
24
|
+
export function sendError(res, error, statusCode = 500, format = 'generic') {
|
|
25
|
+
let errorBody;
|
|
26
|
+
switch (format) {
|
|
27
|
+
case 'openai':
|
|
28
|
+
errorBody = formatOpenAIError(error, statusCode);
|
|
29
|
+
break;
|
|
30
|
+
case 'anthropic':
|
|
31
|
+
errorBody = formatAnthropicError(error, statusCode);
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
errorBody = formatGenericError(error, statusCode);
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
sendJSON(res, errorBody, statusCode);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format error in OpenAI style
|
|
41
|
+
*/
|
|
42
|
+
function formatOpenAIError(error, statusCode) {
|
|
43
|
+
return {
|
|
44
|
+
error: {
|
|
45
|
+
message: error.message,
|
|
46
|
+
type: getOpenAIErrorType(statusCode),
|
|
47
|
+
code: statusCode === 429 ? 'rate_limit_exceeded' : null,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Format error in Anthropic style
|
|
53
|
+
*/
|
|
54
|
+
function formatAnthropicError(error, statusCode) {
|
|
55
|
+
return {
|
|
56
|
+
type: 'error',
|
|
57
|
+
error: {
|
|
58
|
+
type: getAnthropicErrorType(statusCode),
|
|
59
|
+
message: error.message,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Format error in generic style
|
|
65
|
+
*/
|
|
66
|
+
function formatGenericError(error, statusCode) {
|
|
67
|
+
return {
|
|
68
|
+
error: {
|
|
69
|
+
message: error.message,
|
|
70
|
+
status: statusCode,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get OpenAI error type from status code
|
|
76
|
+
*/
|
|
77
|
+
function getOpenAIErrorType(statusCode) {
|
|
78
|
+
switch (statusCode) {
|
|
79
|
+
case 400:
|
|
80
|
+
return 'invalid_request_error';
|
|
81
|
+
case 401:
|
|
82
|
+
return 'authentication_error';
|
|
83
|
+
case 403:
|
|
84
|
+
return 'permission_error';
|
|
85
|
+
case 404:
|
|
86
|
+
return 'not_found_error';
|
|
87
|
+
case 429:
|
|
88
|
+
return 'rate_limit_error';
|
|
89
|
+
case 500:
|
|
90
|
+
return 'server_error';
|
|
91
|
+
case 503:
|
|
92
|
+
return 'service_unavailable_error';
|
|
93
|
+
default:
|
|
94
|
+
return 'api_error';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get Anthropic error type from status code
|
|
99
|
+
*/
|
|
100
|
+
function getAnthropicErrorType(statusCode) {
|
|
101
|
+
switch (statusCode) {
|
|
102
|
+
case 400:
|
|
103
|
+
return 'invalid_request_error';
|
|
104
|
+
case 401:
|
|
105
|
+
return 'authentication_error';
|
|
106
|
+
case 403:
|
|
107
|
+
return 'permission_error';
|
|
108
|
+
case 404:
|
|
109
|
+
return 'not_found_error';
|
|
110
|
+
case 429:
|
|
111
|
+
return 'rate_limit_error';
|
|
112
|
+
case 500:
|
|
113
|
+
return 'api_error';
|
|
114
|
+
case 529:
|
|
115
|
+
return 'overloaded_error';
|
|
116
|
+
default:
|
|
117
|
+
return 'api_error';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Send Server-Sent Events (SSE) headers
|
|
122
|
+
*/
|
|
123
|
+
export function sendSSEHeaders(res, headers = {}) {
|
|
124
|
+
res.statusCode = 200;
|
|
125
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
126
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
127
|
+
res.setHeader('Connection', 'keep-alive');
|
|
128
|
+
// Set custom headers
|
|
129
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
130
|
+
res.setHeader(key, value);
|
|
131
|
+
}
|
|
132
|
+
// Write headers (flushes them to client)
|
|
133
|
+
res.flushHeaders?.();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Send SSE data chunk
|
|
137
|
+
*/
|
|
138
|
+
export function sendSSEChunk(res, data) {
|
|
139
|
+
const json = JSON.stringify(data);
|
|
140
|
+
res.write(`data: ${json}\n\n`);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Send SSE event with custom event type
|
|
144
|
+
*/
|
|
145
|
+
export function sendSSEEvent(res, event, data) {
|
|
146
|
+
const json = JSON.stringify(data);
|
|
147
|
+
res.write(`event: ${event}\ndata: ${json}\n\n`);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Send SSE done marker
|
|
151
|
+
*/
|
|
152
|
+
export function sendSSEDone(res) {
|
|
153
|
+
res.write('data: [DONE]\n\n');
|
|
154
|
+
res.end();
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Send SSE error
|
|
158
|
+
*/
|
|
159
|
+
export function sendSSEError(res, error, format = 'generic') {
|
|
160
|
+
let errorData;
|
|
161
|
+
switch (format) {
|
|
162
|
+
case 'openai':
|
|
163
|
+
errorData = formatOpenAIError(error, 500);
|
|
164
|
+
break;
|
|
165
|
+
case 'anthropic':
|
|
166
|
+
errorData = formatAnthropicError(error, 500);
|
|
167
|
+
break;
|
|
168
|
+
default:
|
|
169
|
+
errorData = formatGenericError(error, 500);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
sendSSEChunk(res, errorData);
|
|
173
|
+
res.end();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Send plain text response
|
|
177
|
+
*/
|
|
178
|
+
export function sendText(res, text, statusCode = 200, headers = {}) {
|
|
179
|
+
res.statusCode = statusCode;
|
|
180
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
181
|
+
// Set custom headers
|
|
182
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
183
|
+
res.setHeader(key, value);
|
|
184
|
+
}
|
|
185
|
+
res.end(text);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Send 204 No Content response
|
|
189
|
+
*/
|
|
190
|
+
export function sendNoContent(res) {
|
|
191
|
+
res.statusCode = 204;
|
|
192
|
+
res.end();
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Detect provider format from request path or headers
|
|
196
|
+
*/
|
|
197
|
+
export function detectProviderFormat(path) {
|
|
198
|
+
if (path.includes('/chat/completions')) {
|
|
199
|
+
return 'openai';
|
|
200
|
+
}
|
|
201
|
+
if (path.includes('/messages')) {
|
|
202
|
+
return 'anthropic';
|
|
203
|
+
}
|
|
204
|
+
return 'generic';
|
|
205
|
+
}
|
|
206
|
+
//# 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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"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route Matcher
|
|
3
|
+
*
|
|
4
|
+
* Matches incoming HTTP requests to configured routes.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Route matcher class
|
|
10
|
+
*/
|
|
11
|
+
export class RouteMatcher {
|
|
12
|
+
routes;
|
|
13
|
+
constructor(routes) {
|
|
14
|
+
this.routes = routes;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Match request to a route
|
|
18
|
+
*/
|
|
19
|
+
match(req) {
|
|
20
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
21
|
+
const path = url.pathname;
|
|
22
|
+
const method = req.method?.toUpperCase() || 'GET';
|
|
23
|
+
for (const route of this.routes) {
|
|
24
|
+
// Check if method matches
|
|
25
|
+
const routeMethods = route.methods || ['POST'];
|
|
26
|
+
if (!routeMethods.includes(method)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// Check if path matches
|
|
30
|
+
const match = matchPath(path, route.path);
|
|
31
|
+
if (match) {
|
|
32
|
+
return {
|
|
33
|
+
config: route,
|
|
34
|
+
params: match.params,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Add a route
|
|
42
|
+
*/
|
|
43
|
+
addRoute(route) {
|
|
44
|
+
this.routes.push(route);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Remove a route
|
|
48
|
+
*/
|
|
49
|
+
removeRoute(path) {
|
|
50
|
+
const index = this.routes.findIndex((r) => r.path === path);
|
|
51
|
+
if (index >= 0) {
|
|
52
|
+
this.routes.splice(index, 1);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get all routes
|
|
59
|
+
*/
|
|
60
|
+
getRoutes() {
|
|
61
|
+
return this.routes;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function matchPath(path, pattern) {
|
|
65
|
+
// Exact match
|
|
66
|
+
if (path === pattern) {
|
|
67
|
+
return { params: {} };
|
|
68
|
+
}
|
|
69
|
+
// Wildcard match (supports simple * wildcards)
|
|
70
|
+
if (pattern.includes('*')) {
|
|
71
|
+
const regex = patternToRegex(pattern);
|
|
72
|
+
if (regex.test(path)) {
|
|
73
|
+
return { params: {} };
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
// Parameter match (supports :param syntax)
|
|
78
|
+
if (pattern.includes(':')) {
|
|
79
|
+
const match = matchParameterizedPath(path, pattern);
|
|
80
|
+
if (match) {
|
|
81
|
+
return match;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Convert path pattern to regex
|
|
88
|
+
*/
|
|
89
|
+
function patternToRegex(pattern) {
|
|
90
|
+
// Escape special regex characters except *
|
|
91
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
|
|
92
|
+
// Convert * to regex wildcard
|
|
93
|
+
const regexPattern = escaped.replace(/\*/g, '.*');
|
|
94
|
+
return new RegExp(`^${regexPattern}$`);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Match parameterized path (e.g., /users/:id)
|
|
98
|
+
*/
|
|
99
|
+
function matchParameterizedPath(path, pattern) {
|
|
100
|
+
const pathParts = path.split('/').filter(Boolean);
|
|
101
|
+
const patternParts = pattern.split('/').filter(Boolean);
|
|
102
|
+
if (pathParts.length !== patternParts.length) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const params = {};
|
|
106
|
+
for (let i = 0; i < patternParts.length; i++) {
|
|
107
|
+
const patternPart = patternParts[i];
|
|
108
|
+
const pathPart = pathParts[i];
|
|
109
|
+
if (!patternPart || !pathPart) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
if (patternPart.startsWith(':')) {
|
|
113
|
+
// Parameter
|
|
114
|
+
const paramName = patternPart.slice(1);
|
|
115
|
+
params[paramName] = pathPart;
|
|
116
|
+
}
|
|
117
|
+
else if (patternPart !== pathPart) {
|
|
118
|
+
// Mismatch
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { params };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Create default routes for common provider endpoints
|
|
126
|
+
*/
|
|
127
|
+
export function createDefaultRoutes(frontendAdapters) {
|
|
128
|
+
const routes = [];
|
|
129
|
+
// OpenAI endpoint
|
|
130
|
+
if (frontendAdapters.has('openai')) {
|
|
131
|
+
routes.push({
|
|
132
|
+
path: '/v1/chat/completions',
|
|
133
|
+
methods: ['POST'],
|
|
134
|
+
frontend: frontendAdapters.get('openai'),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// Anthropic endpoint
|
|
138
|
+
if (frontendAdapters.has('anthropic')) {
|
|
139
|
+
routes.push({
|
|
140
|
+
path: '/v1/messages',
|
|
141
|
+
methods: ['POST'],
|
|
142
|
+
frontend: frontendAdapters.get('anthropic'),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return routes;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Normalize path by removing trailing slashes and adding leading slash
|
|
149
|
+
*/
|
|
150
|
+
export function normalizePath(path) {
|
|
151
|
+
// Add leading slash if missing
|
|
152
|
+
if (!path.startsWith('/')) {
|
|
153
|
+
path = '/' + path;
|
|
154
|
+
}
|
|
155
|
+
// Remove trailing slash (except for root)
|
|
156
|
+
if (path.length > 1 && path.endsWith('/')) {
|
|
157
|
+
path = path.slice(0, -1);
|
|
158
|
+
}
|
|
159
|
+
return path;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Apply path prefix to route paths
|
|
163
|
+
*/
|
|
164
|
+
export function applyPathPrefix(routes, prefix) {
|
|
165
|
+
const normalizedPrefix = normalizePath(prefix);
|
|
166
|
+
return routes.map((route) => ({
|
|
167
|
+
...route,
|
|
168
|
+
path: normalizedPrefix + normalizePath(route.path),
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=route-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-matcher.js","sourceRoot":"","sources":["../../src/route-matcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles Server-Sent Events (SSE) streaming for HTTP responses.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { sendSSEHeaders, sendSSEChunk, sendSSEDone, sendSSEError, sendSSEEvent, } from './response-formatter.js';
|
|
9
|
+
/**
|
|
10
|
+
* Handle streaming request
|
|
11
|
+
*/
|
|
12
|
+
export async function handleStreamingRequest(bridge, request, res, format = 'generic', headers = {}) {
|
|
13
|
+
// Send SSE headers
|
|
14
|
+
sendSSEHeaders(res, headers);
|
|
15
|
+
try {
|
|
16
|
+
// Get streaming response from bridge
|
|
17
|
+
const stream = bridge.chatStream(request);
|
|
18
|
+
// Stream chunks to client
|
|
19
|
+
for await (const chunk of stream) {
|
|
20
|
+
// Check if response is still writable
|
|
21
|
+
if (!res.writable) {
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
// Format and send chunk based on provider format
|
|
25
|
+
if (format === 'anthropic') {
|
|
26
|
+
// Anthropic uses named events
|
|
27
|
+
sendAnthropicChunk(res, chunk);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// OpenAI and generic use data-only format
|
|
31
|
+
sendSSEChunk(res, chunk);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Send done marker (OpenAI style)
|
|
35
|
+
if (format === 'openai' || format === 'generic') {
|
|
36
|
+
sendSSEDone(res);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Anthropic doesn't use [DONE] marker, just end the stream
|
|
40
|
+
res.end();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
// Send error in stream
|
|
45
|
+
sendSSEError(res, error instanceof Error ? error : new Error(String(error)), format);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Send Anthropic-formatted SSE chunk
|
|
50
|
+
*/
|
|
51
|
+
function sendAnthropicChunk(res, chunk) {
|
|
52
|
+
// Anthropic uses event types
|
|
53
|
+
if (chunk.type) {
|
|
54
|
+
sendSSEEvent(res, chunk.type, chunk);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
sendSSEChunk(res, chunk);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create SSE keep-alive mechanism
|
|
62
|
+
*/
|
|
63
|
+
export class SSEKeepAlive {
|
|
64
|
+
intervalId = null;
|
|
65
|
+
/**
|
|
66
|
+
* Start sending keep-alive pings
|
|
67
|
+
*/
|
|
68
|
+
start(res, intervalMs = 15000) {
|
|
69
|
+
this.intervalId = setInterval(() => {
|
|
70
|
+
if (res.writable) {
|
|
71
|
+
res.write(': ping\n\n');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.stop();
|
|
75
|
+
}
|
|
76
|
+
}, intervalMs);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Stop sending keep-alive pings
|
|
80
|
+
*/
|
|
81
|
+
stop() {
|
|
82
|
+
if (this.intervalId) {
|
|
83
|
+
clearInterval(this.intervalId);
|
|
84
|
+
this.intervalId = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Handle client disconnect
|
|
90
|
+
*/
|
|
91
|
+
export function onClientDisconnect(res, callback) {
|
|
92
|
+
res.on('close', callback);
|
|
93
|
+
res.on('finish', callback);
|
|
94
|
+
res.on('error', callback);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if response supports streaming
|
|
98
|
+
*/
|
|
99
|
+
export function supportsStreaming(res) {
|
|
100
|
+
return typeof res.flushHeaders === 'function';
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create streaming abort controller from response
|
|
104
|
+
*/
|
|
105
|
+
export function createAbortController(res) {
|
|
106
|
+
const controller = new AbortController();
|
|
107
|
+
onClientDisconnect(res, () => {
|
|
108
|
+
controller.abort();
|
|
109
|
+
});
|
|
110
|
+
return controller;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=streaming-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming-handler.js","sourceRoot":"","sources":["../../src/streaming-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles authentication validation for HTTP requests.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { AuthValidator } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Default auth validator (always allows)
|
|
11
|
+
*/
|
|
12
|
+
export declare const defaultAuthValidator: AuthValidator;
|
|
13
|
+
/**
|
|
14
|
+
* Create bearer token validator
|
|
15
|
+
*/
|
|
16
|
+
export declare function createBearerTokenValidator(validTokens: string[] | Set<string> | ((token: string) => boolean | Promise<boolean>)): AuthValidator;
|
|
17
|
+
/**
|
|
18
|
+
* Create API key validator (checks x-api-key header)
|
|
19
|
+
*/
|
|
20
|
+
export declare function createAPIKeyValidator(validKeys: string[] | Set<string> | ((key: string) => boolean | Promise<boolean>)): AuthValidator;
|
|
21
|
+
/**
|
|
22
|
+
* Create basic auth validator
|
|
23
|
+
*/
|
|
24
|
+
export declare function createBasicAuthValidator(credentials: Map<string, string> | ((username: string, password: string) => boolean | Promise<boolean>)): AuthValidator;
|
|
25
|
+
/**
|
|
26
|
+
* Combine multiple auth validators (OR logic)
|
|
27
|
+
*/
|
|
28
|
+
export declare function combineAuthValidators(...validators: AuthValidator[]): AuthValidator;
|
|
29
|
+
/**
|
|
30
|
+
* Require all auth validators to pass (AND logic)
|
|
31
|
+
*/
|
|
32
|
+
export declare function requireAllAuth(...validators: AuthValidator[]): AuthValidator;
|
|
33
|
+
/**
|
|
34
|
+
* Skip auth for certain paths
|
|
35
|
+
*/
|
|
36
|
+
export declare function skipAuthForPaths(validator: AuthValidator, paths: string[] | ((path: string) => boolean)): AuthValidator;
|
|
37
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqBhD;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAA0B,CAAC;AAE9D;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GACpF,aAAa,CA8Bf;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GAChF,aAAa,CA8Bf;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EACP,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACnB,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GACvE,aAAa,CA8Bf;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,CASnF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,CAS5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,GAC5C,aAAa,CAef"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles Cross-Origin Resource Sharing (CORS) for HTTP requests.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
9
|
+
import type { CORSOptions } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Normalize CORS options
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeCORSOptions(options: boolean | CORSOptions | undefined): Required<CORSOptions> | null;
|
|
14
|
+
/**
|
|
15
|
+
* Handle CORS headers
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleCORS(req: IncomingMessage, res: ServerResponse, options: Required<CORSOptions>): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Handle CORS preflight (OPTIONS) request
|
|
20
|
+
*/
|
|
21
|
+
export declare function handlePreflight(req: IncomingMessage, res: ServerResponse, options: Required<CORSOptions>): void;
|
|
22
|
+
/**
|
|
23
|
+
* Check if request is a CORS preflight request
|
|
24
|
+
*/
|
|
25
|
+
export declare function isPreflight(req: IncomingMessage): boolean;
|
|
26
|
+
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/cors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAc9C;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GACzC,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAiB9B;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC7B,OAAO,CAgCT;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAC7B,IAAI,CAgDN;AA4BD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAMzD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles errors in HTTP requests and formats appropriate responses.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { IncomingMessage, ServerResponse } from 'http';
|
|
9
|
+
import type { ErrorHandler } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default error handler
|
|
12
|
+
*/
|
|
13
|
+
export declare const defaultErrorHandler: ErrorHandler;
|
|
14
|
+
/**
|
|
15
|
+
* Create error handler that logs to a custom logger
|
|
16
|
+
*/
|
|
17
|
+
export declare function createLoggingErrorHandler(log: (message: string, error: Error) => void): ErrorHandler;
|
|
18
|
+
/**
|
|
19
|
+
* Create error handler that reports errors to an external service
|
|
20
|
+
*/
|
|
21
|
+
export declare function createReportingErrorHandler(reporter: (error: Error, req: IncomingMessage) => Promise<void>): ErrorHandler;
|
|
22
|
+
/**
|
|
23
|
+
* Wrap error handler with custom logic
|
|
24
|
+
*/
|
|
25
|
+
export declare function wrapErrorHandler(baseHandler: ErrorHandler, wrapper: (error: Error, req: IncomingMessage, res: ServerResponse, next: () => Promise<void>) => Promise<void>): ErrorHandler;
|
|
26
|
+
/**
|
|
27
|
+
* Check if error should be retried
|
|
28
|
+
*/
|
|
29
|
+
export declare function isRetryableError(error: Error): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Check if error is a client error (4xx)
|
|
32
|
+
*/
|
|
33
|
+
export declare function isClientError(error: Error): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Check if error is a server error (5xx)
|
|
36
|
+
*/
|
|
37
|
+
export declare function isServerError(error: Error): boolean;
|
|
38
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAY/C;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAmBjC,CAAC;AAkEF;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAC3C,YAAY,CAKd;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAC9D,YAAY,CAUd;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,YAAY,EACzB,OAAO,EAAE,CACP,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KACtB,OAAO,CAAC,IAAI,CAAC,GACjB,YAAY,CAMd;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAetD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAGnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAGnD"}
|