@tambo-ai/react 0.67.1 → 0.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/README.md +3 -5
  2. package/dist/context-helpers/context-helpers.test.js +16 -4
  3. package/dist/context-helpers/context-helpers.test.js.map +1 -1
  4. package/dist/context-helpers/current-interactables-context-helper.d.ts +2 -2
  5. package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  6. package/dist/context-helpers/current-interactables-context-helper.js +31 -12
  7. package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
  8. package/dist/context-helpers/registry.d.ts +2 -2
  9. package/dist/context-helpers/registry.d.ts.map +1 -1
  10. package/dist/context-helpers/registry.js.map +1 -1
  11. package/dist/context-helpers/types.d.ts +2 -2
  12. package/dist/context-helpers/types.d.ts.map +1 -1
  13. package/dist/context-helpers/types.js.map +1 -1
  14. package/dist/hoc/with-tambo-interactable.d.ts +50 -4
  15. package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
  16. package/dist/hoc/with-tambo-interactable.js +20 -5
  17. package/dist/hoc/with-tambo-interactable.js.map +1 -1
  18. package/dist/hooks/use-component-state.d.ts +3 -8
  19. package/dist/hooks/use-component-state.d.ts.map +1 -1
  20. package/dist/hooks/use-component-state.js +8 -0
  21. package/dist/hooks/use-component-state.js.map +1 -1
  22. package/dist/hooks/use-component-state.test.js +37 -0
  23. package/dist/hooks/use-component-state.test.js.map +1 -1
  24. package/dist/hooks/use-message-images.test.js +174 -37
  25. package/dist/hooks/use-message-images.test.js.map +1 -1
  26. package/dist/hooks/use-tambo-threads.js +1 -1
  27. package/dist/hooks/use-tambo-threads.js.map +1 -1
  28. package/dist/hooks/use-tambo-voice.d.ts +1 -1
  29. package/dist/hooks/use-tambo-voice.js +1 -1
  30. package/dist/hooks/use-tambo-voice.js.map +1 -1
  31. package/dist/hooks/use-tambo-voice.test.d.ts +2 -0
  32. package/dist/hooks/use-tambo-voice.test.d.ts.map +1 -0
  33. package/dist/hooks/use-tambo-voice.test.js +239 -0
  34. package/dist/hooks/use-tambo-voice.test.js.map +1 -0
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/mcp/elicitation.d.ts.map +1 -1
  39. package/dist/mcp/elicitation.js +12 -0
  40. package/dist/mcp/elicitation.js.map +1 -1
  41. package/dist/mcp/elicitation.test.js +8 -1
  42. package/dist/mcp/elicitation.test.js.map +1 -1
  43. package/dist/mcp/mcp-client.d.ts +6 -10
  44. package/dist/mcp/mcp-client.d.ts.map +1 -1
  45. package/dist/mcp/mcp-client.js.map +1 -1
  46. package/dist/mcp/mcp-constants.d.ts +19 -0
  47. package/dist/mcp/mcp-constants.d.ts.map +1 -0
  48. package/dist/mcp/mcp-constants.js +21 -0
  49. package/dist/mcp/mcp-constants.js.map +1 -0
  50. package/dist/mcp/mcp-hooks.d.ts +21 -40
  51. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  52. package/dist/mcp/mcp-hooks.js +130 -39
  53. package/dist/mcp/mcp-hooks.js.map +1 -1
  54. package/dist/mcp/mcp-hooks.test.js +431 -5
  55. package/dist/mcp/mcp-hooks.test.js.map +1 -1
  56. package/dist/mcp/tambo-mcp-provider.d.ts +7 -0
  57. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  58. package/dist/mcp/tambo-mcp-provider.js +205 -155
  59. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  60. package/dist/mcp/tambo-mcp-provider.test.js +37 -0
  61. package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
  62. package/dist/model/component-metadata.d.ts +54 -21
  63. package/dist/model/component-metadata.d.ts.map +1 -1
  64. package/dist/model/component-metadata.js.map +1 -1
  65. package/dist/model/tambo-interactable.d.ts +13 -5
  66. package/dist/model/tambo-interactable.d.ts.map +1 -1
  67. package/dist/model/tambo-interactable.js.map +1 -1
  68. package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
  69. package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
  70. package/dist/providers/__tests__/thread-input-resource-resolution.test.js +592 -0
  71. package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
  72. package/dist/providers/index.d.ts +1 -1
  73. package/dist/providers/index.d.ts.map +1 -1
  74. package/dist/providers/index.js.map +1 -1
  75. package/dist/providers/tambo-client-provider.d.ts +8 -0
  76. package/dist/providers/tambo-client-provider.d.ts.map +1 -1
  77. package/dist/providers/tambo-client-provider.js +10 -11
  78. package/dist/providers/tambo-client-provider.js.map +1 -1
  79. package/dist/providers/tambo-client-provider.test.d.ts +2 -0
  80. package/dist/providers/tambo-client-provider.test.d.ts.map +1 -0
  81. package/dist/providers/tambo-client-provider.test.js +208 -0
  82. package/dist/providers/tambo-client-provider.test.js.map +1 -0
  83. package/dist/providers/tambo-context-attachment-provider.d.ts +34 -92
  84. package/dist/providers/tambo-context-attachment-provider.d.ts.map +1 -1
  85. package/dist/providers/tambo-context-attachment-provider.js +62 -105
  86. package/dist/providers/tambo-context-attachment-provider.js.map +1 -1
  87. package/dist/providers/tambo-context-attachment-provider.test.js +229 -463
  88. package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -1
  89. package/dist/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
  90. package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  91. package/dist/providers/tambo-interactable-provider.d.ts +5 -2
  92. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  93. package/dist/providers/tambo-interactable-provider.js +126 -17
  94. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  95. package/dist/providers/tambo-interactable-provider.test.js +242 -0
  96. package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
  97. package/dist/providers/tambo-interactables-additional-context.test.js +2 -5
  98. package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
  99. package/dist/providers/tambo-provider.d.ts +2 -3
  100. package/dist/providers/tambo-provider.d.ts.map +1 -1
  101. package/dist/providers/tambo-provider.js +6 -5
  102. package/dist/providers/tambo-provider.js.map +1 -1
  103. package/dist/providers/tambo-registry-provider.test.js +16 -0
  104. package/dist/providers/tambo-registry-provider.test.js.map +1 -1
  105. package/dist/providers/tambo-registry-schema-compat.test.js +31 -0
  106. package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
  107. package/dist/providers/tambo-thread-input-provider.d.ts +1 -1
  108. package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
  109. package/dist/providers/tambo-thread-input-provider.js +26 -4
  110. package/dist/providers/tambo-thread-input-provider.js.map +1 -1
  111. package/dist/providers/tambo-thread-provider-initial-messages.test.js +84 -2
  112. package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  113. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  114. package/dist/providers/tambo-thread-provider.js +53 -42
  115. package/dist/providers/tambo-thread-provider.js.map +1 -1
  116. package/dist/providers/tambo-thread-provider.test.js +368 -262
  117. package/dist/providers/tambo-thread-provider.test.js.map +1 -1
  118. package/dist/schema/index.d.ts +1 -1
  119. package/dist/schema/index.d.ts.map +1 -1
  120. package/dist/schema/index.js +2 -1
  121. package/dist/schema/index.js.map +1 -1
  122. package/dist/schema/json-schema.d.ts +7 -0
  123. package/dist/schema/json-schema.d.ts.map +1 -1
  124. package/dist/schema/json-schema.js +40 -29
  125. package/dist/schema/json-schema.js.map +1 -1
  126. package/dist/schema/json-schema.test.d.ts +2 -0
  127. package/dist/schema/json-schema.test.d.ts.map +1 -0
  128. package/dist/schema/json-schema.test.js +204 -0
  129. package/dist/schema/json-schema.test.js.map +1 -0
  130. package/dist/schema/schema.test.js +237 -0
  131. package/dist/schema/schema.test.js.map +1 -1
  132. package/dist/schema/standard-schema.d.ts +1 -0
  133. package/dist/schema/standard-schema.d.ts.map +1 -1
  134. package/dist/schema/standard-schema.js +18 -13
  135. package/dist/schema/standard-schema.js.map +1 -1
  136. package/dist/schema/standard-schema.test.d.ts +2 -0
  137. package/dist/schema/standard-schema.test.d.ts.map +1 -0
  138. package/dist/schema/standard-schema.test.js +165 -0
  139. package/dist/schema/standard-schema.test.js.map +1 -0
  140. package/dist/schema/validate.test.js +149 -0
  141. package/dist/schema/validate.test.js.map +1 -1
  142. package/dist/schema/zod.d.ts +7 -4
  143. package/dist/schema/zod.d.ts.map +1 -1
  144. package/dist/schema/zod.js +65 -22
  145. package/dist/schema/zod.js.map +1 -1
  146. package/dist/schema/zod.test.js +112 -0
  147. package/dist/schema/zod.test.js.map +1 -1
  148. package/dist/setupTests.js +3 -0
  149. package/dist/setupTests.js.map +1 -1
  150. package/dist/testing/tools.d.ts +4 -1
  151. package/dist/testing/tools.d.ts.map +1 -1
  152. package/dist/testing/tools.js +6 -1
  153. package/dist/testing/tools.js.map +1 -1
  154. package/dist/util/generate-component.d.ts.map +1 -1
  155. package/dist/util/generate-component.js +18 -3
  156. package/dist/util/generate-component.js.map +1 -1
  157. package/dist/util/generate-component.test.d.ts +2 -0
  158. package/dist/util/generate-component.test.d.ts.map +1 -0
  159. package/dist/util/generate-component.test.js +340 -0
  160. package/dist/util/generate-component.test.js.map +1 -0
  161. package/dist/util/is-promise.d.ts +9 -0
  162. package/dist/util/is-promise.d.ts.map +1 -0
  163. package/dist/util/is-promise.js +20 -0
  164. package/dist/util/is-promise.js.map +1 -0
  165. package/dist/util/is-promise.test.d.ts +2 -0
  166. package/dist/util/is-promise.test.d.ts.map +1 -0
  167. package/dist/util/is-promise.test.js +48 -0
  168. package/dist/util/is-promise.test.js.map +1 -0
  169. package/dist/util/message-builder.d.ts +3 -1
  170. package/dist/util/message-builder.d.ts.map +1 -1
  171. package/dist/util/message-builder.js +20 -3
  172. package/dist/util/message-builder.js.map +1 -1
  173. package/dist/util/message-builder.test.js +269 -0
  174. package/dist/util/message-builder.test.js.map +1 -1
  175. package/dist/util/query-utils.test.d.ts +2 -0
  176. package/dist/util/query-utils.test.d.ts.map +1 -0
  177. package/dist/util/query-utils.test.js +382 -0
  178. package/dist/util/query-utils.test.js.map +1 -0
  179. package/dist/util/registry-validators.d.ts.map +1 -1
  180. package/dist/util/registry-validators.js +7 -0
  181. package/dist/util/registry-validators.js.map +1 -1
  182. package/dist/util/registry-validators.test.js +57 -0
  183. package/dist/util/registry-validators.test.js.map +1 -1
  184. package/dist/util/registry.d.ts.map +1 -1
  185. package/dist/util/registry.js +9 -0
  186. package/dist/util/registry.js.map +1 -1
  187. package/dist/util/registry.test.js +323 -1
  188. package/dist/util/registry.test.js.map +1 -1
  189. package/dist/util/resource-content-resolver.d.ts +20 -0
  190. package/dist/util/resource-content-resolver.d.ts.map +1 -0
  191. package/dist/util/resource-content-resolver.js +93 -0
  192. package/dist/util/resource-content-resolver.js.map +1 -0
  193. package/dist/util/resource-content-resolver.test.d.ts +2 -0
  194. package/dist/util/resource-content-resolver.test.d.ts.map +1 -0
  195. package/dist/util/resource-content-resolver.test.js +254 -0
  196. package/dist/util/resource-content-resolver.test.js.map +1 -0
  197. package/dist/util/resource-validators.test.d.ts +2 -0
  198. package/dist/util/resource-validators.test.d.ts.map +1 -0
  199. package/dist/util/resource-validators.test.js +90 -0
  200. package/dist/util/resource-validators.test.js.map +1 -0
  201. package/dist/util/tool-caller.d.ts +2 -2
  202. package/dist/util/tool-caller.d.ts.map +1 -1
  203. package/dist/util/tool-caller.js +8 -8
  204. package/dist/util/tool-caller.js.map +1 -1
  205. package/dist/util/validate-component-name.test.d.ts +2 -0
  206. package/dist/util/validate-component-name.test.d.ts.map +1 -0
  207. package/dist/util/validate-component-name.test.js +35 -0
  208. package/dist/util/validate-component-name.test.js.map +1 -0
  209. package/esm/context-helpers/context-helpers.test.js +16 -4
  210. package/esm/context-helpers/context-helpers.test.js.map +1 -1
  211. package/esm/context-helpers/current-interactables-context-helper.d.ts +2 -2
  212. package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  213. package/esm/context-helpers/current-interactables-context-helper.js +31 -12
  214. package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
  215. package/esm/context-helpers/registry.d.ts +2 -2
  216. package/esm/context-helpers/registry.d.ts.map +1 -1
  217. package/esm/context-helpers/registry.js.map +1 -1
  218. package/esm/context-helpers/types.d.ts +2 -2
  219. package/esm/context-helpers/types.d.ts.map +1 -1
  220. package/esm/context-helpers/types.js.map +1 -1
  221. package/esm/hoc/with-tambo-interactable.d.ts +50 -4
  222. package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
  223. package/esm/hoc/with-tambo-interactable.js +20 -5
  224. package/esm/hoc/with-tambo-interactable.js.map +1 -1
  225. package/esm/hooks/use-component-state.d.ts +3 -8
  226. package/esm/hooks/use-component-state.d.ts.map +1 -1
  227. package/esm/hooks/use-component-state.js +8 -0
  228. package/esm/hooks/use-component-state.js.map +1 -1
  229. package/esm/hooks/use-component-state.test.js +37 -0
  230. package/esm/hooks/use-component-state.test.js.map +1 -1
  231. package/esm/hooks/use-message-images.test.js +174 -37
  232. package/esm/hooks/use-message-images.test.js.map +1 -1
  233. package/esm/hooks/use-tambo-threads.js +1 -1
  234. package/esm/hooks/use-tambo-threads.js.map +1 -1
  235. package/esm/hooks/use-tambo-voice.d.ts +1 -1
  236. package/esm/hooks/use-tambo-voice.js +1 -1
  237. package/esm/hooks/use-tambo-voice.js.map +1 -1
  238. package/esm/hooks/use-tambo-voice.test.d.ts +2 -0
  239. package/esm/hooks/use-tambo-voice.test.d.ts.map +1 -0
  240. package/esm/hooks/use-tambo-voice.test.js +234 -0
  241. package/esm/hooks/use-tambo-voice.test.js.map +1 -0
  242. package/esm/index.d.ts +2 -2
  243. package/esm/index.d.ts.map +1 -1
  244. package/esm/index.js.map +1 -1
  245. package/esm/mcp/elicitation.d.ts.map +1 -1
  246. package/esm/mcp/elicitation.js +12 -0
  247. package/esm/mcp/elicitation.js.map +1 -1
  248. package/esm/mcp/elicitation.test.js +8 -1
  249. package/esm/mcp/elicitation.test.js.map +1 -1
  250. package/esm/mcp/mcp-client.d.ts +6 -10
  251. package/esm/mcp/mcp-client.d.ts.map +1 -1
  252. package/esm/mcp/mcp-client.js.map +1 -1
  253. package/esm/mcp/mcp-constants.d.ts +19 -0
  254. package/esm/mcp/mcp-constants.d.ts.map +1 -0
  255. package/esm/mcp/mcp-constants.js +18 -0
  256. package/esm/mcp/mcp-constants.js.map +1 -0
  257. package/esm/mcp/mcp-hooks.d.ts +21 -40
  258. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  259. package/esm/mcp/mcp-hooks.js +97 -40
  260. package/esm/mcp/mcp-hooks.js.map +1 -1
  261. package/esm/mcp/mcp-hooks.test.js +431 -5
  262. package/esm/mcp/mcp-hooks.test.js.map +1 -1
  263. package/esm/mcp/tambo-mcp-provider.d.ts +7 -0
  264. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  265. package/esm/mcp/tambo-mcp-provider.js +204 -154
  266. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  267. package/esm/mcp/tambo-mcp-provider.test.js +37 -0
  268. package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
  269. package/esm/model/component-metadata.d.ts +54 -21
  270. package/esm/model/component-metadata.d.ts.map +1 -1
  271. package/esm/model/component-metadata.js.map +1 -1
  272. package/esm/model/tambo-interactable.d.ts +13 -5
  273. package/esm/model/tambo-interactable.d.ts.map +1 -1
  274. package/esm/model/tambo-interactable.js.map +1 -1
  275. package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
  276. package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
  277. package/esm/providers/__tests__/thread-input-resource-resolution.test.js +587 -0
  278. package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
  279. package/esm/providers/index.d.ts +1 -1
  280. package/esm/providers/index.d.ts.map +1 -1
  281. package/esm/providers/index.js.map +1 -1
  282. package/esm/providers/tambo-client-provider.d.ts +8 -0
  283. package/esm/providers/tambo-client-provider.d.ts.map +1 -1
  284. package/esm/providers/tambo-client-provider.js +11 -12
  285. package/esm/providers/tambo-client-provider.js.map +1 -1
  286. package/esm/providers/tambo-client-provider.test.d.ts +2 -0
  287. package/esm/providers/tambo-client-provider.test.d.ts.map +1 -0
  288. package/esm/providers/tambo-client-provider.test.js +203 -0
  289. package/esm/providers/tambo-client-provider.test.js.map +1 -0
  290. package/esm/providers/tambo-context-attachment-provider.d.ts +34 -92
  291. package/esm/providers/tambo-context-attachment-provider.d.ts.map +1 -1
  292. package/esm/providers/tambo-context-attachment-provider.js +63 -106
  293. package/esm/providers/tambo-context-attachment-provider.js.map +1 -1
  294. package/esm/providers/tambo-context-attachment-provider.test.js +230 -464
  295. package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -1
  296. package/esm/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
  297. package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  298. package/esm/providers/tambo-interactable-provider.d.ts +5 -2
  299. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  300. package/esm/providers/tambo-interactable-provider.js +126 -17
  301. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  302. package/esm/providers/tambo-interactable-provider.test.js +242 -0
  303. package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
  304. package/esm/providers/tambo-interactables-additional-context.test.js +2 -5
  305. package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
  306. package/esm/providers/tambo-provider.d.ts +2 -3
  307. package/esm/providers/tambo-provider.d.ts.map +1 -1
  308. package/esm/providers/tambo-provider.js +6 -5
  309. package/esm/providers/tambo-provider.js.map +1 -1
  310. package/esm/providers/tambo-registry-provider.test.js +16 -0
  311. package/esm/providers/tambo-registry-provider.test.js.map +1 -1
  312. package/esm/providers/tambo-registry-schema-compat.test.js +31 -0
  313. package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
  314. package/esm/providers/tambo-thread-input-provider.d.ts +1 -1
  315. package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
  316. package/esm/providers/tambo-thread-input-provider.js +26 -4
  317. package/esm/providers/tambo-thread-input-provider.js.map +1 -1
  318. package/esm/providers/tambo-thread-provider-initial-messages.test.js +84 -2
  319. package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  320. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  321. package/esm/providers/tambo-thread-provider.js +53 -42
  322. package/esm/providers/tambo-thread-provider.js.map +1 -1
  323. package/esm/providers/tambo-thread-provider.test.js +368 -262
  324. package/esm/providers/tambo-thread-provider.test.js.map +1 -1
  325. package/esm/schema/index.d.ts +1 -1
  326. package/esm/schema/index.d.ts.map +1 -1
  327. package/esm/schema/index.js +1 -1
  328. package/esm/schema/index.js.map +1 -1
  329. package/esm/schema/json-schema.d.ts +7 -0
  330. package/esm/schema/json-schema.d.ts.map +1 -1
  331. package/esm/schema/json-schema.js +11 -1
  332. package/esm/schema/json-schema.js.map +1 -1
  333. package/esm/schema/json-schema.test.d.ts +2 -0
  334. package/esm/schema/json-schema.test.d.ts.map +1 -0
  335. package/esm/schema/json-schema.test.js +202 -0
  336. package/esm/schema/json-schema.test.js.map +1 -0
  337. package/esm/schema/schema.test.js +238 -1
  338. package/esm/schema/schema.test.js.map +1 -1
  339. package/esm/schema/standard-schema.d.ts +1 -0
  340. package/esm/schema/standard-schema.d.ts.map +1 -1
  341. package/esm/schema/standard-schema.js +18 -13
  342. package/esm/schema/standard-schema.js.map +1 -1
  343. package/esm/schema/standard-schema.test.d.ts +2 -0
  344. package/esm/schema/standard-schema.test.d.ts.map +1 -0
  345. package/esm/schema/standard-schema.test.js +130 -0
  346. package/esm/schema/standard-schema.test.js.map +1 -0
  347. package/esm/schema/validate.test.js +149 -0
  348. package/esm/schema/validate.test.js.map +1 -1
  349. package/esm/schema/zod.d.ts +7 -4
  350. package/esm/schema/zod.d.ts.map +1 -1
  351. package/esm/schema/zod.js +65 -22
  352. package/esm/schema/zod.js.map +1 -1
  353. package/esm/schema/zod.test.js +113 -1
  354. package/esm/schema/zod.test.js.map +1 -1
  355. package/esm/setupTests.js +3 -0
  356. package/esm/setupTests.js.map +1 -1
  357. package/esm/testing/tools.d.ts +4 -1
  358. package/esm/testing/tools.d.ts.map +1 -1
  359. package/esm/testing/tools.js +6 -1
  360. package/esm/testing/tools.js.map +1 -1
  361. package/esm/util/generate-component.d.ts.map +1 -1
  362. package/esm/util/generate-component.js +18 -3
  363. package/esm/util/generate-component.js.map +1 -1
  364. package/esm/util/generate-component.test.d.ts +2 -0
  365. package/esm/util/generate-component.test.d.ts.map +1 -0
  366. package/esm/util/generate-component.test.js +302 -0
  367. package/esm/util/generate-component.test.js.map +1 -0
  368. package/esm/util/is-promise.d.ts +9 -0
  369. package/esm/util/is-promise.d.ts.map +1 -0
  370. package/esm/util/is-promise.js +17 -0
  371. package/esm/util/is-promise.js.map +1 -0
  372. package/esm/util/is-promise.test.d.ts +2 -0
  373. package/esm/util/is-promise.test.d.ts.map +1 -0
  374. package/esm/util/is-promise.test.js +46 -0
  375. package/esm/util/is-promise.test.js.map +1 -0
  376. package/esm/util/message-builder.d.ts +3 -1
  377. package/esm/util/message-builder.d.ts.map +1 -1
  378. package/esm/util/message-builder.js +20 -3
  379. package/esm/util/message-builder.js.map +1 -1
  380. package/esm/util/message-builder.test.js +269 -0
  381. package/esm/util/message-builder.test.js.map +1 -1
  382. package/esm/util/query-utils.test.d.ts +2 -0
  383. package/esm/util/query-utils.test.d.ts.map +1 -0
  384. package/esm/util/query-utils.test.js +380 -0
  385. package/esm/util/query-utils.test.js.map +1 -0
  386. package/esm/util/registry-validators.d.ts.map +1 -1
  387. package/esm/util/registry-validators.js +7 -0
  388. package/esm/util/registry-validators.js.map +1 -1
  389. package/esm/util/registry-validators.test.js +57 -0
  390. package/esm/util/registry-validators.test.js.map +1 -1
  391. package/esm/util/registry.d.ts.map +1 -1
  392. package/esm/util/registry.js +9 -0
  393. package/esm/util/registry.js.map +1 -1
  394. package/esm/util/registry.test.js +324 -2
  395. package/esm/util/registry.test.js.map +1 -1
  396. package/esm/util/resource-content-resolver.d.ts +20 -0
  397. package/esm/util/resource-content-resolver.d.ts.map +1 -0
  398. package/esm/util/resource-content-resolver.js +89 -0
  399. package/esm/util/resource-content-resolver.js.map +1 -0
  400. package/esm/util/resource-content-resolver.test.d.ts +2 -0
  401. package/esm/util/resource-content-resolver.test.d.ts.map +1 -0
  402. package/esm/util/resource-content-resolver.test.js +252 -0
  403. package/esm/util/resource-content-resolver.test.js.map +1 -0
  404. package/esm/util/resource-validators.test.d.ts +2 -0
  405. package/esm/util/resource-validators.test.d.ts.map +1 -0
  406. package/esm/util/resource-validators.test.js +88 -0
  407. package/esm/util/resource-validators.test.js.map +1 -0
  408. package/esm/util/tool-caller.d.ts +2 -2
  409. package/esm/util/tool-caller.d.ts.map +1 -1
  410. package/esm/util/tool-caller.js +8 -8
  411. package/esm/util/tool-caller.js.map +1 -1
  412. package/esm/util/validate-component-name.test.d.ts +2 -0
  413. package/esm/util/validate-component-name.test.d.ts.map +1 -0
  414. package/esm/util/validate-component-name.test.js +33 -0
  415. package/esm/util/validate-component-name.test.js.map +1 -0
  416. package/package.json +15 -23
  417. package/dist/schema/alias.d.ts +0 -3
  418. package/dist/schema/alias.d.ts.map +0 -1
  419. package/dist/schema/alias.js +0 -6
  420. package/dist/schema/alias.js.map +0 -1
  421. package/esm/schema/alias.d.ts +0 -3
  422. package/esm/schema/alias.d.ts.map +0 -1
  423. package/esm/schema/alias.js +0 -13
  424. package/esm/schema/alias.js.map +0 -1
