@copilotkit/aimock 1.42.1 → 1.43.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 (338) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +50 -0
  4. package/README.md +102 -16
  5. package/dist/agui-mock.cjs +1 -1
  6. package/dist/agui-mock.cjs.map +1 -1
  7. package/dist/agui-mock.d.cts.map +1 -1
  8. package/dist/agui-mock.d.ts.map +1 -1
  9. package/dist/agui-mock.js +1 -1
  10. package/dist/agui-mock.js.map +1 -1
  11. package/dist/agui-recorder.cjs +33 -11
  12. package/dist/agui-recorder.cjs.map +1 -1
  13. package/dist/agui-recorder.d.cts +10 -1
  14. package/dist/agui-recorder.d.cts.map +1 -1
  15. package/dist/agui-recorder.d.ts +10 -1
  16. package/dist/agui-recorder.d.ts.map +1 -1
  17. package/dist/agui-recorder.js +33 -11
  18. package/dist/agui-recorder.js.map +1 -1
  19. package/dist/agui-types.d.cts +1 -0
  20. package/dist/agui-types.d.cts.map +1 -1
  21. package/dist/agui-types.d.ts +1 -0
  22. package/dist/agui-types.d.ts.map +1 -1
  23. package/dist/aimock-cli.cjs +38 -10
  24. package/dist/aimock-cli.cjs.map +1 -1
  25. package/dist/aimock-cli.d.cts +5 -0
  26. package/dist/aimock-cli.d.cts.map +1 -1
  27. package/dist/aimock-cli.d.ts +5 -0
  28. package/dist/aimock-cli.d.ts.map +1 -1
  29. package/dist/aimock-cli.js +38 -10
  30. package/dist/aimock-cli.js.map +1 -1
  31. package/dist/batches.cjs +458 -0
  32. package/dist/batches.cjs.map +1 -0
  33. package/dist/batches.d.cts +57 -0
  34. package/dist/batches.d.cts.map +1 -0
  35. package/dist/batches.d.ts +57 -0
  36. package/dist/batches.d.ts.map +1 -0
  37. package/dist/batches.js +453 -0
  38. package/dist/batches.js.map +1 -0
  39. package/dist/bedrock-converse.cjs +12 -8
  40. package/dist/bedrock-converse.cjs.map +1 -1
  41. package/dist/bedrock-converse.d.cts.map +1 -1
  42. package/dist/bedrock-converse.d.ts.map +1 -1
  43. package/dist/bedrock-converse.js +14 -10
  44. package/dist/bedrock-converse.js.map +1 -1
  45. package/dist/bedrock.cjs +10 -8
  46. package/dist/bedrock.cjs.map +1 -1
  47. package/dist/bedrock.d.cts.map +1 -1
  48. package/dist/bedrock.d.ts.map +1 -1
  49. package/dist/bedrock.js +12 -10
  50. package/dist/bedrock.js.map +1 -1
  51. package/dist/byteplus-video.cjs +3 -3
  52. package/dist/byteplus-video.cjs.map +1 -1
  53. package/dist/byteplus-video.js +4 -4
  54. package/dist/byteplus-video.js.map +1 -1
  55. package/dist/chaos.cjs +622 -72
  56. package/dist/chaos.cjs.map +1 -1
  57. package/dist/chaos.d.cts +164 -7
  58. package/dist/chaos.d.cts.map +1 -1
  59. package/dist/chaos.d.ts +164 -7
  60. package/dist/chaos.d.ts.map +1 -1
  61. package/dist/chaos.js +613 -74
  62. package/dist/chaos.js.map +1 -1
  63. package/dist/cli.cjs +42 -23
  64. package/dist/cli.cjs.map +1 -1
  65. package/dist/cli.js +42 -23
  66. package/dist/cli.js.map +1 -1
  67. package/dist/cohere.cjs +10 -8
  68. package/dist/cohere.cjs.map +1 -1
  69. package/dist/cohere.d.cts.map +1 -1
  70. package/dist/cohere.d.ts.map +1 -1
  71. package/dist/cohere.js +12 -10
  72. package/dist/cohere.js.map +1 -1
  73. package/dist/config-loader.d.ts.map +1 -1
  74. package/dist/convert.cjs +1 -1
  75. package/dist/convert.cjs.map +1 -1
  76. package/dist/convert.js +1 -1
  77. package/dist/convert.js.map +1 -1
  78. package/dist/elevenlabs-audio.cjs +3 -3
  79. package/dist/elevenlabs-audio.cjs.map +1 -1
  80. package/dist/elevenlabs-audio.js +4 -4
  81. package/dist/elevenlabs-audio.js.map +1 -1
  82. package/dist/elevenlabs-voice.cjs +1053 -0
  83. package/dist/elevenlabs-voice.cjs.map +1 -0
  84. package/dist/elevenlabs-voice.d.cts +72 -0
  85. package/dist/elevenlabs-voice.d.cts.map +1 -0
  86. package/dist/elevenlabs-voice.d.ts +72 -0
  87. package/dist/elevenlabs-voice.d.ts.map +1 -0
  88. package/dist/elevenlabs-voice.js +1048 -0
  89. package/dist/elevenlabs-voice.js.map +1 -0
  90. package/dist/embeddings.cjs +8 -4
  91. package/dist/embeddings.cjs.map +1 -1
  92. package/dist/embeddings.d.cts.map +1 -1
  93. package/dist/embeddings.d.ts.map +1 -1
  94. package/dist/embeddings.js +9 -5
  95. package/dist/embeddings.js.map +1 -1
  96. package/dist/fal-audio.cjs +3 -3
  97. package/dist/fal-audio.cjs.map +1 -1
  98. package/dist/fal-audio.js +4 -4
  99. package/dist/fal-audio.js.map +1 -1
  100. package/dist/fal.cjs +28 -4
  101. package/dist/fal.cjs.map +1 -1
  102. package/dist/fal.d.cts +16 -1
  103. package/dist/fal.d.cts.map +1 -1
  104. package/dist/fal.d.ts +16 -1
  105. package/dist/fal.d.ts.map +1 -1
  106. package/dist/fal.js +28 -5
  107. package/dist/fal.js.map +1 -1
  108. package/dist/files.cjs +1071 -0
  109. package/dist/files.cjs.map +1 -0
  110. package/dist/files.d.cts +68 -0
  111. package/dist/files.d.cts.map +1 -0
  112. package/dist/files.d.ts +68 -0
  113. package/dist/files.d.ts.map +1 -0
  114. package/dist/files.js +1059 -0
  115. package/dist/files.js.map +1 -0
  116. package/dist/fine-tuning.cjs +1051 -0
  117. package/dist/fine-tuning.cjs.map +1 -0
  118. package/dist/fine-tuning.d.cts +96 -0
  119. package/dist/fine-tuning.d.cts.map +1 -0
  120. package/dist/fine-tuning.d.ts +96 -0
  121. package/dist/fine-tuning.d.ts.map +1 -0
  122. package/dist/fine-tuning.js +1044 -0
  123. package/dist/fine-tuning.js.map +1 -0
  124. package/dist/fixture-loader.cjs +0 -0
  125. package/dist/fixture-loader.cjs.map +1 -1
  126. package/dist/fixture-loader.d.cts +37 -5
  127. package/dist/fixture-loader.d.cts.map +1 -1
  128. package/dist/fixture-loader.d.ts +37 -5
  129. package/dist/fixture-loader.d.ts.map +1 -1
  130. package/dist/fixture-loader.js +0 -0
  131. package/dist/fixture-loader.js.map +1 -1
  132. package/dist/gemini-embeddings.cjs +2 -2
  133. package/dist/gemini-embeddings.cjs.map +1 -1
  134. package/dist/gemini-embeddings.js +3 -3
  135. package/dist/gemini-embeddings.js.map +1 -1
  136. package/dist/gemini-interactions.cjs +13 -7
  137. package/dist/gemini-interactions.cjs.map +1 -1
  138. package/dist/gemini-interactions.d.cts.map +1 -1
  139. package/dist/gemini-interactions.d.ts.map +1 -1
  140. package/dist/gemini-interactions.js +15 -9
  141. package/dist/gemini-interactions.js.map +1 -1
  142. package/dist/gemini.cjs +11 -7
  143. package/dist/gemini.cjs.map +1 -1
  144. package/dist/gemini.d.cts.map +1 -1
  145. package/dist/gemini.d.ts.map +1 -1
  146. package/dist/gemini.js +13 -9
  147. package/dist/gemini.js.map +1 -1
  148. package/dist/grok-video.cjs +14 -14
  149. package/dist/grok-video.cjs.map +1 -1
  150. package/dist/grok-video.js +15 -15
  151. package/dist/grok-video.js.map +1 -1
  152. package/dist/helpers.cjs +221 -5
  153. package/dist/helpers.cjs.map +1 -1
  154. package/dist/helpers.d.cts +38 -2
  155. package/dist/helpers.d.cts.map +1 -1
  156. package/dist/helpers.d.ts +38 -2
  157. package/dist/helpers.d.ts.map +1 -1
  158. package/dist/helpers.js +213 -6
  159. package/dist/helpers.js.map +1 -1
  160. package/dist/images.cjs +54 -123
  161. package/dist/images.cjs.map +1 -1
  162. package/dist/images.d.cts.map +1 -1
  163. package/dist/images.d.ts.map +1 -1
  164. package/dist/images.js +55 -124
  165. package/dist/images.js.map +1 -1
  166. package/dist/index.cjs +41 -8
  167. package/dist/index.d.cts +12 -7
  168. package/dist/index.d.ts +12 -7
  169. package/dist/index.js +14 -10
  170. package/dist/jest.cjs +14 -7
  171. package/dist/jest.cjs.map +1 -1
  172. package/dist/jest.d.cts +3 -2
  173. package/dist/jest.d.cts.map +1 -1
  174. package/dist/jest.d.ts +3 -2
  175. package/dist/jest.d.ts.map +1 -1
  176. package/dist/jest.js +14 -7
  177. package/dist/jest.js.map +1 -1
  178. package/dist/journal.cjs +41 -4
  179. package/dist/journal.cjs.map +1 -1
  180. package/dist/journal.d.cts +44 -3
  181. package/dist/journal.d.cts.map +1 -1
  182. package/dist/journal.d.ts +44 -3
  183. package/dist/journal.d.ts.map +1 -1
  184. package/dist/journal.js +41 -5
  185. package/dist/journal.js.map +1 -1
  186. package/dist/live-fixture.cjs +1192 -0
  187. package/dist/live-fixture.cjs.map +1 -0
  188. package/dist/live-fixture.js +1187 -0
  189. package/dist/live-fixture.js.map +1 -0
  190. package/dist/live-recorder.cjs +256 -0
  191. package/dist/live-recorder.cjs.map +1 -0
  192. package/dist/live-recorder.js +254 -0
  193. package/dist/live-recorder.js.map +1 -0
  194. package/dist/live-replay.cjs +286 -0
  195. package/dist/live-replay.cjs.map +1 -0
  196. package/dist/live-replay.js +285 -0
  197. package/dist/live-replay.js.map +1 -0
  198. package/dist/live-sanitize.cjs +196 -0
  199. package/dist/live-sanitize.cjs.map +1 -0
  200. package/dist/live-sanitize.js +196 -0
  201. package/dist/live-sanitize.js.map +1 -0
  202. package/dist/live-types.d.cts +71 -0
  203. package/dist/live-types.d.cts.map +1 -0
  204. package/dist/live-types.d.ts +71 -0
  205. package/dist/live-types.d.ts.map +1 -0
  206. package/dist/llmock.cjs +52 -41
  207. package/dist/llmock.cjs.map +1 -1
  208. package/dist/llmock.d.cts +16 -5
  209. package/dist/llmock.d.cts.map +1 -1
  210. package/dist/llmock.d.ts +16 -5
  211. package/dist/llmock.d.ts.map +1 -1
  212. package/dist/llmock.js +53 -42
  213. package/dist/llmock.js.map +1 -1
  214. package/dist/messages.cjs +11 -7
  215. package/dist/messages.cjs.map +1 -1
  216. package/dist/messages.d.cts.map +1 -1
  217. package/dist/messages.d.ts.map +1 -1
  218. package/dist/messages.js +13 -9
  219. package/dist/messages.js.map +1 -1
  220. package/dist/metrics.cjs +258 -5
  221. package/dist/metrics.cjs.map +1 -1
  222. package/dist/metrics.d.cts +3 -1
  223. package/dist/metrics.d.cts.map +1 -1
  224. package/dist/metrics.d.ts +3 -1
  225. package/dist/metrics.d.ts.map +1 -1
  226. package/dist/metrics.js +255 -6
  227. package/dist/metrics.js.map +1 -1
  228. package/dist/moderation.cjs +10 -1
  229. package/dist/moderation.cjs.map +1 -1
  230. package/dist/moderation.d.cts.map +1 -1
  231. package/dist/moderation.d.ts.map +1 -1
  232. package/dist/moderation.js +10 -1
  233. package/dist/moderation.js.map +1 -1
  234. package/dist/ollama.cjs +5 -5
  235. package/dist/ollama.cjs.map +1 -1
  236. package/dist/ollama.js +6 -6
  237. package/dist/ollama.js.map +1 -1
  238. package/dist/openrouter-video.cjs +5 -5
  239. package/dist/openrouter-video.cjs.map +1 -1
  240. package/dist/openrouter-video.js +6 -6
  241. package/dist/openrouter-video.js.map +1 -1
  242. package/dist/recorder.cjs +45 -9
  243. package/dist/recorder.cjs.map +1 -1
  244. package/dist/recorder.d.cts.map +1 -1
  245. package/dist/recorder.d.ts.map +1 -1
  246. package/dist/recorder.js +43 -11
  247. package/dist/recorder.js.map +1 -1
  248. package/dist/responses.cjs +4 -3
  249. package/dist/responses.cjs.map +1 -1
  250. package/dist/responses.js +5 -5
  251. package/dist/responses.js.map +1 -1
  252. package/dist/router.cjs +20 -33
  253. package/dist/router.cjs.map +1 -1
  254. package/dist/router.d.cts +4 -1
  255. package/dist/router.d.cts.map +1 -1
  256. package/dist/router.d.ts +4 -1
  257. package/dist/router.d.ts.map +1 -1
  258. package/dist/router.js +20 -34
  259. package/dist/router.js.map +1 -1
  260. package/dist/server.cjs +701 -625
  261. package/dist/server.cjs.map +1 -1
  262. package/dist/server.d.cts +1 -0
  263. package/dist/server.d.cts.map +1 -1
  264. package/dist/server.d.ts +1 -0
  265. package/dist/server.d.ts.map +1 -1
  266. package/dist/server.js +704 -628
  267. package/dist/server.js.map +1 -1
  268. package/dist/speech.cjs +2 -2
  269. package/dist/speech.cjs.map +1 -1
  270. package/dist/speech.js +3 -3
  271. package/dist/speech.js.map +1 -1
  272. package/dist/transcription.cjs +4 -4
  273. package/dist/transcription.cjs.map +1 -1
  274. package/dist/transcription.js +5 -5
  275. package/dist/transcription.js.map +1 -1
  276. package/dist/types.d.cts +119 -16
  277. package/dist/types.d.cts.map +1 -1
  278. package/dist/types.d.ts +119 -16
  279. package/dist/types.d.ts.map +1 -1
  280. package/dist/validate-cli.cjs +925 -0
  281. package/dist/validate-cli.cjs.map +1 -0
  282. package/dist/validate-cli.js +924 -0
  283. package/dist/validate-cli.js.map +1 -0
  284. package/dist/veo-video.cjs +13 -13
  285. package/dist/veo-video.cjs.map +1 -1
  286. package/dist/veo-video.js +14 -14
  287. package/dist/veo-video.js.map +1 -1
  288. package/dist/video.cjs +4 -4
  289. package/dist/video.cjs.map +1 -1
  290. package/dist/video.d.cts +1 -1
  291. package/dist/video.d.cts.map +1 -1
  292. package/dist/video.d.ts +1 -1
  293. package/dist/video.d.ts.map +1 -1
  294. package/dist/video.js +5 -5
  295. package/dist/video.js.map +1 -1
  296. package/dist/vitest.cjs +13 -6
  297. package/dist/vitest.cjs.map +1 -1
  298. package/dist/vitest.d.cts +2 -1
  299. package/dist/vitest.d.cts.map +1 -1
  300. package/dist/vitest.d.ts +2 -1
  301. package/dist/vitest.d.ts.map +1 -1
  302. package/dist/vitest.js +14 -7
  303. package/dist/vitest.js.map +1 -1
  304. package/dist/watcher.cjs +2 -1
  305. package/dist/watcher.cjs.map +1 -1
  306. package/dist/watcher.js +2 -1
  307. package/dist/watcher.js.map +1 -1
  308. package/dist/ws-framing.cjs +150 -35
  309. package/dist/ws-framing.cjs.map +1 -1
  310. package/dist/ws-framing.d.cts +18 -3
  311. package/dist/ws-framing.d.cts.map +1 -1
  312. package/dist/ws-framing.d.ts +18 -3
  313. package/dist/ws-framing.d.ts.map +1 -1
  314. package/dist/ws-framing.js +151 -36
  315. package/dist/ws-framing.js.map +1 -1
  316. package/dist/ws-gemini-live.cjs +2 -2
  317. package/dist/ws-gemini-live.d.ts +2 -2
  318. package/dist/ws-gemini-live.js +2 -2
  319. package/dist/ws-live.cjs +401 -0
  320. package/dist/ws-live.cjs.map +1 -0
  321. package/dist/ws-live.js +400 -0
  322. package/dist/ws-live.js.map +1 -0
  323. package/dist/ws-realtime.cjs +46 -2
  324. package/dist/ws-realtime.cjs.map +1 -1
  325. package/dist/ws-realtime.d.cts.map +1 -1
  326. package/dist/ws-realtime.d.ts +2 -2
  327. package/dist/ws-realtime.d.ts.map +1 -1
  328. package/dist/ws-realtime.js +46 -2
  329. package/dist/ws-realtime.js.map +1 -1
  330. package/dist/ws-responses.cjs +2 -2
  331. package/dist/ws-responses.js +2 -2
  332. package/dist/ws-upstream.cjs +118 -0
  333. package/dist/ws-upstream.cjs.map +1 -0
  334. package/dist/ws-upstream.js +115 -0
  335. package/dist/ws-upstream.js.map +1 -0
  336. package/fixtures/openai-live-client.json +390 -0
  337. package/fixtures/openai-live-managed.json +709 -0
  338. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  import { DEFAULT_TEST_ID } from "./constants.js";
