@copilotkit/aimock 1.7.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/.claude-plugin/marketplace.json +17 -0
- package/.claude-plugin/plugin.json +12 -0
- package/LICENSE +21 -0
- package/README.md +82 -0
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/a2a-handler.cjs +203 -0
- package/dist/a2a-handler.cjs.map +1 -0
- package/dist/a2a-handler.js +199 -0
- package/dist/a2a-handler.js.map +1 -0
- package/dist/a2a-mock.cjs +292 -0
- package/dist/a2a-mock.cjs.map +1 -0
- package/dist/a2a-mock.d.cts +41 -0
- package/dist/a2a-mock.d.cts.map +1 -0
- package/dist/a2a-mock.d.ts +41 -0
- package/dist/a2a-mock.d.ts.map +1 -0
- package/dist/a2a-mock.js +290 -0
- package/dist/a2a-mock.js.map +1 -0
- package/dist/a2a-stub.cjs +4 -0
- package/dist/a2a-stub.d.cts +3 -0
- package/dist/a2a-stub.d.ts +3 -0
- package/dist/a2a-stub.js +3 -0
- package/dist/a2a-types.d.cts +68 -0
- package/dist/a2a-types.d.cts.map +1 -0
- package/dist/a2a-types.d.ts +68 -0
- package/dist/a2a-types.d.ts.map +1 -0
- package/dist/aimock-cli.cjs +112 -0
- package/dist/aimock-cli.cjs.map +1 -0
- package/dist/aimock-cli.d.cts +19 -0
- package/dist/aimock-cli.d.cts.map +1 -0
- package/dist/aimock-cli.d.ts +19 -0
- package/dist/aimock-cli.d.ts.map +1 -0
- package/dist/aimock-cli.js +110 -0
- package/dist/aimock-cli.js.map +1 -0
- package/dist/aws-event-stream.cjs +117 -0
- package/dist/aws-event-stream.cjs.map +1 -0
- package/dist/aws-event-stream.d.cts +38 -0
- package/dist/aws-event-stream.d.cts.map +1 -0
- package/dist/aws-event-stream.d.ts +38 -0
- package/dist/aws-event-stream.d.ts.map +1 -0
- package/dist/aws-event-stream.js +114 -0
- package/dist/aws-event-stream.js.map +1 -0
- package/dist/bedrock-converse.cjs +445 -0
- package/dist/bedrock-converse.cjs.map +1 -0
- package/dist/bedrock-converse.d.cts +50 -0
- package/dist/bedrock-converse.d.cts.map +1 -0
- package/dist/bedrock-converse.d.ts +50 -0
- package/dist/bedrock-converse.d.ts.map +1 -0
- package/dist/bedrock-converse.js +443 -0
- package/dist/bedrock-converse.js.map +1 -0
- package/dist/bedrock.cjs +557 -0
- package/dist/bedrock.cjs.map +1 -0
- package/dist/bedrock.d.cts +41 -0
- package/dist/bedrock.d.cts.map +1 -0
- package/dist/bedrock.d.ts +41 -0
- package/dist/bedrock.d.ts.map +1 -0
- package/dist/bedrock.js +553 -0
- package/dist/bedrock.js.map +1 -0
- package/dist/chaos.cjs +114 -0
- package/dist/chaos.cjs.map +1 -0
- package/dist/chaos.d.cts +27 -0
- package/dist/chaos.d.cts.map +1 -0
- package/dist/chaos.d.ts +27 -0
- package/dist/chaos.d.ts.map +1 -0
- package/dist/chaos.js +113 -0
- package/dist/chaos.js.map +1 -0
- package/dist/cli.cjs +268 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +268 -0
- package/dist/cli.js.map +1 -0
- package/dist/cohere.cjs +434 -0
- package/dist/cohere.cjs.map +1 -0
- package/dist/cohere.d.cts +34 -0
- package/dist/cohere.d.cts.map +1 -0
- package/dist/cohere.d.ts +34 -0
- package/dist/cohere.d.ts.map +1 -0
- package/dist/cohere.js +433 -0
- package/dist/cohere.js.map +1 -0
- package/dist/config-loader.cjs +111 -0
- package/dist/config-loader.cjs.map +1 -0
- package/dist/config-loader.d.cts +100 -0
- package/dist/config-loader.d.cts.map +1 -0
- package/dist/config-loader.d.ts +100 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +107 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/embeddings.cjs +150 -0
- package/dist/embeddings.cjs.map +1 -0
- package/dist/embeddings.d.cts +12 -0
- package/dist/embeddings.d.cts.map +1 -0
- package/dist/embeddings.d.ts +12 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +150 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/fixture-loader.cjs +269 -0
- package/dist/fixture-loader.cjs.map +1 -0
- package/dist/fixture-loader.d.cts +17 -0
- package/dist/fixture-loader.d.cts.map +1 -0
- package/dist/fixture-loader.d.ts +17 -0
- package/dist/fixture-loader.d.ts.map +1 -0
- package/dist/fixture-loader.js +265 -0
- package/dist/fixture-loader.js.map +1 -0
- package/dist/gemini.cjs +403 -0
- package/dist/gemini.cjs.map +1 -0
- package/dist/gemini.d.cts +10 -0
- package/dist/gemini.d.cts.map +1 -0
- package/dist/gemini.d.ts +10 -0
- package/dist/gemini.d.ts.map +1 -0
- package/dist/gemini.js +403 -0
- package/dist/gemini.js.map +1 -0
- package/dist/helpers.cjs +276 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +39 -0
- package/dist/helpers.d.cts.map +1 -0
- package/dist/helpers.d.ts +39 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +259 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +113 -0
- package/dist/index.d.cts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +39 -0
- package/dist/interruption.cjs +40 -0
- package/dist/interruption.cjs.map +1 -0
- package/dist/interruption.d.cts +15 -0
- package/dist/interruption.d.cts.map +1 -0
- package/dist/interruption.d.ts +15 -0
- package/dist/interruption.d.ts.map +1 -0
- package/dist/interruption.js +39 -0
- package/dist/interruption.js.map +1 -0
- package/dist/journal.cjs +65 -0
- package/dist/journal.cjs.map +1 -0
- package/dist/journal.d.cts +23 -0
- package/dist/journal.d.cts.map +1 -0
- package/dist/journal.d.ts +23 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +65 -0
- package/dist/journal.js.map +1 -0
- package/dist/jsonrpc.cjs +91 -0
- package/dist/jsonrpc.cjs.map +1 -0
- package/dist/jsonrpc.d.cts +24 -0
- package/dist/jsonrpc.d.cts.map +1 -0
- package/dist/jsonrpc.d.ts +24 -0
- package/dist/jsonrpc.d.ts.map +1 -0
- package/dist/jsonrpc.js +90 -0
- package/dist/jsonrpc.js.map +1 -0
- package/dist/llmock.cjs +223 -0
- package/dist/llmock.cjs.map +1 -0
- package/dist/llmock.d.cts +70 -0
- package/dist/llmock.d.cts.map +1 -0
- package/dist/llmock.d.ts +70 -0
- package/dist/llmock.d.ts.map +1 -0
- package/dist/llmock.js +223 -0
- package/dist/llmock.js.map +1 -0
- package/dist/logger.cjs +29 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +14 -0
- package/dist/logger.d.cts.map +1 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +28 -0
- package/dist/logger.js.map +1 -0
- package/dist/mcp-handler.cjs +189 -0
- package/dist/mcp-handler.cjs.map +1 -0
- package/dist/mcp-handler.js +188 -0
- package/dist/mcp-handler.js.map +1 -0
- package/dist/mcp-mock.cjs +169 -0
- package/dist/mcp-mock.cjs.map +1 -0
- package/dist/mcp-mock.d.cts +40 -0
- package/dist/mcp-mock.d.cts.map +1 -0
- package/dist/mcp-mock.d.ts +40 -0
- package/dist/mcp-mock.d.ts.map +1 -0
- package/dist/mcp-mock.js +167 -0
- package/dist/mcp-mock.js.map +1 -0
- package/dist/mcp-stub.cjs +4 -0
- package/dist/mcp-stub.d.cts +3 -0
- package/dist/mcp-stub.d.ts +3 -0
- package/dist/mcp-stub.js +3 -0
- package/dist/mcp-types.d.cts +65 -0
- package/dist/mcp-types.d.cts.map +1 -0
- package/dist/mcp-types.d.ts +65 -0
- package/dist/mcp-types.d.ts.map +1 -0
- package/dist/messages.cjs +489 -0
- package/dist/messages.cjs.map +1 -0
- package/dist/messages.d.cts +10 -0
- package/dist/messages.d.cts.map +1 -0
- package/dist/messages.d.ts +10 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +489 -0
- package/dist/messages.js.map +1 -0
- package/dist/metrics.cjs +160 -0
- package/dist/metrics.cjs.map +1 -0
- package/dist/metrics.d.cts +24 -0
- package/dist/metrics.d.cts.map +1 -0
- package/dist/metrics.d.ts +24 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +158 -0
- package/dist/metrics.js.map +1 -0
- package/dist/moderation.cjs +91 -0
- package/dist/moderation.cjs.map +1 -0
- package/dist/moderation.d.cts +23 -0
- package/dist/moderation.d.cts.map +1 -0
- package/dist/moderation.d.ts +23 -0
- package/dist/moderation.d.ts.map +1 -0
- package/dist/moderation.js +91 -0
- package/dist/moderation.js.map +1 -0
- package/dist/ndjson-writer.cjs +31 -0
- package/dist/ndjson-writer.cjs.map +1 -0
- package/dist/ndjson-writer.d.cts +17 -0
- package/dist/ndjson-writer.d.cts.map +1 -0
- package/dist/ndjson-writer.d.ts +17 -0
- package/dist/ndjson-writer.d.ts.map +1 -0
- package/dist/ndjson-writer.js +31 -0
- package/dist/ndjson-writer.js.map +1 -0
- package/dist/ollama.cjs +519 -0
- package/dist/ollama.cjs.map +1 -0
- package/dist/ollama.d.cts +34 -0
- package/dist/ollama.d.cts.map +1 -0
- package/dist/ollama.d.ts +34 -0
- package/dist/ollama.d.ts.map +1 -0
- package/dist/ollama.js +517 -0
- package/dist/ollama.js.map +1 -0
- package/dist/recorder.cjs +311 -0
- package/dist/recorder.cjs.map +1 -0
- package/dist/recorder.d.cts +23 -0
- package/dist/recorder.d.cts.map +1 -0
- package/dist/recorder.d.ts +23 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +305 -0
- package/dist/recorder.js.map +1 -0
- package/dist/rerank.cjs +71 -0
- package/dist/rerank.cjs.map +1 -0
- package/dist/rerank.d.cts +22 -0
- package/dist/rerank.d.cts.map +1 -0
- package/dist/rerank.d.ts +22 -0
- package/dist/rerank.d.ts.map +1 -0
- package/dist/rerank.js +71 -0
- package/dist/rerank.js.map +1 -0
- package/dist/responses.cjs +637 -0
- package/dist/responses.cjs.map +1 -0
- package/dist/responses.d.cts +16 -0
- package/dist/responses.d.cts.map +1 -0
- package/dist/responses.d.ts +16 -0
- package/dist/responses.d.ts.map +1 -0
- package/dist/responses.js +634 -0
- package/dist/responses.js.map +1 -0
- package/dist/router.cjs +68 -0
- package/dist/router.cjs.map +1 -0
- package/dist/router.d.cts +16 -0
- package/dist/router.d.cts.map +1 -0
- package/dist/router.d.ts +16 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +65 -0
- package/dist/router.js.map +1 -0
- package/dist/search.cjs +59 -0
- package/dist/search.cjs.map +1 -0
- package/dist/search.d.cts +23 -0
- package/dist/search.d.cts.map +1 -0
- package/dist/search.d.ts +23 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +59 -0
- package/dist/search.js.map +1 -0
- package/dist/server.cjs +935 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +28 -0
- package/dist/server.d.cts.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +933 -0
- package/dist/server.js.map +1 -0
- package/dist/sse-writer.cjs +59 -0
- package/dist/sse-writer.cjs.map +1 -0
- package/dist/sse-writer.d.cts +19 -0
- package/dist/sse-writer.d.cts.map +1 -0
- package/dist/sse-writer.d.ts +19 -0
- package/dist/sse-writer.d.ts.map +1 -0
- package/dist/sse-writer.js +55 -0
- package/dist/sse-writer.js.map +1 -0
- package/dist/stream-collapse.cjs +496 -0
- package/dist/stream-collapse.cjs.map +1 -0
- package/dist/stream-collapse.d.cts +70 -0
- package/dist/stream-collapse.d.cts.map +1 -0
- package/dist/stream-collapse.d.ts +70 -0
- package/dist/stream-collapse.d.ts.map +1 -0
- package/dist/stream-collapse.js +489 -0
- package/dist/stream-collapse.js.map +1 -0
- package/dist/suite.cjs +46 -0
- package/dist/suite.cjs.map +1 -0
- package/dist/suite.d.cts +31 -0
- package/dist/suite.d.cts.map +1 -0
- package/dist/suite.d.ts +31 -0
- package/dist/suite.d.ts.map +1 -0
- package/dist/suite.js +46 -0
- package/dist/suite.js.map +1 -0
- package/dist/types.d.cts +243 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/url.cjs +21 -0
- package/dist/url.cjs.map +1 -0
- package/dist/url.d.cts +16 -0
- package/dist/url.d.cts.map +1 -0
- package/dist/url.d.ts +16 -0
- package/dist/url.d.ts.map +1 -0
- package/dist/url.js +20 -0
- package/dist/url.js.map +1 -0
- package/dist/vector-handler.cjs +239 -0
- package/dist/vector-handler.cjs.map +1 -0
- package/dist/vector-handler.js +238 -0
- package/dist/vector-handler.js.map +1 -0
- package/dist/vector-mock.cjs +229 -0
- package/dist/vector-mock.cjs.map +1 -0
- package/dist/vector-mock.d.cts +39 -0
- package/dist/vector-mock.d.cts.map +1 -0
- package/dist/vector-mock.d.ts +39 -0
- package/dist/vector-mock.d.ts.map +1 -0
- package/dist/vector-mock.js +227 -0
- package/dist/vector-mock.js.map +1 -0
- package/dist/vector-stub.cjs +4 -0
- package/dist/vector-stub.d.cts +3 -0
- package/dist/vector-stub.d.ts +3 -0
- package/dist/vector-stub.js +3 -0
- package/dist/vector-types.d.cts +32 -0
- package/dist/vector-types.d.cts.map +1 -0
- package/dist/vector-types.d.ts +32 -0
- package/dist/vector-types.d.ts.map +1 -0
- package/dist/watcher.cjs +59 -0
- package/dist/watcher.cjs.map +1 -0
- package/dist/watcher.js +58 -0
- package/dist/watcher.js.map +1 -0
- package/dist/ws-framing.cjs +187 -0
- package/dist/ws-framing.cjs.map +1 -0
- package/dist/ws-framing.d.cts +26 -0
- package/dist/ws-framing.d.cts.map +1 -0
- package/dist/ws-framing.d.ts +26 -0
- package/dist/ws-framing.d.ts.map +1 -0
- package/dist/ws-framing.js +184 -0
- package/dist/ws-framing.js.map +1 -0
- package/dist/ws-gemini-live.cjs +364 -0
- package/dist/ws-gemini-live.cjs.map +1 -0
- package/dist/ws-gemini-live.d.cts +18 -0
- package/dist/ws-gemini-live.d.cts.map +1 -0
- package/dist/ws-gemini-live.d.ts +18 -0
- package/dist/ws-gemini-live.d.ts.map +1 -0
- package/dist/ws-gemini-live.js +364 -0
- package/dist/ws-gemini-live.js.map +1 -0
- package/dist/ws-realtime.cjs +435 -0
- package/dist/ws-realtime.cjs.map +1 -0
- package/dist/ws-realtime.d.cts +17 -0
- package/dist/ws-realtime.d.cts.map +1 -0
- package/dist/ws-realtime.d.ts +17 -0
- package/dist/ws-realtime.d.ts.map +1 -0
- package/dist/ws-realtime.js +435 -0
- package/dist/ws-realtime.js.map +1 -0
- package/dist/ws-responses.cjs +164 -0
- package/dist/ws-responses.cjs.map +1 -0
- package/dist/ws-responses.d.cts +18 -0
- package/dist/ws-responses.d.cts.map +1 -0
- package/dist/ws-responses.d.ts +18 -0
- package/dist/ws-responses.d.ts.map +1 -0
- package/dist/ws-responses.js +164 -0
- package/dist/ws-responses.js.map +1 -0
- package/fixtures/example-greeting.json +12 -0
- package/fixtures/example-multi-turn.json +14 -0
- package/fixtures/example-tool-call.json +15 -0
- package/package.json +118 -0
- package/skills/write-fixtures/SKILL.md +625 -0
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,935 @@
|
|
|
1
|
+
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_helpers = require('./helpers.cjs');
|
|
3
|
+
const require_journal = require('./journal.cjs');
|
|
4
|
+
const require_router = require('./router.cjs');
|
|
5
|
+
const require_fixture_loader = require('./fixture-loader.cjs');
|
|
6
|
+
const require_sse_writer = require('./sse-writer.cjs');
|
|
7
|
+
const require_interruption = require('./interruption.cjs');
|
|
8
|
+
const require_chaos = require('./chaos.cjs');
|
|
9
|
+
const require_recorder = require('./recorder.cjs');
|
|
10
|
+
const require_responses = require('./responses.cjs');
|
|
11
|
+
const require_messages = require('./messages.cjs');
|
|
12
|
+
const require_gemini = require('./gemini.cjs');
|
|
13
|
+
const require_bedrock = require('./bedrock.cjs');
|
|
14
|
+
const require_bedrock_converse = require('./bedrock-converse.cjs');
|
|
15
|
+
const require_embeddings = require('./embeddings.cjs');
|
|
16
|
+
const require_ollama = require('./ollama.cjs');
|
|
17
|
+
const require_cohere = require('./cohere.cjs');
|
|
18
|
+
const require_search = require('./search.cjs');
|
|
19
|
+
const require_rerank = require('./rerank.cjs');
|
|
20
|
+
const require_moderation = require('./moderation.cjs');
|
|
21
|
+
const require_ws_framing = require('./ws-framing.cjs');
|
|
22
|
+
const require_ws_responses = require('./ws-responses.cjs');
|
|
23
|
+
const require_ws_realtime = require('./ws-realtime.cjs');
|
|
24
|
+
const require_ws_gemini_live = require('./ws-gemini-live.cjs');
|
|
25
|
+
const require_logger = require('./logger.cjs');
|
|
26
|
+
const require_metrics = require('./metrics.cjs');
|
|
27
|
+
let node_http = require("node:http");
|
|
28
|
+
node_http = require_runtime.__toESM(node_http);
|
|
29
|
+
|
|
30
|
+
//#region src/server.ts
|
|
31
|
+
const COMPLETIONS_PATH = "/v1/chat/completions";
|
|
32
|
+
const RESPONSES_PATH = "/v1/responses";
|
|
33
|
+
const REALTIME_PATH = "/v1/realtime";
|
|
34
|
+
const GEMINI_LIVE_PATH = "/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent";
|
|
35
|
+
const MESSAGES_PATH = "/v1/messages";
|
|
36
|
+
const EMBEDDINGS_PATH = "/v1/embeddings";
|
|
37
|
+
const COHERE_CHAT_PATH = "/v2/chat";
|
|
38
|
+
const SEARCH_PATH = "/search";
|
|
39
|
+
const RERANK_PATH = "/v2/rerank";
|
|
40
|
+
const MODERATIONS_PATH = "/v1/moderations";
|
|
41
|
+
const DEFAULT_CHUNK_SIZE = 20;
|
|
42
|
+
const GEMINI_PATH_RE = /^\/v1beta\/models\/([^:]+):(generateContent|streamGenerateContent)$/;
|
|
43
|
+
const AZURE_DEPLOYMENT_RE = /^\/openai\/deployments\/([^/]+)\/(chat\/completions|embeddings)$/;
|
|
44
|
+
const BEDROCK_INVOKE_RE = /^\/model\/([^/]+)\/invoke$/;
|
|
45
|
+
const BEDROCK_STREAM_RE = /^\/model\/([^/]+)\/invoke-with-response-stream$/;
|
|
46
|
+
const BEDROCK_CONVERSE_RE = /^\/model\/([^/]+)\/converse$/;
|
|
47
|
+
const BEDROCK_CONVERSE_STREAM_RE = /^\/model\/([^/]+)\/converse-stream$/;
|
|
48
|
+
const VERTEX_AI_RE = /^\/v1\/projects\/[^/]+\/locations\/[^/]+\/publishers\/google\/models\/([^/:]+):(generateContent|streamGenerateContent)$/;
|
|
49
|
+
const OLLAMA_CHAT_PATH = "/api/chat";
|
|
50
|
+
const OLLAMA_GENERATE_PATH = "/api/generate";
|
|
51
|
+
const OLLAMA_TAGS_PATH = "/api/tags";
|
|
52
|
+
const HEALTH_PATH = "/health";
|
|
53
|
+
const READY_PATH = "/ready";
|
|
54
|
+
const MODELS_PATH = "/v1/models";
|
|
55
|
+
const REQUESTS_PATH = "/v1/_requests";
|
|
56
|
+
const DEFAULT_MODELS = [
|
|
57
|
+
"gpt-4",
|
|
58
|
+
"gpt-4o",
|
|
59
|
+
"claude-3-5-sonnet-20241022",
|
|
60
|
+
"gemini-2.0-flash",
|
|
61
|
+
"text-embedding-3-small"
|
|
62
|
+
];
|
|
63
|
+
const CORS_HEADERS = {
|
|
64
|
+
"Access-Control-Allow-Origin": "*",
|
|
65
|
+
"Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
|
|
66
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
67
|
+
};
|
|
68
|
+
function setCorsHeaders(res) {
|
|
69
|
+
for (const [key, value] of Object.entries(CORS_HEADERS)) res.setHeader(key, value);
|
|
70
|
+
}
|
|
71
|
+
async function readBody(req) {
|
|
72
|
+
const buffers = [];
|
|
73
|
+
for await (const chunk of req) buffers.push(chunk);
|
|
74
|
+
return Buffer.concat(buffers).toString();
|
|
75
|
+
}
|
|
76
|
+
function handleOptions(res) {
|
|
77
|
+
setCorsHeaders(res);
|
|
78
|
+
res.writeHead(204);
|
|
79
|
+
res.end();
|
|
80
|
+
}
|
|
81
|
+
function handleNotFound(res, message) {
|
|
82
|
+
setCorsHeaders(res);
|
|
83
|
+
require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
|
|
84
|
+
message,
|
|
85
|
+
type: "not_found"
|
|
86
|
+
} }));
|
|
87
|
+
}
|
|
88
|
+
const CONTROL_PREFIX = "/__aimock";
|
|
89
|
+
/**
|
|
90
|
+
* Handle requests under `/__aimock/`. Returns `true` if the request was
|
|
91
|
+
* handled, `false` if the path doesn't match the control prefix.
|
|
92
|
+
*/
|
|
93
|
+
async function handleControlAPI(req, res, pathname, fixtures, journal) {
|
|
94
|
+
if (!pathname.startsWith(CONTROL_PREFIX)) return false;
|
|
95
|
+
const subPath = pathname.slice(9);
|
|
96
|
+
setCorsHeaders(res);
|
|
97
|
+
if (subPath === "/health" && req.method === "GET") {
|
|
98
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
99
|
+
res.end(JSON.stringify({ status: "ok" }));
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (subPath === "/journal" && req.method === "GET") {
|
|
103
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
104
|
+
res.end(JSON.stringify(journal.getAll()));
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (subPath === "/fixtures" && req.method === "POST") {
|
|
108
|
+
let raw;
|
|
109
|
+
try {
|
|
110
|
+
raw = await readBody(req);
|
|
111
|
+
} catch {
|
|
112
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
113
|
+
res.end(JSON.stringify({ error: "Failed to read request body" }));
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
let parsed;
|
|
117
|
+
try {
|
|
118
|
+
parsed = JSON.parse(raw);
|
|
119
|
+
} catch {
|
|
120
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
121
|
+
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
if (!Array.isArray(parsed.fixtures)) {
|
|
125
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
126
|
+
res.end(JSON.stringify({ error: "Missing or invalid \"fixtures\" array" }));
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
const converted = parsed.fixtures.map(require_fixture_loader.entryToFixture);
|
|
130
|
+
const errors = require_fixture_loader.validateFixtures(converted).filter((i) => i.severity === "error");
|
|
131
|
+
if (errors.length > 0) {
|
|
132
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
133
|
+
res.end(JSON.stringify({
|
|
134
|
+
error: "Validation failed",
|
|
135
|
+
details: errors
|
|
136
|
+
}));
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
fixtures.push(...converted);
|
|
140
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
141
|
+
res.end(JSON.stringify({ added: converted.length }));
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (subPath === "/fixtures" && req.method === "DELETE") {
|
|
145
|
+
fixtures.length = 0;
|
|
146
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
147
|
+
res.end(JSON.stringify({ cleared: true }));
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (subPath === "/reset" && req.method === "POST") {
|
|
151
|
+
fixtures.length = 0;
|
|
152
|
+
journal.clear();
|
|
153
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
154
|
+
res.end(JSON.stringify({ reset: true }));
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
if (subPath === "/error" && req.method === "POST") {
|
|
158
|
+
let raw;
|
|
159
|
+
try {
|
|
160
|
+
raw = await readBody(req);
|
|
161
|
+
} catch {
|
|
162
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
163
|
+
res.end(JSON.stringify({ error: "Failed to read request body" }));
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
let parsed;
|
|
167
|
+
try {
|
|
168
|
+
parsed = JSON.parse(raw);
|
|
169
|
+
} catch {
|
|
170
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
171
|
+
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
const status = parsed.status ?? 500;
|
|
175
|
+
const errorBody = parsed.body;
|
|
176
|
+
const errorFixture = {
|
|
177
|
+
match: { predicate: () => true },
|
|
178
|
+
response: {
|
|
179
|
+
error: {
|
|
180
|
+
message: errorBody?.message ?? "Injected error",
|
|
181
|
+
type: errorBody?.type ?? "server_error",
|
|
182
|
+
code: errorBody?.code
|
|
183
|
+
},
|
|
184
|
+
status
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
fixtures.unshift(errorFixture);
|
|
188
|
+
const original = errorFixture.match.predicate;
|
|
189
|
+
errorFixture.match.predicate = (req) => {
|
|
190
|
+
const result = original(req);
|
|
191
|
+
if (result) queueMicrotask(() => {
|
|
192
|
+
const idx = fixtures.indexOf(errorFixture);
|
|
193
|
+
if (idx !== -1) fixtures.splice(idx, 1);
|
|
194
|
+
});
|
|
195
|
+
return result;
|
|
196
|
+
};
|
|
197
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
198
|
+
res.end(JSON.stringify({ queued: true }));
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
handleNotFound(res, `Unknown control endpoint: ${pathname}`);
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
async function handleCompletions(req, res, fixtures, journal, defaults, modelFallback, providerKey) {
|
|
205
|
+
setCorsHeaders(res);
|
|
206
|
+
let raw;
|
|
207
|
+
try {
|
|
208
|
+
raw = await readBody(req);
|
|
209
|
+
} catch (err) {
|
|
210
|
+
const msg = err instanceof Error ? err.message : "Failed to read request body";
|
|
211
|
+
journal.add({
|
|
212
|
+
method: req.method ?? "POST",
|
|
213
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
214
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
215
|
+
body: null,
|
|
216
|
+
response: {
|
|
217
|
+
status: 500,
|
|
218
|
+
fixture: null
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
222
|
+
message: `Request body read failed: ${msg}`,
|
|
223
|
+
type: "server_error"
|
|
224
|
+
} }));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
let body;
|
|
228
|
+
try {
|
|
229
|
+
body = JSON.parse(raw);
|
|
230
|
+
if (modelFallback && !body.model) body.model = modelFallback;
|
|
231
|
+
} catch {
|
|
232
|
+
journal.add({
|
|
233
|
+
method: req.method ?? "POST",
|
|
234
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
235
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
236
|
+
body: null,
|
|
237
|
+
response: {
|
|
238
|
+
status: 400,
|
|
239
|
+
fixture: null
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
243
|
+
message: "Malformed JSON",
|
|
244
|
+
type: "invalid_request_error",
|
|
245
|
+
code: "invalid_json"
|
|
246
|
+
} }));
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const fixture = require_router.matchFixture(fixtures, body, journal.fixtureMatchCounts);
|
|
250
|
+
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures);
|
|
251
|
+
const method = req.method ?? "POST";
|
|
252
|
+
const path = req.url ?? COMPLETIONS_PATH;
|
|
253
|
+
const flatHeaders = require_helpers.flattenHeaders(req.headers);
|
|
254
|
+
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
|
|
255
|
+
method,
|
|
256
|
+
path,
|
|
257
|
+
headers: flatHeaders,
|
|
258
|
+
body
|
|
259
|
+
}, defaults.registry, defaults.logger)) return;
|
|
260
|
+
if (!fixture) {
|
|
261
|
+
if (defaults.record && providerKey) {
|
|
262
|
+
if (await require_recorder.proxyAndRecord(req, res, body, providerKey, req.url ?? COMPLETIONS_PATH, fixtures, defaults, raw)) {
|
|
263
|
+
journal.add({
|
|
264
|
+
method: req.method ?? "POST",
|
|
265
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
266
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
267
|
+
body,
|
|
268
|
+
response: {
|
|
269
|
+
status: res.statusCode ?? 200,
|
|
270
|
+
fixture: null
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const strictStatus = defaults.strict ? 503 : 404;
|
|
277
|
+
const strictMessage = defaults.strict ? "Strict mode: no fixture matched" : "No fixture matched";
|
|
278
|
+
if (defaults.strict) defaults.logger.error(`STRICT: No fixture matched for ${req.method ?? "POST"} ${req.url ?? COMPLETIONS_PATH}`);
|
|
279
|
+
journal.add({
|
|
280
|
+
method: req.method ?? "POST",
|
|
281
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
282
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
283
|
+
body,
|
|
284
|
+
response: {
|
|
285
|
+
status: strictStatus,
|
|
286
|
+
fixture: null
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
|
|
290
|
+
message: strictMessage,
|
|
291
|
+
type: "invalid_request_error",
|
|
292
|
+
code: "no_fixture_match"
|
|
293
|
+
} }));
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const response = fixture.response;
|
|
297
|
+
const latency = fixture.latency ?? defaults.latency;
|
|
298
|
+
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
299
|
+
if (require_helpers.isErrorResponse(response)) {
|
|
300
|
+
const status = response.status ?? 500;
|
|
301
|
+
journal.add({
|
|
302
|
+
method: req.method ?? "POST",
|
|
303
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
304
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
305
|
+
body,
|
|
306
|
+
response: {
|
|
307
|
+
status,
|
|
308
|
+
fixture
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
require_sse_writer.writeErrorResponse(res, status, JSON.stringify(response));
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (require_helpers.isTextResponse(response)) {
|
|
315
|
+
const journalEntry = journal.add({
|
|
316
|
+
method: req.method ?? "POST",
|
|
317
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
318
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
319
|
+
body,
|
|
320
|
+
response: {
|
|
321
|
+
status: 200,
|
|
322
|
+
fixture
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
if (body.stream !== true) {
|
|
326
|
+
const completion = require_helpers.buildTextCompletion(response.content, body.model);
|
|
327
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
328
|
+
res.end(JSON.stringify(completion));
|
|
329
|
+
} else {
|
|
330
|
+
const chunks = require_helpers.buildTextChunks(response.content, body.model, chunkSize);
|
|
331
|
+
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
332
|
+
if (!await require_sse_writer.writeSSEStream(res, chunks, {
|
|
333
|
+
latency,
|
|
334
|
+
streamingProfile: fixture.streamingProfile,
|
|
335
|
+
signal: interruption?.signal,
|
|
336
|
+
onChunkSent: interruption?.tick
|
|
337
|
+
})) {
|
|
338
|
+
if (!res.writableEnded) res.destroy();
|
|
339
|
+
journalEntry.response.interrupted = true;
|
|
340
|
+
journalEntry.response.interruptReason = interruption?.reason();
|
|
341
|
+
}
|
|
342
|
+
interruption?.cleanup();
|
|
343
|
+
}
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (require_helpers.isToolCallResponse(response)) {
|
|
347
|
+
const journalEntry = journal.add({
|
|
348
|
+
method: req.method ?? "POST",
|
|
349
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
350
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
351
|
+
body,
|
|
352
|
+
response: {
|
|
353
|
+
status: 200,
|
|
354
|
+
fixture
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
if (body.stream !== true) {
|
|
358
|
+
const completion = require_helpers.buildToolCallCompletion(response.toolCalls, body.model);
|
|
359
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
360
|
+
res.end(JSON.stringify(completion));
|
|
361
|
+
} else {
|
|
362
|
+
const chunks = require_helpers.buildToolCallChunks(response.toolCalls, body.model, chunkSize);
|
|
363
|
+
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
364
|
+
if (!await require_sse_writer.writeSSEStream(res, chunks, {
|
|
365
|
+
latency,
|
|
366
|
+
streamingProfile: fixture.streamingProfile,
|
|
367
|
+
signal: interruption?.signal,
|
|
368
|
+
onChunkSent: interruption?.tick
|
|
369
|
+
})) {
|
|
370
|
+
if (!res.writableEnded) res.destroy();
|
|
371
|
+
journalEntry.response.interrupted = true;
|
|
372
|
+
journalEntry.response.interruptReason = interruption?.reason();
|
|
373
|
+
}
|
|
374
|
+
interruption?.cleanup();
|
|
375
|
+
}
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
journal.add({
|
|
379
|
+
method: req.method ?? "POST",
|
|
380
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
381
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
382
|
+
body,
|
|
383
|
+
response: {
|
|
384
|
+
status: 500,
|
|
385
|
+
fixture
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
389
|
+
message: "Fixture response did not match any known type",
|
|
390
|
+
type: "server_error"
|
|
391
|
+
} }));
|
|
392
|
+
}
|
|
393
|
+
async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
394
|
+
const host = options?.host ?? "127.0.0.1";
|
|
395
|
+
const port = options?.port ?? 0;
|
|
396
|
+
const logger = new require_logger.Logger(options?.logLevel ?? "silent");
|
|
397
|
+
const registry = options?.metrics ? require_metrics.createMetricsRegistry() : void 0;
|
|
398
|
+
const serverOptions = options ?? {};
|
|
399
|
+
const defaults = {
|
|
400
|
+
latency: serverOptions.latency ?? 0,
|
|
401
|
+
chunkSize: Math.max(1, serverOptions.chunkSize ?? DEFAULT_CHUNK_SIZE),
|
|
402
|
+
logger,
|
|
403
|
+
get chaos() {
|
|
404
|
+
return serverOptions.chaos;
|
|
405
|
+
},
|
|
406
|
+
registry,
|
|
407
|
+
get record() {
|
|
408
|
+
return serverOptions.record;
|
|
409
|
+
},
|
|
410
|
+
get strict() {
|
|
411
|
+
return serverOptions.strict;
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
if (options?.chaos) {
|
|
415
|
+
const chaosRates = [
|
|
416
|
+
{
|
|
417
|
+
name: "dropRate",
|
|
418
|
+
value: options.chaos.dropRate
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
name: "malformedRate",
|
|
422
|
+
value: options.chaos.malformedRate
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
name: "disconnectRate",
|
|
426
|
+
value: options.chaos.disconnectRate
|
|
427
|
+
}
|
|
428
|
+
];
|
|
429
|
+
for (const { name, value } of chaosRates) if (value !== void 0 && (value < 0 || value > 1)) logger.warn(`Chaos ${name} (${value}) is outside 0-1 range — will be clamped at runtime`);
|
|
430
|
+
}
|
|
431
|
+
const journal = new require_journal.Journal();
|
|
432
|
+
if (mounts) for (const { handler } of mounts) {
|
|
433
|
+
if (handler.setJournal) handler.setJournal(journal);
|
|
434
|
+
if (registry && handler.setRegistry) handler.setRegistry(registry);
|
|
435
|
+
}
|
|
436
|
+
if (registry) registry.setGauge("aimock_fixtures_loaded", {}, fixtures.length);
|
|
437
|
+
const server = node_http.createServer((req, res) => {
|
|
438
|
+
handleHttpRequest(req, res).catch((err) => {
|
|
439
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
440
|
+
defaults.logger.warn(`Unhandled request error: ${msg}`);
|
|
441
|
+
if (!res.headersSent) {
|
|
442
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
443
|
+
res.end(JSON.stringify({ error: {
|
|
444
|
+
message: msg,
|
|
445
|
+
type: "server_error"
|
|
446
|
+
} }));
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
async function handleHttpRequest(req, res) {
|
|
451
|
+
if (req.method === "OPTIONS") {
|
|
452
|
+
handleOptions(res);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const startTime = registry ? process.hrtime.bigint() : 0n;
|
|
456
|
+
const parsedUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
457
|
+
let pathname = parsedUrl.pathname;
|
|
458
|
+
if (registry) {
|
|
459
|
+
const rawPathname = pathname;
|
|
460
|
+
res.on("finish", () => {
|
|
461
|
+
try {
|
|
462
|
+
const normalizedPath = require_metrics.normalizePathLabel(rawPathname);
|
|
463
|
+
const method = req.method ?? "UNKNOWN";
|
|
464
|
+
const status = String(res.statusCode);
|
|
465
|
+
registry.incrementCounter("aimock_requests_total", {
|
|
466
|
+
method,
|
|
467
|
+
path: normalizedPath,
|
|
468
|
+
status
|
|
469
|
+
});
|
|
470
|
+
const elapsed = Number(process.hrtime.bigint() - startTime) / 1e9;
|
|
471
|
+
registry.observeHistogram("aimock_request_duration_seconds", {
|
|
472
|
+
method,
|
|
473
|
+
path: normalizedPath
|
|
474
|
+
}, elapsed);
|
|
475
|
+
} catch (err) {
|
|
476
|
+
defaults.logger.warn("metrics instrumentation error", err);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
if (pathname.startsWith(CONTROL_PREFIX)) {
|
|
481
|
+
await handleControlAPI(req, res, pathname, fixtures, journal);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
if (mounts) {
|
|
485
|
+
for (const { path: mountPath, handler } of mounts) if (pathname === mountPath || pathname.startsWith(mountPath + "/")) {
|
|
486
|
+
const subPath = pathname.slice(mountPath.length) || "/";
|
|
487
|
+
if (await handler.handleRequest(req, res, subPath)) return;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
let azureDeploymentId;
|
|
491
|
+
const azureMatch = pathname.match(AZURE_DEPLOYMENT_RE);
|
|
492
|
+
if (azureMatch && req.method === "POST") {
|
|
493
|
+
azureDeploymentId = azureMatch[1];
|
|
494
|
+
pathname = `/v1/${azureMatch[2]}`;
|
|
495
|
+
}
|
|
496
|
+
if (!azureDeploymentId && pathname.startsWith("/openai/")) pathname = pathname.slice(7);
|
|
497
|
+
if (pathname === HEALTH_PATH && req.method === "GET") {
|
|
498
|
+
setCorsHeaders(res);
|
|
499
|
+
if (mounts && mounts.length > 0) {
|
|
500
|
+
const services = { llm: {
|
|
501
|
+
status: "ok",
|
|
502
|
+
fixtures: fixtures.length
|
|
503
|
+
} };
|
|
504
|
+
for (const { path: mountPath, handler } of mounts) if (handler.health) {
|
|
505
|
+
const name = mountPath.replace(/^\//, "");
|
|
506
|
+
services[name] = handler.health();
|
|
507
|
+
}
|
|
508
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
509
|
+
res.end(JSON.stringify({
|
|
510
|
+
status: "ok",
|
|
511
|
+
services
|
|
512
|
+
}));
|
|
513
|
+
} else {
|
|
514
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
515
|
+
res.end(JSON.stringify({ status: "ok" }));
|
|
516
|
+
}
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
if (pathname === READY_PATH && req.method === "GET") {
|
|
520
|
+
setCorsHeaders(res);
|
|
521
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
522
|
+
res.end(JSON.stringify({ status: "ready" }));
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
if (pathname === "/metrics" && req.method === "GET") {
|
|
526
|
+
if (!registry) {
|
|
527
|
+
handleNotFound(res, "Not found");
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
setCorsHeaders(res);
|
|
531
|
+
res.writeHead(200, { "Content-Type": "text/plain; version=0.0.4; charset=utf-8" });
|
|
532
|
+
res.end(registry.serialize());
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (pathname === MODELS_PATH && req.method === "GET") {
|
|
536
|
+
setCorsHeaders(res);
|
|
537
|
+
const modelIds = /* @__PURE__ */ new Set();
|
|
538
|
+
for (const f of fixtures) if (f.match.model && typeof f.match.model === "string") modelIds.add(f.match.model);
|
|
539
|
+
const data = (modelIds.size > 0 ? [...modelIds] : DEFAULT_MODELS).map((id) => ({
|
|
540
|
+
id,
|
|
541
|
+
object: "model",
|
|
542
|
+
created: 1686935002,
|
|
543
|
+
owned_by: "aimock"
|
|
544
|
+
}));
|
|
545
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
546
|
+
res.end(JSON.stringify({
|
|
547
|
+
object: "list",
|
|
548
|
+
data
|
|
549
|
+
}));
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (pathname === REQUESTS_PATH) {
|
|
553
|
+
setCorsHeaders(res);
|
|
554
|
+
if (req.method === "GET") {
|
|
555
|
+
const limitParam = parsedUrl.searchParams.get("limit");
|
|
556
|
+
let opts;
|
|
557
|
+
if (limitParam) {
|
|
558
|
+
const limit = parseInt(limitParam, 10);
|
|
559
|
+
if (Number.isNaN(limit) || limit <= 0) {
|
|
560
|
+
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
561
|
+
message: `Invalid limit parameter: "${limitParam}"`,
|
|
562
|
+
type: "invalid_request_error"
|
|
563
|
+
} }));
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
opts = { limit };
|
|
567
|
+
}
|
|
568
|
+
const entries = journal.getAll(opts);
|
|
569
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
570
|
+
res.end(JSON.stringify(entries));
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
if (req.method === "DELETE") {
|
|
574
|
+
journal.clear();
|
|
575
|
+
res.writeHead(204);
|
|
576
|
+
res.end();
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
handleNotFound(res, "Not found");
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
if (pathname === RESPONSES_PATH && req.method === "POST") {
|
|
583
|
+
readBody(req).then((raw) => require_responses.handleResponses(req, res, raw, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
584
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
585
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
586
|
+
message: msg,
|
|
587
|
+
type: "server_error"
|
|
588
|
+
} }));
|
|
589
|
+
else if (!res.writableEnded) {
|
|
590
|
+
try {
|
|
591
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
592
|
+
} catch (writeErr) {
|
|
593
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
594
|
+
}
|
|
595
|
+
res.end();
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (pathname === MESSAGES_PATH && req.method === "POST") {
|
|
601
|
+
readBody(req).then((raw) => require_messages.handleMessages(req, res, raw, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
602
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
603
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
604
|
+
message: msg,
|
|
605
|
+
type: "server_error"
|
|
606
|
+
} }));
|
|
607
|
+
else if (!res.writableEnded) {
|
|
608
|
+
try {
|
|
609
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
610
|
+
} catch (writeErr) {
|
|
611
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
612
|
+
}
|
|
613
|
+
res.end();
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
if (pathname === COHERE_CHAT_PATH && req.method === "POST") {
|
|
619
|
+
readBody(req).then((raw) => require_cohere.handleCohere(req, res, raw, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
620
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
621
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
622
|
+
message: msg,
|
|
623
|
+
type: "server_error"
|
|
624
|
+
} }));
|
|
625
|
+
else if (!res.writableEnded) {
|
|
626
|
+
try {
|
|
627
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
628
|
+
} catch (writeErr) {
|
|
629
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
630
|
+
}
|
|
631
|
+
res.end();
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
if (pathname === EMBEDDINGS_PATH && req.method === "POST") {
|
|
637
|
+
const deploymentId = azureDeploymentId;
|
|
638
|
+
readBody(req).then((raw) => {
|
|
639
|
+
if (deploymentId) try {
|
|
640
|
+
const parsed = JSON.parse(raw);
|
|
641
|
+
if (!parsed.model) {
|
|
642
|
+
parsed.model = deploymentId;
|
|
643
|
+
return require_embeddings.handleEmbeddings(req, res, JSON.stringify(parsed), fixtures, journal, defaults, setCorsHeaders);
|
|
644
|
+
}
|
|
645
|
+
} catch {}
|
|
646
|
+
return require_embeddings.handleEmbeddings(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
|
|
647
|
+
}).catch((err) => {
|
|
648
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
649
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
650
|
+
message: msg,
|
|
651
|
+
type: "server_error"
|
|
652
|
+
} }));
|
|
653
|
+
else if (!res.writableEnded) res.destroy();
|
|
654
|
+
});
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const geminiMatch = pathname.match(GEMINI_PATH_RE);
|
|
658
|
+
if (geminiMatch && req.method === "POST") {
|
|
659
|
+
const geminiModel = geminiMatch[1];
|
|
660
|
+
const streaming = geminiMatch[2] === "streamGenerateContent";
|
|
661
|
+
readBody(req).then((raw) => require_gemini.handleGemini(req, res, raw, geminiModel, streaming, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
662
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
663
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
664
|
+
message: msg,
|
|
665
|
+
type: "server_error"
|
|
666
|
+
} }));
|
|
667
|
+
else if (!res.writableEnded) {
|
|
668
|
+
try {
|
|
669
|
+
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
670
|
+
} catch (writeErr) {
|
|
671
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
672
|
+
}
|
|
673
|
+
res.end();
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
const vertexMatch = pathname.match(VERTEX_AI_RE);
|
|
679
|
+
if (vertexMatch && req.method === "POST") {
|
|
680
|
+
const vertexModel = vertexMatch[1];
|
|
681
|
+
const streaming = vertexMatch[2] === "streamGenerateContent";
|
|
682
|
+
readBody(req).then((raw) => require_gemini.handleGemini(req, res, raw, vertexModel, streaming, fixtures, journal, defaults, setCorsHeaders, "vertexai")).catch((err) => {
|
|
683
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
684
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
685
|
+
message: msg,
|
|
686
|
+
type: "server_error"
|
|
687
|
+
} }));
|
|
688
|
+
else if (!res.writableEnded) {
|
|
689
|
+
try {
|
|
690
|
+
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
691
|
+
} catch (writeErr) {
|
|
692
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
693
|
+
}
|
|
694
|
+
res.end();
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
const bedrockMatch = pathname.match(BEDROCK_INVOKE_RE);
|
|
700
|
+
if (bedrockMatch && req.method === "POST") {
|
|
701
|
+
const bedrockModelId = bedrockMatch[1];
|
|
702
|
+
readBody(req).then((raw) => require_bedrock.handleBedrock(req, res, raw, bedrockModelId, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
703
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
704
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
705
|
+
message: msg,
|
|
706
|
+
type: "server_error"
|
|
707
|
+
} }));
|
|
708
|
+
else if (!res.writableEnded) res.destroy();
|
|
709
|
+
});
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const bedrockStreamMatch = pathname.match(BEDROCK_STREAM_RE);
|
|
713
|
+
if (bedrockStreamMatch && req.method === "POST") {
|
|
714
|
+
const bedrockModelId = bedrockStreamMatch[1];
|
|
715
|
+
readBody(req).then((raw) => require_bedrock.handleBedrockStream(req, res, raw, bedrockModelId, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
716
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
717
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
718
|
+
message: msg,
|
|
719
|
+
type: "server_error"
|
|
720
|
+
} }));
|
|
721
|
+
else if (!res.writableEnded) res.destroy();
|
|
722
|
+
});
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const converseMatch = pathname.match(BEDROCK_CONVERSE_RE);
|
|
726
|
+
if (converseMatch && req.method === "POST") {
|
|
727
|
+
const converseModelId = converseMatch[1];
|
|
728
|
+
readBody(req).then((raw) => require_bedrock_converse.handleConverse(req, res, raw, converseModelId, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
729
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
730
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
731
|
+
message: msg,
|
|
732
|
+
type: "server_error"
|
|
733
|
+
} }));
|
|
734
|
+
else if (!res.writableEnded) res.destroy();
|
|
735
|
+
});
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
const converseStreamMatch = pathname.match(BEDROCK_CONVERSE_STREAM_RE);
|
|
739
|
+
if (converseStreamMatch && req.method === "POST") {
|
|
740
|
+
const converseStreamModelId = converseStreamMatch[1];
|
|
741
|
+
readBody(req).then((raw) => require_bedrock_converse.handleConverseStream(req, res, raw, converseStreamModelId, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
742
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
743
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
744
|
+
message: msg,
|
|
745
|
+
type: "server_error"
|
|
746
|
+
} }));
|
|
747
|
+
else if (!res.writableEnded) res.destroy();
|
|
748
|
+
});
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (pathname === OLLAMA_CHAT_PATH && req.method === "POST") {
|
|
752
|
+
readBody(req).then((raw) => require_ollama.handleOllama(req, res, raw, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
753
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
754
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
755
|
+
message: msg,
|
|
756
|
+
type: "server_error"
|
|
757
|
+
} }));
|
|
758
|
+
else if (!res.writableEnded) res.destroy();
|
|
759
|
+
});
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
if (pathname === OLLAMA_GENERATE_PATH && req.method === "POST") {
|
|
763
|
+
readBody(req).then((raw) => require_ollama.handleOllamaGenerate(req, res, raw, fixtures, journal, defaults, setCorsHeaders)).catch((err) => {
|
|
764
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
765
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
766
|
+
message: msg,
|
|
767
|
+
type: "server_error"
|
|
768
|
+
} }));
|
|
769
|
+
else if (!res.writableEnded) res.destroy();
|
|
770
|
+
});
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
if (pathname === OLLAMA_TAGS_PATH && req.method === "GET") {
|
|
774
|
+
setCorsHeaders(res);
|
|
775
|
+
const modelIds = /* @__PURE__ */ new Set();
|
|
776
|
+
for (const f of fixtures) if (f.match.model && typeof f.match.model === "string") modelIds.add(f.match.model);
|
|
777
|
+
const models = (modelIds.size > 0 ? [...modelIds] : DEFAULT_MODELS).map((name) => ({
|
|
778
|
+
name,
|
|
779
|
+
model: name,
|
|
780
|
+
modified_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
781
|
+
size: 0,
|
|
782
|
+
digest: "",
|
|
783
|
+
details: {}
|
|
784
|
+
}));
|
|
785
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
786
|
+
res.end(JSON.stringify({ models }));
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
if (pathname === SEARCH_PATH && req.method === "POST") {
|
|
790
|
+
readBody(req).then((raw) => require_search.handleSearch(req, res, raw, serviceFixtures?.search ?? [], journal, defaults, setCorsHeaders)).catch((err) => {
|
|
791
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
792
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
793
|
+
message: msg,
|
|
794
|
+
type: "server_error"
|
|
795
|
+
} }));
|
|
796
|
+
else if (!res.writableEnded) res.destroy();
|
|
797
|
+
});
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
if (pathname === RERANK_PATH && req.method === "POST") {
|
|
801
|
+
readBody(req).then((raw) => require_rerank.handleRerank(req, res, raw, serviceFixtures?.rerank ?? [], journal, defaults, setCorsHeaders)).catch((err) => {
|
|
802
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
803
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
804
|
+
message: msg,
|
|
805
|
+
type: "server_error"
|
|
806
|
+
} }));
|
|
807
|
+
else if (!res.writableEnded) res.destroy();
|
|
808
|
+
});
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (pathname === MODERATIONS_PATH && req.method === "POST") {
|
|
812
|
+
readBody(req).then((raw) => require_moderation.handleModeration(req, res, raw, serviceFixtures?.moderation ?? [], journal, defaults, setCorsHeaders)).catch((err) => {
|
|
813
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
814
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
815
|
+
message: msg,
|
|
816
|
+
type: "server_error"
|
|
817
|
+
} }));
|
|
818
|
+
else if (!res.writableEnded) res.destroy();
|
|
819
|
+
});
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
if (pathname !== COMPLETIONS_PATH) {
|
|
823
|
+
handleNotFound(res, "Not found");
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
if (req.method !== "POST") {
|
|
827
|
+
handleNotFound(res, "Not found");
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
handleCompletions(req, res, fixtures, journal, defaults, azureDeploymentId, azureDeploymentId ? "azure" : "openai").catch((err) => {
|
|
831
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
832
|
+
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
833
|
+
message: msg,
|
|
834
|
+
type: "server_error"
|
|
835
|
+
} }));
|
|
836
|
+
else if (!res.writableEnded) {
|
|
837
|
+
try {
|
|
838
|
+
res.write(`data: ${JSON.stringify({ error: {
|
|
839
|
+
message: msg,
|
|
840
|
+
type: "server_error"
|
|
841
|
+
} })}\n\n`);
|
|
842
|
+
} catch (writeErr) {
|
|
843
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
844
|
+
}
|
|
845
|
+
res.end();
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
const activeConnections = /* @__PURE__ */ new Set();
|
|
850
|
+
server.on("upgrade", (req, socket, head) => {
|
|
851
|
+
handleUpgradeRequest(req, socket, head).catch((err) => {
|
|
852
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
853
|
+
defaults.logger.warn(`Unhandled upgrade error: ${msg}`);
|
|
854
|
+
if (!socket.destroyed) socket.destroy();
|
|
855
|
+
});
|
|
856
|
+
});
|
|
857
|
+
async function handleUpgradeRequest(req, socket, head) {
|
|
858
|
+
const parsedUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
859
|
+
const pathname = parsedUrl.pathname;
|
|
860
|
+
if (mounts) {
|
|
861
|
+
for (const { path: mountPath, handler } of mounts) if ((pathname === mountPath || pathname.startsWith(mountPath + "/")) && handler.handleUpgrade) {
|
|
862
|
+
const subPath = pathname.slice(mountPath.length) || "/";
|
|
863
|
+
if (await handler.handleUpgrade(socket, head, subPath)) return;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
if (pathname !== RESPONSES_PATH && pathname !== REALTIME_PATH && pathname !== GEMINI_LIVE_PATH) {
|
|
867
|
+
socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
|
|
868
|
+
socket.destroy();
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
if (head.length > 0) socket.unshift(head);
|
|
872
|
+
let ws;
|
|
873
|
+
try {
|
|
874
|
+
ws = require_ws_framing.upgradeToWebSocket(req, socket);
|
|
875
|
+
} catch (err) {
|
|
876
|
+
const msg = err instanceof Error ? err.message : "WebSocket upgrade failed";
|
|
877
|
+
logger.error(`WebSocket upgrade error: ${msg}`);
|
|
878
|
+
if (!socket.destroyed) socket.destroy();
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
activeConnections.add(ws);
|
|
882
|
+
ws.on("error", (err) => {
|
|
883
|
+
logger.error(`WebSocket error: ${err.message}`);
|
|
884
|
+
activeConnections.delete(ws);
|
|
885
|
+
});
|
|
886
|
+
ws.on("close", () => {
|
|
887
|
+
activeConnections.delete(ws);
|
|
888
|
+
});
|
|
889
|
+
if (pathname === RESPONSES_PATH) require_ws_responses.handleWebSocketResponses(ws, fixtures, journal, {
|
|
890
|
+
...defaults,
|
|
891
|
+
model: "gpt-4"
|
|
892
|
+
});
|
|
893
|
+
else if (pathname === REALTIME_PATH) {
|
|
894
|
+
const model = parsedUrl.searchParams.get("model") ?? "gpt-4o-realtime";
|
|
895
|
+
require_ws_realtime.handleWebSocketRealtime(ws, fixtures, journal, {
|
|
896
|
+
...defaults,
|
|
897
|
+
model
|
|
898
|
+
});
|
|
899
|
+
} else if (pathname === GEMINI_LIVE_PATH) require_ws_gemini_live.handleWebSocketGeminiLive(ws, fixtures, journal, {
|
|
900
|
+
...defaults,
|
|
901
|
+
model: "gemini-2.0-flash"
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
const originalClose = server.close.bind(server);
|
|
905
|
+
server.close = function(callback) {
|
|
906
|
+
for (const ws of activeConnections) ws.close(1001, "Server shutting down");
|
|
907
|
+
activeConnections.clear();
|
|
908
|
+
originalClose(callback);
|
|
909
|
+
return this;
|
|
910
|
+
};
|
|
911
|
+
return new Promise((resolve, reject) => {
|
|
912
|
+
server.on("error", reject);
|
|
913
|
+
server.listen(port, host, () => {
|
|
914
|
+
const addr = server.address();
|
|
915
|
+
if (!addr || typeof addr === "string") {
|
|
916
|
+
reject(/* @__PURE__ */ new Error("Unexpected address format"));
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
const url = `http://${addr.address}:${addr.port}`;
|
|
920
|
+
if (mounts) {
|
|
921
|
+
for (const { path: mountPath, handler } of mounts) if (handler.setBaseUrl) handler.setBaseUrl(url + mountPath);
|
|
922
|
+
}
|
|
923
|
+
resolve({
|
|
924
|
+
server,
|
|
925
|
+
journal,
|
|
926
|
+
url,
|
|
927
|
+
defaults
|
|
928
|
+
});
|
|
929
|
+
});
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
//#endregion
|
|
934
|
+
exports.createServer = createServer;
|
|
935
|
+
//# sourceMappingURL=server.cjs.map
|