@@ -0,0 +1,380 @@
1
+ import { combineMutationResults, combineQueryResults } from "./query-utils";
2
+ function createMutationResult(status, overrides = {}) {
3
+ const base = {
4
+ data: undefined,
5
+ error: null,
6
+ isPaused: false,
7
+ variables: undefined,
8
+ context: undefined,
9
+ failureCount: 0,
10
+ failureReason: null,
11
+ submittedAt: 0,
12
+ mutate: jest.fn(),
13
+ mutateAsync: jest.fn(),
14
+ reset: jest.fn(),
15
+ ...overrides,
16
+ isError: status === "error",
17
+ isIdle: status === "idle",
18
+ isPending: status === "pending",
19
+ isSuccess: status === "success",
20
+ status,
21
+ };
22
+ return base;
23
+ }
24
+ const idleMutation = (overrides = {}) => createMutationResult("idle", overrides);
25
+ const pendingMutation = (overrides = {}) => createMutationResult("pending", overrides);
26
+ const successMutation = (overrides = {}) => createMutationResult("success", overrides);
27
+ const errorMutation = (error, overrides = {}) => createMutationResult("error", { ...overrides, error });
28
+ function createQueryResult(status, overrides = {}) {
29
+ const base = {
30
+ data: undefined,
31
+ error: null,
32
+ isFetched: false,
33
+ isFetchedAfterMount: false,
34
+ isFetching: false,
35
+ isInitialLoading: false,
36
+ isLoading: false,
37
+ isLoadingError: false,
38
+ isPaused: false,
39
+ isPlaceholderData: false,
40
+ isRefetchError: false,
41
+ isRefetching: false,
42
+ isStale: false,
43
+ dataUpdatedAt: 0,
44
+ errorUpdatedAt: 0,
45
+ errorUpdateCount: 0,
46
+ failureCount: 0,
47
+ failureReason: null,
48
+ fetchStatus: "idle",
49
+ refetch: jest.fn(),
50
+ promise: Promise.resolve(undefined),
51
+ isEnabled: true,
52
+ ...overrides,
53
+ isError: status === "error",
54
+ isPending: status === "pending",
55
+ isSuccess: status === "success",
56
+ status,
57
+ };
58
+ return base;
59
+ }
60
+ const pendingQuery = (overrides = {}) => createQueryResult("pending", overrides);
61
+ const successQuery = (overrides = {}) => createQueryResult("success", overrides);
62
+ const errorQuery = (error, overrides = {}) => createQueryResult("error", { ...overrides, error });
63
+ describe("combineMutationResults", () => {
64
+ describe("status determination", () => {
65
+ it("returns pending when first mutation is pending", () => {
66
+ const resultA = pendingMutation();
67
+ const resultB = idleMutation();
68
+ const combined = combineMutationResults(resultA, resultB);
69
+ expect(combined.status).toBe("pending");
70
+ expect(combined.isPending).toBe(true);
71
+ });
72
+ it("returns pending when second mutation is pending", () => {
73
+ const resultA = successMutation();
74
+ const resultB = pendingMutation();
75
+ const combined = combineMutationResults(resultA, resultB);
76
+ expect(combined.status).toBe("pending");
77
+ expect(combined.isPending).toBe(true);
78
+ });
79
+ it("returns error when first mutation has error (and neither pending)", () => {
80
+ const errorA = new Error("First error");
81
+ const resultA = errorMutation(errorA);
82
+ const resultB = successMutation();
83
+ const combined = combineMutationResults(resultA, resultB);
84
+ expect(combined.status).toBe("error");
85
+ expect(combined.isError).toBe(true);
86
+ expect(combined.error).toBe(errorA);
87
+ });
88
+ it("returns error when second mutation has error (and neither pending)", () => {
89
+ const errorB = new Error("Second error");
90
+ const resultA = successMutation();
91
+ const resultB = errorMutation(errorB);
92
+ const combined = combineMutationResults(resultA, resultB);
93
+ expect(combined.status).toBe("error");
94
+ expect(combined.isError).toBe(true);
95
+ expect(combined.error).toBe(errorB);
96
+ });
97
+ it("returns success when both mutations are successful", () => {
98
+ const resultA = successMutation();
99
+ const resultB = successMutation();
100
+ const combined = combineMutationResults(resultA, resultB);
101
+ expect(combined.status).toBe("success");
102
+ expect(combined.isSuccess).toBe(true);
103
+ });
104
+ it("returns idle when both mutations are idle", () => {
105
+ const resultA = idleMutation();
106
+ const resultB = idleMutation();
107
+ const combined = combineMutationResults(resultA, resultB);
108
+ expect(combined.status).toBe("idle");
109
+ expect(combined.isIdle).toBe(true);
110
+ });
111
+ it("returns idle when one is idle and one is success (not both success)", () => {
112
+ const resultA = idleMutation();
113
+ const resultB = successMutation();
114
+ const combined = combineMutationResults(resultA, resultB);
115
+ expect(combined.status).toBe("idle");
116
+ // isIdle is only true if BOTH are idle
117
+ expect(combined.isIdle).toBe(false);
118
+ });
119
+ });
120
+ describe("boolean flags", () => {
121
+ it("isPending is true if either is pending", () => {
122
+ const resultA = pendingMutation();
123
+ const resultB = idleMutation();
124
+ expect(combineMutationResults(resultA, resultB).isPending).toBe(true);
125
+ expect(combineMutationResults(resultB, resultA).isPending).toBe(true);
126
+ });
127
+ it("isSuccess is true only if both are successful", () => {
128
+ const success = successMutation();
129
+ const notSuccess = idleMutation();
130
+ expect(combineMutationResults(success, success).isSuccess).toBe(true);
131
+ expect(combineMutationResults(success, notSuccess).isSuccess).toBe(false);
132
+ expect(combineMutationResults(notSuccess, success).isSuccess).toBe(false);
133
+ });
134
+ it("isError is true if either has error", () => {
135
+ const error = errorMutation(new Error("Error A"));
136
+ const noError = idleMutation();
137
+ expect(combineMutationResults(error, noError).isError).toBe(true);
138
+ expect(combineMutationResults(noError, error).isError).toBe(true);
139
+ expect(combineMutationResults(noError, noError).isError).toBe(false);
140
+ });
141
+ it("isIdle is true only if both are idle", () => {
142
+ const idle = idleMutation();
143
+ const notIdle = pendingMutation();
144
+ expect(combineMutationResults(idle, idle).isIdle).toBe(true);
145
+ expect(combineMutationResults(idle, notIdle).isIdle).toBe(false);
146
+ expect(combineMutationResults(notIdle, idle).isIdle).toBe(false);
147
+ });
148
+ it("isPaused is true if either is paused", () => {
149
+ const paused = idleMutation({ isPaused: true });
150
+ const notPaused = idleMutation();
151
+ expect(combineMutationResults(paused, notPaused).isPaused).toBe(true);
152
+ expect(combineMutationResults(notPaused, paused).isPaused).toBe(true);
153
+ });
154
+ });
155
+ describe("numeric aggregation", () => {
156
+ it("sums failureCount from both mutations", () => {
157
+ const resultA = idleMutation({ failureCount: 2 });
158
+ const resultB = idleMutation({ failureCount: 3 });
159
+ expect(combineMutationResults(resultA, resultB).failureCount).toBe(5);
160
+ });
161
+ it("uses first non-null submittedAt", () => {
162
+ const resultA = idleMutation({ submittedAt: 1000 });
163
+ const resultB = idleMutation({ submittedAt: 2000 });
164
+ expect(combineMutationResults(resultA, resultB).submittedAt).toBe(1000);
165
+ });
166
+ it("uses second submittedAt if first is falsy", () => {
167
+ const resultA = idleMutation({ submittedAt: 0 });
168
+ const resultB = idleMutation({ submittedAt: 2000 });
169
+ expect(combineMutationResults(resultA, resultB).submittedAt).toBe(2000);
170
+ });
171
+ });
172
+ describe("error and failureReason", () => {
173
+ it("uses first error if present", () => {
174
+ const errorA = new Error("Error A");
175
+ const errorB = new Error("Error B");
176
+ const resultA = errorMutation(errorA);
177
+ const resultB = errorMutation(errorB);
178
+ expect(combineMutationResults(resultA, resultB).error).toBe(errorA);
179
+ });
180
+ it("uses second error if first is null", () => {
181
+ const errorB = new Error("Error B");
182
+ const resultA = idleMutation();
183
+ const resultB = errorMutation(errorB);
184
+ expect(combineMutationResults(resultA, resultB).error).toBe(errorB);
185
+ });
186
+ it("uses first failureReason if present", () => {
187
+ const reasonA = new Error("Reason A");
188
+ const reasonB = new Error("Reason B");
189
+ const resultA = idleMutation({ failureReason: reasonA });
190
+ const resultB = idleMutation({ failureReason: reasonB });
191
+ expect(combineMutationResults(resultA, resultB).failureReason).toBe(reasonA);
192
+ });
193
+ });
194
+ });
195
+ describe("combineQueryResults", () => {
196
+ describe("status determination", () => {
197
+ it("returns pending when first query is pending", () => {
198
+ const resultA = pendingQuery();
199
+ const resultB = successQuery();
200
+ const combined = combineQueryResults(resultA, resultB);
201
+ expect(combined.status).toBe("pending");
202
+ expect(combined.isPending).toBe(true);
203
+ });
204
+ it("returns pending when second query is pending", () => {
205
+ const resultA = successQuery();
206
+ const resultB = pendingQuery();
207
+ const combined = combineQueryResults(resultA, resultB);
208
+ expect(combined.status).toBe("pending");
209
+ });
210
+ it("returns error when first query has error (and neither pending)", () => {
211
+ const errorA = new Error("Query error");
212
+ const resultA = errorQuery(errorA);
213
+ const resultB = successQuery();
214
+ const combined = combineQueryResults(resultA, resultB);
215
+ expect(combined.status).toBe("error");
216
+ expect(combined.isError).toBe(true);
217
+ });
218
+ it("returns success when both queries are successful", () => {
219
+ const resultA = successQuery();
220
+ const resultB = successQuery();
221
+ const combined = combineQueryResults(resultA, resultB);
222
+ expect(combined.status).toBe("success");
223
+ expect(combined.isSuccess).toBe(true);
224
+ });
225
+ it("returns pending as fallback when neither pending, error, nor both success", () => {
226
+ // This is an edge case - one success, one not (but not error or pending)
227
+ const resultA = successQuery();
228
+ const resultB = {
229
+ ...pendingQuery(),
230
+ isPending: false,
231
+ isSuccess: false,
232
+ isError: false,
233
+ };
234
+ const combined = combineQueryResults(resultA, resultB);
235
+ expect(combined.status).toBe("pending");
236
+ });
237
+ });
238
+ describe("fetchStatus determination", () => {
239
+ it("returns fetching when either is fetching", () => {
240
+ const resultA = pendingQuery({
241
+ isFetching: true,
242
+ fetchStatus: "fetching",
243
+ });
244
+ const resultB = pendingQuery({
245
+ isFetching: false,
246
+ fetchStatus: "idle",
247
+ });
248
+ expect(combineQueryResults(resultA, resultB).fetchStatus).toBe("fetching");
249
+ expect(combineQueryResults(resultB, resultA).fetchStatus).toBe("fetching");
250
+ });
251
+ it("returns paused when either is paused (and neither fetching)", () => {
252
+ const resultA = pendingQuery({
253
+ isPaused: true,
254
+ isFetching: false,
255
+ fetchStatus: "paused",
256
+ });
257
+ const resultB = pendingQuery({
258
+ isPaused: false,
259
+ isFetching: false,
260
+ fetchStatus: "idle",
261
+ });
262
+ expect(combineQueryResults(resultA, resultB).fetchStatus).toBe("paused");
263
+ });
264
+ it("returns idle when neither fetching nor paused", () => {
265
+ const resultA = pendingQuery({
266
+ isFetching: false,
267
+ isPaused: false,
268
+ fetchStatus: "idle",
269
+ });
270
+ const resultB = pendingQuery({
271
+ isFetching: false,
272
+ isPaused: false,
273
+ fetchStatus: "idle",
274
+ });
275
+ expect(combineQueryResults(resultA, resultB).fetchStatus).toBe("idle");
276
+ });
277
+ });
278
+ describe("boolean flags", () => {
279
+ it("isLoading is true if either is loading", () => {
280
+ const loading = pendingQuery({ isLoading: true });
281
+ const notLoading = pendingQuery({ isLoading: false });
282
+ expect(combineQueryResults(loading, notLoading).isLoading).toBe(true);
283
+ expect(combineQueryResults(notLoading, notLoading).isLoading).toBe(false);
284
+ });
285
+ it("isFetched is true only if both are fetched", () => {
286
+ const fetched = pendingQuery({ isFetched: true });
287
+ const notFetched = pendingQuery({ isFetched: false });
288
+ expect(combineQueryResults(fetched, fetched).isFetched).toBe(true);
289
+ expect(combineQueryResults(fetched, notFetched).isFetched).toBe(false);
290
+ });
291
+ it("isFetchedAfterMount is true only if both are fetched after mount", () => {
292
+ const fetched = pendingQuery({ isFetchedAfterMount: true });
293
+ const notFetched = pendingQuery({ isFetchedAfterMount: false });
294
+ expect(combineQueryResults(fetched, fetched).isFetchedAfterMount).toBe(true);
295
+ expect(combineQueryResults(fetched, notFetched).isFetchedAfterMount).toBe(false);
296
+ });
297
+ it("isInitialLoading is true if either is initial loading", () => {
298
+ const loading = pendingQuery({ isInitialLoading: true });
299
+ const notLoading = pendingQuery({ isInitialLoading: false });
300
+ expect(combineQueryResults(loading, notLoading).isInitialLoading).toBe(true);
301
+ });
302
+ it("isLoadingError is true if either has loading error", () => {
303
+ const error = pendingQuery({ isLoadingError: true });
304
+ const noError = pendingQuery({ isLoadingError: false });
305
+ expect(combineQueryResults(error, noError).isLoadingError).toBe(true);
306
+ });
307
+ it("isRefetchError is true if either has refetch error", () => {
308
+ const error = pendingQuery({ isRefetchError: true });
309
+ const noError = pendingQuery({ isRefetchError: false });
310
+ expect(combineQueryResults(error, noError).isRefetchError).toBe(true);
311
+ });
312
+ it("isPlaceholderData is true if either has placeholder data", () => {
313
+ const placeholder = pendingQuery({ isPlaceholderData: true });
314
+ const noPlaceholder = pendingQuery({ isPlaceholderData: false });
315
+ expect(combineQueryResults(placeholder, noPlaceholder).isPlaceholderData).toBe(true);
316
+ });
317
+ it("isStale is true if either is stale", () => {
318
+ const stale = pendingQuery({ isStale: true });
319
+ const notStale = pendingQuery({ isStale: false });
320
+ expect(combineQueryResults(stale, notStale).isStale).toBe(true);
321
+ });
322
+ it("isRefetching is true if either is refetching", () => {
323
+ const refetching = pendingQuery({ isRefetching: true });
324
+ const notRefetching = pendingQuery({ isRefetching: false });
325
+ expect(combineQueryResults(refetching, notRefetching).isRefetching).toBe(true);
326
+ });
327
+ it("isEnabled is true only if both are enabled", () => {
328
+ const enabled = pendingQuery({ isEnabled: true });
329
+ const disabled = pendingQuery({ isEnabled: false });
330
+ expect(combineQueryResults(enabled, enabled).isEnabled).toBe(true);
331
+ expect(combineQueryResults(enabled, disabled).isEnabled).toBe(false);
332
+ });
333
+ });
334
+ describe("numeric aggregation", () => {
335
+ it("sums failureCount from both queries", () => {
336
+ const resultA = pendingQuery({ failureCount: 1 });
337
+ const resultB = pendingQuery({ failureCount: 4 });
338
+ expect(combineQueryResults(resultA, resultB).failureCount).toBe(5);
339
+ });
340
+ it("sums errorUpdateCount from both queries", () => {
341
+ const resultA = pendingQuery({ errorUpdateCount: 2 });
342
+ const resultB = pendingQuery({ errorUpdateCount: 3 });
343
+ expect(combineQueryResults(resultA, resultB).errorUpdateCount).toBe(5);
344
+ });
345
+ it("uses max dataUpdatedAt", () => {
346
+ const resultA = pendingQuery({ dataUpdatedAt: 1000 });
347
+ const resultB = pendingQuery({ dataUpdatedAt: 2000 });
348
+ expect(combineQueryResults(resultA, resultB).dataUpdatedAt).toBe(2000);
349
+ expect(combineQueryResults(resultB, resultA).dataUpdatedAt).toBe(2000);
350
+ });
351
+ it("uses max errorUpdatedAt", () => {
352
+ const resultA = pendingQuery({ errorUpdatedAt: 500 });
353
+ const resultB = pendingQuery({ errorUpdatedAt: 1500 });
354
+ expect(combineQueryResults(resultA, resultB).errorUpdatedAt).toBe(1500);
355
+ });
356
+ });
357
+ describe("error and failureReason", () => {
358
+ it("uses first error if present", () => {
359
+ const errorA = new Error("Error A");
360
+ const errorB = new Error("Error B");
361
+ const resultA = errorQuery(errorA);
362
+ const resultB = errorQuery(errorB);
363
+ expect(combineQueryResults(resultA, resultB).error).toBe(errorA);
364
+ });
365
+ it("uses second error if first is null", () => {
366
+ const errorB = new Error("Error B");
367
+ const resultA = pendingQuery();
368
+ const resultB = errorQuery(errorB);
369
+ expect(combineQueryResults(resultA, resultB).error).toBe(errorB);
370
+ });
371
+ it("uses first failureReason if present", () => {
372
+ const reasonA = new Error("Reason A");
373
+ const reasonB = new Error("Reason B");
374
+ const resultA = pendingQuery({ failureReason: reasonA });
375
+ const resultB = pendingQuery({ failureReason: reasonB });
376
+ expect(combineQueryResults(resultA, resultB).failureReason).toBe(reasonA);
377
+ });
378
+ });
379
+ });
380
+ //# sourceMappingURL=query-utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-utils.test.js","sourceRoot":"","sources":["../../src/util/query-utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { UseMutationResult, UseQueryResult } from \"@tanstack/react-query\";\nimport { combineMutationResults, combineQueryResults } from \"./query-utils\";\n\ntype MutationStatus = \"idle\" | \"pending\" | \"success\" | \"error\";\ntype QueryStatus = \"pending\" | \"success\" | \"error\";\n\ntype MutationOverrides = Omit<\n Partial<UseMutationResult>,\n \"status\" | \"isError\" | \"isIdle\" | \"isPending\" | \"isSuccess\"\n>;\n\nfunction createMutationResult(\n status: MutationStatus,\n overrides: MutationOverrides = {},\n): UseMutationResult {\n const base = {\n data: undefined,\n error: null,\n isPaused: false,\n variables: undefined,\n context: undefined,\n failureCount: 0,\n failureReason: null,\n submittedAt: 0,\n mutate: jest.fn(),\n mutateAsync: jest.fn(),\n reset: jest.fn(),\n ...overrides,\n isError: status === \"error\",\n isIdle: status === \"idle\",\n isPending: status === \"pending\",\n isSuccess: status === \"success\",\n status,\n } as UseMutationResult;\n\n return base;\n}\n\nconst idleMutation = (overrides: MutationOverrides = {}) =>\n createMutationResult(\"idle\", overrides);\n\nconst pendingMutation = (overrides: MutationOverrides = {}) =>\n createMutationResult(\"pending\", overrides);\n\nconst successMutation = (overrides: MutationOverrides = {}) =>\n createMutationResult(\"success\", overrides);\n\nconst errorMutation = (error: Error, overrides: MutationOverrides = {}) =>\n createMutationResult(\"error\", { ...overrides, error });\n\ntype QueryOverrides = Omit<\n Partial<UseQueryResult>,\n \"status\" | \"isError\" | \"isPending\" | \"isSuccess\"\n>;\n\nfunction createQueryResult(\n status: QueryStatus,\n overrides: QueryOverrides = {},\n): UseQueryResult {\n const base = {\n data: undefined,\n error: null,\n isFetched: false,\n isFetchedAfterMount: false,\n isFetching: false,\n isInitialLoading: false,\n isLoading: false,\n isLoadingError: false,\n isPaused: false,\n isPlaceholderData: false,\n isRefetchError: false,\n isRefetching: false,\n isStale: false,\n dataUpdatedAt: 0,\n errorUpdatedAt: 0,\n errorUpdateCount: 0,\n failureCount: 0,\n failureReason: null,\n fetchStatus: \"idle\",\n refetch: jest.fn(),\n promise: Promise.resolve(undefined),\n isEnabled: true,\n ...overrides,\n isError: status === \"error\",\n isPending: status === \"pending\",\n isSuccess: status === \"success\",\n status,\n } as UseQueryResult;\n\n return base;\n}\n\nconst pendingQuery = (overrides: QueryOverrides = {}) =>\n createQueryResult(\"pending\", overrides);\n\nconst successQuery = (overrides: QueryOverrides = {}) =>\n createQueryResult(\"success\", overrides);\n\nconst errorQuery = (error: Error, overrides: QueryOverrides = {}) =>\n createQueryResult(\"error\", { ...overrides, error });\n\ndescribe(\"combineMutationResults\", () => {\n describe(\"status determination\", () => {\n it(\"returns pending when first mutation is pending\", () => {\n const resultA = pendingMutation();\n const resultB = idleMutation();\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"pending\");\n expect(combined.isPending).toBe(true);\n });\n\n it(\"returns pending when second mutation is pending\", () => {\n const resultA = successMutation();\n const resultB = pendingMutation();\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"pending\");\n expect(combined.isPending).toBe(true);\n });\n\n it(\"returns error when first mutation has error (and neither pending)\", () => {\n const errorA = new Error(\"First error\");\n const resultA = errorMutation(errorA);\n const resultB = successMutation();\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"error\");\n expect(combined.isError).toBe(true);\n expect(combined.error).toBe(errorA);\n });\n\n it(\"returns error when second mutation has error (and neither pending)\", () => {\n const errorB = new Error(\"Second error\");\n const resultA = successMutation();\n const resultB = errorMutation(errorB);\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"error\");\n expect(combined.isError).toBe(true);\n expect(combined.error).toBe(errorB);\n });\n\n it(\"returns success when both mutations are successful\", () => {\n const resultA = successMutation();\n const resultB = successMutation();\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"success\");\n expect(combined.isSuccess).toBe(true);\n });\n\n it(\"returns idle when both mutations are idle\", () => {\n const resultA = idleMutation();\n const resultB = idleMutation();\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"idle\");\n expect(combined.isIdle).toBe(true);\n });\n\n it(\"returns idle when one is idle and one is success (not both success)\", () => {\n const resultA = idleMutation();\n const resultB = successMutation();\n\n const combined = combineMutationResults(resultA, resultB);\n\n expect(combined.status).toBe(\"idle\");\n // isIdle is only true if BOTH are idle\n expect(combined.isIdle).toBe(false);\n });\n });\n\n describe(\"boolean flags\", () => {\n it(\"isPending is true if either is pending\", () => {\n const resultA = pendingMutation();\n const resultB = idleMutation();\n\n expect(combineMutationResults(resultA, resultB).isPending).toBe(true);\n expect(combineMutationResults(resultB, resultA).isPending).toBe(true);\n });\n\n it(\"isSuccess is true only if both are successful\", () => {\n const success = successMutation();\n const notSuccess = idleMutation();\n\n expect(combineMutationResults(success, success).isSuccess).toBe(true);\n expect(combineMutationResults(success, notSuccess).isSuccess).toBe(false);\n expect(combineMutationResults(notSuccess, success).isSuccess).toBe(false);\n });\n\n it(\"isError is true if either has error\", () => {\n const error = errorMutation(new Error(\"Error A\"));\n const noError = idleMutation();\n\n expect(combineMutationResults(error, noError).isError).toBe(true);\n expect(combineMutationResults(noError, error).isError).toBe(true);\n expect(combineMutationResults(noError, noError).isError).toBe(false);\n });\n\n it(\"isIdle is true only if both are idle\", () => {\n const idle = idleMutation();\n const notIdle = pendingMutation();\n\n expect(combineMutationResults(idle, idle).isIdle).toBe(true);\n expect(combineMutationResults(idle, notIdle).isIdle).toBe(false);\n expect(combineMutationResults(notIdle, idle).isIdle).toBe(false);\n });\n\n it(\"isPaused is true if either is paused\", () => {\n const paused = idleMutation({ isPaused: true });\n const notPaused = idleMutation();\n\n expect(combineMutationResults(paused, notPaused).isPaused).toBe(true);\n expect(combineMutationResults(notPaused, paused).isPaused).toBe(true);\n });\n });\n\n describe(\"numeric aggregation\", () => {\n it(\"sums failureCount from both mutations\", () => {\n const resultA = idleMutation({ failureCount: 2 });\n const resultB = idleMutation({ failureCount: 3 });\n\n expect(combineMutationResults(resultA, resultB).failureCount).toBe(5);\n });\n\n it(\"uses first non-null submittedAt\", () => {\n const resultA = idleMutation({ submittedAt: 1000 });\n const resultB = idleMutation({ submittedAt: 2000 });\n\n expect(combineMutationResults(resultA, resultB).submittedAt).toBe(1000);\n });\n\n it(\"uses second submittedAt if first is falsy\", () => {\n const resultA = idleMutation({ submittedAt: 0 });\n const resultB = idleMutation({ submittedAt: 2000 });\n\n expect(combineMutationResults(resultA, resultB).submittedAt).toBe(2000);\n });\n });\n\n describe(\"error and failureReason\", () => {\n it(\"uses first error if present\", () => {\n const errorA = new Error(\"Error A\");\n const errorB = new Error(\"Error B\");\n const resultA = errorMutation(errorA);\n const resultB = errorMutation(errorB);\n\n expect(combineMutationResults(resultA, resultB).error).toBe(errorA);\n });\n\n it(\"uses second error if first is null\", () => {\n const errorB = new Error(\"Error B\");\n const resultA = idleMutation();\n const resultB = errorMutation(errorB);\n\n expect(combineMutationResults(resultA, resultB).error).toBe(errorB);\n });\n\n it(\"uses first failureReason if present\", () => {\n const reasonA = new Error(\"Reason A\");\n const reasonB = new Error(\"Reason B\");\n const resultA = idleMutation({ failureReason: reasonA });\n const resultB = idleMutation({ failureReason: reasonB });\n\n expect(combineMutationResults(resultA, resultB).failureReason).toBe(\n reasonA,\n );\n });\n });\n});\n\ndescribe(\"combineQueryResults\", () => {\n describe(\"status determination\", () => {\n it(\"returns pending when first query is pending\", () => {\n const resultA = pendingQuery();\n const resultB = successQuery();\n\n const combined = combineQueryResults(resultA, resultB);\n\n expect(combined.status).toBe(\"pending\");\n expect(combined.isPending).toBe(true);\n });\n\n it(\"returns pending when second query is pending\", () => {\n const resultA = successQuery();\n const resultB = pendingQuery();\n\n const combined = combineQueryResults(resultA, resultB);\n\n expect(combined.status).toBe(\"pending\");\n });\n\n it(\"returns error when first query has error (and neither pending)\", () => {\n const errorA = new Error(\"Query error\");\n const resultA = errorQuery(errorA);\n const resultB = successQuery();\n\n const combined = combineQueryResults(resultA, resultB);\n\n expect(combined.status).toBe(\"error\");\n expect(combined.isError).toBe(true);\n });\n\n it(\"returns success when both queries are successful\", () => {\n const resultA = successQuery();\n const resultB = successQuery();\n\n const combined = combineQueryResults(resultA, resultB);\n\n expect(combined.status).toBe(\"success\");\n expect(combined.isSuccess).toBe(true);\n });\n\n it(\"returns pending as fallback when neither pending, error, nor both success\", () => {\n // This is an edge case - one success, one not (but not error or pending)\n const resultA = successQuery();\n const resultB = {\n ...pendingQuery(),\n isPending: false,\n isSuccess: false,\n isError: false,\n } as unknown as UseQueryResult;\n\n const combined = combineQueryResults(resultA, resultB);\n\n expect(combined.status).toBe(\"pending\");\n });\n });\n\n describe(\"fetchStatus determination\", () => {\n it(\"returns fetching when either is fetching\", () => {\n const resultA = pendingQuery({\n isFetching: true,\n fetchStatus: \"fetching\",\n });\n const resultB = pendingQuery({\n isFetching: false,\n fetchStatus: \"idle\",\n });\n\n expect(combineQueryResults(resultA, resultB).fetchStatus).toBe(\n \"fetching\",\n );\n expect(combineQueryResults(resultB, resultA).fetchStatus).toBe(\n \"fetching\",\n );\n });\n\n it(\"returns paused when either is paused (and neither fetching)\", () => {\n const resultA = pendingQuery({\n isPaused: true,\n isFetching: false,\n fetchStatus: \"paused\",\n });\n const resultB = pendingQuery({\n isPaused: false,\n isFetching: false,\n fetchStatus: \"idle\",\n });\n\n expect(combineQueryResults(resultA, resultB).fetchStatus).toBe(\"paused\");\n });\n\n it(\"returns idle when neither fetching nor paused\", () => {\n const resultA = pendingQuery({\n isFetching: false,\n isPaused: false,\n fetchStatus: \"idle\",\n });\n const resultB = pendingQuery({\n isFetching: false,\n isPaused: false,\n fetchStatus: \"idle\",\n });\n\n expect(combineQueryResults(resultA, resultB).fetchStatus).toBe(\"idle\");\n });\n });\n\n describe(\"boolean flags\", () => {\n it(\"isLoading is true if either is loading\", () => {\n const loading = pendingQuery({ isLoading: true });\n const notLoading = pendingQuery({ isLoading: false });\n\n expect(combineQueryResults(loading, notLoading).isLoading).toBe(true);\n expect(combineQueryResults(notLoading, notLoading).isLoading).toBe(false);\n });\n\n it(\"isFetched is true only if both are fetched\", () => {\n const fetched = pendingQuery({ isFetched: true });\n const notFetched = pendingQuery({ isFetched: false });\n\n expect(combineQueryResults(fetched, fetched).isFetched).toBe(true);\n expect(combineQueryResults(fetched, notFetched).isFetched).toBe(false);\n });\n\n it(\"isFetchedAfterMount is true only if both are fetched after mount\", () => {\n const fetched = pendingQuery({ isFetchedAfterMount: true });\n const notFetched = pendingQuery({ isFetchedAfterMount: false });\n\n expect(combineQueryResults(fetched, fetched).isFetchedAfterMount).toBe(\n true,\n );\n expect(combineQueryResults(fetched, notFetched).isFetchedAfterMount).toBe(\n false,\n );\n });\n\n it(\"isInitialLoading is true if either is initial loading\", () => {\n const loading = pendingQuery({ isInitialLoading: true });\n const notLoading = pendingQuery({ isInitialLoading: false });\n\n expect(combineQueryResults(loading, notLoading).isInitialLoading).toBe(\n true,\n );\n });\n\n it(\"isLoadingError is true if either has loading error\", () => {\n const error = pendingQuery({ isLoadingError: true });\n const noError = pendingQuery({ isLoadingError: false });\n\n expect(combineQueryResults(error, noError).isLoadingError).toBe(true);\n });\n\n it(\"isRefetchError is true if either has refetch error\", () => {\n const error = pendingQuery({ isRefetchError: true });\n const noError = pendingQuery({ isRefetchError: false });\n\n expect(combineQueryResults(error, noError).isRefetchError).toBe(true);\n });\n\n it(\"isPlaceholderData is true if either has placeholder data\", () => {\n const placeholder = pendingQuery({ isPlaceholderData: true });\n const noPlaceholder = pendingQuery({ isPlaceholderData: false });\n\n expect(\n combineQueryResults(placeholder, noPlaceholder).isPlaceholderData,\n ).toBe(true);\n });\n\n it(\"isStale is true if either is stale\", () => {\n const stale = pendingQuery({ isStale: true });\n const notStale = pendingQuery({ isStale: false });\n\n expect(combineQueryResults(stale, notStale).isStale).toBe(true);\n });\n\n it(\"isRefetching is true if either is refetching\", () => {\n const refetching = pendingQuery({ isRefetching: true });\n const notRefetching = pendingQuery({ isRefetching: false });\n\n expect(combineQueryResults(refetching, notRefetching).isRefetching).toBe(\n true,\n );\n });\n\n it(\"isEnabled is true only if both are enabled\", () => {\n const enabled = pendingQuery({ isEnabled: true });\n const disabled = pendingQuery({ isEnabled: false });\n\n expect(combineQueryResults(enabled, enabled).isEnabled).toBe(true);\n expect(combineQueryResults(enabled, disabled).isEnabled).toBe(false);\n });\n });\n\n describe(\"numeric aggregation\", () => {\n it(\"sums failureCount from both queries\", () => {\n const resultA = pendingQuery({ failureCount: 1 });\n const resultB = pendingQuery({ failureCount: 4 });\n\n expect(combineQueryResults(resultA, resultB).failureCount).toBe(5);\n });\n\n it(\"sums errorUpdateCount from both queries\", () => {\n const resultA = pendingQuery({ errorUpdateCount: 2 });\n const resultB = pendingQuery({ errorUpdateCount: 3 });\n\n expect(combineQueryResults(resultA, resultB).errorUpdateCount).toBe(5);\n });\n\n it(\"uses max dataUpdatedAt\", () => {\n const resultA = pendingQuery({ dataUpdatedAt: 1000 });\n const resultB = pendingQuery({ dataUpdatedAt: 2000 });\n\n expect(combineQueryResults(resultA, resultB).dataUpdatedAt).toBe(2000);\n expect(combineQueryResults(resultB, resultA).dataUpdatedAt).toBe(2000);\n });\n\n it(\"uses max errorUpdatedAt\", () => {\n const resultA = pendingQuery({ errorUpdatedAt: 500 });\n const resultB = pendingQuery({ errorUpdatedAt: 1500 });\n\n expect(combineQueryResults(resultA, resultB).errorUpdatedAt).toBe(1500);\n });\n });\n\n describe(\"error and failureReason\", () => {\n it(\"uses first error if present\", () => {\n const errorA = new Error(\"Error A\");\n const errorB = new Error(\"Error B\");\n const resultA = errorQuery(errorA);\n const resultB = errorQuery(errorB);\n\n expect(combineQueryResults(resultA, resultB).error).toBe(errorA);\n });\n\n it(\"uses second error if first is null\", () => {\n const errorB = new Error(\"Error B\");\n const resultA = pendingQuery();\n const resultB = errorQuery(errorB);\n\n expect(combineQueryResults(resultA, resultB).error).toBe(errorB);\n });\n\n it(\"uses first failureReason if present\", () => {\n const reasonA = new Error(\"Reason A\");\n const reasonB = new Error(\"Reason B\");\n const resultA = pendingQuery({ failureReason: reasonA });\n const resultB = pendingQuery({ failureReason: reasonB });\n\n expect(combineQueryResults(resultA, resultB).failureReason).toBe(reasonA);\n });\n });\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"registry-validators.d.ts","sourceRoot":"","sources":["../../src/util/registry-validators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAoDrC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,uBAAuB,GAAG,IAAI,CAuB5E;AA0CD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,cAAc,GAAG;IACtE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CA6BA;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,OAAO,EACxB,UAAU,EAAE,OAAO,GAClB,IAAI,CAWN"}
1
+ {"version":3,"file":"registry-validators.d.ts","sourceRoot":"","sources":["../../src/util/registry-validators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EACT,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AAoDrC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,uBAAuB,GAAG,IAAI,CAiC5E;AA0CD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,cAAc,GAAG;IACtE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CA6BA;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,OAAO,EACxB,UAAU,EAAE,OAAO,GAClB,IAAI,CAWN"}
@@ -63,6 +63,13 @@ export function validateTool(tool) {
63
63
  }
64
64
  assertNoRecordSchema(inputSchema, `toolSchema of tool "${tool.name}"`);
65
65
  }
