@mcpmesh/sdk 1.3.4 → 2.0.0-beta.1

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 (262) hide show
  1. package/dist/__tests__/a2a/a2a-bearer.spec.d.ts +2 -0
  2. package/dist/__tests__/a2a/a2a-bearer.spec.d.ts.map +1 -0
  3. package/dist/__tests__/a2a/a2a-bearer.spec.js +58 -0
  4. package/dist/__tests__/a2a/a2a-bearer.spec.js.map +1 -0
  5. package/dist/__tests__/a2a/a2a-client.spec.d.ts +2 -0
  6. package/dist/__tests__/a2a/a2a-client.spec.d.ts.map +1 -0
  7. package/dist/__tests__/a2a/a2a-client.spec.js +334 -0
  8. package/dist/__tests__/a2a/a2a-client.spec.js.map +1 -0
  9. package/dist/__tests__/a2a/a2a-job.spec.d.ts +2 -0
  10. package/dist/__tests__/a2a/a2a-job.spec.d.ts.map +1 -0
  11. package/dist/__tests__/a2a/a2a-job.spec.js +255 -0
  12. package/dist/__tests__/a2a/a2a-job.spec.js.map +1 -0
  13. package/dist/__tests__/a2a/a2a-stream.spec.d.ts +2 -0
  14. package/dist/__tests__/a2a/a2a-stream.spec.d.ts.map +1 -0
  15. package/dist/__tests__/a2a/a2a-stream.spec.js +278 -0
  16. package/dist/__tests__/a2a/a2a-stream.spec.js.map +1 -0
  17. package/dist/__tests__/a2a/agent-a2a-config.spec.d.ts +2 -0
  18. package/dist/__tests__/a2a/agent-a2a-config.spec.d.ts.map +1 -0
  19. package/dist/__tests__/a2a/agent-a2a-config.spec.js +262 -0
  20. package/dist/__tests__/a2a/agent-a2a-config.spec.js.map +1 -0
  21. package/dist/__tests__/a2a/producer/auth-filter.spec.d.ts +2 -0
  22. package/dist/__tests__/a2a/producer/auth-filter.spec.d.ts.map +1 -0
  23. package/dist/__tests__/a2a/producer/auth-filter.spec.js +127 -0
  24. package/dist/__tests__/a2a/producer/auth-filter.spec.js.map +1 -0
  25. package/dist/__tests__/a2a/producer/card-builder.spec.d.ts +2 -0
  26. package/dist/__tests__/a2a/producer/card-builder.spec.d.ts.map +1 -0
  27. package/dist/__tests__/a2a/producer/card-builder.spec.js +113 -0
  28. package/dist/__tests__/a2a/producer/card-builder.spec.js.map +1 -0
  29. package/dist/__tests__/a2a/producer/dispatcher.spec.d.ts +2 -0
  30. package/dist/__tests__/a2a/producer/dispatcher.spec.d.ts.map +1 -0
  31. package/dist/__tests__/a2a/producer/dispatcher.spec.js +850 -0
  32. package/dist/__tests__/a2a/producer/dispatcher.spec.js.map +1 -0
  33. package/dist/__tests__/a2a/producer/mount-surface-push.spec.d.ts +2 -0
  34. package/dist/__tests__/a2a/producer/mount-surface-push.spec.d.ts.map +1 -0
  35. package/dist/__tests__/a2a/producer/mount-surface-push.spec.js +164 -0
  36. package/dist/__tests__/a2a/producer/mount-surface-push.spec.js.map +1 -0
  37. package/dist/__tests__/a2a/producer/mount.spec.d.ts +2 -0
  38. package/dist/__tests__/a2a/producer/mount.spec.d.ts.map +1 -0
  39. package/dist/__tests__/a2a/producer/mount.spec.js +433 -0
  40. package/dist/__tests__/a2a/producer/mount.spec.js.map +1 -0
  41. package/dist/__tests__/a2a/producer/public-url-cache.spec.d.ts +2 -0
  42. package/dist/__tests__/a2a/producer/public-url-cache.spec.d.ts.map +1 -0
  43. package/dist/__tests__/a2a/producer/public-url-cache.spec.js +116 -0
  44. package/dist/__tests__/a2a/producer/public-url-cache.spec.js.map +1 -0
  45. package/dist/__tests__/a2a/producer/sse-emitter.spec.d.ts +2 -0
  46. package/dist/__tests__/a2a/producer/sse-emitter.spec.d.ts.map +1 -0
  47. package/dist/__tests__/a2a/producer/sse-emitter.spec.js +754 -0
  48. package/dist/__tests__/a2a/producer/sse-emitter.spec.js.map +1 -0
  49. package/dist/__tests__/a2a/producer/state-translator.spec.d.ts +2 -0
  50. package/dist/__tests__/a2a/producer/state-translator.spec.d.ts.map +1 -0
  51. package/dist/__tests__/a2a/producer/state-translator.spec.js +124 -0
  52. package/dist/__tests__/a2a/producer/state-translator.spec.js.map +1 -0
  53. package/dist/__tests__/a2a/producer/task-store.spec.d.ts +2 -0
  54. package/dist/__tests__/a2a/producer/task-store.spec.d.ts.map +1 -0
  55. package/dist/__tests__/a2a/producer/task-store.spec.js +180 -0
  56. package/dist/__tests__/a2a/producer/task-store.spec.js.map +1 -0
  57. package/dist/__tests__/agent-add-tool.spec.d.ts +2 -0
  58. package/dist/__tests__/agent-add-tool.spec.d.ts.map +1 -0
  59. package/dist/__tests__/agent-add-tool.spec.js +483 -0
  60. package/dist/__tests__/agent-add-tool.spec.js.map +1 -0
  61. package/dist/__tests__/api-runtime-race.spec.d.ts +2 -0
  62. package/dist/__tests__/api-runtime-race.spec.d.ts.map +1 -0
  63. package/dist/__tests__/api-runtime-race.spec.js +193 -0
  64. package/dist/__tests__/api-runtime-race.spec.js.map +1 -0
  65. package/dist/__tests__/claim-dispatcher.spec.d.ts +2 -0
  66. package/dist/__tests__/claim-dispatcher.spec.d.ts.map +1 -0
  67. package/dist/__tests__/claim-dispatcher.spec.js +408 -0
  68. package/dist/__tests__/claim-dispatcher.spec.js.map +1 -0
  69. package/dist/__tests__/inbound-job-dispatch.spec.d.ts +2 -0
  70. package/dist/__tests__/inbound-job-dispatch.spec.d.ts.map +1 -0
  71. package/dist/__tests__/inbound-job-dispatch.spec.js +185 -0
  72. package/dist/__tests__/inbound-job-dispatch.spec.js.map +1 -0
  73. package/dist/__tests__/job-controller-progress.spec.d.ts +2 -0
  74. package/dist/__tests__/job-controller-progress.spec.d.ts.map +1 -0
  75. package/dist/__tests__/job-controller-progress.spec.js +85 -0
  76. package/dist/__tests__/job-controller-progress.spec.js.map +1 -0
  77. package/dist/__tests__/jobs-cancel-route.spec.d.ts +2 -0
  78. package/dist/__tests__/jobs-cancel-route.spec.d.ts.map +1 -0
  79. package/dist/__tests__/jobs-cancel-route.spec.js +88 -0
  80. package/dist/__tests__/jobs-cancel-route.spec.js.map +1 -0
  81. package/dist/__tests__/llm-agent-stream.test.d.ts +14 -0
  82. package/dist/__tests__/llm-agent-stream.test.d.ts.map +1 -0
  83. package/dist/__tests__/llm-agent-stream.test.js +341 -0
  84. package/dist/__tests__/llm-agent-stream.test.js.map +1 -0
  85. package/dist/__tests__/llm-provider.test.js +22 -1
  86. package/dist/__tests__/llm-provider.test.js.map +1 -1
  87. package/dist/__tests__/media-resolver.test.js +40 -0
  88. package/dist/__tests__/media-resolver.test.js.map +1 -1
  89. package/dist/__tests__/mesh-job-submitter.spec.d.ts +2 -0
  90. package/dist/__tests__/mesh-job-submitter.spec.d.ts.map +1 -0
  91. package/dist/__tests__/mesh-job-submitter.spec.js +110 -0
  92. package/dist/__tests__/mesh-job-submitter.spec.js.map +1 -0
  93. package/dist/__tests__/proxy-stream.test.d.ts +9 -0
  94. package/dist/__tests__/proxy-stream.test.d.ts.map +1 -0
  95. package/dist/__tests__/proxy-stream.test.js +347 -0
  96. package/dist/__tests__/proxy-stream.test.js.map +1 -0
  97. package/dist/__tests__/resolver-meshjob.spec.d.ts +26 -0
  98. package/dist/__tests__/resolver-meshjob.spec.d.ts.map +1 -0
  99. package/dist/__tests__/resolver-meshjob.spec.js +201 -0
  100. package/dist/__tests__/resolver-meshjob.spec.js.map +1 -0
  101. package/dist/__tests__/schema-verdict-policy.test.d.ts +6 -0
  102. package/dist/__tests__/schema-verdict-policy.test.d.ts.map +1 -0
  103. package/dist/__tests__/schema-verdict-policy.test.js +126 -0
  104. package/dist/__tests__/schema-verdict-policy.test.js.map +1 -0
  105. package/dist/__tests__/sse-stream.test.d.ts +12 -0
  106. package/dist/__tests__/sse-stream.test.d.ts.map +1 -0
  107. package/dist/__tests__/sse-stream.test.js +170 -0
  108. package/dist/__tests__/sse-stream.test.js.map +1 -0
  109. package/dist/a2a/a2a-bearer.d.ts +27 -0
  110. package/dist/a2a/a2a-bearer.d.ts.map +1 -0
  111. package/dist/a2a/a2a-bearer.js +63 -0
  112. package/dist/a2a/a2a-bearer.js.map +1 -0
  113. package/dist/a2a/a2a-client.d.ts +114 -0
  114. package/dist/a2a/a2a-client.d.ts.map +1 -0
  115. package/dist/a2a/a2a-client.js +405 -0
  116. package/dist/a2a/a2a-client.js.map +1 -0
  117. package/dist/a2a/a2a-event.d.ts +25 -0
  118. package/dist/a2a/a2a-event.d.ts.map +1 -0
  119. package/dist/a2a/a2a-event.js +9 -0
  120. package/dist/a2a/a2a-event.js.map +1 -0
  121. package/dist/a2a/a2a-job.d.ts +58 -0
  122. package/dist/a2a/a2a-job.d.ts.map +1 -0
  123. package/dist/a2a/a2a-job.js +264 -0
  124. package/dist/a2a/a2a-job.js.map +1 -0
  125. package/dist/a2a/a2a-stream.d.ts +39 -0
  126. package/dist/a2a/a2a-stream.d.ts.map +1 -0
  127. package/dist/a2a/a2a-stream.js +290 -0
  128. package/dist/a2a/a2a-stream.js.map +1 -0
  129. package/dist/a2a/errors.d.ts +29 -0
  130. package/dist/a2a/errors.d.ts.map +1 -0
  131. package/dist/a2a/errors.js +48 -0
  132. package/dist/a2a/errors.js.map +1 -0
  133. package/dist/a2a/index.d.ts +12 -0
  134. package/dist/a2a/index.d.ts.map +1 -0
  135. package/dist/a2a/index.js +11 -0
  136. package/dist/a2a/index.js.map +1 -0
  137. package/dist/a2a/producer/auth-filter.d.ts +34 -0
  138. package/dist/a2a/producer/auth-filter.d.ts.map +1 -0
  139. package/dist/a2a/producer/auth-filter.js +39 -0
  140. package/dist/a2a/producer/auth-filter.js.map +1 -0
  141. package/dist/a2a/producer/card-builder.d.ts +59 -0
  142. package/dist/a2a/producer/card-builder.d.ts.map +1 -0
  143. package/dist/a2a/producer/card-builder.js +59 -0
  144. package/dist/a2a/producer/card-builder.js.map +1 -0
  145. package/dist/a2a/producer/dispatcher.d.ts +276 -0
  146. package/dist/a2a/producer/dispatcher.d.ts.map +1 -0
  147. package/dist/a2a/producer/dispatcher.js +896 -0
  148. package/dist/a2a/producer/dispatcher.js.map +1 -0
  149. package/dist/a2a/producer/index.d.ts +26 -0
  150. package/dist/a2a/producer/index.d.ts.map +1 -0
  151. package/dist/a2a/producer/index.js +23 -0
  152. package/dist/a2a/producer/index.js.map +1 -0
  153. package/dist/a2a/producer/mount.d.ts +75 -0
  154. package/dist/a2a/producer/mount.d.ts.map +1 -0
  155. package/dist/a2a/producer/mount.js +422 -0
  156. package/dist/a2a/producer/mount.js.map +1 -0
  157. package/dist/a2a/producer/public-url-cache.d.ts +73 -0
  158. package/dist/a2a/producer/public-url-cache.d.ts.map +1 -0
  159. package/dist/a2a/producer/public-url-cache.js +0 -0
  160. package/dist/a2a/producer/public-url-cache.js.map +1 -0
  161. package/dist/a2a/producer/registry.d.ts +138 -0
  162. package/dist/a2a/producer/registry.d.ts.map +1 -0
  163. package/dist/a2a/producer/registry.js +117 -0
  164. package/dist/a2a/producer/registry.js.map +1 -0
  165. package/dist/a2a/producer/sse-emitter.d.ts +85 -0
  166. package/dist/a2a/producer/sse-emitter.d.ts.map +1 -0
  167. package/dist/a2a/producer/sse-emitter.js +405 -0
  168. package/dist/a2a/producer/sse-emitter.js.map +1 -0
  169. package/dist/a2a/producer/state-translator.d.ts +63 -0
  170. package/dist/a2a/producer/state-translator.d.ts.map +1 -0
  171. package/dist/a2a/producer/state-translator.js +108 -0
  172. package/dist/a2a/producer/state-translator.js.map +1 -0
  173. package/dist/a2a/producer/task-store.d.ts +128 -0
  174. package/dist/a2a/producer/task-store.d.ts.map +1 -0
  175. package/dist/a2a/producer/task-store.js +128 -0
  176. package/dist/a2a/producer/task-store.js.map +1 -0
  177. package/dist/agent.d.ts +99 -0
  178. package/dist/agent.d.ts.map +1 -1
  179. package/dist/agent.js +754 -19
  180. package/dist/agent.js.map +1 -1
  181. package/dist/api-runtime.d.ts +25 -0
  182. package/dist/api-runtime.d.ts.map +1 -1
  183. package/dist/api-runtime.js +75 -2
  184. package/dist/api-runtime.js.map +1 -1
  185. package/dist/claim-dispatcher.d.ts +126 -0
  186. package/dist/claim-dispatcher.d.ts.map +1 -0
  187. package/dist/claim-dispatcher.js +478 -0
  188. package/dist/claim-dispatcher.js.map +1 -0
  189. package/dist/express.d.ts.map +1 -1
  190. package/dist/express.js +33 -6
  191. package/dist/express.js.map +1 -1
  192. package/dist/inbound-job-dispatch.d.ts +105 -0
  193. package/dist/inbound-job-dispatch.d.ts.map +1 -0
  194. package/dist/inbound-job-dispatch.js +335 -0
  195. package/dist/inbound-job-dispatch.js.map +1 -0
  196. package/dist/index.d.ts +40 -4
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js +40 -3
  199. package/dist/index.js.map +1 -1
  200. package/dist/job-context.d.ts +107 -0
  201. package/dist/job-context.d.ts.map +1 -0
  202. package/dist/job-context.js +95 -0
  203. package/dist/job-context.js.map +1 -0
  204. package/dist/jobs-cancel-route.d.ts +36 -0
  205. package/dist/jobs-cancel-route.d.ts.map +1 -0
  206. package/dist/jobs-cancel-route.js +60 -0
  207. package/dist/jobs-cancel-route.js.map +1 -0
  208. package/dist/jobs-helper-tools.d.ts +48 -0
  209. package/dist/jobs-helper-tools.d.ts.map +1 -0
  210. package/dist/jobs-helper-tools.js +133 -0
  211. package/dist/jobs-helper-tools.js.map +1 -0
  212. package/dist/llm-agent.d.ts +62 -53
  213. package/dist/llm-agent.d.ts.map +1 -1
  214. package/dist/llm-agent.js +211 -292
  215. package/dist/llm-agent.js.map +1 -1
  216. package/dist/llm-provider.d.ts +11 -4
  217. package/dist/llm-provider.d.ts.map +1 -1
  218. package/dist/llm-provider.js +57 -4
  219. package/dist/llm-provider.js.map +1 -1
  220. package/dist/llm.d.ts +4 -1
  221. package/dist/llm.d.ts.map +1 -1
  222. package/dist/llm.js +7 -17
  223. package/dist/llm.js.map +1 -1
  224. package/dist/media/resolver.d.ts.map +1 -1
  225. package/dist/media/resolver.js +3 -2
  226. package/dist/media/resolver.js.map +1 -1
  227. package/dist/mesh-job-submitter.d.ts +83 -0
  228. package/dist/mesh-job-submitter.d.ts.map +1 -0
  229. package/dist/mesh-job-submitter.js +143 -0
  230. package/dist/mesh-job-submitter.js.map +1 -0
  231. package/dist/provider-handlers/gemini-handler.js +5 -0
  232. package/dist/provider-handlers/gemini-handler.js.map +1 -1
  233. package/dist/proxy.d.ts +40 -0
  234. package/dist/proxy.d.ts.map +1 -1
  235. package/dist/proxy.js +375 -2
  236. package/dist/proxy.js.map +1 -1
  237. package/dist/resolver-meshjob.d.ts +170 -0
  238. package/dist/resolver-meshjob.d.ts.map +1 -0
  239. package/dist/resolver-meshjob.js +159 -0
  240. package/dist/resolver-meshjob.js.map +1 -0
  241. package/dist/route.d.ts +4 -0
  242. package/dist/route.d.ts.map +1 -1
  243. package/dist/route.js.map +1 -1
  244. package/dist/schema-normalize.d.ts +62 -0
  245. package/dist/schema-normalize.d.ts.map +1 -0
  246. package/dist/schema-normalize.js +128 -0
  247. package/dist/schema-normalize.js.map +1 -0
  248. package/dist/sse-stream.d.ts +44 -0
  249. package/dist/sse-stream.d.ts.map +1 -0
  250. package/dist/sse-stream.js +173 -0
  251. package/dist/sse-stream.js.map +1 -0
  252. package/dist/tool-worker-entry.d.ts +21 -0
  253. package/dist/tool-worker-entry.d.ts.map +1 -0
  254. package/dist/tool-worker-entry.js +162 -0
  255. package/dist/tool-worker-entry.js.map +1 -0
  256. package/dist/tool-worker-pool.d.ts +49 -0
  257. package/dist/tool-worker-pool.d.ts.map +1 -0
  258. package/dist/tool-worker-pool.js +272 -0
  259. package/dist/tool-worker-pool.js.map +1 -0
  260. package/dist/types.d.ts +351 -9
  261. package/dist/types.d.ts.map +1 -1
  262. package/package.json +5 -3
