skybridge 0.0.0-dev.febf292 → 0.0.0-dev.fec0253

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 (535) hide show
  1. package/README.md +126 -116
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +107 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +132 -0
  6. package/dist/cli/build-helpers.test.js.map +1 -0
  7. package/dist/cli/build-steps.d.ts +2 -0
  8. package/dist/cli/build-steps.js +73 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +52 -0
  11. package/dist/cli/build-steps.test.js.map +1 -0
  12. package/dist/cli/detect-port.d.ts +2 -2
  13. package/dist/cli/detect-port.js +8 -20
  14. package/dist/cli/detect-port.js.map +1 -1
  15. package/dist/cli/header.d.ts +1 -1
  16. package/dist/cli/header.js +1 -1
  17. package/dist/cli/header.js.map +1 -1
  18. package/dist/cli/resolve-skybridge-config.d.ts +5 -0
  19. package/dist/cli/resolve-skybridge-config.js +18 -0
  20. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  21. package/dist/cli/run-command.js.map +1 -1
  22. package/dist/cli/run-plain.d.ts +18 -0
  23. package/dist/cli/run-plain.js +90 -0
  24. package/dist/cli/run-plain.js.map +1 -0
  25. package/dist/cli/telemetry.js +2 -0
  26. package/dist/cli/telemetry.js.map +1 -1
  27. package/dist/cli/tunnel-control-server.d.ts +9 -0
  28. package/dist/cli/tunnel-control-server.js +31 -0
  29. package/dist/cli/tunnel-control-server.js.map +1 -0
  30. package/dist/cli/tunnel-control-server.test.js +39 -0
  31. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  32. package/dist/cli/tunnel-handler.d.ts +3 -0
  33. package/dist/cli/tunnel-handler.js +48 -0
  34. package/dist/cli/tunnel-handler.js.map +1 -0
  35. package/dist/cli/tunnel-handler.test.js +105 -0
  36. package/dist/cli/tunnel-handler.test.js.map +1 -0
  37. package/dist/cli/tunnel.d.ts +57 -0
  38. package/dist/cli/tunnel.js +154 -0
  39. package/dist/cli/tunnel.js.map +1 -0
  40. package/dist/cli/tunnel.test.js +190 -0
  41. package/dist/cli/tunnel.test.js.map +1 -0
  42. package/dist/cli/types.d.ts +5 -0
  43. package/dist/cli/types.js +2 -0
  44. package/dist/cli/types.js.map +1 -0
  45. package/dist/cli/use-execute-steps.d.ts +1 -1
  46. package/dist/cli/use-execute-steps.js.map +1 -1
  47. package/dist/cli/use-messages.d.ts +3 -0
  48. package/dist/cli/use-messages.js +11 -0
  49. package/dist/cli/use-messages.js.map +1 -0
  50. package/dist/cli/use-nodemon.d.ts +26 -7
  51. package/dist/cli/use-nodemon.js +97 -67
  52. package/dist/cli/use-nodemon.js.map +1 -1
  53. package/dist/cli/use-open-browser.d.ts +1 -0
  54. package/dist/cli/use-open-browser.js +44 -0
  55. package/dist/cli/use-open-browser.js.map +1 -0
  56. package/dist/cli/use-tunnel.d.ts +14 -0
  57. package/dist/cli/use-tunnel.js +131 -0
  58. package/dist/cli/use-tunnel.js.map +1 -0
  59. package/dist/cli/use-typescript-check.d.ts +9 -2
  60. package/dist/cli/use-typescript-check.js +89 -51
  61. package/dist/cli/use-typescript-check.js.map +1 -1
  62. package/dist/commands/build.d.ts +0 -3
  63. package/dist/commands/build.js +3 -18
  64. package/dist/commands/build.js.map +1 -1
  65. package/dist/commands/create.d.ts +9 -0
  66. package/dist/commands/create.js +30 -0
  67. package/dist/commands/create.js.map +1 -0
  68. package/dist/commands/dev.d.ts +4 -1
  69. package/dist/commands/dev.js +95 -9
  70. package/dist/commands/dev.js.map +1 -1
  71. package/dist/commands/start.js +13 -10
  72. package/dist/commands/start.js.map +1 -1
  73. package/dist/commands/telemetry/disable.js.map +1 -1
  74. package/dist/commands/telemetry/enable.js.map +1 -1
  75. package/dist/commands/telemetry/status.js.map +1 -1
  76. package/dist/context-warnings.d.ts +5 -0
  77. package/dist/context-warnings.js +31 -0
  78. package/dist/context-warnings.js.map +1 -0
  79. package/dist/context-warnings.test.js +28 -0
  80. package/dist/context-warnings.test.js.map +1 -0
  81. package/dist/server/app.d.ts +194 -0
  82. package/dist/server/app.js +266 -0
  83. package/dist/server/app.js.map +1 -0
  84. package/dist/server/app.test.d.ts +1 -0
  85. package/dist/server/app.test.js +97 -0
  86. package/dist/server/app.test.js.map +1 -0
  87. package/dist/server/asset-base-url-transform-plugin.d.ts +6 -6
  88. package/dist/server/asset-base-url-transform-plugin.js +25 -11
  89. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  90. package/dist/server/asset-base-url-transform-plugin.test.js +92 -14
  91. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  92. package/dist/server/auth/discovery.d.ts +33 -0
  93. package/dist/server/auth/discovery.js +56 -0
  94. package/dist/server/auth/discovery.js.map +1 -0
  95. package/dist/server/auth/discovery.test.d.ts +1 -0
  96. package/dist/server/auth/discovery.test.js +93 -0
  97. package/dist/server/auth/discovery.test.js.map +1 -0
  98. package/dist/server/auth/index.d.ts +48 -0
  99. package/dist/server/auth/index.js +2 -0
  100. package/dist/server/auth/index.js.map +1 -0
  101. package/dist/server/auth/providers/auth0.d.ts +40 -0
  102. package/dist/server/auth/providers/auth0.js +36 -0
  103. package/dist/server/auth/providers/auth0.js.map +1 -0
  104. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  105. package/dist/server/auth/providers/auth0.test.js +50 -0
  106. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  107. package/dist/server/auth/providers/authplane.d.ts +49 -0
  108. package/dist/server/auth/providers/authplane.js +57 -0
  109. package/dist/server/auth/providers/authplane.js.map +1 -0
  110. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  111. package/dist/server/auth/providers/authplane.test.js +143 -0
  112. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  113. package/dist/server/auth/providers/clerk.d.ts +51 -0
  114. package/dist/server/auth/providers/clerk.js +19 -0
  115. package/dist/server/auth/providers/clerk.js.map +1 -0
  116. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  117. package/dist/server/auth/providers/clerk.test.js +30 -0
  118. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  119. package/dist/server/auth/providers/custom.d.ts +42 -0
  120. package/dist/server/auth/providers/custom.js +59 -0
  121. package/dist/server/auth/providers/custom.js.map +1 -0
  122. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  123. package/dist/server/auth/providers/custom.test.js +161 -0
  124. package/dist/server/auth/providers/custom.test.js.map +1 -0
  125. package/dist/server/auth/providers/descope.d.ts +44 -0
  126. package/dist/server/auth/providers/descope.js +44 -0
  127. package/dist/server/auth/providers/descope.js.map +1 -0
  128. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  129. package/dist/server/auth/providers/descope.test.js +62 -0
  130. package/dist/server/auth/providers/descope.test.js.map +1 -0
  131. package/dist/server/auth/providers/shared.d.ts +2 -0
  132. package/dist/server/auth/providers/shared.js +6 -0
  133. package/dist/server/auth/providers/shared.js.map +1 -0
  134. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  135. package/dist/server/auth/providers/shared.test.js +10 -0
  136. package/dist/server/auth/providers/shared.test.js.map +1 -0
  137. package/dist/server/auth/providers/stytch.d.ts +25 -0
  138. package/dist/server/auth/providers/stytch.js +16 -0
  139. package/dist/server/auth/providers/stytch.js.map +1 -0
  140. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  141. package/dist/server/auth/providers/verify-spy.js +21 -0
  142. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  143. package/dist/server/auth/providers/workos.d.ts +34 -0
  144. package/dist/server/auth/providers/workos.js +16 -0
  145. package/dist/server/auth/providers/workos.js.map +1 -0
  146. package/dist/server/auth/security-schemes.d.ts +23 -0
  147. package/dist/server/auth/security-schemes.js +64 -0
  148. package/dist/server/auth/security-schemes.js.map +1 -0
  149. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  150. package/dist/server/auth/security-schemes.test.js +99 -0
  151. package/dist/server/auth/security-schemes.test.js.map +1 -0
  152. package/dist/server/auth/setup.d.ts +6 -0
  153. package/dist/server/auth/setup.js +91 -0
  154. package/dist/server/auth/setup.js.map +1 -0
  155. package/dist/server/auth/setup.test.d.ts +1 -0
  156. package/dist/server/auth/setup.test.js +514 -0
  157. package/dist/server/auth/setup.test.js.map +1 -0
  158. package/dist/server/auth/verify.d.ts +48 -0
  159. package/dist/server/auth/verify.js +62 -0
  160. package/dist/server/auth/verify.js.map +1 -0
  161. package/dist/server/auth/verify.test.d.ts +1 -0
  162. package/dist/server/auth/verify.test.js +165 -0
  163. package/dist/server/auth/verify.test.js.map +1 -0
  164. package/dist/server/auth-extra.test-d.d.ts +1 -0
  165. package/dist/server/auth-extra.test-d.js +130 -0
  166. package/dist/server/auth-extra.test-d.js.map +1 -0
  167. package/dist/server/auth.d.ts +57 -0
  168. package/dist/server/auth.js +27 -0
  169. package/dist/server/auth.js.map +1 -0
  170. package/dist/server/build-manifest.test.d.ts +1 -0
  171. package/dist/server/build-manifest.test.js +28 -0
  172. package/dist/server/build-manifest.test.js.map +1 -0
  173. package/dist/server/content-helpers.d.ts +67 -0
  174. package/dist/server/content-helpers.js +79 -0
  175. package/dist/server/content-helpers.js.map +1 -0
  176. package/dist/server/content-helpers.test.d.ts +1 -0
  177. package/dist/server/content-helpers.test.js +70 -0
  178. package/dist/server/content-helpers.test.js.map +1 -0
  179. package/dist/server/events.d.ts +113 -0
  180. package/dist/server/events.js +318 -0
  181. package/dist/server/events.js.map +1 -0
  182. package/dist/server/events.test.d.ts +1 -0
  183. package/dist/server/events.test.js +172 -0
  184. package/dist/server/events.test.js.map +1 -0
  185. package/dist/server/express.d.ts +27 -5
  186. package/dist/server/express.js +83 -43
  187. package/dist/server/express.js.map +1 -1
  188. package/dist/server/express.test.js +557 -22
  189. package/dist/server/express.test.js.map +1 -1
  190. package/dist/server/file-ref.d.ts +28 -0
  191. package/dist/server/file-ref.js +27 -0
  192. package/dist/server/file-ref.js.map +1 -0
  193. package/dist/server/form-input.d.ts +120 -0
  194. package/dist/server/form-input.js +89 -0
  195. package/dist/server/form-input.js.map +1 -0
  196. package/dist/server/host.d.ts +2 -0
  197. package/dist/server/host.js +11 -0
  198. package/dist/server/host.js.map +1 -0
  199. package/dist/server/host.test.d.ts +1 -0
  200. package/dist/server/host.test.js +13 -0
  201. package/dist/server/host.test.js.map +1 -0
  202. package/dist/server/index.d.ts +23 -3
  203. package/dist/server/index.js +19 -2
  204. package/dist/server/index.js.map +1 -1
  205. package/dist/server/inferUtilityTypes.d.ts +6 -6
  206. package/dist/server/inferUtilityTypes.js.map +1 -1
  207. package/dist/server/mcp-errors.test.d.ts +1 -0
  208. package/dist/server/mcp-errors.test.js +41 -0
  209. package/dist/server/mcp-errors.test.js.map +1 -0
  210. package/dist/server/metric.d.ts +14 -0
  211. package/dist/server/metric.js +62 -0
  212. package/dist/server/metric.js.map +1 -0
  213. package/dist/server/middleware.d.ts +162 -0
  214. package/dist/server/middleware.js +126 -0
  215. package/dist/server/middleware.js.map +1 -0
  216. package/dist/server/middleware.test-d.d.ts +1 -0
  217. package/dist/server/middleware.test-d.js +75 -0
  218. package/dist/server/middleware.test-d.js.map +1 -0
  219. package/dist/server/middleware.test.d.ts +1 -0
  220. package/dist/server/middleware.test.js +601 -0
  221. package/dist/server/middleware.test.js.map +1 -0
  222. package/dist/server/register-tool.test.d.ts +1 -0
  223. package/dist/server/register-tool.test.js +230 -0
  224. package/dist/server/register-tool.test.js.map +1 -0
  225. package/dist/server/requestOrigin.d.ts +7 -0
  226. package/dist/server/requestOrigin.js +25 -0
  227. package/dist/server/requestOrigin.js.map +1 -0
  228. package/dist/server/server.d.ts +629 -70
  229. package/dist/server/server.js +758 -165
  230. package/dist/server/server.js.map +1 -1
  231. package/dist/server/skills-integration.test.d.ts +1 -0
  232. package/dist/server/skills-integration.test.js +86 -0
  233. package/dist/server/skills-integration.test.js.map +1 -0
  234. package/dist/server/skills.d.ts +27 -0
  235. package/dist/server/skills.js +188 -0
  236. package/dist/server/skills.js.map +1 -0
  237. package/dist/server/skills.test.d.ts +1 -0
  238. package/dist/server/skills.test.js +243 -0
  239. package/dist/server/skills.test.js.map +1 -0
  240. package/dist/server/templateHelper.d.ts +2 -8
  241. package/dist/server/templateHelper.js +3 -22
  242. package/dist/server/templateHelper.js.map +1 -1
  243. package/dist/server/templates.generated.d.ts +4 -0
  244. package/dist/server/templates.generated.js +43 -0
  245. package/dist/server/templates.generated.js.map +1 -0
  246. package/dist/server/tool-extra.test.d.ts +1 -0
  247. package/dist/server/tool-extra.test.js +167 -0
  248. package/dist/server/tool-extra.test.js.map +1 -0
  249. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  250. package/dist/server/tunnel-proxy-router.js +110 -0
  251. package/dist/server/tunnel-proxy-router.js.map +1 -0
  252. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  253. package/dist/server/tunnel-proxy-router.test.js +229 -0
  254. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  255. package/dist/server/view-name.test-d.d.ts +1 -0
  256. package/dist/server/view-name.test-d.js +8 -0
  257. package/dist/server/view-name.test-d.js.map +1 -0
  258. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  259. package/dist/server/view-resource-resolution.test.js +176 -0
  260. package/dist/server/view-resource-resolution.test.js.map +1 -0
  261. package/dist/server/viewsDevServer.d.ts +14 -0
  262. package/dist/server/viewsDevServer.js +48 -0
  263. package/dist/server/viewsDevServer.js.map +1 -0
  264. package/dist/test/utils.d.ts +21 -31
  265. package/dist/test/utils.js +222 -198
  266. package/dist/test/utils.js.map +1 -1
  267. package/dist/test/view.test.d.ts +1 -0
  268. package/dist/test/view.test.js +540 -0
  269. package/dist/test/view.test.js.map +1 -0
  270. package/dist/version.d.ts +1 -0
  271. package/dist/version.js +3 -0
  272. package/dist/version.js.map +1 -0
  273. package/dist/views/index.d.ts +10 -0
  274. package/dist/views/index.js +3 -0
  275. package/dist/views/index.js.map +1 -0
  276. package/dist/views/scan-views.d.ts +16 -0
  277. package/dist/views/scan-views.js +88 -0
  278. package/dist/views/scan-views.js.map +1 -0
  279. package/dist/views/scan-views.test.d.ts +1 -0
  280. package/dist/views/scan-views.test.js +99 -0
  281. package/dist/views/scan-views.test.js.map +1 -0
  282. package/dist/views/validate-view.d.ts +1 -0
  283. package/dist/views/validate-view.js +9 -0
  284. package/dist/views/validate-view.js.map +1 -0
  285. package/dist/views/validate-view.test.d.ts +1 -0
  286. package/dist/views/validate-view.test.js +24 -0
  287. package/dist/views/validate-view.test.js.map +1 -0
  288. package/dist/web/bridges/adaptor.d.ts +62 -0
  289. package/dist/web/bridges/adaptor.js +471 -0
  290. package/dist/web/bridges/adaptor.js.map +1 -0
  291. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  292. package/dist/web/bridges/adaptor.test.js +264 -0
  293. package/dist/web/bridges/adaptor.test.js.map +1 -0
  294. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  295. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  296. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  297. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  298. package/dist/web/bridges/apps-sdk/index.js +0 -1
  299. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  300. package/dist/web/bridges/apps-sdk/types.d.ts +18 -6
  301. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  302. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  303. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  304. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  305. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  306. package/dist/web/bridges/get-adaptor.js +9 -7
  307. package/dist/web/bridges/get-adaptor.js.map +1 -1
  308. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  309. package/dist/web/bridges/get-adaptor.test.js +32 -0
  310. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  311. package/dist/web/bridges/index.js.map +1 -1
  312. package/dist/web/bridges/mcp-app/bridge.d.ts +27 -31
  313. package/dist/web/bridges/mcp-app/bridge.js +118 -203
  314. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  315. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  316. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  317. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  318. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  319. package/dist/web/bridges/mcp-app/index.js +0 -1
  320. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  321. package/dist/web/bridges/mcp-app/types.d.ts +19 -2
  322. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  323. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +17 -3
  324. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +14 -2
  325. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  326. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +2 -42
  327. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  328. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  329. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  330. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  331. package/dist/web/bridges/types.d.ts +182 -12
  332. package/dist/web/bridges/types.js +14 -1
  333. package/dist/web/bridges/types.js.map +1 -1
  334. package/dist/web/bridges/types.test.d.ts +1 -0
  335. package/dist/web/bridges/types.test.js +19 -0
  336. package/dist/web/bridges/types.test.js.map +1 -0
  337. package/dist/web/bridges/use-host-context.d.ts +5 -0
  338. package/dist/web/bridges/use-host-context.js +5 -0
  339. package/dist/web/bridges/use-host-context.js.map +1 -1
  340. package/dist/web/components/modal-provider.d.ts +1 -1
  341. package/dist/web/components/modal-provider.js +5 -6
  342. package/dist/web/components/modal-provider.js.map +1 -1
  343. package/dist/web/create-store.d.ts +26 -0
  344. package/dist/web/create-store.js +43 -3
  345. package/dist/web/create-store.js.map +1 -1
  346. package/dist/web/create-store.test.js +27 -24
  347. package/dist/web/create-store.test.js.map +1 -1
  348. package/dist/web/data-llm.d.ts +35 -2
  349. package/dist/web/data-llm.js +34 -5
  350. package/dist/web/data-llm.js.map +1 -1
  351. package/dist/web/data-llm.test.js +49 -29
  352. package/dist/web/data-llm.test.js.map +1 -1
  353. package/dist/web/generate-helpers.d.ts +40 -32
  354. package/dist/web/generate-helpers.js +38 -30
  355. package/dist/web/generate-helpers.js.map +1 -1
  356. package/dist/web/generate-helpers.test-d.js +33 -31
  357. package/dist/web/generate-helpers.test-d.js.map +1 -1
  358. package/dist/web/generate-helpers.test.js +2 -2
  359. package/dist/web/generate-helpers.test.js.map +1 -1
  360. package/dist/web/helpers/state.d.ts +2 -2
  361. package/dist/web/helpers/state.js +11 -11
  362. package/dist/web/helpers/state.js.map +1 -1
  363. package/dist/web/helpers/state.test.js +9 -9
  364. package/dist/web/helpers/state.test.js.map +1 -1
  365. package/dist/web/hooks/index.d.ts +11 -2
  366. package/dist/web/hooks/index.js +11 -2
  367. package/dist/web/hooks/index.js.map +1 -1
  368. package/dist/web/hooks/openai-extensions.test.d.ts +1 -0
  369. package/dist/web/hooks/openai-extensions.test.js +107 -0
  370. package/dist/web/hooks/openai-extensions.test.js.map +1 -0
  371. package/dist/web/hooks/test/utils.d.ts +7 -2
  372. package/dist/web/hooks/test/utils.js +18 -3
  373. package/dist/web/hooks/test/utils.js.map +1 -1
  374. package/dist/web/hooks/use-call-tool.d.ts +47 -2
  375. package/dist/web/hooks/use-call-tool.js +43 -10
  376. package/dist/web/hooks/use-call-tool.js.map +1 -1
  377. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  378. package/dist/web/hooks/use-call-tool.test.js +75 -29
  379. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  380. package/dist/web/hooks/use-deep-link.d.ts +22 -0
  381. package/dist/web/hooks/use-deep-link.js +34 -0
  382. package/dist/web/hooks/use-deep-link.js.map +1 -0
  383. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  384. package/dist/web/hooks/use-display-mode.js +20 -0
  385. package/dist/web/hooks/use-display-mode.js.map +1 -1
  386. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  387. package/dist/web/hooks/use-display-mode.test.js +57 -21
  388. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  389. package/dist/web/hooks/use-download.d.ts +3 -0
  390. package/dist/web/hooks/use-download.js +7 -0
  391. package/dist/web/hooks/use-download.js.map +1 -0
  392. package/dist/web/hooks/use-download.test.d.ts +1 -0
  393. package/dist/web/hooks/use-download.test.js +103 -0
  394. package/dist/web/hooks/use-download.test.js.map +1 -0
  395. package/dist/web/hooks/use-file-resource.d.ts +37 -0
  396. package/dist/web/hooks/use-file-resource.js +98 -0
  397. package/dist/web/hooks/use-file-resource.js.map +1 -0
  398. package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
  399. package/dist/web/hooks/use-file-resource.test.js +65 -0
  400. package/dist/web/hooks/use-file-resource.test.js.map +1 -0
  401. package/dist/web/hooks/use-files.d.ts +34 -1
  402. package/dist/web/hooks/use-files.js +33 -0
  403. package/dist/web/hooks/use-files.js.map +1 -1
  404. package/dist/web/hooks/use-files.test.js +31 -3
  405. package/dist/web/hooks/use-files.test.js.map +1 -1
  406. package/dist/web/hooks/use-host.d.ts +44 -0
  407. package/dist/web/hooks/use-host.js +45 -0
  408. package/dist/web/hooks/use-host.js.map +1 -0
  409. package/dist/web/hooks/use-host.test.d.ts +1 -0
  410. package/dist/web/hooks/use-host.test.js +59 -0
  411. package/dist/web/hooks/use-host.test.js.map +1 -0
  412. package/dist/web/hooks/use-model-context.d.ts +44 -0
  413. package/dist/web/hooks/use-model-context.js +63 -0
  414. package/dist/web/hooks/use-model-context.js.map +1 -0
  415. package/dist/web/hooks/use-open-external.d.ts +17 -0
  416. package/dist/web/hooks/use-open-external.js +16 -0
  417. package/dist/web/hooks/use-open-external.js.map +1 -1
  418. package/dist/web/hooks/use-open-external.test.js +30 -15
  419. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  420. package/dist/web/hooks/use-open-file.d.ts +20 -0
  421. package/dist/web/hooks/use-open-file.js +25 -0
  422. package/dist/web/hooks/use-open-file.js.map +1 -0
  423. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  424. package/dist/web/hooks/use-register-view-tool.js +50 -0
  425. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  426. package/dist/web/hooks/use-request-close.d.ts +16 -0
  427. package/dist/web/hooks/use-request-close.js +21 -0
  428. package/dist/web/hooks/use-request-close.js.map +1 -0
  429. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  430. package/dist/web/hooks/use-request-close.test.js +47 -0
  431. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  432. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  433. package/dist/web/hooks/use-request-modal.js +19 -4
  434. package/dist/web/hooks/use-request-modal.js.map +1 -1
  435. package/dist/web/hooks/use-request-modal.test.js +16 -2
  436. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  437. package/dist/web/hooks/use-request-size.d.ts +20 -0
  438. package/dist/web/hooks/use-request-size.js +24 -0
  439. package/dist/web/hooks/use-request-size.js.map +1 -0
  440. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  441. package/dist/web/hooks/use-request-size.test.js +47 -0
  442. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  443. package/dist/web/hooks/use-send-follow-up-message.d.ts +25 -1
  444. package/dist/web/hooks/use-send-follow-up-message.js +25 -2
  445. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  446. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  447. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  448. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  449. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  450. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  451. package/dist/web/hooks/use-tool-info.d.ts +46 -14
  452. package/dist/web/hooks/use-tool-info.js +29 -7
  453. package/dist/web/hooks/use-tool-info.js.map +1 -1
  454. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  455. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  456. package/dist/web/hooks/use-tool-info.test.js +43 -38
  457. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  458. package/dist/web/hooks/use-user.d.ts +5 -2
  459. package/dist/web/hooks/use-user.js +23 -4
  460. package/dist/web/hooks/use-user.js.map +1 -1
  461. package/dist/web/hooks/use-user.test.js +105 -29
  462. package/dist/web/hooks/use-user.test.js.map +1 -1
  463. package/dist/web/hooks/use-view-state.d.ts +25 -0
  464. package/dist/web/hooks/use-view-state.js +42 -0
  465. package/dist/web/hooks/use-view-state.js.map +1 -0
  466. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  467. package/dist/web/hooks/use-view-state.test.js +212 -0
  468. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  469. package/dist/web/hooks/use-viewport.d.ts +20 -0
  470. package/dist/web/hooks/use-viewport.js +21 -0
  471. package/dist/web/hooks/use-viewport.js.map +1 -0
  472. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  473. package/dist/web/hooks/use-viewport.test.js +109 -0
  474. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  475. package/dist/web/index.d.ts +1 -2
  476. package/dist/web/index.js +1 -2
  477. package/dist/web/index.js.map +1 -1
  478. package/dist/web/mount-view.d.ts +21 -0
  479. package/dist/web/mount-view.js +43 -0
  480. package/dist/web/mount-view.js.map +1 -0
  481. package/dist/web/proxy.js.map +1 -1
  482. package/dist/web/types.d.ts +4 -0
  483. package/dist/web/types.js.map +1 -1
  484. package/package.json +50 -28
  485. package/tsconfig.base.json +5 -0
  486. package/dist/server/const.d.ts +0 -1
  487. package/dist/server/const.js +0 -2
  488. package/dist/server/const.js.map +0 -1
  489. package/dist/server/templates/development.hbs +0 -67
  490. package/dist/server/templates/production.hbs +0 -6
  491. package/dist/server/widgetsDevServer.d.ts +0 -12
  492. package/dist/server/widgetsDevServer.js +0 -63
  493. package/dist/server/widgetsDevServer.js.map +0 -1
  494. package/dist/test/widget.test.js +0 -261
  495. package/dist/test/widget.test.js.map +0 -1
  496. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -22
  497. package/dist/web/bridges/apps-sdk/adaptor.js +0 -75
  498. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  499. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -36
  500. package/dist/web/bridges/mcp-app/adaptor.js +0 -190
  501. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  502. package/dist/web/hooks/use-layout.d.ts +0 -22
  503. package/dist/web/hooks/use-layout.js +0 -23
  504. package/dist/web/hooks/use-layout.js.map +0 -1
  505. package/dist/web/hooks/use-layout.test.js +0 -96
  506. package/dist/web/hooks/use-layout.test.js.map +0 -1
  507. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  508. package/dist/web/hooks/use-widget-state.js +0 -32
  509. package/dist/web/hooks/use-widget-state.js.map +0 -1
  510. package/dist/web/hooks/use-widget-state.test.js +0 -64
  511. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  512. package/dist/web/mount-widget.d.ts +0 -1
  513. package/dist/web/mount-widget.js +0 -27
  514. package/dist/web/mount-widget.js.map +0 -1
  515. package/dist/web/plugin/data-llm.test.js +0 -81
  516. package/dist/web/plugin/data-llm.test.js.map +0 -1
  517. package/dist/web/plugin/plugin.d.ts +0 -2
  518. package/dist/web/plugin/plugin.js +0 -54
  519. package/dist/web/plugin/plugin.js.map +0 -1
  520. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  521. package/dist/web/plugin/transform-data-llm.js +0 -96
  522. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  523. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  524. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  525. package/dist/web/plugin/validate-widget.d.ts +0 -5
  526. package/dist/web/plugin/validate-widget.js +0 -27
  527. package/dist/web/plugin/validate-widget.js.map +0 -1
  528. package/dist/web/plugin/validate-widget.test.js +0 -42
  529. package/dist/web/plugin/validate-widget.test.js.map +0 -1
  530. /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  531. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  532. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  533. /package/dist/{web/plugin/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  534. /package/dist/{web/plugin/transform-data-llm.test.d.ts → cli/tunnel.test.d.ts} +0 -0
  535. /package/dist/{web/plugin/validate-widget.test.d.ts → context-warnings.test.d.ts} +0 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Returns a base64-encoded string.
3
+ * - `Uint8Array` input is encoded via `Buffer.toString("base64")`.
4
+ * - `string` input is assumed to be **already base64-encoded** and is returned
5
+ * as-is. Passing raw/unencoded string bytes will produce invalid MCP content.
6
+ */
7
+ function toBase64(data) {
8
+ if (typeof data === "string") {
9
+ return data;
10
+ }
11
+ return Buffer.from(data).toString("base64");
12
+ }
13
+ /**
14
+ * Build an MCP text content block.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * return { content: [text("Found 3 results.")] };
19
+ * ```
20
+ */
21
+ export function text(value, annotations) {
22
+ return { type: "text", text: value, ...(annotations && { annotations }) };
23
+ }
24
+ /**
25
+ * Build an MCP image content block.
26
+ *
27
+ * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is
28
+ * **already base64-encoded**. Passing a raw byte-string will produce invalid
29
+ * content.
30
+ */
31
+ export function image(data, mimeType, annotations) {
32
+ return {
33
+ type: "image",
34
+ data: toBase64(data),
35
+ mimeType,
36
+ ...(annotations && { annotations }),
37
+ };
38
+ }
39
+ /**
40
+ * Build an MCP audio content block.
41
+ *
42
+ * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is
43
+ * **already base64-encoded**.
44
+ */
45
+ export function audio(data, mimeType, annotations) {
46
+ return {
47
+ type: "audio",
48
+ data: toBase64(data),
49
+ mimeType,
50
+ ...(annotations && { annotations }),
51
+ };
52
+ }
53
+ /**
54
+ * Build an MCP embedded resource — the full content travels inline. Use this
55
+ * when the client needs the bytes themselves rather than a link.
56
+ *
57
+ * Pass either `text` (UTF-8 string) or `blob` (base64-encoded bytes).
58
+ */
59
+ export function embeddedResource(resource, annotations) {
60
+ return {
61
+ type: "resource",
62
+ resource,
63
+ ...(annotations && { annotations }),
64
+ };
65
+ }
66
+ /**
67
+ * Build an MCP resource link — a `type: "resource_link"` block carrying a URI
68
+ * the client can fetch (or subscribe to) on demand. Use a link when the
69
+ * client should retrieve the bytes itself; use {@link embeddedResource} when
70
+ * the content must travel inline with the response.
71
+ */
72
+ export function resourceLink(link, annotations) {
73
+ return {
74
+ type: "resource_link",
75
+ ...link,
76
+ ...(annotations && { annotations }),
77
+ };
78
+ }
79
+ //# sourceMappingURL=content-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-helpers.js","sourceRoot":"","sources":["../../src/server/content-helpers.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAyB;IACzC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,IAAI,CAClB,KAAa,EACb,WAAgC;IAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CACnB,IAAyB,EACzB,QAAgB,EAChB,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;QACpB,QAAQ;QACR,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CACnB,IAAyB,EACzB,QAAgB,EAChB,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;QACpB,QAAQ;QACR,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAEoD,EACpD,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ;QACR,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,IAOC,EACD,WAAgC;IAEhC,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,GAAG,IAAI;QACP,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,CAAC;KACpC,CAAC;AACJ,CAAC","sourcesContent":["import type {\n AudioContent,\n EmbeddedResource,\n ImageContent,\n ResourceLink,\n TextContent,\n} from \"@modelcontextprotocol/server\";\n\n/**\n * MCP content annotations applied to any returned block.\n *\n * - `audience` — who is meant to see the content (`\"user\"`, `\"assistant\"`, or both).\n * - `priority` — relative importance hint for the host.\n * - `lastModified` — ISO timestamp for when the content was produced.\n */\ntype ContentAnnotations = {\n audience?: (\"user\" | \"assistant\")[];\n priority?: number;\n lastModified?: string;\n};\n\n/**\n * Returns a base64-encoded string.\n * - `Uint8Array` input is encoded via `Buffer.toString(\"base64\")`.\n * - `string` input is assumed to be **already base64-encoded** and is returned\n * as-is. Passing raw/unencoded string bytes will produce invalid MCP content.\n */\nfunction toBase64(data: string | Uint8Array): string {\n if (typeof data === \"string\") {\n return data;\n }\n return Buffer.from(data).toString(\"base64\");\n}\n\n/**\n * Build an MCP text content block.\n *\n * @example\n * ```ts\n * return { content: [text(\"Found 3 results.\")] };\n * ```\n */\nexport function text(\n value: string,\n annotations?: ContentAnnotations,\n): TextContent {\n return { type: \"text\", text: value, ...(annotations && { annotations }) };\n}\n\n/**\n * Build an MCP image content block.\n *\n * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is\n * **already base64-encoded**. Passing a raw byte-string will produce invalid\n * content.\n */\nexport function image(\n data: string | Uint8Array,\n mimeType: string,\n annotations?: ContentAnnotations,\n): ImageContent {\n return {\n type: \"image\",\n data: toBase64(data),\n mimeType,\n ...(annotations && { annotations }),\n };\n}\n\n/**\n * Build an MCP audio content block.\n *\n * `data` may be a `Uint8Array` (encoded to base64 for you) or a string that is\n * **already base64-encoded**.\n */\nexport function audio(\n data: string | Uint8Array,\n mimeType: string,\n annotations?: ContentAnnotations,\n): AudioContent {\n return {\n type: \"audio\",\n data: toBase64(data),\n mimeType,\n ...(annotations && { annotations }),\n };\n}\n\n/**\n * Build an MCP embedded resource — the full content travels inline. Use this\n * when the client needs the bytes themselves rather than a link.\n *\n * Pass either `text` (UTF-8 string) or `blob` (base64-encoded bytes).\n */\nexport function embeddedResource(\n resource:\n | { uri: string; mimeType?: string; text: string }\n | { uri: string; mimeType?: string; blob: string },\n annotations?: ContentAnnotations,\n): EmbeddedResource {\n return {\n type: \"resource\",\n resource,\n ...(annotations && { annotations }),\n };\n}\n\n/**\n * Build an MCP resource link — a `type: \"resource_link\"` block carrying a URI\n * the client can fetch (or subscribe to) on demand. Use a link when the\n * client should retrieve the bytes itself; use {@link embeddedResource} when\n * the content must travel inline with the response.\n */\nexport function resourceLink(\n link: {\n uri: string;\n name: string;\n title?: string;\n description?: string;\n mimeType?: string;\n size?: number;\n },\n annotations?: ContentAnnotations,\n): ResourceLink {\n return {\n type: \"resource_link\",\n ...link,\n ...(annotations && { annotations }),\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,70 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { audio, embeddedResource, image, resourceLink, text, } from "./content-helpers.js";
3
+ describe("text", () => {
4
+ it("returns a TextContent without annotations when none given", () => {
5
+ expect(text("hello")).toEqual({ type: "text", text: "hello" });
6
+ });
7
+ it("includes annotations when provided", () => {
8
+ expect(text("hi", { priority: 1 })).toEqual({
9
+ type: "text",
10
+ text: "hi",
11
+ annotations: { priority: 1 },
12
+ });
13
+ });
14
+ });
15
+ describe("image", () => {
16
+ it("base64-encodes Uint8Array data", () => {
17
+ const bytes = new Uint8Array([104, 105]);
18
+ expect(image(bytes, "image/png")).toEqual({
19
+ type: "image",
20
+ data: "aGk=",
21
+ mimeType: "image/png",
22
+ });
23
+ });
24
+ it("passes string data through unchanged (caller is responsible for base64)", () => {
25
+ expect(image("YWxyZWFkeS1iNjQ=", "image/png")).toEqual({
26
+ type: "image",
27
+ data: "YWxyZWFkeS1iNjQ=",
28
+ mimeType: "image/png",
29
+ });
30
+ });
31
+ });
32
+ describe("audio", () => {
33
+ it("base64-encodes Uint8Array data", () => {
34
+ const bytes = new Uint8Array([104, 105]);
35
+ expect(audio(bytes, "audio/mpeg")).toMatchObject({
36
+ type: "audio",
37
+ data: "aGk=",
38
+ mimeType: "audio/mpeg",
39
+ });
40
+ });
41
+ });
42
+ describe("embeddedResource", () => {
43
+ it("wraps a text resource with a type tag", () => {
44
+ expect(embeddedResource({
45
+ uri: "file:///a.txt",
46
+ mimeType: "text/plain",
47
+ text: "x",
48
+ })).toEqual({
49
+ type: "resource",
50
+ resource: { uri: "file:///a.txt", mimeType: "text/plain", text: "x" },
51
+ });
52
+ });
53
+ it("wraps a blob resource with a type tag", () => {
54
+ expect(embeddedResource({ uri: "file:///a.bin", blob: "YmFy" })).toEqual({
55
+ type: "resource",
56
+ resource: { uri: "file:///a.bin", blob: "YmFy" },
57
+ });
58
+ });
59
+ });
60
+ describe("resourceLink", () => {
61
+ it("spreads link fields alongside the type tag", () => {
62
+ expect(resourceLink({ uri: "file:///a", name: "a", title: "A" })).toEqual({
63
+ type: "resource_link",
64
+ uri: "file:///a",
65
+ name: "a",
66
+ title: "A",
67
+ });
68
+ });
69
+ });
70
+ //# sourceMappingURL=content-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-helpers.test.js","sourceRoot":"","sources":["../../src/server/content-helpers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,IAAI,GACL,MAAM,sBAAsB,CAAC;AAE9B,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1C,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,IAAI;YACV,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;SAC7B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;YACxC,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;YACrD,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,kBAAkB;YACxB,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;YAC/C,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,YAAY;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CACJ,gBAAgB,CAAC;YACf,GAAG,EAAE,eAAe;YACpB,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,GAAG;SACV,CAAC,CACH,CAAC,OAAO,CAAC;YACR,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE;SACtE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YACvE,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE;SACjD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YACxE,IAAI,EAAE,eAAe;YACrB,GAAG,EAAE,WAAW;YAChB,IAAI,EAAE,GAAG;YACT,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport {\n audio,\n embeddedResource,\n image,\n resourceLink,\n text,\n} from \"./content-helpers.js\";\n\ndescribe(\"text\", () => {\n it(\"returns a TextContent without annotations when none given\", () => {\n expect(text(\"hello\")).toEqual({ type: \"text\", text: \"hello\" });\n });\n\n it(\"includes annotations when provided\", () => {\n expect(text(\"hi\", { priority: 1 })).toEqual({\n type: \"text\",\n text: \"hi\",\n annotations: { priority: 1 },\n });\n });\n});\n\ndescribe(\"image\", () => {\n it(\"base64-encodes Uint8Array data\", () => {\n const bytes = new Uint8Array([104, 105]);\n expect(image(bytes, \"image/png\")).toEqual({\n type: \"image\",\n data: \"aGk=\",\n mimeType: \"image/png\",\n });\n });\n\n it(\"passes string data through unchanged (caller is responsible for base64)\", () => {\n expect(image(\"YWxyZWFkeS1iNjQ=\", \"image/png\")).toEqual({\n type: \"image\",\n data: \"YWxyZWFkeS1iNjQ=\",\n mimeType: \"image/png\",\n });\n });\n});\n\ndescribe(\"audio\", () => {\n it(\"base64-encodes Uint8Array data\", () => {\n const bytes = new Uint8Array([104, 105]);\n expect(audio(bytes, \"audio/mpeg\")).toMatchObject({\n type: \"audio\",\n data: \"aGk=\",\n mimeType: \"audio/mpeg\",\n });\n });\n});\n\ndescribe(\"embeddedResource\", () => {\n it(\"wraps a text resource with a type tag\", () => {\n expect(\n embeddedResource({\n uri: \"file:///a.txt\",\n mimeType: \"text/plain\",\n text: \"x\",\n }),\n ).toEqual({\n type: \"resource\",\n resource: { uri: \"file:///a.txt\", mimeType: \"text/plain\", text: \"x\" },\n });\n });\n\n it(\"wraps a blob resource with a type tag\", () => {\n expect(embeddedResource({ uri: \"file:///a.bin\", blob: \"YmFy\" })).toEqual({\n type: \"resource\",\n resource: { uri: \"file:///a.bin\", blob: \"YmFy\" },\n });\n });\n});\n\ndescribe(\"resourceLink\", () => {\n it(\"spreads link fields alongside the type tag\", () => {\n expect(resourceLink({ uri: \"file:///a\", name: \"a\", title: \"A\" })).toEqual({\n type: \"resource_link\",\n uri: \"file:///a\",\n name: \"a\",\n title: \"A\",\n });\n });\n});\n"]}
@@ -0,0 +1,113 @@
1
+ import { type McpServer as SdkMcpServer, type StandardSchemaV1, type StandardSchemaWithJSON } from "@modelcontextprotocol/server";
2
+ /**
3
+ * A webhook subscription, as passed to `onSubscribe`. Whatever delivers the
4
+ * events POSTs them to `url`, signed with `secret`, until `expiresAt`.
5
+ */
6
+ export interface EventSubscription {
7
+ /** Stable across refreshes: the same user subscribing to the same event with the same arguments and callback gets the same `id`. */
8
+ id: string;
9
+ /** Callback URL deliveries are POSTed to. */
10
+ url: string;
11
+ /** Standard Webhooks signing secret (`whsec_…`). A refresh may carry a new one. */
12
+ secret: string;
13
+ /** When the subscription lapses unless the host refreshes it. */
14
+ expiresAt: Date;
15
+ }
16
+ /** An event occurrence, as passed to {@link deliverEvent}. */
17
+ export interface EventOccurrence {
18
+ /** Event type name, as registered with `registerEvent`. */
19
+ name: string;
20
+ /** Stable identifier the host uses to drop duplicates, ideally the upstream's. Reuse it when retrying. */
21
+ id: string;
22
+ /** When the event happened. Defaults to now. */
23
+ timestamp?: Date;
24
+ /** Payload matching the event's `payloadSchema`. */
25
+ data: unknown;
26
+ }
27
+ /** Outcome of {@link deliverEvent}. Retry with the same event `id` when `retryable`. */
28
+ export type DeliveryResult = {
29
+ ok: true;
30
+ } | {
31
+ ok: false;
32
+ reason: string;
33
+ retryable: boolean;
34
+ status?: number;
35
+ };
36
+ type EventSchema = Record<string, StandardSchemaWithJSON> | StandardSchemaWithJSON;
37
+ export type InferEventSchema<T extends EventSchema> = T extends StandardSchemaWithJSON ? StandardSchemaV1.InferOutput<T> : T extends Record<string, StandardSchemaWithJSON> ? {
38
+ [K in keyof T as undefined extends StandardSchemaV1.InferOutput<T[K]> ? never : K]: StandardSchemaV1.InferOutput<T[K]>;
39
+ } & {
40
+ [K in keyof T as undefined extends StandardSchemaV1.InferOutput<T[K]> ? K : never]?: StandardSchemaV1.InferOutput<T[K]>;
41
+ } : never;
42
+ /** The `registerEvent` config: how the event type is described in `events/list`. */
43
+ export interface EventConfig<TInput extends EventSchema> {
44
+ /** Stable, specific name such as `comment.created`. */
45
+ name: string;
46
+ /** What the event is and when it fires. */
47
+ description?: string;
48
+ /** Subscription arguments (filters): a Zod shape or a Standard Schema object. */
49
+ inputSchema?: TInput;
50
+ /** Shape of the delivered `data`: a Zod shape or a Standard Schema object. */
51
+ payloadSchema: EventSchema;
52
+ _meta?: Record<string, unknown>;
53
+ }
54
+ /** What `registerEvent` does when the host subscribes and unsubscribes. */
55
+ export interface EventHooks<TArguments, TExtra> {
56
+ /**
57
+ * Runs on every `events/subscribe`, including the host's refreshes, once
58
+ * the callback URL is verified. Hand the subscription to whatever delivers
59
+ * the events, keyed by `subscription.id`. Throw (e.g. a `ProtocolError`) to
60
+ * reject it, for instance when the user may not access what the arguments
61
+ * point to.
62
+ */
63
+ onSubscribe(args: TArguments, context: {
64
+ subscription: EventSubscription;
65
+ extra: TExtra;
66
+ }): void | Promise<void>;
67
+ /** Runs on `events/unsubscribe`. Stop delivering to `subscription.id`. */
68
+ onUnsubscribe(args: TArguments, context: {
69
+ subscription: Pick<EventSubscription, "id">;
70
+ extra: TExtra;
71
+ }): void | Promise<void>;
72
+ }
73
+ /**
74
+ * @experimental POST one event to a subscription handed out by `onSubscribe`,
75
+ * as MCP Events expects: the event envelope, Standard Webhooks signature
76
+ * headers, a 10 second deadline and, outside development, no requests to
77
+ * private addresses. Pass the old and new secrets during a rotation so both
78
+ * sign the delivery. A subscription past `expiresAt` is not posted to.
79
+ * Retrying is up to the caller. API may change.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * const result = await deliverEvent(subscription, {
84
+ * name: "comment.created",
85
+ * id: comment.id,
86
+ * data: { documentId: comment.documentId, excerpt: comment.text.slice(0, 280) },
87
+ * });
88
+ * if (!result.ok && result.retryable) {
89
+ * await queue.retryLater(subscription, comment);
90
+ * }
91
+ * ```
92
+ *
93
+ * @see https://docs.skybridge.tech/api-reference/register-event
94
+ */
95
+ export declare function deliverEvent(subscription: Pick<EventSubscription, "id" | "url"> & {
96
+ secret: string | string[];
97
+ expiresAt: Date | string;
98
+ }, event: EventOccurrence): Promise<DeliveryResult>;
99
+ /**
100
+ * The event types registered on one server, and the `events/*` handlers that
101
+ * serve them.
102
+ *
103
+ * @internal
104
+ */
105
+ export declare class EventRegistry {
106
+ private readonly server;
107
+ private readonly events;
108
+ constructor(server: Pick<SdkMcpServer["server"], "setRequestHandler">);
109
+ add(config: EventConfig<EventSchema>, hooks: EventHooks<never, never>): void;
110
+ private install;
111
+ private resolve;
112
+ }
113
+ export {};
@@ -0,0 +1,318 @@
1
+ import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
2
+ import http from "node:http";
3
+ import https from "node:https";
4
+ import { INVALID_PARAMS, ProtocolError, } from "@modelcontextprotocol/server";
5
+ import { globalHttpAgent, globalHttpsAgent } from "request-filtering-agent";
6
+ import { Webhook } from "standardwebhooks";
7
+ import { z } from "zod/v4";
8
+ const EVENTS_ERROR = {
9
+ NotFound: -32011,
10
+ Forbidden: -32012,
11
+ Unsupported: -32014,
12
+ CallbackEndpointError: -32015,
13
+ };
14
+ const MAX_PAYLOAD_BYTES = 256 * 1024;
15
+ const DELIVERY_TIMEOUT_MS = 10_000;
16
+ const VERIFICATION_CACHE_MS = 60 * 60_000;
17
+ const MIN_TTL_MS = 60_000;
18
+ const DEFAULT_TTL_MS = 30 * 60_000;
19
+ const MAX_TTL_MS = 24 * 60 * 60_000;
20
+ function toStandardSchema(schema) {
21
+ return "~standard" in schema
22
+ ? schema
23
+ : z.object(schema);
24
+ }
25
+ async function validate(schema, value) {
26
+ const result = await schema["~standard"].validate(value);
27
+ if (result.issues) {
28
+ throw new ProtocolError(INVALID_PARAMS, `Invalid arguments: ${result.issues.map((issue) => issue.message).join(", ")}`);
29
+ }
30
+ return result.value;
31
+ }
32
+ function canonicalJson(value) {
33
+ if (Array.isArray(value)) {
34
+ return `[${value.map(canonicalJson).join(",")}]`;
35
+ }
36
+ if (value && typeof value === "object") {
37
+ return `{${Object.keys(value)
38
+ .sort()
39
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
40
+ .join(",")}}`;
41
+ }
42
+ return JSON.stringify(value);
43
+ }
44
+ function subscriberOf(ctx) {
45
+ const authInfo = ctx.http?.authInfo;
46
+ const subject = authInfo?.extra?.subject;
47
+ const subscriber = typeof subject === "string" ? subject : authInfo?.clientId;
48
+ if (!subscriber) {
49
+ throw new ProtocolError(EVENTS_ERROR.Forbidden, "Webhook subscriptions require an authenticated caller");
50
+ }
51
+ return subscriber;
52
+ }
53
+ function isValidSecret(secret) {
54
+ const encoded = secret.startsWith("whsec_") ? secret.slice(6) : "";
55
+ if (!/^[A-Za-z0-9+/]+={0,2}$/.test(encoded)) {
56
+ return false;
57
+ }
58
+ const length = Buffer.from(encoded, "base64").length;
59
+ return length >= 24 && length <= 64;
60
+ }
61
+ const insecureCallbacksAllowed = () => process.env.NODE_ENV !== "production";
62
+ function checkCallbackUrl(raw) {
63
+ let url;
64
+ try {
65
+ url = new URL(raw);
66
+ }
67
+ catch {
68
+ throw new ProtocolError(INVALID_PARAMS, "delivery.url is not a valid URL");
69
+ }
70
+ const allowed = url.protocol === "https:" ||
71
+ (url.protocol === "http:" && insecureCallbacksAllowed());
72
+ if (!allowed) {
73
+ throw new ProtocolError(INVALID_PARAMS, "delivery.url must use https");
74
+ }
75
+ return url.href;
76
+ }
77
+ function post(url, headers, body) {
78
+ const signal = AbortSignal.timeout(DELIVERY_TIMEOUT_MS);
79
+ const failure = (error) => ({
80
+ ok: false,
81
+ reason: signal.aborted
82
+ ? "timeout"
83
+ : error?.code?.startsWith("ERR_TLS") || error?.code?.includes("CERT")
84
+ ? "tls_error"
85
+ : "connection_refused",
86
+ });
87
+ const [client, agent] = url.startsWith("https:")
88
+ ? [https, globalHttpsAgent]
89
+ : [http, globalHttpAgent];
90
+ return new Promise((resolve) => {
91
+ const request = client.request(url, {
92
+ method: "POST",
93
+ headers: { ...headers, "content-length": Buffer.byteLength(body) },
94
+ signal,
95
+ ...(!insecureCallbacksAllowed() && { agent }),
96
+ }, (response) => {
97
+ const status = response.statusCode ?? 0;
98
+ const chunks = [];
99
+ let size = 0;
100
+ response.on("data", (chunk) => {
101
+ size += chunk.length;
102
+ if (size <= 64 * 1024) {
103
+ chunks.push(chunk);
104
+ }
105
+ });
106
+ response.on("end", () => {
107
+ if (status >= 200 && status < 300) {
108
+ resolve({ ok: true, body: Buffer.concat(chunks).toString() });
109
+ }
110
+ else {
111
+ resolve({
112
+ ok: false,
113
+ status,
114
+ reason: status >= 500 ? "http_5xx" : "http_4xx",
115
+ });
116
+ }
117
+ });
118
+ response.on("error", (error) => resolve(failure(error)));
119
+ response.on("close", () => resolve(failure()));
120
+ });
121
+ request.on("error", (error) => resolve(failure(error)));
122
+ request.end(body);
123
+ });
124
+ }
125
+ function signedPost(subscription, messageId, body) {
126
+ const signedAt = new Date();
127
+ const secrets = [subscription.secret].flat();
128
+ return post(subscription.url, {
129
+ "content-type": "application/json",
130
+ "webhook-id": messageId,
131
+ "webhook-timestamp": String(Math.floor(signedAt.getTime() / 1000)),
132
+ "webhook-signature": secrets
133
+ .map((secret) => new Webhook(secret).sign(messageId, signedAt, body))
134
+ .join(" "),
135
+ "x-mcp-subscription-id": subscription.id,
136
+ }, body);
137
+ }
138
+ /**
139
+ * @experimental POST one event to a subscription handed out by `onSubscribe`,
140
+ * as MCP Events expects: the event envelope, Standard Webhooks signature
141
+ * headers, a 10 second deadline and, outside development, no requests to
142
+ * private addresses. Pass the old and new secrets during a rotation so both
143
+ * sign the delivery. A subscription past `expiresAt` is not posted to.
144
+ * Retrying is up to the caller. API may change.
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const result = await deliverEvent(subscription, {
149
+ * name: "comment.created",
150
+ * id: comment.id,
151
+ * data: { documentId: comment.documentId, excerpt: comment.text.slice(0, 280) },
152
+ * });
153
+ * if (!result.ok && result.retryable) {
154
+ * await queue.retryLater(subscription, comment);
155
+ * }
156
+ * ```
157
+ *
158
+ * @see https://docs.skybridge.tech/api-reference/register-event
159
+ */
160
+ export async function deliverEvent(subscription, event) {
161
+ if (!(new Date(subscription.expiresAt).getTime() > Date.now())) {
162
+ return { ok: false, reason: "expired", retryable: false };
163
+ }
164
+ const body = JSON.stringify({
165
+ eventId: event.id,
166
+ name: event.name,
167
+ timestamp: (event.timestamp ?? new Date()).toISOString(),
168
+ data: event.data,
169
+ cursor: null,
170
+ });
171
+ if (Buffer.byteLength(body) > MAX_PAYLOAD_BYTES) {
172
+ throw new Error(`Event "${event.name}" payload exceeds ${MAX_PAYLOAD_BYTES} bytes; send a summary and expose a tool to fetch the rest.`);
173
+ }
174
+ const outcome = await signedPost(subscription, event.id, body);
175
+ if (outcome.ok) {
176
+ return { ok: true };
177
+ }
178
+ const status = outcome.status ?? 0;
179
+ return {
180
+ ...outcome,
181
+ retryable: status !== 410 && status !== 413 && (status < 300 || status >= 400),
182
+ };
183
+ }
184
+ const verifiedCallbacks = new Map();
185
+ async function verifyCallback(subscriber, subscription) {
186
+ const key = `${subscriber}\n${subscription.url}`;
187
+ const now = Date.now();
188
+ if ((verifiedCallbacks.get(key) ?? 0) > now) {
189
+ return;
190
+ }
191
+ const challenge = randomBytes(24).toString("base64url");
192
+ const outcome = await signedPost(subscription, `msg_verification_${randomBytes(12).toString("hex")}`, JSON.stringify({ type: "verification", challenge }));
193
+ let echoed;
194
+ if (outcome.ok) {
195
+ try {
196
+ echoed = JSON.parse(outcome.body)?.challenge;
197
+ }
198
+ catch { }
199
+ }
200
+ const matched = typeof echoed === "string" &&
201
+ echoed.length === challenge.length &&
202
+ timingSafeEqual(Buffer.from(echoed), Buffer.from(challenge));
203
+ if (!matched) {
204
+ throw new ProtocolError(EVENTS_ERROR.CallbackEndpointError, "Callback endpoint verification failed", { reason: outcome.ok ? "challenge_failed" : outcome.reason });
205
+ }
206
+ for (const [cached, until] of verifiedCallbacks) {
207
+ if (until <= now) {
208
+ verifiedCallbacks.delete(cached);
209
+ }
210
+ }
211
+ verifiedCallbacks.set(key, now + VERIFICATION_CACHE_MS);
212
+ }
213
+ const SubscriptionKeySchema = z.object({
214
+ name: z.string(),
215
+ arguments: z.record(z.string(), z.unknown()).optional(),
216
+ delivery: z.object({ url: z.string() }),
217
+ });
218
+ const SubscribeParamsSchema = SubscriptionKeySchema.extend({
219
+ delivery: z.object({
220
+ mode: z.string().optional(),
221
+ url: z.string(),
222
+ secret: z.string(),
223
+ }),
224
+ cursor: z.string().nullable().optional(),
225
+ ttlMs: z.number().nullable().optional(),
226
+ });
227
+ /**
228
+ * The event types registered on one server, and the `events/*` handlers that
229
+ * serve them.
230
+ *
231
+ * @internal
232
+ */
233
+ export class EventRegistry {
234
+ server;
235
+ events = new Map();
236
+ constructor(server) {
237
+ this.server = server;
238
+ }
239
+ add(config, hooks) {
240
+ if (this.events.has(config.name)) {
241
+ throw new Error(`Event "${config.name}" is already registered.`);
242
+ }
243
+ if (this.events.size === 0) {
244
+ this.install();
245
+ }
246
+ this.events.set(config.name, {
247
+ name: config.name,
248
+ description: config.description,
249
+ inputSchema: toStandardSchema(config.inputSchema ?? {}),
250
+ payloadSchema: toStandardSchema(config.payloadSchema),
251
+ _meta: config._meta,
252
+ hooks,
253
+ });
254
+ }
255
+ install() {
256
+ this.server.setRequestHandler("events/list", { params: z.object({ cursor: z.string().optional() }).optional() }, () => ({
257
+ events: [...this.events.values()].map((event) => ({
258
+ name: event.name,
259
+ ...(event.description && { description: event.description }),
260
+ delivery: ["webhook"],
261
+ inputSchema: event.inputSchema["~standard"].jsonSchema.input({
262
+ target: "draft-2020-12",
263
+ }),
264
+ payloadSchema: event.payloadSchema["~standard"].jsonSchema.output({
265
+ target: "draft-2020-12",
266
+ }),
267
+ ...(event._meta && { _meta: event._meta }),
268
+ })),
269
+ }));
270
+ this.server.setRequestHandler("events/subscribe", { params: SubscribeParamsSchema }, async (params, ctx) => {
271
+ if (params.delivery.mode && params.delivery.mode !== "webhook") {
272
+ throw new ProtocolError(EVENTS_ERROR.Unsupported, `Unsupported delivery mode: ${params.delivery.mode}`, { feature: "deliveryMode", value: params.delivery.mode });
273
+ }
274
+ if (!isValidSecret(params.delivery.secret)) {
275
+ throw new ProtocolError(INVALID_PARAMS, "delivery.secret must be whsec_ followed by base64 of 24 to 64 bytes");
276
+ }
277
+ const { event, subscriber, args, id, url } = await this.resolve(params, ctx);
278
+ const ttl = params.ttlMs === null ? MAX_TTL_MS : (params.ttlMs ?? DEFAULT_TTL_MS);
279
+ const subscription = {
280
+ id,
281
+ url,
282
+ secret: params.delivery.secret,
283
+ expiresAt: new Date(Date.now() + Math.min(Math.max(ttl, MIN_TTL_MS), MAX_TTL_MS)),
284
+ };
285
+ await verifyCallback(subscriber, subscription);
286
+ await event.hooks.onSubscribe(args, { subscription, extra: ctx });
287
+ return {
288
+ id,
289
+ refreshBefore: subscription.expiresAt.toISOString(),
290
+ cursor: null,
291
+ truncated: false,
292
+ };
293
+ });
294
+ this.server.setRequestHandler("events/unsubscribe", { params: SubscriptionKeySchema }, async (params, ctx) => {
295
+ const { event, args, id } = await this.resolve(params, ctx);
296
+ await event.hooks.onUnsubscribe(args, {
297
+ subscription: { id },
298
+ extra: ctx,
299
+ });
300
+ return {};
301
+ });
302
+ }
303
+ async resolve(params, ctx) {
304
+ const event = this.events.get(params.name);
305
+ if (!event) {
306
+ throw new ProtocolError(EVENTS_ERROR.NotFound, `Unknown event: ${params.name}`, { kind: "event" });
307
+ }
308
+ const url = checkCallbackUrl(params.delivery.url);
309
+ const subscriber = subscriberOf(ctx);
310
+ const rawArguments = params.arguments ?? {};
311
+ const args = await validate(event.inputSchema, rawArguments);
312
+ const hash = createHash("sha256")
313
+ .update(canonicalJson([subscriber, url, event.name, rawArguments]))
314
+ .digest("hex");
315
+ return { event, subscriber, args, url, id: `sub_${hash.slice(0, 32)}` };
316
+ }
317
+ }
318
+ //# sourceMappingURL=events.js.map