66
+ // Validate maxCalls if provided - must be a positive integer
67
+ if ("maxCalls" in tool && tool.maxCalls !== undefined) {
68
+ const maxCalls = tool.maxCalls;
69
+ if (!Number.isInteger(maxCalls) || maxCalls < 0) {
70
+ throw new Error(`maxCalls for tool "${tool.name}" must be a positive integer`);
71
+ }
72
+ }
66
73
  }
67
74
  /**
68
75
  * Converts a props schema to a serialized JSON Schema format.
@@ -1 +1 @@
1
- {"version":3,"file":"registry-validators.js","sourceRoot":"","sources":["../../src/util/registry-validators.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;GAIG;AACH,SAAS,cAAc,CAAC,MAAmB;IACzC,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC;AACrE,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,MAAe,EAAE,OAAe;IAC1D,IAAI,UAAuB,CAAC;IAE5B,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,OAAO;QACT,CAAC;IACH,CAAC;SAAM,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,UAAU,GAAG,MAAM,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,sCAAsC;QACtC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,GAAG,OAAO,qDAAqD;YAC7D,mBAAmB,UAAU,CAAC,IAAI,IAAI,SAAS,KAAK;YACpD,yDAAyD,CAC5D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAyC;IACpE,qBAAqB;IACrB,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAEnC,wBAAwB;IACxB,uBAAuB;IACvB,IAAI,aAAa,IAAI,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QAC9C,uCAAuC;QACvC,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,wBAAwB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAC3E,oBAAoB,CAClB,IAAI,CAAC,WAAW,EAChB,wBAAwB,IAAI,CAAC,IAAI,GAAG,CACrC,CAAC;IACJ,CAAC;IACD,iCAAiC;SAC5B,IAAI,YAAY,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACjD,IAAI,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,wEAAwE;QACxE,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpD,CAAC;QACD,oBAAoB,CAAC,WAAW,EAAE,uBAAuB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CACzB,eAAwB,EACxB,WAAoB,EACpB,IAAY;IAEZ,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;QACxE,OAAO,eAA0C,CAAC;IACpD,CAAC;IAED,0DAA0D;IAC1D,IAAI,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,kBAAkB,CAAC,WAAW,CAA4B,CAAC;QACpE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CACX,oBAAoB,IAAI,+BAA+B,EACvD,KAAK,CACN,CAAC;YACF,MAAM,IAAI,KAAK,CACb,oBAAoB,IAAI,iCAAiC,KAAK,EAAE,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,OAAO,WAAsC,CAAC;IAChD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,SAAyB;IAGnE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC;IAEzD,0BAA0B;IAC1B,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAEnC,0DAA0D;IAC1D,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,aAAa,IAAI,wEAAwE,CAC1F,CAAC;IACJ,CAAC;IAED,sDAAsD;IACtD,IAAI,WAAW,IAAI,eAAe,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,aAAa,IAAI,0GAA0G,CAC5H,CAAC;IACJ,CAAC;IAED,8DAA8D;IAC9D,IAAI,WAAW,EAAE,CAAC;QAChB,oBAAoB,CAAC,WAAW,EAAE,6BAA6B,IAAI,GAAG,CAAC,CAAC;IAC1E,CAAC;IAED,kDAAkD;IAClD,MAAM,KAAK,GAAG,kBAAkB,CAAC,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IAErE,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACrC,aAAqB,EACrB,QAAgB,EAChB,eAAwB,EACxB,UAAmB;IAEnB,oCAAoC;IACpC,eAAe,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAC5C,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAElC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,aAAa,aAAa,wBAAwB,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,wBAAwB,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC","sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport type {\n TamboComponent,\n TamboTool,\n TamboToolWithToolSchema,\n} from \"../model/component-metadata\";\nimport {\n assertNoRecordSchema,\n getZodFunctionArgs,\n isStandardSchema,\n looksLikeJSONSchema,\n schemaToJsonSchema,\n} from \"../schema\";\nimport { isZodFunctionSchema } from \"../schema/zod\";\nimport { assertValidName } from \"./validate-component-name\";\n\n/**\n * Checks if a JSON Schema represents an object type.\n * @param schema - The JSON Schema to check\n * @returns True if the schema is an object type\n */\nfunction isObjectSchema(schema: JSONSchema7): boolean {\n return schema.type === \"object\" || schema.properties !== undefined;\n}\n\n/**\n * Validates that a schema is an object type.\n * Throws an error if it's not.\n * @param schema - The schema to validate (Standard Schema or JSON Schema)\n * @param context - Description of where the schema is used (for error messages)\n */\nfunction assertObjectSchema(schema: unknown, context: string): void {\n let jsonSchema: JSONSchema7;\n\n if (isStandardSchema(schema)) {\n try {\n jsonSchema = schemaToJsonSchema(schema);\n } catch {\n // If conversion fails, we can't validate - let it fail later\n return;\n }\n } else if (looksLikeJSONSchema(schema)) {\n jsonSchema = schema;\n } else {\n // Unknown schema type, can't validate\n return;\n }\n\n if (!isObjectSchema(jsonSchema)) {\n throw new Error(\n `${context} must be an object schema (e.g., z.object({...})). ` +\n `Received type: \"${jsonSchema.type ?? \"unknown\"}\". ` +\n `Tool parameters are passed as a single object argument.`,\n );\n }\n}\n\n/**\n * Validates a tool before registration.\n * Throws an error if the tool is invalid.\n * @param tool - The tool to validate\n */\nexport function validateTool(tool: TamboTool | TamboToolWithToolSchema): void {\n // Validate tool name\n assertValidName(tool.name, \"tool\");\n\n // Validate tool schemas\n // 1. check inputSchema\n if (\"inputSchema\" in tool && tool.inputSchema) {\n // inputSchema must be an object schema\n assertObjectSchema(tool.inputSchema, `inputSchema of tool \"${tool.name}\"`);\n assertNoRecordSchema(\n tool.inputSchema,\n `inputSchema of tool \"${tool.name}\"`,\n );\n }\n // 2. check deprecated toolSchema\n else if (\"toolSchema\" in tool && tool.toolSchema) {\n let inputSchema = tool.toolSchema;\n // toolSchema may sometimes be a zod function schema, extract args if so\n if (isZodFunctionSchema(tool.toolSchema)) {\n inputSchema = getZodFunctionArgs(tool.toolSchema);\n }\n assertNoRecordSchema(inputSchema, `toolSchema of tool \"${tool.name}\"`);\n }\n}\n\n/**\n * Converts a props schema to a serialized JSON Schema format.\n * @param propsDefinition - Deprecated: legacy props definition (will log warning)\n * @param propsSchema - The props schema (Standard Schema or JSON Schema)\n * @param name - Component/tool name for error messages\n * @returns Serialized JSON Schema object\n */\nfunction getSerializedProps(\n propsDefinition: unknown,\n propsSchema: unknown,\n name: string,\n): Record<string, unknown> {\n if (propsDefinition) {\n console.warn(`propsDefinition is deprecated. Use propsSchema instead.`);\n return propsDefinition as Record<string, unknown>;\n }\n\n // Check for Standard Schema (Zod, Valibot, ArkType, etc.)\n if (isStandardSchema(propsSchema)) {\n try {\n return schemaToJsonSchema(propsSchema) as Record<string, unknown>;\n } catch (error) {\n console.error(\n `Error converting ${name} props schema to JSON Schema:`,\n error,\n );\n throw new Error(\n `Error converting ${name} props schema to JSON Schema: ${error}`,\n );\n }\n }\n\n // Check for JSON Schema\n if (looksLikeJSONSchema(propsSchema)) {\n return propsSchema as Record<string, unknown>;\n }\n\n throw new Error(`Invalid props schema for ${name}`);\n}\n\n/**\n * Validates a component and prepares its props for registration.\n * Throws an error if the component is invalid.\n * @param component - The component to validate and prepare\n * @returns Object containing the serialized props\n */\nexport function validateAndPrepareComponent(component: TamboComponent): {\n props: Record<string, unknown>;\n} {\n const { name, propsSchema, propsDefinition } = component;\n\n // Validate component name\n assertValidName(name, \"component\");\n\n // Validate that at least one props definition is provided\n if (!propsSchema && !propsDefinition) {\n throw new Error(\n `Component ${name} must have either propsSchema (recommended) or propsDefinition defined`,\n );\n }\n\n // Validate that only one props definition is provided\n if (propsSchema && propsDefinition) {\n throw new Error(\n `Component ${name} cannot have both propsSchema and propsDefinition defined. Use only one. We recommend using propsSchema.`,\n );\n }\n\n // Validate that the propsSchema does not include record types\n if (propsSchema) {\n assertNoRecordSchema(propsSchema, `propsSchema of component \"${name}\"`);\n }\n\n // Convert propsSchema to JSON Schema if it exists\n const props = getSerializedProps(propsDefinition, propsSchema, name);\n\n return { props };\n}\n\n/**\n * Validates a tool association between a component and tool.\n * Throws an error if the association is invalid.\n * @param componentName - The component name\n * @param toolName - The tool name\n * @param componentExists - Whether the component exists in the registry\n * @param toolExists - Whether the tool exists in the registry\n */\nexport function validateToolAssociation(\n componentName: string,\n toolName: string,\n componentExists: boolean,\n toolExists: boolean,\n): void {\n // Validate component and tool names\n assertValidName(componentName, \"component\");\n assertValidName(toolName, \"tool\");\n\n if (!componentExists) {\n throw new Error(`Component ${componentName} not found in registry`);\n }\n if (!toolExists) {\n throw new Error(`Tool ${toolName} not found in registry`);\n }\n}\n"]}
1
+ {"version":3,"file":"registry-validators.js","sourceRoot":"","sources":["../../src/util/registry-validators.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport type {\n TamboComponent,\n TamboTool,\n TamboToolWithToolSchema,\n} from \"../model/component-metadata\";\nimport {\n assertNoRecordSchema,\n getZodFunctionArgs,\n isStandardSchema,\n looksLikeJSONSchema,\n schemaToJsonSchema,\n} from \"../schema\";\nimport { isZodFunctionSchema } from \"../schema/zod\";\nimport { assertValidName } from \"./validate-component-name\";\n\n/**\n * Checks if a JSON Schema represents an object type.\n * @param schema - The JSON Schema to check\n * @returns True if the schema is an object type\n */\nfunction isObjectSchema(schema: JSONSchema7): boolean {\n return schema.type === \"object\" || schema.properties !== undefined;\n}\n\n/**\n * Validates that a schema is an object type.\n * Throws an error if it's not.\n * @param schema - The schema to validate (Standard Schema or JSON Schema)\n * @param context - Description of where the schema is used (for error messages)\n */\nfunction assertObjectSchema(schema: unknown, context: string): void {\n let jsonSchema: JSONSchema7;\n\n if (isStandardSchema(schema)) {\n try {\n jsonSchema = schemaToJsonSchema(schema);\n } catch {\n // If conversion fails, we can't validate - let it fail later\n return;\n }\n } else if (looksLikeJSONSchema(schema)) {\n jsonSchema = schema;\n } else {\n // Unknown schema type, can't validate\n return;\n }\n\n if (!isObjectSchema(jsonSchema)) {\n throw new Error(\n `${context} must be an object schema (e.g., z.object({...})). ` +\n `Received type: \"${jsonSchema.type ?? \"unknown\"}\". ` +\n `Tool parameters are passed as a single object argument.`,\n );\n }\n}\n\n/**\n * Validates a tool before registration.\n * Throws an error if the tool is invalid.\n * @param tool - The tool to validate\n */\nexport function validateTool(tool: TamboTool | TamboToolWithToolSchema): void {\n // Validate tool name\n assertValidName(tool.name, \"tool\");\n\n // Validate tool schemas\n // 1. check inputSchema\n if (\"inputSchema\" in tool && tool.inputSchema) {\n // inputSchema must be an object schema\n assertObjectSchema(tool.inputSchema, `inputSchema of tool \"${tool.name}\"`);\n assertNoRecordSchema(\n tool.inputSchema,\n `inputSchema of tool \"${tool.name}\"`,\n );\n }\n // 2. check deprecated toolSchema\n else if (\"toolSchema\" in tool && tool.toolSchema) {\n let inputSchema = tool.toolSchema;\n // toolSchema may sometimes be a zod function schema, extract args if so\n if (isZodFunctionSchema(tool.toolSchema)) {\n inputSchema = getZodFunctionArgs(tool.toolSchema);\n }\n assertNoRecordSchema(inputSchema, `toolSchema of tool \"${tool.name}\"`);\n }\n\n // Validate maxCalls if provided - must be a positive integer\n if (\"maxCalls\" in tool && tool.maxCalls !== undefined) {\n const maxCalls = tool.maxCalls;\n if (!Number.isInteger(maxCalls) || maxCalls < 0) {\n throw new Error(\n `maxCalls for tool \"${tool.name}\" must be a positive integer`,\n );\n }\n }\n}\n\n/**\n * Converts a props schema to a serialized JSON Schema format.\n * @param propsDefinition - Deprecated: legacy props definition (will log warning)\n * @param propsSchema - The props schema (Standard Schema or JSON Schema)\n * @param name - Component/tool name for error messages\n * @returns Serialized JSON Schema object\n */\nfunction getSerializedProps(\n propsDefinition: unknown,\n propsSchema: unknown,\n name: string,\n): Record<string, unknown> {\n if (propsDefinition) {\n console.warn(`propsDefinition is deprecated. Use propsSchema instead.`);\n return propsDefinition as Record<string, unknown>;\n }\n\n // Check for Standard Schema (Zod, Valibot, ArkType, etc.)\n if (isStandardSchema(propsSchema)) {\n try {\n return schemaToJsonSchema(propsSchema) as Record<string, unknown>;\n } catch (error) {\n console.error(\n `Error converting ${name} props schema to JSON Schema:`,\n error,\n );\n throw new Error(\n `Error converting ${name} props schema to JSON Schema: ${error}`,\n );\n }\n }\n\n // Check for JSON Schema\n if (looksLikeJSONSchema(propsSchema)) {\n return propsSchema as Record<string, unknown>;\n }\n\n throw new Error(`Invalid props schema for ${name}`);\n}\n\n/**\n * Validates a component and prepares its props for registration.\n * Throws an error if the component is invalid.\n * @param component - The component to validate and prepare\n * @returns Object containing the serialized props\n */\nexport function validateAndPrepareComponent(component: TamboComponent): {\n props: Record<string, unknown>;\n} {\n const { name, propsSchema, propsDefinition } = component;\n\n // Validate component name\n assertValidName(name, \"component\");\n\n // Validate that at least one props definition is provided\n if (!propsSchema && !propsDefinition) {\n throw new Error(\n `Component ${name} must have either propsSchema (recommended) or propsDefinition defined`,\n );\n }\n\n // Validate that only one props definition is provided\n if (propsSchema && propsDefinition) {\n throw new Error(\n `Component ${name} cannot have both propsSchema and propsDefinition defined. Use only one. We recommend using propsSchema.`,\n );\n }\n\n // Validate that the propsSchema does not include record types\n if (propsSchema) {\n assertNoRecordSchema(propsSchema, `propsSchema of component \"${name}\"`);\n }\n\n // Convert propsSchema to JSON Schema if it exists\n const props = getSerializedProps(propsDefinition, propsSchema, name);\n\n return { props };\n}\n\n/**\n * Validates a tool association between a component and tool.\n * Throws an error if the association is invalid.\n * @param componentName - The component name\n * @param toolName - The tool name\n * @param componentExists - Whether the component exists in the registry\n * @param toolExists - Whether the tool exists in the registry\n */\nexport function validateToolAssociation(\n componentName: string,\n toolName: string,\n componentExists: boolean,\n toolExists: boolean,\n): void {\n // Validate component and tool names\n assertValidName(componentName, \"component\");\n assertValidName(toolName, \"tool\");\n\n if (!componentExists) {\n throw new Error(`Component ${componentName} not found in registry`);\n }\n if (!toolExists) {\n throw new Error(`Tool ${toolName} not found in registry`);\n }\n}\n"]}
@@ -146,6 +146,63 @@ describe("validateTool", () => {
146
146
  };
147
147
  expect(() => validateTool(tool)).not.toThrow();
148
148
  });