2
2
  import { extractOverrides, flattenHeaders, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, resolveReasoningForModel, resolveResponse, resolveStrictMode, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField } from "./helpers.js";
3
- import "./journal.js";
4
- import { matchFixtureDiagnostic } from "./router.js";
5
3
  import { calculateDelay, delay } from "./sse-writer.js";
4
+ import { matchFixtureDiagnostic } from "./router.js";
5
+ import "./journal.js";
6
6
  import { createInterruptionSignal } from "./interruption.js";
7
7
  import { buildContentWithToolCallsStreamEvents, buildTextStreamEvents, buildToolCallStreamEvents, requestIncludesEncryptedReasoning, requestWantsEncryptedReasoning, responsesToCompletionRequest } from "./responses.js";
8
8
 
@@ -0,0 +1,118 @@
1
+ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
2
+ const require_ws_framing = require('./ws-framing.cjs');
3
+ let node_http = require("node:http");
4
+ node_http = require_runtime.__toESM(node_http);
5
+ let node_crypto = require("node:crypto");
6
+ let node_https = require("node:https");
7
+ node_https = require_runtime.__toESM(node_https);
8
+
9
+ //#region src/ws-upstream.ts
10
+ const REFUSAL_BODY_LIMIT = 64 * 1024;
11
+ const UPGRADE_TIMEOUT_MS = 3e4;
12
+ const MAX_TIMER_DELAY_MS = 2147483647;
13
+ const PROVIDER_HEADERS = new Set(["authorization"]);
14
+ /** Connect to a provider using verified TLS, or an explicitly configured loopback test peer.
15
+ * The caller's signal owns the session lifetime; the upgrade budget defaults to thirty seconds.
16
+ */
17
+ async function connectUpstreamWebSocket(url, headers, limits, signal, upstreamTimeoutMs = UPGRADE_TIMEOUT_MS) {
18
+ if (!Number.isSafeInteger(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) throw new RangeError("Upstream WebSocket timeout must be a positive safe integer");
19
+ const target = new URL(url.href);
20
+ const secure = target.protocol === "https:" || target.protocol === "wss:";
21
+ const loopback = target.hostname === "localhost" || target.hostname === "[::1]" || /^127\.(?:\d{1,3}\.){2}\d{1,3}$/.test(target.hostname);
22
+ if (target.username || target.password || target.hash || !secure && (!(target.protocol === "http:" || target.protocol === "ws:") || !loopback)) throw new Error("Invalid upstream WebSocket URL");
23
+ for (const value of [
24
+ limits.maxMessageBytes,
25
+ limits.maxBufferedBytes,
26
+ limits.maxWriteBytes
27
+ ]) if (value !== void 0 && (!Number.isSafeInteger(value) || value <= 0)) throw new RangeError("WebSocket limits must be positive safe integers");
28
+ if (signal.aborted) throw new Error("Upstream WebSocket aborted");
29
+ target.protocol = secure ? "https:" : "http:";
30
+ const key = (0, node_crypto.randomBytes)(16).toString("base64");
31
+ const outgoing = {};
32
+ for (const [name, value] of Object.entries(headers)) if (PROVIDER_HEADERS.has(name.toLowerCase())) outgoing[name.toLowerCase()] = value;
33
+ Object.assign(outgoing, {
34
+ Upgrade: "websocket",
35
+ Connection: "Upgrade",
36
+ "Sec-WebSocket-Key": key,
37
+ "Sec-WebSocket-Version": "13"
38
+ });
39
+ return new Promise((resolve, reject) => {
40
+ let settled = false;
41
+ let connection;
42
+ const request = (secure ? node_https : node_http).request(target, {
43
+ method: "GET",
44
+ headers: outgoing,
45
+ agent: false,
46
+ ...secure ? { rejectUnauthorized: true } : {}
47
+ });
48
+ const started = performance.now();
49
+ const onTimeout = () => {
50
+ const remaining = upstreamTimeoutMs - (performance.now() - started);
51
+ if (remaining > 0) timer = setTimeout(onTimeout, Math.min(remaining, MAX_TIMER_DELAY_MS));
52
+ else fail("Upstream WebSocket upgrade timed out");
53
+ };
54
+ let timer = setTimeout(onTimeout, Math.min(upstreamTimeoutMs, MAX_TIMER_DELAY_MS));
55
+ const cleanup = () => {
56
+ clearTimeout(timer);
57
+ signal.removeEventListener("abort", abort);
58
+ };
59
+ const fail = (message) => {
60
+ if (settled) return;
61
+ settled = true;
62
+ cleanup();
63
+ request.destroy();
64
+ reject(new Error(message));
65
+ };
66
+ const abort = () => {
67
+ if (connection) connection.destroy();
68
+ else fail("Upstream WebSocket aborted");
69
+ };
70
+ signal.addEventListener("abort", abort, { once: true });
71
+ request.on("error", () => fail("Upstream WebSocket connection failed"));
72
+ request.once("response", (response) => {
73
+ let bytes = 0;
74
+ response.on("data", (chunk) => {
75
+ bytes += chunk.length;
76
+ if (bytes > REFUSAL_BODY_LIMIT) {
77
+ fail("Upstream WebSocket refusal body limit exceeded");
78
+ response.destroy();
79
+ }
80
+ });
81
+ response.once("end", () => fail(`Upstream WebSocket refused (HTTP ${response.statusCode ?? 0})`));
82
+ response.once("error", () => fail("Upstream WebSocket response failed"));
83
+ response.once("aborted", () => fail("Upstream WebSocket response failed"));
84
+ });
85
+ request.once("upgrade", (response, socket, head) => {
86
+ if (settled) {
87
+ socket.destroy();
88
+ return;
89
+ }
90
+ const tokens = (value) => value?.split(",").map((token) => token.trim().toLowerCase()) ?? [];
91
+ if (response.statusCode !== 101 || !tokens(response.headers.upgrade).includes("websocket") || !tokens(response.headers.connection).includes("upgrade") || response.headers["sec-websocket-accept"] !== require_ws_framing.computeAcceptKey(key) || response.headers["sec-websocket-extensions"] !== void 0 || response.headers["sec-websocket-protocol"] !== void 0) {
92
+ socket.destroy();
93
+ fail("Invalid upstream WebSocket upgrade");
94
+ return;
95
+ }
96
+ socket.pause();
97
+ connection = new require_ws_framing.WebSocketConnection(socket, {
98
+ maxMessageBytes: limits.maxMessageBytes ?? 1024 * 1024,
99
+ maxBufferedBytes: limits.maxBufferedBytes ?? 2 * 1024 * 1024,
100
+ maxWriteBytes: limits.maxWriteBytes ?? 1024 * 1024,
101
+ maskOutgoing: true
102
+ });
103
+ connection.once("close", cleanup);
104
+ settled = true;
105
+ clearTimeout(timer);
106
+ if (head.length) socket.unshift(head);
107
+ resolve(connection);
108
+ setImmediate(() => {
109
+ if (!socket.destroyed) socket.resume();
110
+ });
111
+ });
112
+ request.end();
113
+ });
114
+ }
115
+
116
+ //#endregion
117
+ exports.connectUpstreamWebSocket = connectUpstreamWebSocket;
118
+ //# sourceMappingURL=ws-upstream.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-upstream.cjs","names":["https","http","computeAcceptKey","WebSocketConnection"],"sources":["../src/ws-upstream.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport { randomBytes } from \"node:crypto\";\nimport { WebSocketConnection, computeAcceptKey, type WebSocketLimits } from \"./ws-framing.js\";\n\nconst REFUSAL_BODY_LIMIT = 64 * 1024;\nconst UPGRADE_TIMEOUT_MS = 30_000;\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\n// Reviewed Live startup uses Authorization plus connector-owned RFC 6455 headers.\nconst PROVIDER_HEADERS = new Set([\"authorization\"]);\n\n/** Connect to a provider using verified TLS, or an explicitly configured loopback test peer.\n * The caller's signal owns the session lifetime; the upgrade budget defaults to thirty seconds.\n */\nexport async function connectUpstreamWebSocket(\n url: URL,\n headers: Record<string, string>,\n limits: WebSocketLimits,\n signal: AbortSignal,\n upstreamTimeoutMs = UPGRADE_TIMEOUT_MS,\n): Promise<WebSocketConnection> {\n if (!Number.isSafeInteger(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) {\n throw new RangeError(\"Upstream WebSocket timeout must be a positive safe integer\");\n }\n const target = new URL(url.href);\n const secure = target.protocol === \"https:\" || target.protocol === \"wss:\";\n const loopback =\n target.hostname === \"localhost\" ||\n target.hostname === \"[::1]\" ||\n /^127\\.(?:\\d{1,3}\\.){2}\\d{1,3}$/.test(target.hostname);\n if (\n target.username ||\n target.password ||\n target.hash ||\n (!secure && (!(target.protocol === \"http:\" || target.protocol === \"ws:\") || !loopback))\n ) {\n throw new Error(\"Invalid upstream WebSocket URL\");\n }\n for (const value of [limits.maxMessageBytes, limits.maxBufferedBytes, limits.maxWriteBytes]) {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0))\n throw new RangeError(\"WebSocket limits must be positive safe integers\");\n }\n if (signal.aborted) throw new Error(\"Upstream WebSocket aborted\");\n target.protocol = secure ? \"https:\" : \"http:\";\n const key = randomBytes(16).toString(\"base64\");\n const outgoing: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n if (PROVIDER_HEADERS.has(name.toLowerCase())) outgoing[name.toLowerCase()] = value;\n }\n Object.assign(outgoing, {\n Upgrade: \"websocket\",\n Connection: \"Upgrade\",\n \"Sec-WebSocket-Key\": key,\n \"Sec-WebSocket-Version\": \"13\",\n });\n return new Promise<WebSocketConnection>((resolve, reject) => {\n let settled = false;\n let connection: WebSocketConnection | undefined;\n const request = (secure ? https : http).request(target, {\n method: \"GET\",\n headers: outgoing,\n agent: false,\n ...(secure ? { rejectUnauthorized: true } : {}),\n });\n const started = performance.now();\n const onTimeout = () => {\n const remaining = upstreamTimeoutMs - (performance.now() - started);\n if (remaining > 0) timer = setTimeout(onTimeout, Math.min(remaining, MAX_TIMER_DELAY_MS));\n else fail(\"Upstream WebSocket upgrade timed out\");\n };\n // Node clamps overflowing setTimeout delays to one millisecond. Keep the\n // full validated budget by scheduling bounded segments against elapsed time.\n let timer = setTimeout(onTimeout, Math.min(upstreamTimeoutMs, MAX_TIMER_DELAY_MS));\n const cleanup = () => {\n clearTimeout(timer);\n signal.removeEventListener(\"abort\", abort);\n };\n const fail = (message: string) => {\n if (settled) return;\n settled = true;\n cleanup();\n request.destroy();\n reject(new Error(message));\n };\n const abort = () => {\n if (connection) connection.destroy();\n else fail(\"Upstream WebSocket aborted\");\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n request.on(\"error\", () => fail(\"Upstream WebSocket connection failed\"));\n request.once(\"response\", (response) => {\n let bytes = 0;\n response.on(\"data\", (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > REFUSAL_BODY_LIMIT) {\n fail(\"Upstream WebSocket refusal body limit exceeded\");\n response.destroy();\n }\n });\n response.once(\"end\", () =>\n fail(`Upstream WebSocket refused (HTTP ${response.statusCode ?? 0})`),\n );\n response.once(\"error\", () => fail(\"Upstream WebSocket response failed\"));\n response.once(\"aborted\", () => fail(\"Upstream WebSocket response failed\"));\n });\n request.once(\"upgrade\", (response, socket, head) => {\n if (settled) {\n socket.destroy();\n return;\n }\n const tokens = (value: string | undefined) =>\n value?.split(\",\").map((token) => token.trim().toLowerCase()) ?? [];\n if (\n response.statusCode !== 101 ||\n !tokens(response.headers.upgrade).includes(\"websocket\") ||\n !tokens(response.headers.connection).includes(\"upgrade\") ||\n response.headers[\"sec-websocket-accept\"] !== computeAcceptKey(key) ||\n response.headers[\"sec-websocket-extensions\"] !== undefined ||\n response.headers[\"sec-websocket-protocol\"] !== undefined\n ) {\n socket.destroy();\n fail(\"Invalid upstream WebSocket upgrade\");\n return;\n }\n socket.pause();\n connection = new WebSocketConnection(socket, {\n maxMessageBytes: limits.maxMessageBytes ?? 1024 * 1024,\n maxBufferedBytes: limits.maxBufferedBytes ?? 2 * 1024 * 1024,\n maxWriteBytes: limits.maxWriteBytes ?? 1024 * 1024,\n maskOutgoing: true,\n });\n connection.once(\"close\", cleanup);\n settled = true;\n clearTimeout(timer);\n // Pause until the promise consumer can register its message/error listeners.\n // unshift preserves ordering between upgrade head and subsequent socket bytes.\n if (head.length) socket.unshift(head);\n resolve(connection);\n setImmediate(() => {\n if (!socket.destroyed) socket.resume();\n });\n });\n request.end();\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ import { WebSocketConnection, computeAcceptKey } from "./ws-framing.js";
2
+ import * as http$1 from "node:http";
3
+ import { randomBytes } from "node:crypto";
4
+ import * as https from "node:https";
5
+
6
+ //#region src/ws-upstream.ts
7
+ const REFUSAL_BODY_LIMIT = 64 * 1024;
8
+ const UPGRADE_TIMEOUT_MS = 3e4;
9
+ const MAX_TIMER_DELAY_MS = 2147483647;
10
+ const PROVIDER_HEADERS = new Set(["authorization"]);
11
+ /** Connect to a provider using verified TLS, or an explicitly configured loopback test peer.
12
+ * The caller's signal owns the session lifetime; the upgrade budget defaults to thirty seconds.
13
+ */
14
+ async function connectUpstreamWebSocket(url, headers, limits, signal, upstreamTimeoutMs = UPGRADE_TIMEOUT_MS) {
15
+ if (!Number.isSafeInteger(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) throw new RangeError("Upstream WebSocket timeout must be a positive safe integer");
16
+ const target = new URL(url.href);
17
+ const secure = target.protocol === "https:" || target.protocol === "wss:";
18
+ const loopback = target.hostname === "localhost" || target.hostname === "[::1]" || /^127\.(?:\d{1,3}\.){2}\d{1,3}$/.test(target.hostname);
19
+ if (target.username || target.password || target.hash || !secure && (!(target.protocol === "http:" || target.protocol === "ws:") || !loopback)) throw new Error("Invalid upstream WebSocket URL");
20
+ for (const value of [
21
+ limits.maxMessageBytes,
22
+ limits.maxBufferedBytes,
23
+ limits.maxWriteBytes
24
+ ]) if (value !== void 0 && (!Number.isSafeInteger(value) || value <= 0)) throw new RangeError("WebSocket limits must be positive safe integers");
25
+ if (signal.aborted) throw new Error("Upstream WebSocket aborted");
26
+ target.protocol = secure ? "https:" : "http:";
27
+ const key = randomBytes(16).toString("base64");
28
+ const outgoing = {};
29
+ for (const [name, value] of Object.entries(headers)) if (PROVIDER_HEADERS.has(name.toLowerCase())) outgoing[name.toLowerCase()] = value;
30
+ Object.assign(outgoing, {
31
+ Upgrade: "websocket",
32
+ Connection: "Upgrade",
33
+ "Sec-WebSocket-Key": key,
34
+ "Sec-WebSocket-Version": "13"
35
+ });
36
+ return new Promise((resolve, reject) => {
37
+ let settled = false;
38
+ let connection;
39
+ const request = (secure ? https : http$1).request(target, {
40
+ method: "GET",
41
+ headers: outgoing,
42
+ agent: false,
43
+ ...secure ? { rejectUnauthorized: true } : {}
44
+ });
45
+ const started = performance.now();
46
+ const onTimeout = () => {
47
+ const remaining = upstreamTimeoutMs - (performance.now() - started);
48
+ if (remaining > 0) timer = setTimeout(onTimeout, Math.min(remaining, MAX_TIMER_DELAY_MS));
49
+ else fail("Upstream WebSocket upgrade timed out");
50
+ };
51
+ let timer = setTimeout(onTimeout, Math.min(upstreamTimeoutMs, MAX_TIMER_DELAY_MS));
52
+ const cleanup = () => {
53
+ clearTimeout(timer);
54
+ signal.removeEventListener("abort", abort);
55
+ };
56
+ const fail = (message) => {
57
+ if (settled) return;
58
+ settled = true;
59
+ cleanup();
60
+ request.destroy();
61
+ reject(new Error(message));
62
+ };
63
+ const abort = () => {
64
+ if (connection) connection.destroy();
65
+ else fail("Upstream WebSocket aborted");
66
+ };
67
+ signal.addEventListener("abort", abort, { once: true });
68
+ request.on("error", () => fail("Upstream WebSocket connection failed"));
69
+ request.once("response", (response) => {
70
+ let bytes = 0;
71
+ response.on("data", (chunk) => {
72
+ bytes += chunk.length;
73
+ if (bytes > REFUSAL_BODY_LIMIT) {
74
+ fail("Upstream WebSocket refusal body limit exceeded");
75
+ response.destroy();
76
+ }
77
+ });
78
+ response.once("end", () => fail(`Upstream WebSocket refused (HTTP ${response.statusCode ?? 0})`));
79
+ response.once("error", () => fail("Upstream WebSocket response failed"));
80
+ response.once("aborted", () => fail("Upstream WebSocket response failed"));
81
+ });
82
+ request.once("upgrade", (response, socket, head) => {
83
+ if (settled) {
84
+ socket.destroy();
85
+ return;
86
+ }
87
+ const tokens = (value) => value?.split(",").map((token) => token.trim().toLowerCase()) ?? [];
88
+ if (response.statusCode !== 101 || !tokens(response.headers.upgrade).includes("websocket") || !tokens(response.headers.connection).includes("upgrade") || response.headers["sec-websocket-accept"] !== computeAcceptKey(key) || response.headers["sec-websocket-extensions"] !== void 0 || response.headers["sec-websocket-protocol"] !== void 0) {
89
+ socket.destroy();
90
+ fail("Invalid upstream WebSocket upgrade");
91
+ return;
92
+ }
93
+ socket.pause();
94
+ connection = new WebSocketConnection(socket, {
95
+ maxMessageBytes: limits.maxMessageBytes ?? 1024 * 1024,
96
+ maxBufferedBytes: limits.maxBufferedBytes ?? 2 * 1024 * 1024,
97
+ maxWriteBytes: limits.maxWriteBytes ?? 1024 * 1024,
98
+ maskOutgoing: true
99
+ });
100
+ connection.once("close", cleanup);
101
+ settled = true;
102
+ clearTimeout(timer);
103
+ if (head.length) socket.unshift(head);
104
+ resolve(connection);
105
+ setImmediate(() => {
106
+ if (!socket.destroyed) socket.resume();
107
+ });
108
+ });
109
+ request.end();
110
+ });
111
+ }
112
+
113
+ //#endregion
114
+ export { connectUpstreamWebSocket };
115
+ //# sourceMappingURL=ws-upstream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-upstream.js","names":["http"],"sources":["../src/ws-upstream.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport { randomBytes } from \"node:crypto\";\nimport { WebSocketConnection, computeAcceptKey, type WebSocketLimits } from \"./ws-framing.js\";\n\nconst REFUSAL_BODY_LIMIT = 64 * 1024;\nconst UPGRADE_TIMEOUT_MS = 30_000;\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\n// Reviewed Live startup uses Authorization plus connector-owned RFC 6455 headers.\nconst PROVIDER_HEADERS = new Set([\"authorization\"]);\n\n/** Connect to a provider using verified TLS, or an explicitly configured loopback test peer.\n * The caller's signal owns the session lifetime; the upgrade budget defaults to thirty seconds.\n */\nexport async function connectUpstreamWebSocket(\n url: URL,\n headers: Record<string, string>,\n limits: WebSocketLimits,\n signal: AbortSignal,\n upstreamTimeoutMs = UPGRADE_TIMEOUT_MS,\n): Promise<WebSocketConnection> {\n if (!Number.isSafeInteger(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) {\n throw new RangeError(\"Upstream WebSocket timeout must be a positive safe integer\");\n }\n const target = new URL(url.href);\n const secure = target.protocol === \"https:\" || target.protocol === \"wss:\";\n const loopback =\n target.hostname === \"localhost\" ||\n target.hostname === \"[::1]\" ||\n /^127\\.(?:\\d{1,3}\\.){2}\\d{1,3}$/.test(target.hostname);\n if (\n target.username ||\n target.password ||\n target.hash ||\n (!secure && (!(target.protocol === \"http:\" || target.protocol === \"ws:\") || !loopback))\n ) {\n throw new Error(\"Invalid upstream WebSocket URL\");\n }\n for (const value of [limits.maxMessageBytes, limits.maxBufferedBytes, limits.maxWriteBytes]) {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0))\n throw new RangeError(\"WebSocket limits must be positive safe integers\");\n }\n if (signal.aborted) throw new Error(\"Upstream WebSocket aborted\");\n target.protocol = secure ? \"https:\" : \"http:\";\n const key = randomBytes(16).toString(\"base64\");\n const outgoing: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n if (PROVIDER_HEADERS.has(name.toLowerCase())) outgoing[name.toLowerCase()] = value;\n }\n Object.assign(outgoing, {\n Upgrade: \"websocket\",\n Connection: \"Upgrade\",\n \"Sec-WebSocket-Key\": key,\n \"Sec-WebSocket-Version\": \"13\",\n });\n return new Promise<WebSocketConnection>((resolve, reject) => {\n let settled = false;\n let connection: WebSocketConnection | undefined;\n const request = (secure ? https : http).request(target, {\n method: \"GET\",\n headers: outgoing,\n agent: false,\n ...(secure ? { rejectUnauthorized: true } : {}),\n });\n const started = performance.now();\n const onTimeout = () => {\n const remaining = upstreamTimeoutMs - (performance.now() - started);\n if (remaining > 0) timer = setTimeout(onTimeout, Math.min(remaining, MAX_TIMER_DELAY_MS));\n else fail(\"Upstream WebSocket upgrade timed out\");\n };\n // Node clamps overflowing setTimeout delays to one millisecond. Keep the\n // full validated budget by scheduling bounded segments against elapsed time.\n let timer = setTimeout(onTimeout, Math.min(upstreamTimeoutMs, MAX_TIMER_DELAY_MS));\n const cleanup = () => {\n clearTimeout(timer);\n signal.removeEventListener(\"abort\", abort);\n };\n const fail = (message: string) => {\n if (settled) return;\n settled = true;\n cleanup();\n request.destroy();\n reject(new Error(message));\n };\n const abort = () => {\n if (connection) connection.destroy();\n else fail(\"Upstream WebSocket aborted\");\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n request.on(\"error\", () => fail(\"Upstream WebSocket connection failed\"));\n request.once(\"response\", (response) => {\n let bytes = 0;\n response.on(\"data\", (chunk: Buffer) => {\n bytes += chunk.length;\n if (bytes > REFUSAL_BODY_LIMIT) {\n fail(\"Upstream WebSocket refusal body limit exceeded\");\n response.destroy();\n }\n });\n response.once(\"end\", () =>\n fail(`Upstream WebSocket refused (HTTP ${response.statusCode ?? 0})`),\n );\n response.once(\"error\", () => fail(\"Upstream WebSocket response failed\"));\n response.once(\"aborted\", () => fail(\"Upstream WebSocket response failed\"));\n });\n request.once(\"upgrade\", (response, socket, head) => {\n if (settled) {\n socket.destroy();\n return;\n }\n const tokens = (value: string | undefined) =>\n value?.split(\",\").map((token) => token.trim().toLowerCase()) ?? [];\n if (\n response.statusCode !== 101 ||\n !tokens(response.headers.upgrade).includes(\"websocket\") ||\n !tokens(response.headers.connection).includes(\"upgrade\") ||\n response.headers[\"sec-websocket-accept\"] !== computeAcceptKey(key) ||\n response.headers[\"sec-websocket-extensions\"] !== undefined ||\n response.headers[\"sec-websocket-protocol\"] !== undefined\n ) {\n socket.destroy();\n fail(\"Invalid upstream WebSocket upgrade\");\n return;\n }\n socket.pause();\n connection = new WebSocketConnection(socket, {\n maxMessageBytes: limits.maxMessageBytes ?? 1024 * 1024,\n maxBufferedBytes: limits.maxBufferedBytes ?? 2 * 1024 * 1024,\n maxWriteBytes: limits.maxWriteBytes ?? 1024 * 1024,\n maskOutgoing: true,\n });\n connection.once(\"close\", cleanup);\n settled = true;\n clearTimeout(timer);\n // Pause until the promise consumer can register its message/error listeners.\n // unshift preserves ordering between upgrade head and subsequent socket bytes.\n if (head.length) socket.unshift(head);\n resolve(connection);\n setImmediate(() => {\n if (!socket.destroyed) socket.resume();\n });\n });\n request.end();\n });\n}\n"],"mappings":"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"}