@@ -0,0 +1,433 @@
1
+ /**
2
+ * End-to-end tests for `mount.ts` (issue #933).
3
+ *
4
+ * Coverage:
5
+ * - POST {path} with sync handler -> Task envelope (state=completed)
6
+ * - POST {path} with JobProxy return -> state=working
7
+ * - GET {path}/.well-known/agent.json -> agent card
8
+ * - GET {path}/.well-known/agent.json/ (trailing slash, spec §3.1) -> card
9
+ * - POST {path} malformed JSON -> HTTP 400 + -32700
10
+ * - POST {path} missing method field -> -32600 (NOT -32601 'null')
11
+ * - POST {path} unknown method -> -32601 with actual method name
12
+ * - POST {path} tasks/sendSubscribe -> SSE (text/event-stream)
13
+ * - Auth gate: missing Authorization on bearer-mount -> 401 + -32001
14
+ * - Multi-mount: routes don't collide
15
+ *
16
+ * Uses a real Express app behind Node http server (mirrors existing
17
+ * `__tests__/a2a/a2a-job.spec.ts` server pattern). No supertest dep.
18
+ *
19
+ * Mocks `api-runtime.ts` so `getApiRuntime().scheduleStart()` doesn't
20
+ * try to bind the real napi runtime — same pattern as existing
21
+ * `mesh-job-submitter.spec.ts`.
22
+ */
23
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
24
+ import * as http from "node:http";
25
+ import express from "express";
26
+ // Mock api-runtime so mount() doesn't try to spin up the real Rust core
27
+ // when scheduleStart() is invoked.
28
+ vi.mock("../../../api-runtime.js", () => ({
29
+ getApiRuntime: () => ({
30
+ scheduleStart: vi.fn(),
31
+ }),
32
+ }));
33
+ // Mock @mcpmesh/core so JobProxy class detection can short-circuit on
34
+ // the duck-typed fallback path (we never actually construct a real
35
+ // JobProxy here).
36
+ vi.mock("@mcpmesh/core", async () => {
37
+ const actual = await vi.importActual("@mcpmesh/core");
38
+ return {
39
+ ...actual,
40
+ };
41
+ });
42
+ import { mount, __getA2ATaskStore } from "../../../a2a/producer/mount.js";
43
+ import { A2AProducerRegistry } from "../../../a2a/producer/registry.js";
44
+ import { RouteRegistry } from "../../../route.js";
45
+ async function startServer(app) {
46
+ return new Promise((resolve) => {
47
+ const server = http.createServer(app);
48
+ server.listen(0, "127.0.0.1", () => {
49
+ const port = server.address().port;
50
+ resolve({
51
+ url: `http://127.0.0.1:${port}`,
52
+ close: () => new Promise((rs, rj) => server.close((err) => (err ? rj(err) : rs()))),
53
+ });
54
+ });
55
+ });
56
+ }
57
+ async function postJson(url, body, headers = {}) {
58
+ return doRequest(url, "POST", JSON.stringify(body), {
59
+ "Content-Type": "application/json",
60
+ ...headers,
61
+ });
62
+ }
63
+ async function get(url) {
64
+ return doRequest(url, "GET", undefined, {});
65
+ }
66
+ function doRequest(url, method, body, headers) {
67
+ const u = new URL(url);
68
+ return new Promise((resolve, reject) => {
69
+ const req = http.request({
70
+ host: u.hostname,
71
+ port: u.port,
72
+ path: u.pathname + u.search,
73
+ method,
74
+ headers,
75
+ }, (res) => {
76
+ const chunks = [];
77
+ res.on("data", (c) => chunks.push(c));
78
+ res.on("end", () => {
79
+ const text = Buffer.concat(chunks).toString("utf8");
80
+ resolve({
81
+ status: res.statusCode ?? 0,
82
+ contentType: res.headers["content-type"],
83
+ body: text,
84
+ json: () => JSON.parse(text),
85
+ });
86
+ });
87
+ });
88
+ req.on("error", reject);
89
+ if (body !== undefined)
90
+ req.write(body);
91
+ req.end();
92
+ });
93
+ }
94
+ /** Send POST and read response as raw stream (for SSE checks). */
95
+ function postRaw(url, body, headers = {}) {
96
+ return doRequest(url, "POST", JSON.stringify(body), {
97
+ "Content-Type": "application/json",
98
+ ...headers,
99
+ });
100
+ }
101
+ /**
102
+ * Send POST with a hand-crafted body string (no JSON.stringify) — used to
103
+ * verify body-parser parse-error handling against malformed bodies.
104
+ */
105
+ function postRawString(url, rawBody, headers = {}) {
106
+ return doRequest(url, "POST", rawBody, {
107
+ "Content-Type": "application/json",
108
+ ...headers,
109
+ });
110
+ }
111
+ // ────────────────────────────────────────────────────────────────────────
112
+ // Tests
113
+ // ────────────────────────────────────────────────────────────────────────
114
+ describe("mesh.a2a.mount: end-to-end via Express + node http", () => {
115
+ let server = null;
116
+ beforeEach(() => {
117
+ A2AProducerRegistry.reset();
118
+ RouteRegistry.reset();
119
+ __getA2ATaskStore().clear();
120
+ });
121
+ afterEach(async () => {
122
+ if (server) {
123
+ await server.close();
124
+ server = null;
125
+ }
126
+ });
127
+ /** Spec §4.3 sync path: handler return -> state=completed Task envelope. */
128
+ it("POST {path} with sync handler -> state=completed envelope (spec §4.3)", async () => {
129
+ const app = express();
130
+ app.use(express.json());
131
+ mount(app, { path: "/agents/sync", skillId: "sync-skill" }, async (_deps, payload) => ({ echo: payload }));
132
+ server = await startServer(app);
133
+ const res = await postJson(`${server.url}/agents/sync`, {
134
+ jsonrpc: "2.0",
135
+ id: 1,
136
+ method: "tasks/send",
137
+ params: { id: "t1", message: { role: "user", parts: [] } },
138
+ });
139
+ expect(res.status).toBe(200);
140
+ expect(res.contentType).toMatch(/application\/json/);
141
+ const json = res.json();
142
+ expect(json.id).toBe(1);
143
+ const result = json.result;
144
+ const status = result.status;
145
+ expect(status.state).toBe("completed");
146
+ const artifacts = result.artifacts;
147
+ const parts = artifacts[0].parts;
148
+ expect(parts[0].type).toBe("text");
149
+ });
150
+ /** Spec §4.3 long-running: JobProxy return -> state=working. */
151
+ it("POST {path} with JobProxy return -> state=working", async () => {
152
+ const fakeProxy = {
153
+ jobId: "job-mount",
154
+ status: async () => ({ status: "running" }),
155
+ wait: async () => null,
156
+ cancel: async () => undefined,
157
+ };
158
+ const app = express();
159
+ app.use(express.json());
160
+ mount(app, { path: "/agents/lr", skillId: "lr-skill" }, async () => fakeProxy);
161
+ server = await startServer(app);
162
+ const res = await postJson(`${server.url}/agents/lr`, {
163
+ jsonrpc: "2.0",
164
+ id: 2,
165
+ method: "tasks/send",
166
+ params: { id: "t-lr" },
167
+ });
168
+ const result = res.json().result;
169
+ expect(result.status.state).toBe("working");
170
+ });
171
+ /** Spec §3.2: agent card returned on GET {path}/.well-known/agent.json. */
172
+ it("GET {path}/.well-known/agent.json -> valid card", async () => {
173
+ const app = express();
174
+ app.use(express.json());
175
+ mount(app, {
176
+ path: "/agents/card",
177
+ skillId: "card-skill",
178
+ skillName: "Card Skill",
179
+ description: "Skill that has a card",
180
+ tags: ["x"],
181
+ }, async () => "ok");
182
+ server = await startServer(app);
183
+ const res = await get(`${server.url}/agents/card/.well-known/agent.json`);
184
+ expect(res.status).toBe(200);
185
+ expect(res.contentType).toMatch(/application\/json/);
186
+ const card = res.json();
187
+ expect(card.name).toBeTypeOf("string");
188
+ expect(card.capabilities.streaming).toBe(true);
189
+ const skills = card.skills;
190
+ expect(skills).toHaveLength(1);
191
+ expect(skills[0].id).toBe("card-skill");
192
+ expect(skills[0].tags).toEqual(["x"]);
193
+ });
194
+ /** Spec §3.1: trailing slash also returns the card. */
195
+ it("GET {path}/.well-known/agent.json/ (trailing slash) -> card", async () => {
196
+ const app = express();
197
+ app.use(express.json());
198
+ mount(app, { path: "/agents/ts", skillId: "ts" }, async () => "ok");
199
+ server = await startServer(app);
200
+ const res = await get(`${server.url}/agents/ts/.well-known/agent.json/`);
201
+ expect(res.status).toBe(200);
202
+ const card = res.json();
203
+ expect(card.skills[0].id).toBe("ts");
204
+ });
205
+ /**
206
+ * Spec §4.1: empty body that express.json() leaves as `null` parsed →
207
+ * HTTP 400 + JSON-RPC -32700.
208
+ *
209
+ * Note: when express.json() ITSELF fails to parse (malformed JSON), it
210
+ * emits its own HTML 400 — the dispatcher's -32700 path is only
211
+ * reachable when express.json() succeeded but produced null/undefined.
212
+ * We bypass express.json() here to drive the dispatcher directly with
213
+ * a hand-built req.body = null path: use a no-op body parser so the
214
+ * dispatcher sees the empty body.
215
+ */
216
+ it("POST {path} empty body -> HTTP 400 + -32700 JSON-RPC error", async () => {
217
+ const app = express();
218
+ // Custom body parser that leaves req.body as `undefined` for our
219
+ // dispatcher to handle — exercises the spec §4.1 -32700 path.
220
+ app.use((req, _res, next) => {
221
+ req.body = undefined;
222
+ next();
223
+ });
224
+ mount(app, { path: "/agents/bad", skillId: "bad" }, async () => "ok");
225
+ server = await startServer(app);
226
+ const res = await postJson(`${server.url}/agents/bad`, {});
227
+ expect(res.status).toBe(400);
228
+ const body = res.json();
229
+ expect(body.error.code).toBe(-32700);
230
+ });
231
+ /**
232
+ * Spec §4.1: malformed JSON body rejected by `express.json()` -> producer
233
+ * still returns a structured `-32700 Parse error` JSON-RPC envelope (HTTP
234
+ * 400 + `application/json`), not Express's default HTML 400 page.
235
+ *
236
+ * Verifies the path-scoped body-parser error handler installed by
237
+ * `mount()` — without it `express.json()` would short-circuit with an
238
+ * HTML response and A2A clients would have no way to recover.
239
+ */
240
+ it("POST {path} malformed JSON body -> 400 + -32700 JSON-RPC envelope", async () => {
241
+ const app = express();
242
+ app.use(express.json());
243
+ mount(app, { path: "/agents/malformed", skillId: "malformed" }, async () => "ok");
244
+ server = await startServer(app);
245
+ const res = await postRawString(`${server.url}/agents/malformed`, "not json at all");
246
+ expect(res.status).toBe(400);
247
+ expect(res.contentType).toMatch(/application\/json/);
248
+ // Parse structurally — don't string-grep the body shape.
249
+ const body = res.json();
250
+ expect(body.jsonrpc).toBe("2.0");
251
+ expect(body.id).toBeNull();
252
+ const err = body.error;
253
+ expect(err.code).toBe(-32700);
254
+ expect(typeof err.message).toBe("string");
255
+ });
256
+ /**
257
+ * Regression guard for the parse-error handler: valid JSON bodies on the
258
+ * producer route still dispatch normally — the error handler must only
259
+ * fire on body-parser failures, never on the happy path.
260
+ */
261
+ it("POST {path} valid JSON body still dispatches after parse-error handler is wired", async () => {
262
+ const app = express();
263
+ app.use(express.json());
264
+ mount(app, { path: "/agents/post-fix", skillId: "post-fix" }, async () => "happy-path");
265
+ server = await startServer(app);
266
+ const res = await postJson(`${server.url}/agents/post-fix`, {
267
+ jsonrpc: "2.0",
268
+ id: 7,
269
+ method: "tasks/send",
270
+ params: { id: "t-pf" },
271
+ });
272
+ expect(res.status).toBe(200);
273
+ const result = res.json().result;
274
+ expect(result.status.state).toBe("completed");
275
+ });
276
+ /**
277
+ * Path-scope guard: the body-parser error handler must NOT intercept
278
+ * parse errors on unrelated user routes mounted on the same Express app.
279
+ * Hosts that wire their own routes outside the producer surface get
280
+ * Express's default behavior (HTML 400) untouched.
281
+ */
282
+ it("unrelated route on same app with malformed JSON -> not intercepted by producer's parse-error handler", async () => {
283
+ const app = express();
284
+ app.use(express.json());
285
+ // Unrelated user route — registered before the mount so a global
286
+ // handler would catch its errors. Mount registers a path-scoped one.
287
+ app.post("/user/echo", (req, res) => {
288
+ res.status(200).json({ ok: true, echo: req.body });
289
+ });
290
+ mount(app, { path: "/agents/scoped", skillId: "scoped" }, async () => "ok");
291
+ server = await startServer(app);
292
+ const res = await postRawString(`${server.url}/user/echo`, "not json at all");
293
+ // Default Express behavior is HTML 400 ("SyntaxError: Unexpected token …"
294
+ // wrapped in a stack-trace page). The key assertion is that we do NOT
295
+ // see the producer's JSON-RPC -32700 envelope leak onto the user route.
296
+ expect(res.status).toBe(400);
297
+ const contentType = res.contentType ?? "";
298
+ if (contentType.includes("application/json")) {
299
+ // If a future Express version starts emitting JSON for body-parser
300
+ // errors, make sure it's NOT our -32700 envelope (which would mean
301
+ // the path scope leaked).
302
+ try {
303
+ const body = JSON.parse(res.body);
304
+ const err = body.error;
305
+ expect(err?.code).not.toBe(-32700);
306
+ }
307
+ catch {
308
+ // Body wasn't JSON — fine, the scope didn't leak.
309
+ }
310
+ }
311
+ });
312
+ /** Spec §4.1 + #934: missing method field -> -32600 (NOT -32601 'null'). */
313
+ it("POST {path} missing method field -> -32600 Invalid Request (#934)", async () => {
314
+ const app = express();
315
+ app.use(express.json());
316
+ mount(app, { path: "/agents/mm", skillId: "mm" }, async () => "ok");
317
+ server = await startServer(app);
318
+ const res = await postJson(`${server.url}/agents/mm`, {
319
+ jsonrpc: "2.0",
320
+ id: 1,
321
+ });
322
+ const body = res.json();
323
+ const err = body.error;
324
+ expect(err.code).toBe(-32600);
325
+ expect(err.message.toLowerCase()).not.toContain("'null'");
326
+ });
327
+ /** Spec §4.1: unknown method -> -32601 with actual method name. */
328
+ it("POST {path} unknown method -> -32601 with method name (#934 guard)", async () => {
329
+ const app = express();
330
+ app.use(express.json());
331
+ mount(app, { path: "/agents/um", skillId: "um" }, async () => "ok");
332
+ server = await startServer(app);
333
+ const res = await postJson(`${server.url}/agents/um`, {
334
+ jsonrpc: "2.0",
335
+ id: 1,
336
+ method: "tasks/madeUp",
337
+ params: {},
338
+ });
339
+ const body = res.json();
340
+ const err = body.error;
341
+ expect(err.code).toBe(-32601);
342
+ expect(err.message).toContain("tasks/madeUp");
343
+ expect(err.message.toLowerCase()).not.toContain("'null'");
344
+ });
345
+ /** Spec §4.6: tasks/sendSubscribe returns text/event-stream. */
346
+ it("POST {path} tasks/sendSubscribe -> Content-Type: text/event-stream", async () => {
347
+ const app = express();
348
+ app.use(express.json());
349
+ mount(app, { path: "/agents/sse", skillId: "sse" }, async () => "sync-ok");
350
+ server = await startServer(app);
351
+ const res = await postRaw(`${server.url}/agents/sse`, {
352
+ jsonrpc: "2.0",
353
+ id: 1,
354
+ method: "tasks/sendSubscribe",
355
+ params: { id: "t-sse" },
356
+ });
357
+ expect(res.contentType).toMatch(/text\/event-stream/);
358
+ // Body has at least one `data:` frame.
359
+ expect(res.body).toMatch(/^data: /m);
360
+ });
361
+ /** Spec §6.2: bearer auth gate rejects missing header with -32001. */
362
+ it("POST {path} without Authorization on bearer-mount -> 401 + -32001", async () => {
363
+ const app = express();
364
+ app.use(express.json());
365
+ mount(app, { path: "/agents/auth", skillId: "auth", auth: "bearer" }, async () => "ok");
366
+ server = await startServer(app);
367
+ const res = await postJson(`${server.url}/agents/auth`, {
368
+ jsonrpc: "2.0",
369
+ id: 1,
370
+ method: "tasks/send",
371
+ params: { id: "t-auth" },
372
+ });
373
+ expect(res.status).toBe(401);
374
+ const err = res.json().error;
375
+ expect(err.code).toBe(-32001);
376
+ });
377
+ /** Spec §6.2 + conformance checklist: card endpoint is always public. */
378
+ it("GET card endpoint is public even on bearer-mount", async () => {
379
+ const app = express();
380
+ app.use(express.json());
381
+ mount(app, { path: "/agents/auth2", skillId: "auth2", auth: "bearer" }, async () => "ok");
382
+ server = await startServer(app);
383
+ const res = await get(`${server.url}/agents/auth2/.well-known/agent.json`);
384
+ expect(res.status).toBe(200);
385
+ const card = res.json();
386
+ const auth = card.authentication;
387
+ expect(auth.schemes).toEqual(["bearer"]);
388
+ });
389
+ /** Spec §4: multiple mounts on the same app dispatch independently. */
390
+ it("multiple mounts on same Express app -> routes do not collide", async () => {
391
+ const app = express();
392
+ app.use(express.json());
393
+ mount(app, { path: "/m1", skillId: "m1" }, async () => "from-m1");
394
+ mount(app, { path: "/m2", skillId: "m2" }, async () => "from-m2");
395
+ server = await startServer(app);
396
+ const r1 = await postJson(`${server.url}/m1`, {
397
+ jsonrpc: "2.0",
398
+ id: 1,
399
+ method: "tasks/send",
400
+ params: { id: "tm1" },
401
+ });
402
+ const r2 = await postJson(`${server.url}/m2`, {
403
+ jsonrpc: "2.0",
404
+ id: 2,
405
+ method: "tasks/send",
406
+ params: { id: "tm2" },
407
+ });
408
+ const a1 = r1.json().result.artifacts;
409
+ const a2 = r2.json().result.artifacts;
410
+ const p1 = a1[0].parts;
411
+ const p2 = a2[0].parts;
412
+ expect(p1[0].text).toBe("from-m1");
413
+ expect(p2[0].text).toBe("from-m2");
414
+ });
415
+ });
416
+ describe("mesh.a2a.mount: config.path validation (spec §3.1)", () => {
417
+ beforeEach(() => {
418
+ A2AProducerRegistry.reset();
419
+ RouteRegistry.reset();
420
+ __getA2ATaskStore().clear();
421
+ });
422
+ /**
423
+ * Regression: mounting at root produces a card URL with a double-slash
424
+ * (`//.well-known/agent.json`) which is unreachable. Validation must
425
+ * reject `config.path === "/"` outright with a clear error message.
426
+ */
427
+ it("rejects config.path === '/' (would produce '//.well-known/agent.json')", () => {
428
+ const app = express();
429
+ app.use(express.json());
430
+ expect(() => mount(app, { path: "/", skillId: "root-skill" }, async () => "ok")).toThrow(/must not be '\/'/i);
431
+ });
432
+ });
433
+ //# sourceMappingURL=mount.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.spec.js","sourceRoot":"","sources":["../../../../src/__tests__/a2a/producer/mount.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,wEAAwE;AACxE,mCAAmC;AACnC,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;QACpB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;KACvB,CAAC;CACH,CAAC,CAAC,CAAC;AAEJ,sEAAsE;AACtE,mEAAmE;AACnE,kBAAkB;AAClB,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;IAClC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAA0B,eAAe,CAAC,CAAC;IAC/E,OAAO;QACL,GAAG,MAAM;KACV,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAWlD,KAAK,UAAU,WAAW,CAAC,GAAwB;IACjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,IAAI,GAAI,MAAM,CAAC,OAAO,EAAkB,CAAC,IAAI,CAAC;YACpD,OAAO,CAAC;gBACN,GAAG,EAAE,oBAAoB,IAAI,EAAE;gBAC/B,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAC3B,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAC9C;aACJ,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AASD,KAAK,UAAU,QAAQ,CACrB,GAAW,EACX,IAAa,EACb,UAAkC,EAAE;IAEpC,OAAO,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QAClD,cAAc,EAAE,kBAAkB;QAClC,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,GAAW;IAC5B,OAAO,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,SAAS,CAChB,GAAW,EACX,MAAc,EACd,IAAwB,EACxB,OAA+B;IAE/B,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CACtB;YACE,IAAI,EAAE,CAAC,CAAC,QAAQ;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,MAAM;YAC3B,MAAM;YACN,OAAO;SACR,EACD,CAAC,GAAG,EAAE,EAAE;YACN,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACtC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACpD,OAAO,CAAC;oBACN,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC;oBAC3B,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;oBACxC,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B;iBACxD,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,IAAI,IAAI,KAAK,SAAS;YAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,kEAAkE;AAClE,SAAS,OAAO,CACd,GAAW,EACX,IAAa,EACb,UAAkC,EAAE;IAEpC,OAAO,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QAClD,cAAc,EAAE,kBAAkB;QAClC,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CACpB,GAAW,EACX,OAAe,EACf,UAAkC,EAAE;IAEpC,OAAO,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QACrC,cAAc,EAAE,kBAAkB;QAClC,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,QAAQ;AACR,2EAA2E;AAE3E,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,IAAI,MAAM,GAAsB,IAAI,CAAC;IAErC,UAAU,CAAC,GAAG,EAAE;QACd,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC5B,aAAa,CAAC,KAAK,EAAE,CAAC;QACtB,iBAAiB,EAAE,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,EAC/C,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAC9C,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,cAAc,EAAE;YACtD,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;SAC3D,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAiC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAiC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,MAAM,CAAC,SAA2C,CAAC;QACrE,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,KAAuC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAChE,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,SAAS,GAAG;YAChB,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAC3C,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;YACtB,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;SAC9B,CAAC;QACF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,EAC3C,KAAK,IAAI,EAAE,CAAC,SAAkB,CAC/B,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,YAAY,EAAE;YACpD,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;SACvB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,MAAiC,CAAC;QAC5D,MAAM,CAAE,MAAM,CAAC,MAAkC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,2EAA2E;IAC3E,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH;YACE,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,YAAY;YACrB,SAAS,EAAE,YAAY;YACvB,WAAW,EAAE,uBAAuB;YACpC,IAAI,EAAE,CAAC,GAAG,CAAC;SACZ,EACD,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,qCAAqC,CAAC,CAAC;QAC1E,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,CAAE,IAAI,CAAC,YAAwC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAwC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,uDAAuD;IACvD,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,EACrC,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,oCAAoC,CAAC,CAAC;QACzE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,CAAE,IAAI,CAAC,MAAyC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH;;;;;;;;;;OAUG;IACH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,iEAAiE;QACjE,8DAA8D;QAC9D,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YACzB,GAAoC,CAAC,IAAI,GAAG,SAAS,CAAC;YACvD,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QACH,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,EACvC,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,aAAa,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,CAAE,IAAI,CAAC,KAAiC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH;;;;;;;;OAQG;IACH,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,WAAW,EAAE,EACnD,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,aAAa,CAC7B,GAAG,MAAM,CAAC,GAAG,mBAAmB,EAChC,iBAAiB,CAClB,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACrD,yDAAyD;QACzD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAgC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,UAAU,EAAE,EACjD,KAAK,IAAI,EAAE,CAAC,YAAY,CACzB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,kBAAkB,EAAE;YAC1D,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;SACvB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,MAAiC,CAAC;QAC5D,MAAM,CAAE,MAAM,CAAC,MAAkC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH;;;;;OAKG;IACH,EAAE,CAAC,sGAAsG,EAAE,KAAK,IAAI,EAAE;QACpH,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,iEAAiE;QACjE,qEAAqE;QACrE,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAClC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QACH,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAC7C,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,GAAG,MAAM,CAAC,GAAG,YAAY,EAAE,iBAAiB,CAAC,CAAC;QAC9E,0EAA0E;QAC1E,sEAAsE;QACtE,wEAAwE;QACxE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QAC1C,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7C,mEAAmE;YACnE,mEAAmE;YACnE,0BAA0B;YAC1B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAA4B,CAAC;gBAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,KAA4C,CAAC;gBAC9D,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,kDAAkD;YACpD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,YAAY,EAAE;YACpD,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;SACN,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAgC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAE,GAAG,CAAC,OAAkB,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,mEAAmE;IACnE,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,YAAY,EAAE;YACpD,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,cAAc;YACtB,MAAM,EAAE,EAAE;SACX,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAgC,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,CAAE,GAAG,CAAC,OAAkB,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,gEAAgE;IAChE,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,EACvC,KAAK,IAAI,EAAE,CAAC,SAAS,CACtB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,aAAa,EAAE;YACpD,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,qBAAqB;YAC7B,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;SACxB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACtD,uCAAuC;QACvC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,sEAAsE;IACtE,EAAE,CAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;QACjF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EACzD,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,cAAc,EAAE;YACtD,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;SACzB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAgC,CAAC;QACxD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAC3D,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC;QACF,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,sCAAsC,CAAC,CAAC;QAC3E,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAyC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC;QAClE,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC;QAClE,MAAM,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,EAAE;YAC5C,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE;SACtB,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,EAAE;YAC5C,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,CAAC;YACL,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE;SACtB,CAAC,CAAC;QAEH,MAAM,EAAE,GAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAkC,CAAC,SAExD,CAAC;QACF,MAAM,EAAE,GAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAkC,CAAC,SAExD,CAAC;QACF,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,KAAuC,CAAC;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,KAAuC,CAAC;QACzD,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,UAAU,CAAC,GAAG,EAAE;QACd,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC5B,aAAa,CAAC,KAAK,EAAE,CAAC;QACtB,iBAAiB,EAAE,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,EAAE,CACV,KAAK,CACH,GAAG,EACH,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,EACpC,KAAK,IAAI,EAAE,CAAC,IAAI,CACjB,CACF,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=public-url-cache.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-url-cache.spec.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/a2a/producer/public-url-cache.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Unit tests for `public-url-cache.ts` (spec §2.4 + §8.2).
3
+ *
4
+ * Coverage:
5
+ * - put/get round-trip
6
+ * - put with empty / null / undefined clears the entry (Java fix from #934)
7
+ * - Different (path, skillId) keys don't collide
8
+ * - clear() drops all entries
9
+ * - Singleton reset works between tests
10
+ * - buildLocalFallbackUrl host/port/path composition
11
+ * - IPv6 host handling (parity flag with Java #934 A6 fix)
12
+ *
13
+ * Mirrors Java's `MeshA2APublicUrlCacheTest`.
14
+ */
15
+ import { describe, it, expect, beforeEach } from "vitest";
16
+ import { A2APublicUrlCache, buildLocalFallbackUrl, } from "../../../a2a/producer/public-url-cache.js";
17
+ describe("A2APublicUrlCache (spec §8.2)", () => {
18
+ beforeEach(() => {
19
+ A2APublicUrlCache.reset();
20
+ });
21
+ /** Singleton: `getInstance()` always returns the same object until reset. */
22
+ it("returns the same singleton across calls; reset rebuilds it", () => {
23
+ const a = A2APublicUrlCache.getInstance();
24
+ const b = A2APublicUrlCache.getInstance();
25
+ expect(a).toBe(b);
26
+ A2APublicUrlCache.reset();
27
+ const c = A2APublicUrlCache.getInstance();
28
+ expect(c).not.toBe(a);
29
+ });
30
+ /** Basic put + get round-trip. */
31
+ it("put + get round-trip", () => {
32
+ const c = A2APublicUrlCache.getInstance();
33
+ c.put("/agents/date", "get-date", "https://prod.example.com/agents/date");
34
+ expect(c.get("/agents/date", "get-date")).toBe("https://prod.example.com/agents/date");
35
+ });
36
+ /** Java #934 fix: empty URL clears the cached entry. */
37
+ it("put with empty string clears the cached entry", () => {
38
+ const c = A2APublicUrlCache.getInstance();
39
+ c.put("/agents/x", "x", "https://a.example.com/x");
40
+ expect(c.get("/agents/x", "x")).toBe("https://a.example.com/x");
41
+ c.put("/agents/x", "x", "");
42
+ expect(c.get("/agents/x", "x")).toBeUndefined();
43
+ });
44
+ /** Java #934 fix: null URL clears the cached entry. */
45
+ it("put with null clears the cached entry", () => {
46
+ const c = A2APublicUrlCache.getInstance();
47
+ c.put("/agents/y", "y", "https://a.example.com/y");
48
+ c.put("/agents/y", "y", null);
49
+ expect(c.get("/agents/y", "y")).toBeUndefined();
50
+ });
51
+ /** Java #934 fix: undefined URL clears the cached entry. */
52
+ it("put with undefined clears the cached entry", () => {
53
+ const c = A2APublicUrlCache.getInstance();
54
+ c.put("/agents/z", "z", "https://a.example.com/z");
55
+ c.put("/agents/z", "z", undefined);
56
+ expect(c.get("/agents/z", "z")).toBeUndefined();
57
+ });
58
+ /** Distinct (path, skillId) keys are independent. */
59
+ it("different (path, skillId) keys do not collide", () => {
60
+ const c = A2APublicUrlCache.getInstance();
61
+ c.put("/p1", "s1", "https://example.com/p1");
62
+ c.put("/p1", "s2", "https://example.com/p1-alt");
63
+ c.put("/p2", "s1", "https://example.com/p2");
64
+ expect(c.get("/p1", "s1")).toBe("https://example.com/p1");
65
+ expect(c.get("/p1", "s2")).toBe("https://example.com/p1-alt");
66
+ expect(c.get("/p2", "s1")).toBe("https://example.com/p2");
67
+ expect(c.size()).toBe(3);
68
+ });
69
+ /** clear() drops every entry. */
70
+ it("clear() removes all entries", () => {
71
+ const c = A2APublicUrlCache.getInstance();
72
+ c.put("/a", "a", "https://x");
73
+ c.put("/b", "b", "https://y");
74
+ expect(c.size()).toBe(2);
75
+ c.clear();
76
+ expect(c.size()).toBe(0);
77
+ expect(c.get("/a", "a")).toBeUndefined();
78
+ });
79
+ });
80
+ describe("buildLocalFallbackUrl (spec §2.4)", () => {
81
+ /** Standard case: host + port + path. */
82
+ it("composes host:port path", () => {
83
+ expect(buildLocalFallbackUrl("localhost", 8080, "/agents/x")).toBe("http://localhost:8080/agents/x");
84
+ });
85
+ /** Missing host defaults to localhost; missing/zero port is omitted. */
86
+ it("defaults missing host to localhost and drops zero/missing port", () => {
87
+ expect(buildLocalFallbackUrl(undefined, 0, "/x")).toBe("http://localhost/x");
88
+ expect(buildLocalFallbackUrl("", 0, "/x")).toBe("http://localhost/x");
89
+ expect(buildLocalFallbackUrl(undefined, undefined, "/x")).toBe("http://localhost/x");
90
+ });
91
+ /** Custom host without port. */
92
+ it("supports custom host without a port", () => {
93
+ expect(buildLocalFallbackUrl("svc.example.com", undefined, "/agents/y")).toBe("http://svc.example.com/agents/y");
94
+ });
95
+ /**
96
+ * Java #934 A6 fix parity: IPv6 hosts MUST be bracketed per RFC 3986
97
+ * §3.2.2 so the `:port` separator isn't ambiguous with the IPv6
98
+ * literal's own colons.
99
+ */
100
+ it("brackets IPv6 host literals (RFC 3986 §3.2.2 / Java #934 A6 parity)", () => {
101
+ expect(buildLocalFallbackUrl("::1", 8080, "/x")).toBe("http://[::1]:8080/x");
102
+ expect(buildLocalFallbackUrl("fe80::1234:5678:9abc:def0", 443, "/y")).toBe("http://[fe80::1234:5678:9abc:def0]:443/y");
103
+ // No port: brackets still applied so the host is a valid `host`
104
+ // production per RFC 3986.
105
+ expect(buildLocalFallbackUrl("::1", undefined, "/z")).toBe("http://[::1]/z");
106
+ });
107
+ /**
108
+ * A host that arrives already bracketed (caller pre-formatted it) MUST
109
+ * NOT be wrapped a second time — `[[::1]]` is not a valid URL.
110
+ */
111
+ it("does not double-bracket a host already in `[...]` form", () => {
112
+ expect(buildLocalFallbackUrl("[::1]", 8080, "/x")).toBe("http://[::1]:8080/x");
113
+ expect(buildLocalFallbackUrl("[::1]", undefined, "/y")).toBe("http://[::1]/y");
114
+ });
115
+ });
116
+ //# sourceMappingURL=public-url-cache.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-url-cache.spec.js","sourceRoot":"","sources":["../../../../src/__tests__/a2a/producer/public-url-cache.spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,EACL,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AAEnD,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,UAAU,CAAC,GAAG,EAAE;QACd,iBAAiB,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAElB,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,kCAAkC;IAClC,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,EAAE,sCAAsC,CAAC,CAAC;QAC1E,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAC5C,sCAAsC,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,wDAAwD;IACxD,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,yBAAyB,CAAC,CAAC;QACnD,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAEhE,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,uDAAuD;IACvD,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,yBAAyB,CAAC,CAAC;QAEnD,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC9B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,4DAA4D;IAC5D,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,yBAAyB,CAAC,CAAC;QAEnD,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QACnC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,qDAAqD;IACrD,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,wBAAwB,CAAC,CAAC;QAC7C,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,4BAA4B,CAAC,CAAC;QACjD,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,wBAAwB,CAAC,CAAC;QAE7C,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC1D,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC9D,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC1D,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,iCAAiC;IACjC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,GAAG,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1C,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QAC9B,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QAC9B,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzB,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,yCAAyC;IACzC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,qBAAqB,CAAC,WAAW,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAChE,gCAAgC,CACjC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,wEAAwE;IACxE,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC7E,MAAM,CAAC,qBAAqB,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACtE,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAC5D,oBAAoB,CACrB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,gCAAgC;IAChC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAC3E,iCAAiC,CAClC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH;;;;OAIG;IACH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC7E,MAAM,CAAC,qBAAqB,CAAC,2BAA2B,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACxE,0CAA0C,CAC3C,CAAC;QACF,gEAAgE;QAChE,2BAA2B;QAC3B,MAAM,CAAC,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH;;;OAGG;IACH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC/E,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sse-emitter.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-emitter.spec.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/a2a/producer/sse-emitter.spec.ts"],"names":[],"mappings":""}