149
+ describe("maxCalls validation", () => {
150
+ it("should throw when maxCalls is a negative integer", () => {
151
+ const tool = {
152
+ name: "tool-with-negative-maxcalls",
153
+ description: "A tool with negative maxCalls",
154
+ tool: () => "result",
155
+ inputSchema: z.object({ query: z.string() }),
156
+ outputSchema: z.string(),
157
+ maxCalls: -1,
158
+ };
159
+ expect(() => validateTool(tool)).toThrow('maxCalls for tool "tool-with-negative-maxcalls" must be a positive integer');
160
+ });
161
+ it("should throw when maxCalls is a decimal number", () => {
162
+ const tool = {
163
+ name: "tool-with-decimal-maxcalls",
164
+ description: "A tool with decimal maxCalls",
165
+ tool: () => "result",
166
+ inputSchema: z.object({ query: z.string() }),
167
+ outputSchema: z.string(),
168
+ maxCalls: 1.5,
169
+ };
170
+ expect(() => validateTool(tool)).toThrow('maxCalls for tool "tool-with-decimal-maxcalls" must be a positive integer');
171
+ });
172
+ it("should throw when maxCalls is NaN", () => {
173
+ const tool = {
174
+ name: "tool-with-nan-maxcalls",
175
+ description: "A tool with NaN maxCalls",
176
+ tool: () => "result",
177
+ inputSchema: z.object({ query: z.string() }),
178
+ outputSchema: z.string(),
179
+ maxCalls: NaN,
180
+ };
181
+ expect(() => validateTool(tool)).toThrow('maxCalls for tool "tool-with-nan-maxcalls" must be a positive integer');
182
+ });
183
+ it("should accept tool with maxCalls as zero", () => {
184
+ const tool = {
185
+ name: "tool-with-zero-maxcalls",
186
+ description: "A tool with zero maxCalls",
187
+ tool: () => "result",
188
+ inputSchema: z.object({ query: z.string() }),
189
+ outputSchema: z.string(),
190
+ maxCalls: 0,
191
+ };
192
+ expect(() => validateTool(tool)).not.toThrow();
193
+ });
194
+ it("should accept tool with explicitly undefined maxCalls", () => {
195
+ const tool = {
196
+ name: "tool-with-undefined-maxcalls",
197
+ description: "A tool with undefined maxCalls",
198
+ tool: () => "result",
199
+ inputSchema: z.object({ query: z.string() }),
200
+ outputSchema: z.string(),
201
+ maxCalls: undefined,
202
+ };
203
+ expect(() => validateTool(tool)).not.toThrow();
204
+ });
205
+ });
149
206
  });
150
207
  describe("validateAndPrepareComponent", () => {
151
208
  it("should validate component with propsSchema", () => {