@lovrozagar/honey 0.6.8 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (674) hide show
  1. package/README.md +514 -192
  2. package/bin/honey.js +25 -0
  3. package/dist/accepts.d.ts +7 -1
  4. package/dist/accepts.d.ts.map +1 -1
  5. package/dist/accepts.js +126 -0
  6. package/dist/accepts.js.map +1 -0
  7. package/dist/body-kind.d.ts +26 -0
  8. package/dist/body-kind.d.ts.map +1 -0
  9. package/dist/body-kind.js +70 -0
  10. package/dist/body-kind.js.map +1 -0
  11. package/dist/body-limit.d.ts +5 -1
  12. package/dist/body-limit.d.ts.map +1 -1
  13. package/dist/body-limit.js +126 -0
  14. package/dist/body-limit.js.map +1 -0
  15. package/dist/build/index.d.ts +19 -3
  16. package/dist/build/index.d.ts.map +1 -1
  17. package/dist/build/index.js +173 -0
  18. package/dist/build/index.js.map +1 -0
  19. package/dist/cli-args.d.ts +33 -0
  20. package/dist/cli-args.d.ts.map +1 -0
  21. package/dist/cli-args.js +102 -0
  22. package/dist/cli-args.js.map +1 -0
  23. package/dist/cli-go/auth.go +26 -0
  24. package/dist/cli-go/config.go +192 -0
  25. package/dist/cli-go/errors.go +75 -0
  26. package/dist/cli-go/multipart.go +79 -0
  27. package/dist/cli-go/output.go +163 -0
  28. package/dist/cli-go/root.go +30 -0
  29. package/dist/cli-go/stream.go +88 -0
  30. package/dist/cli-go/version.go +5 -0
  31. package/dist/cli.d.ts +1 -1
  32. package/dist/cli.js +209 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/client/defaults.js +48 -0
  35. package/dist/client/defaults.js.map +1 -0
  36. package/dist/client/error.d.ts +35 -0
  37. package/dist/client/error.d.ts.map +1 -1
  38. package/dist/client/error.js +71 -0
  39. package/dist/client/error.js.map +1 -0
  40. package/dist/client/http.d.ts +67 -8
  41. package/dist/client/http.d.ts.map +1 -1
  42. package/dist/client/http.js +571 -0
  43. package/dist/client/http.js.map +1 -0
  44. package/dist/client/index.d.ts +3 -2
  45. package/dist/client/index.d.ts.map +1 -1
  46. package/dist/client/index.js +95 -0
  47. package/dist/client/index.js.map +1 -0
  48. package/dist/client/path.d.ts +26 -0
  49. package/dist/client/path.d.ts.map +1 -0
  50. package/dist/client/path.js +163 -0
  51. package/dist/client/path.js.map +1 -0
  52. package/dist/client/redirect-policy.d.ts +12 -0
  53. package/dist/client/redirect-policy.d.ts.map +1 -0
  54. package/dist/client/redirect-policy.js +20 -0
  55. package/dist/client/redirect-policy.js.map +1 -0
  56. package/dist/client/sdk.d.ts +36 -0
  57. package/dist/client/sdk.d.ts.map +1 -1
  58. package/dist/client/sdk.js +292 -0
  59. package/dist/client/sdk.js.map +1 -0
  60. package/dist/client/sse.d.ts +13 -0
  61. package/dist/client/sse.d.ts.map +1 -1
  62. package/dist/client/sse.js +129 -0
  63. package/dist/client/sse.js.map +1 -0
  64. package/dist/client/types.js +2 -0
  65. package/dist/client/types.js.map +1 -0
  66. package/dist/client/ws.d.ts +9 -2
  67. package/dist/client/ws.d.ts.map +1 -1
  68. package/dist/client/ws.js +112 -0
  69. package/dist/client/ws.js.map +1 -0
  70. package/dist/client-go/errors.go +236 -0
  71. package/dist/client-go/export.go +44 -0
  72. package/dist/client-go/invalidation.go +371 -0
  73. package/dist/client-go/nullable.go +62 -0
  74. package/dist/client-go/realtime.go +354 -0
  75. package/dist/client-go/result.go +20 -0
  76. package/dist/client-go/runtime.go +975 -0
  77. package/dist/client-go/sse.go +159 -0
  78. package/dist/client-go/transport.go +495 -0
  79. package/dist/client-go/ws.go +128 -0
  80. package/dist/client-info.d.ts +36 -0
  81. package/dist/client-info.d.ts.map +1 -0
  82. package/dist/client-info.js +53 -0
  83. package/dist/client-info.js.map +1 -0
  84. package/dist/client-mcp/README.md +10 -0
  85. package/dist/client-mcp/server.ts +221 -0
  86. package/dist/client-mcp/types.ts +19 -0
  87. package/dist/client-python/_errors.py +115 -0
  88. package/dist/client-python/_invalidation.py +494 -0
  89. package/dist/client-python/_realtime.py +179 -0
  90. package/dist/client-python/_runtime.py +860 -0
  91. package/dist/client-python/_sse.py +155 -0
  92. package/dist/client-python/_transport.py +366 -0
  93. package/dist/client-python/_ws.py +159 -0
  94. package/dist/client-python/py.typed +0 -0
  95. package/dist/client-rust/errors.rs +220 -0
  96. package/dist/client-rust/invalidation.rs +412 -0
  97. package/dist/client-rust/invalidation_sync.rs +93 -0
  98. package/dist/client-rust/nullable.rs +17 -0
  99. package/dist/client-rust/realtime.rs +702 -0
  100. package/dist/client-rust/result.rs +22 -0
  101. package/dist/client-rust/runtime.rs +980 -0
  102. package/dist/client-rust/runtime_sync.rs +484 -0
  103. package/dist/client-rust/sse.rs +188 -0
  104. package/dist/client-rust/ws.rs +167 -0
  105. package/dist/codegen-go-cli.d.ts.map +1 -1
  106. package/dist/codegen-go-cli.js +964 -0
  107. package/dist/codegen-go-cli.js.map +1 -0
  108. package/dist/codegen-go.d.ts +15 -3
  109. package/dist/codegen-go.d.ts.map +1 -1
  110. package/dist/codegen-go.js +872 -0
  111. package/dist/codegen-go.js.map +1 -0
  112. package/dist/codegen-hash.js +9 -0
  113. package/dist/codegen-hash.js.map +1 -0
  114. package/dist/codegen-ir.d.ts +69 -2
  115. package/dist/codegen-ir.d.ts.map +1 -1
  116. package/dist/codegen-ir.js +661 -0
  117. package/dist/codegen-ir.js.map +1 -0
  118. package/dist/codegen-lang.d.ts +65 -0
  119. package/dist/codegen-lang.d.ts.map +1 -0
  120. package/dist/codegen-lang.js +526 -0
  121. package/dist/codegen-lang.js.map +1 -0
  122. package/dist/codegen-load.d.ts +31 -0
  123. package/dist/codegen-load.d.ts.map +1 -0
  124. package/dist/codegen-load.js +138 -0
  125. package/dist/codegen-load.js.map +1 -0
  126. package/dist/codegen-loaders.js +55 -0
  127. package/dist/codegen-loaders.js.map +1 -0
  128. package/dist/codegen-mcp.d.ts.map +1 -1
  129. package/dist/codegen-mcp.js +368 -0
  130. package/dist/codegen-mcp.js.map +1 -0
  131. package/dist/codegen-python.d.ts +13 -1
  132. package/dist/codegen-python.d.ts.map +1 -1
  133. package/dist/codegen-python.js +828 -0
  134. package/dist/codegen-python.js.map +1 -0
  135. package/dist/codegen-route-tree-intern.d.ts +15 -5
  136. package/dist/codegen-route-tree-intern.d.ts.map +1 -1
  137. package/dist/codegen-route-tree-intern.js +221 -0
  138. package/dist/codegen-route-tree-intern.js.map +1 -0
  139. package/dist/codegen-rust.d.ts.map +1 -1
  140. package/dist/codegen-rust.js +1293 -0
  141. package/dist/codegen-rust.js.map +1 -0
  142. package/dist/codegen-sanitize.d.ts.map +1 -1
  143. package/dist/codegen-sanitize.js +56 -0
  144. package/dist/codegen-sanitize.js.map +1 -0
  145. package/dist/codegen-schema-naming.d.ts +5 -0
  146. package/dist/codegen-schema-naming.d.ts.map +1 -1
  147. package/dist/codegen-schema-naming.js +150 -0
  148. package/dist/codegen-schema-naming.js.map +1 -0
  149. package/dist/codegen-sdk-model.d.ts +71 -0
  150. package/dist/codegen-sdk-model.d.ts.map +1 -0
  151. package/dist/codegen-sdk-model.js +179 -0
  152. package/dist/codegen-sdk-model.js.map +1 -0
  153. package/dist/codegen.d.ts +41 -23
  154. package/dist/codegen.d.ts.map +1 -1
  155. package/dist/codegen.js +4610 -0
  156. package/dist/codegen.js.map +1 -0
  157. package/dist/context.d.ts +36 -6
  158. package/dist/context.d.ts.map +1 -1
  159. package/dist/context.js +242 -0
  160. package/dist/context.js.map +1 -0
  161. package/dist/cookie-sign.d.ts +16 -2
  162. package/dist/cookie-sign.d.ts.map +1 -1
  163. package/dist/cookie-sign.js +104 -0
  164. package/dist/cookie-sign.js.map +1 -0
  165. package/dist/cookie.d.ts +12 -0
  166. package/dist/cookie.d.ts.map +1 -1
  167. package/dist/cookie.js +138 -0
  168. package/dist/cookie.js.map +1 -0
  169. package/dist/cors.d.ts +1 -0
  170. package/dist/cors.d.ts.map +1 -1
  171. package/dist/cors.js +87 -0
  172. package/dist/cors.js.map +1 -0
  173. package/dist/crypto.d.ts +6 -1
  174. package/dist/crypto.d.ts.map +1 -1
  175. package/dist/crypto.js +38 -0
  176. package/dist/crypto.js.map +1 -0
  177. package/dist/csrf.d.ts +19 -0
  178. package/dist/csrf.d.ts.map +1 -1
  179. package/dist/csrf.js +79 -0
  180. package/dist/csrf.js.map +1 -0
  181. package/dist/curl-logger.d.ts +14 -3
  182. package/dist/curl-logger.d.ts.map +1 -1
  183. package/dist/curl-logger.js +199 -0
  184. package/dist/curl-logger.js.map +1 -0
  185. package/dist/detect-runtime.js +13 -0
  186. package/dist/detect-runtime.js.map +1 -0
  187. package/dist/dict.d.ts +11 -0
  188. package/dist/dict.d.ts.map +1 -0
  189. package/dist/dict.js +13 -0
  190. package/dist/dict.js.map +1 -0
  191. package/dist/error.d.ts.map +1 -1
  192. package/dist/error.js +44 -0
  193. package/dist/error.js.map +1 -0
  194. package/dist/errors.js +39 -0
  195. package/dist/errors.js.map +1 -0
  196. package/dist/etag.d.ts +2 -0
  197. package/dist/etag.d.ts.map +1 -1
  198. package/dist/etag.js +82 -0
  199. package/dist/etag.js.map +1 -0
  200. package/dist/feature-detect.d.ts +25 -0
  201. package/dist/feature-detect.d.ts.map +1 -0
  202. package/dist/feature-detect.js +144 -0
  203. package/dist/feature-detect.js.map +1 -0
  204. package/dist/feature-load.js +36 -0
  205. package/dist/feature-load.js.map +1 -0
  206. package/dist/feature-slots.d.ts +44 -0
  207. package/dist/feature-slots.d.ts.map +1 -0
  208. package/dist/feature-slots.js +48 -0
  209. package/dist/feature-slots.js.map +1 -0
  210. package/dist/fetch-request.d.ts +10 -0
  211. package/dist/fetch-request.d.ts.map +1 -0
  212. package/dist/fetch-request.js +13 -0
  213. package/dist/fetch-request.js.map +1 -0
  214. package/dist/gen-process.d.ts +15 -0
  215. package/dist/gen-process.d.ts.map +1 -0
  216. package/dist/gen-process.js +43 -0
  217. package/dist/gen-process.js.map +1 -0
  218. package/dist/gen-write.d.ts +19 -0
  219. package/dist/gen-write.d.ts.map +1 -0
  220. package/dist/gen-write.js +120 -0
  221. package/dist/gen-write.js.map +1 -0
  222. package/dist/glob.d.ts +21 -0
  223. package/dist/glob.d.ts.map +1 -0
  224. package/dist/glob.js +115 -0
  225. package/dist/glob.js.map +1 -0
  226. package/dist/go-type-emitter.d.ts +18 -4
  227. package/dist/go-type-emitter.d.ts.map +1 -1
  228. package/dist/go-type-emitter.js +594 -0
  229. package/dist/go-type-emitter.js.map +1 -0
  230. package/dist/honey-response.d.ts.map +1 -1
  231. package/dist/honey-response.js +338 -0
  232. package/dist/honey-response.js.map +1 -0
  233. package/dist/i18n-slot.d.ts +8 -0
  234. package/dist/i18n-slot.d.ts.map +1 -1
  235. package/dist/i18n-slot.js +14 -0
  236. package/dist/i18n-slot.js.map +1 -0
  237. package/dist/i18n.d.ts +3 -0
  238. package/dist/i18n.d.ts.map +1 -1
  239. package/dist/i18n.js +250 -0
  240. package/dist/i18n.js.map +1 -0
  241. package/dist/index.d.ts +408 -148
  242. package/dist/index.d.ts.map +1 -1
  243. package/dist/index.js +2324 -0
  244. package/dist/index.js.map +1 -0
  245. package/dist/init.d.ts +3 -5
  246. package/dist/init.d.ts.map +1 -1
  247. package/dist/init.js +140 -0
  248. package/dist/init.js.map +1 -0
  249. package/dist/input.js +4 -0
  250. package/dist/input.js.map +1 -0
  251. package/dist/invalidate-check.d.ts +11 -0
  252. package/dist/invalidate-check.d.ts.map +1 -1
  253. package/dist/invalidate-check.js +163 -0
  254. package/dist/invalidate-check.js.map +1 -0
  255. package/dist/invoke-user.d.ts +35 -0
  256. package/dist/invoke-user.d.ts.map +1 -0
  257. package/dist/invoke-user.js +73 -0
  258. package/dist/invoke-user.js.map +1 -0
  259. package/dist/ip-restrict.d.ts +13 -1
  260. package/dist/ip-restrict.d.ts.map +1 -1
  261. package/dist/ip-restrict.js +60 -0
  262. package/dist/ip-restrict.js.map +1 -0
  263. package/dist/ip.d.ts +39 -0
  264. package/dist/ip.d.ts.map +1 -0
  265. package/dist/ip.js +209 -0
  266. package/dist/ip.js.map +1 -0
  267. package/dist/logger.d.ts.map +1 -1
  268. package/dist/logger.js +113 -0
  269. package/dist/logger.js.map +1 -0
  270. package/dist/media-type.d.ts +30 -0
  271. package/dist/media-type.d.ts.map +1 -0
  272. package/dist/media-type.js +97 -0
  273. package/dist/media-type.js.map +1 -0
  274. package/dist/meta-spec-merge.d.ts +32 -0
  275. package/dist/meta-spec-merge.d.ts.map +1 -0
  276. package/dist/meta-spec-merge.js +68 -0
  277. package/dist/meta-spec-merge.js.map +1 -0
  278. package/dist/meta-spec.d.ts +16 -3
  279. package/dist/meta-spec.d.ts.map +1 -1
  280. package/dist/meta-spec.js +535 -0
  281. package/dist/meta-spec.js.map +1 -0
  282. package/dist/middleware.d.ts +23 -6
  283. package/dist/middleware.d.ts.map +1 -1
  284. package/dist/middleware.js +253 -0
  285. package/dist/middleware.js.map +1 -0
  286. package/dist/node-request.d.ts +57 -12
  287. package/dist/node-request.d.ts.map +1 -1
  288. package/dist/node-request.js +407 -0
  289. package/dist/node-request.js.map +1 -0
  290. package/dist/node.d.ts +20 -3
  291. package/dist/node.d.ts.map +1 -1
  292. package/dist/node.js +396 -0
  293. package/dist/node.js.map +1 -0
  294. package/dist/openapi/collect.d.ts +6 -3
  295. package/dist/openapi/collect.d.ts.map +1 -1
  296. package/dist/openapi/collect.js +30 -0
  297. package/dist/openapi/collect.js.map +1 -0
  298. package/dist/openapi/docs-page.d.ts +42 -0
  299. package/dist/openapi/docs-page.d.ts.map +1 -0
  300. package/dist/openapi/docs-page.js +80 -0
  301. package/dist/openapi/docs-page.js.map +1 -0
  302. package/dist/openapi/document.d.ts +4 -0
  303. package/dist/openapi/document.d.ts.map +1 -1
  304. package/dist/openapi/document.js +785 -0
  305. package/dist/openapi/document.js.map +1 -0
  306. package/dist/openapi/json-schema-slot.d.ts +7 -0
  307. package/dist/openapi/json-schema-slot.d.ts.map +1 -1
  308. package/dist/openapi/json-schema-slot.js +38 -0
  309. package/dist/openapi/json-schema-slot.js.map +1 -0
  310. package/dist/openapi/register.d.ts.map +1 -1
  311. package/dist/openapi/register.js +20 -0
  312. package/dist/openapi/register.js.map +1 -0
  313. package/dist/openapi/scalar.d.ts +3 -1
  314. package/dist/openapi/scalar.d.ts.map +1 -1
  315. package/dist/openapi/scalar.js +21 -0
  316. package/dist/openapi/scalar.js.map +1 -0
  317. package/dist/openapi/serve.d.ts +9 -0
  318. package/dist/openapi/serve.d.ts.map +1 -0
  319. package/dist/openapi/serve.js +36 -0
  320. package/dist/openapi/serve.js.map +1 -0
  321. package/dist/openapi/spec-factory.d.ts +30 -1
  322. package/dist/openapi/spec-factory.d.ts.map +1 -1
  323. package/dist/openapi/spec-factory.js +52 -0
  324. package/dist/openapi/spec-factory.js.map +1 -0
  325. package/dist/openapi/spec.d.ts +14 -5
  326. package/dist/openapi/spec.d.ts.map +1 -1
  327. package/dist/openapi/spec.js +50 -0
  328. package/dist/openapi/spec.js.map +1 -0
  329. package/dist/openapi/swagger.d.ts +3 -1
  330. package/dist/openapi/swagger.d.ts.map +1 -1
  331. package/dist/openapi/swagger.js +22 -0
  332. package/dist/openapi/swagger.js.map +1 -0
  333. package/dist/pattern.d.ts +71 -0
  334. package/dist/pattern.d.ts.map +1 -0
  335. package/dist/pattern.js +239 -0
  336. package/dist/pattern.js.map +1 -0
  337. package/dist/peer.d.ts +17 -0
  338. package/dist/peer.d.ts.map +1 -0
  339. package/dist/peer.js +50 -0
  340. package/dist/peer.js.map +1 -0
  341. package/dist/plugin.d.ts +67 -16
  342. package/dist/plugin.d.ts.map +1 -1
  343. package/dist/plugin.js +649 -0
  344. package/dist/plugin.js.map +1 -0
  345. package/dist/powered-by.d.ts.map +1 -1
  346. package/dist/powered-by.js +11 -0
  347. package/dist/powered-by.js.map +1 -0
  348. package/dist/pretty-json.d.ts.map +1 -1
  349. package/dist/pretty-json.js +47 -0
  350. package/dist/pretty-json.js.map +1 -0
  351. package/dist/producer-stream.d.ts +47 -0
  352. package/dist/producer-stream.d.ts.map +1 -0
  353. package/dist/producer-stream.js +267 -0
  354. package/dist/producer-stream.js.map +1 -0
  355. package/dist/proxy.d.ts +47 -8
  356. package/dist/proxy.d.ts.map +1 -1
  357. package/dist/proxy.js +274 -0
  358. package/dist/proxy.js.map +1 -0
  359. package/dist/python-type-emitter.d.ts +14 -1
  360. package/dist/python-type-emitter.d.ts.map +1 -1
  361. package/dist/python-type-emitter.js +157 -0
  362. package/dist/python-type-emitter.js.map +1 -0
  363. package/dist/realtime/bus.d.ts +17 -1
  364. package/dist/realtime/bus.d.ts.map +1 -1
  365. package/dist/realtime/bus.js +112 -0
  366. package/dist/realtime/bus.js.map +1 -0
  367. package/dist/realtime/register.d.ts +3 -0
  368. package/dist/realtime/register.d.ts.map +1 -0
  369. package/dist/realtime/register.js +10 -0
  370. package/dist/realtime/register.js.map +1 -0
  371. package/dist/realtime/route.d.ts +65 -26
  372. package/dist/realtime/route.d.ts.map +1 -1
  373. package/dist/realtime/route.js +72 -0
  374. package/dist/realtime/route.js.map +1 -0
  375. package/dist/realtime/server.d.ts +43 -0
  376. package/dist/realtime/server.d.ts.map +1 -0
  377. package/dist/realtime/server.js +255 -0
  378. package/dist/realtime/server.js.map +1 -0
  379. package/dist/request-id.d.ts +7 -0
  380. package/dist/request-id.d.ts.map +1 -1
  381. package/dist/request-id.js +16 -0
  382. package/dist/request-id.js.map +1 -0
  383. package/dist/request-limits.d.ts +3 -0
  384. package/dist/request-limits.d.ts.map +1 -0
  385. package/dist/request-limits.js +3 -0
  386. package/dist/request-limits.js.map +1 -0
  387. package/dist/request-path.d.ts +33 -0
  388. package/dist/request-path.d.ts.map +1 -0
  389. package/dist/request-path.js +178 -0
  390. package/dist/request-path.js.map +1 -0
  391. package/dist/request-to-curl.d.ts +7 -1
  392. package/dist/request-to-curl.d.ts.map +1 -1
  393. package/dist/request-to-curl.js +48 -0
  394. package/dist/request-to-curl.js.map +1 -0
  395. package/dist/response.d.ts +25 -2
  396. package/dist/response.d.ts.map +1 -1
  397. package/dist/response.js +313 -0
  398. package/dist/response.js.map +1 -0
  399. package/dist/rust-type-emitter.d.ts +14 -2
  400. package/dist/rust-type-emitter.d.ts.map +1 -1
  401. package/dist/rust-type-emitter.js +463 -0
  402. package/dist/rust-type-emitter.js.map +1 -0
  403. package/dist/secure-headers.d.ts.map +1 -1
  404. package/dist/secure-headers.js +53 -0
  405. package/dist/secure-headers.js.map +1 -0
  406. package/dist/serve-register.d.ts +4 -0
  407. package/dist/serve-register.d.ts.map +1 -1
  408. package/dist/serve-register.js +9 -0
  409. package/dist/serve-register.js.map +1 -0
  410. package/dist/serve-slot.d.ts +3 -0
  411. package/dist/serve-slot.d.ts.map +1 -1
  412. package/dist/serve-slot.js +52 -0
  413. package/dist/serve-slot.js.map +1 -0
  414. package/dist/serve.d.ts +18 -1
  415. package/dist/serve.d.ts.map +1 -1
  416. package/dist/serve.js +157 -0
  417. package/dist/serve.js.map +1 -0
  418. package/dist/server-timing.d.ts.map +1 -1
  419. package/dist/server-timing.js +51 -0
  420. package/dist/server-timing.js.map +1 -0
  421. package/dist/static.d.ts +9 -0
  422. package/dist/static.d.ts.map +1 -1
  423. package/dist/static.js +102 -0
  424. package/dist/static.js.map +1 -0
  425. package/dist/telemetry/otel.d.ts +2 -0
  426. package/dist/telemetry/otel.d.ts.map +1 -1
  427. package/dist/telemetry/otel.js +135 -0
  428. package/dist/telemetry/otel.js.map +1 -0
  429. package/dist/testing.d.ts +12 -0
  430. package/dist/testing.d.ts.map +1 -1
  431. package/dist/testing.js +124 -0
  432. package/dist/testing.js.map +1 -0
  433. package/dist/timeout.d.ts +6 -0
  434. package/dist/timeout.d.ts.map +1 -1
  435. package/dist/timeout.js +36 -0
  436. package/dist/timeout.js.map +1 -0
  437. package/dist/tree.d.ts +133 -36
  438. package/dist/tree.d.ts.map +1 -1
  439. package/dist/tree.js +437 -0
  440. package/dist/tree.js.map +1 -0
  441. package/dist/trust.d.ts +21 -0
  442. package/dist/trust.d.ts.map +1 -0
  443. package/dist/trust.js +100 -0
  444. package/dist/trust.js.map +1 -0
  445. package/dist/ts-type-emitter.d.ts.map +1 -1
  446. package/dist/ts-type-emitter.js +150 -0
  447. package/dist/ts-type-emitter.js.map +1 -0
  448. package/dist/type-emitter.d.ts +16 -2
  449. package/dist/type-emitter.d.ts.map +1 -1
  450. package/dist/type-emitter.js +729 -0
  451. package/dist/type-emitter.js.map +1 -0
  452. package/dist/type-extractor.d.ts +8 -4
  453. package/dist/type-extractor.d.ts.map +1 -1
  454. package/dist/type-extractor.js +819 -0
  455. package/dist/type-extractor.js.map +1 -0
  456. package/dist/types.d.ts +7 -0
  457. package/dist/types.d.ts.map +1 -1
  458. package/dist/types.js +96 -0
  459. package/dist/types.js.map +1 -0
  460. package/dist/validation.d.ts +14 -2
  461. package/dist/validation.d.ts.map +1 -1
  462. package/dist/validation.js +335 -0
  463. package/dist/validation.js.map +1 -0
  464. package/dist/with-headers.d.ts +15 -0
  465. package/dist/with-headers.d.ts.map +1 -0
  466. package/dist/with-headers.js +45 -0
  467. package/dist/with-headers.js.map +1 -0
  468. package/dist/ws/bun.d.ts +11 -5
  469. package/dist/ws/bun.d.ts.map +1 -1
  470. package/dist/ws/bun.js +82 -0
  471. package/dist/ws/bun.js.map +1 -0
  472. package/dist/ws/cloudflare.d.ts +25 -3
  473. package/dist/ws/cloudflare.d.ts.map +1 -1
  474. package/dist/ws/cloudflare.js +117 -0
  475. package/dist/ws/cloudflare.js.map +1 -0
  476. package/dist/ws/deno.d.ts +4 -4
  477. package/dist/ws/deno.d.ts.map +1 -1
  478. package/dist/ws/deno.js +133 -0
  479. package/dist/ws/deno.js.map +1 -0
  480. package/dist/ws/node.d.ts +20 -3
  481. package/dist/ws/node.d.ts.map +1 -1
  482. package/dist/ws/node.js +173 -0
  483. package/dist/ws/node.js.map +1 -0
  484. package/dist/ws/session.d.ts +11 -0
  485. package/dist/ws/session.d.ts.map +1 -0
  486. package/dist/ws/session.js +60 -0
  487. package/dist/ws/session.js.map +1 -0
  488. package/dist/ws/shared.d.ts +65 -0
  489. package/dist/ws/shared.d.ts.map +1 -0
  490. package/dist/ws/shared.js +103 -0
  491. package/dist/ws/shared.js.map +1 -0
  492. package/dist/ws-origin.d.ts +20 -0
  493. package/dist/ws-origin.d.ts.map +1 -0
  494. package/dist/ws-origin.js +41 -0
  495. package/dist/ws-origin.js.map +1 -0
  496. package/dist/yaml.d.ts +15 -1
  497. package/dist/yaml.d.ts.map +1 -1
  498. package/dist/yaml.js +101 -0
  499. package/dist/yaml.js.map +1 -0
  500. package/docs/invalidate-spec.md +13 -1
  501. package/docs/meta-spec.md +36 -12
  502. package/docs/packaging.md +43 -24
  503. package/docs/regression-matrix/README.md +32 -0
  504. package/docs/regression-matrix/review.md +44 -0
  505. package/docs/regression-matrix/ws1-3.md +97 -0
  506. package/docs/regression-matrix/ws4-8.md +107 -0
  507. package/docs/regression-matrix/ws9-12.md +266 -0
  508. package/docs/sdk.md +102 -52
  509. package/package.json +183 -52
  510. package/src/accepts.ts +91 -33
  511. package/src/body-kind.ts +67 -0
  512. package/src/body-limit.ts +102 -87
  513. package/src/build/index.ts +104 -54
  514. package/src/cli-args.ts +123 -0
  515. package/src/cli-go/auth.go +12 -1
  516. package/src/cli-go/config.go +29 -2
  517. package/src/cli-go/errors.go +28 -10
  518. package/src/cli-go/multipart.go +51 -27
  519. package/src/cli-go/output.go +58 -4
  520. package/src/cli-go/root.go +1 -1
  521. package/src/cli-go/version.go +2 -2
  522. package/src/cli.ts +154 -148
  523. package/src/client/error.ts +56 -1
  524. package/src/client/http.ts +479 -256
  525. package/src/client/index.ts +55 -17
  526. package/src/client/path.ts +169 -0
  527. package/src/client/redirect-policy.ts +19 -0
  528. package/src/client/sdk.ts +180 -101
  529. package/src/client/sse.ts +92 -66
  530. package/src/client/ws.ts +67 -31
  531. package/src/client-go/errors.go +41 -12
  532. package/src/client-go/export.go +44 -0
  533. package/src/client-go/invalidation.go +52 -54
  534. package/src/client-go/nullable.go +62 -0
  535. package/src/client-go/realtime.go +147 -110
  536. package/src/client-go/runtime.go +646 -88
  537. package/src/client-go/sse.go +104 -94
  538. package/src/client-go/transport.go +67 -27
  539. package/src/client-go/ws.go +49 -25
  540. package/src/client-info.ts +79 -0
  541. package/src/client-mcp/server.ts +133 -3
  542. package/src/client-python/_invalidation.py +207 -291
  543. package/src/client-python/_realtime.py +63 -40
  544. package/src/client-python/_runtime.py +501 -119
  545. package/src/client-python/_sse.py +130 -74
  546. package/src/client-python/_transport.py +37 -9
  547. package/src/client-python/_ws.py +50 -22
  548. package/src/client-rust/errors.rs +21 -1
  549. package/src/client-rust/invalidation.rs +202 -231
  550. package/src/client-rust/invalidation_sync.rs +16 -229
  551. package/src/client-rust/nullable.rs +17 -0
  552. package/src/client-rust/realtime.rs +217 -217
  553. package/src/client-rust/runtime.rs +602 -177
  554. package/src/client-rust/runtime_sync.rs +169 -145
  555. package/src/client-rust/sse.rs +142 -121
  556. package/src/client-rust/ws.rs +61 -37
  557. package/src/codegen-go-cli.ts +607 -728
  558. package/src/codegen-go.ts +710 -770
  559. package/src/codegen-ir.ts +381 -75
  560. package/src/codegen-lang.ts +517 -0
  561. package/src/codegen-load.ts +150 -0
  562. package/src/codegen-mcp.ts +207 -108
  563. package/src/codegen-python.ts +684 -816
  564. package/src/codegen-route-tree-intern.ts +51 -25
  565. package/src/codegen-rust.ts +946 -1240
  566. package/src/codegen-sanitize.ts +0 -4
  567. package/src/codegen-schema-naming.ts +19 -6
  568. package/src/codegen-sdk-model.ts +228 -0
  569. package/src/codegen.ts +1488 -1140
  570. package/src/context.ts +130 -11
  571. package/src/cookie-sign.ts +85 -16
  572. package/src/cookie.ts +66 -11
  573. package/src/cors.ts +55 -54
  574. package/src/crypto.ts +27 -5
  575. package/src/csrf.ts +57 -25
  576. package/src/curl-logger.ts +155 -114
  577. package/src/dict.ts +12 -0
  578. package/src/error.ts +4 -2
  579. package/src/etag.ts +58 -34
  580. package/src/feature-detect.ts +147 -0
  581. package/src/feature-slots.ts +70 -0
  582. package/src/fetch-request.ts +13 -0
  583. package/src/gen-process.ts +42 -0
  584. package/src/gen-write.ts +127 -0
  585. package/src/glob.ts +109 -0
  586. package/src/go-type-emitter.ts +406 -155
  587. package/src/honey-response.ts +36 -9
  588. package/src/i18n-slot.ts +10 -0
  589. package/src/i18n.ts +98 -23
  590. package/src/index.ts +1887 -1756
  591. package/src/init.ts +40 -28
  592. package/src/invalidate-check.ts +42 -4
  593. package/src/invoke-user.ts +95 -0
  594. package/src/ip-restrict.ts +47 -161
  595. package/src/ip.ts +194 -0
  596. package/src/logger.ts +65 -36
  597. package/src/media-type.ts +104 -0
  598. package/src/meta-spec-merge.ts +80 -0
  599. package/src/meta-spec.ts +0 -0
  600. package/src/middleware.ts +112 -12
  601. package/src/node-request.ts +242 -52
  602. package/src/node.ts +318 -75
  603. package/src/openapi/collect.ts +19 -44
  604. package/src/openapi/docs-page.ts +89 -0
  605. package/src/openapi/document.ts +503 -224
  606. package/src/openapi/json-schema-slot.ts +40 -0
  607. package/src/openapi/register.ts +7 -2
  608. package/src/openapi/scalar.ts +11 -10
  609. package/src/openapi/serve.ts +39 -0
  610. package/src/openapi/spec-factory.ts +50 -1
  611. package/src/openapi/spec.ts +53 -30
  612. package/src/openapi/swagger.ts +12 -11
  613. package/src/pattern.ts +245 -0
  614. package/src/peer.ts +53 -0
  615. package/src/plugin.ts +270 -185
  616. package/src/powered-by.ts +2 -2
  617. package/src/pretty-json.ts +25 -9
  618. package/src/producer-stream.ts +296 -0
  619. package/src/proxy.ts +253 -55
  620. package/src/python-type-emitter.ts +68 -56
  621. package/src/realtime/bus.ts +56 -9
  622. package/src/realtime/register.ts +13 -0
  623. package/src/realtime/route.ts +129 -80
  624. package/src/realtime/server.ts +298 -0
  625. package/src/request-id.ts +13 -3
  626. package/src/request-limits.ts +2 -0
  627. package/src/request-path.ts +165 -0
  628. package/src/request-to-curl.ts +28 -7
  629. package/src/response.ts +143 -103
  630. package/src/rust-type-emitter.ts +265 -170
  631. package/src/secure-headers.ts +8 -4
  632. package/src/serve-register.ts +4 -0
  633. package/src/serve-slot.ts +38 -0
  634. package/src/serve.ts +113 -25
  635. package/src/server-timing.ts +11 -7
  636. package/src/static.ts +85 -32
  637. package/src/telemetry/otel.ts +29 -7
  638. package/src/testing.ts +76 -14
  639. package/src/timeout.ts +15 -7
  640. package/src/tree.ts +405 -333
  641. package/src/trust.ts +117 -0
  642. package/src/ts-type-emitter.ts +18 -12
  643. package/src/type-emitter.ts +227 -89
  644. package/src/type-extractor.ts +603 -423
  645. package/src/types.ts +8 -0
  646. package/src/validation.ts +221 -96
  647. package/src/with-headers.ts +45 -0
  648. package/src/ws/bun.ts +53 -15
  649. package/src/ws/cloudflare.ts +81 -19
  650. package/src/ws/deno.ts +124 -36
  651. package/src/ws/node.ts +173 -79
  652. package/src/ws/session.ts +73 -0
  653. package/src/ws/shared.ts +140 -0
  654. package/src/ws-origin.ts +53 -0
  655. package/src/yaml.ts +45 -22
  656. package/dist/client-mcp/server.d.ts +0 -10
  657. package/dist/client-mcp/server.d.ts.map +0 -1
  658. package/dist/client-mcp/types.d.ts +0 -16
  659. package/dist/client-mcp/types.d.ts.map +0 -1
  660. package/dist/cloudflare/realtime.d.ts +0 -30
  661. package/dist/cloudflare/realtime.d.ts.map +0 -1
  662. package/dist/realtime/buffer.d.ts +0 -18
  663. package/dist/realtime/buffer.d.ts.map +0 -1
  664. package/dist/realtime/longpoll.d.ts +0 -23
  665. package/dist/realtime/longpoll.d.ts.map +0 -1
  666. package/dist/realtime/protocol.d.ts +0 -50
  667. package/dist/realtime/protocol.d.ts.map +0 -1
  668. package/dist/realtime/runtime.d.ts +0 -74
  669. package/dist/realtime/runtime.d.ts.map +0 -1
  670. package/src/cloudflare/realtime.ts +0 -234
  671. package/src/realtime/buffer.ts +0 -101
  672. package/src/realtime/longpoll.ts +0 -148
  673. package/src/realtime/protocol.ts +0 -128
  674. package/src/realtime/runtime.ts +0 -427
@@ -1,10 +1,16 @@
1
- /* MCP server code generator. Spec-driven (not IR-driven) — OpenAPI parameters[]
2
- * + requestBody.content['application/json'].schema are already JSON Schema,
3
- * no translation layer needed. Mirrors codegen-python.ts structure. */
1
+ /* MCP server code generator.
2
+ *
3
+ * Which operations become tools, their ids, their place in the TypeScript SDK and their parameter
4
+ * set come from the IR the TypeScript SDK is built from, so a tool always calls a method that
5
+ * exists. Only the JSON Schema of each parameter and JSON body is copied from the document,
6
+ * verbatim and with refs inlined: a tool's input contract is JSON Schema, and the IR keeps less
7
+ * than JSON Schema says (lengths, patterns, formats), which tool validation needs. */
4
8
 
5
9
  import { readFileSync } from "node:fs"
6
10
  import type { OpenApiSpecInput } from "./codegen.ts"
7
- import { toIR } from "./codegen-ir.ts"
11
+ import { sdkMemberPaths } from "./codegen.ts"
12
+ import { bodiesOf, toIR } from "./codegen-ir.ts"
13
+ import { isJsonMedia } from "./codegen-sdk-model.ts"
8
14
 
9
15
  type MCPOptions = {
10
16
  projectName: string
@@ -32,8 +38,6 @@ type MCPOp = {
32
38
 
33
39
  type SpecRecord = Record<string, unknown>
34
40
 
35
- const HTTP_METHODS = ["get", "post", "put", "patch", "delete", "head", "options"] as const
36
-
37
41
  const TEMPLATE_FILE_NAMES = ["server.ts", "types.ts"] as const
38
42
  const TEMPLATE_CACHE = new Map<string, string>()
39
43
 
@@ -51,16 +55,6 @@ function envVarNames(projectName: string): { apiKey: string; baseUrl: string } {
51
55
  return { apiKey: `${upper}_API_KEY`, baseUrl: `${upper}_BASE_URL` }
52
56
  }
53
57
 
54
- function hasSSEResponse(op: SpecRecord): boolean {
55
- const responses = op.responses as Record<string, SpecRecord> | undefined
56
- if (!responses) return false
57
- for (const resp of Object.values(responses)) {
58
- const content = resp.content as SpecRecord | undefined
59
- if (content && "text/event-stream" in content) return true
60
- }
61
- return false
62
- }
63
-
64
58
  function toSnakeCase(id: string): string {
65
59
  /* camelCase + dots -> snake_case. "createUser" -> "create_user",
66
60
  * "docs.extract" -> "docs_extract", "docs.listAll" -> "docs_list_all". */
@@ -71,88 +65,176 @@ function toSnakeCase(id: string): string {
71
65
  .toLowerCase()
72
66
  }
73
67
 
68
+ /** Follow a `$ref` chain to a concrete schema. A chain that loops back on itself is an error. */
69
+ /** MCP tool names: `^[a-zA-Z0-9_-]{1,64}$`. */
70
+ const MAX_TOOL_NAME = 64
71
+
72
+ function sanitizeToolName(name: string): string {
73
+ return (
74
+ name
75
+ .replace(/[^A-Za-z0-9_-]+/g, "_")
76
+ .replace(/_+/g, "_")
77
+ .replace(/^_|_$/g, "") || "tool"
78
+ )
79
+ }
80
+
81
+ /** Deterministic, sanitized, unique tool names; a collision is an error naming both operations. */
82
+ function assignToolNames(ops: MCPOp[], projectName: string): void {
83
+ const byName = new Map<string, string>()
84
+ for (const op of ops) {
85
+ let name = sanitizeToolName(`${projectName}_${toSnakeCase(op.operationId)}`)
86
+ if (name.length > MAX_TOOL_NAME) {
87
+ let hash = 0
88
+ for (let i = 0; i < op.operationId.length; i++) hash = (Math.imul(hash, 31) + op.operationId.charCodeAt(i)) >>> 0
89
+ const suffix = `_${hash.toString(36)}`
90
+ name = `${name.slice(0, MAX_TOOL_NAME - suffix.length)}${suffix}`
91
+ }
92
+ const other = byName.get(name)
93
+ if (other !== undefined) {
94
+ throw new Error(
95
+ `MCP codegen: operations ${JSON.stringify(other)} and ${JSON.stringify(op.operationId)} both map to tool ${JSON.stringify(name)}`,
96
+ )
97
+ }
98
+ byName.set(name, op.operationId)
99
+ op.toolName = name
100
+ }
101
+ }
102
+
74
103
  function resolveSchema(spec: SpecRecord, schema: SpecRecord | undefined): SpecRecord | undefined {
75
- if (!schema) return undefined
76
- if (!schema.$ref) return schema
77
- const ref = schema.$ref as string
78
- const parts = ref.replace(/^#\//, "").split("/")
79
- let cur: unknown = spec
80
- for (const part of parts) {
81
- if (cur === null || typeof cur !== "object") return undefined
82
- cur = (cur as SpecRecord)[part]
104
+ let cur: SpecRecord | undefined = schema
105
+ const chain = new Set<string>()
106
+ while (cur && typeof cur.$ref === "string") {
107
+ const ref = cur.$ref
108
+ if (chain.has(ref))
109
+ throw new Error(`MCP codegen: $ref cycle with no schema in between: ${[...chain, ref].join(" -> ")}`)
110
+ chain.add(ref)
111
+ if (!ref.startsWith("#/")) return undefined
112
+ let next: unknown = spec
113
+ for (const raw of ref.slice(2).split("/")) {
114
+ const part = raw.replace(/~1/g, "/").replace(/~0/g, "~")
115
+ if (next === null || typeof next !== "object" || !Object.hasOwn(next, part)) return undefined
116
+ next = (next as SpecRecord)[part]
117
+ }
118
+ cur = next as SpecRecord | undefined
119
+ }
120
+ return cur
121
+ }
122
+
123
+ /* Inlining expands each $ref; a schema graph with many shared refs can grow exponentially,
124
+ so the output size is bounded and the generator fails loudly instead of hanging. */
125
+ const MAX_INLINED_NODES = 50_000
126
+
127
+ type InlineState = {
128
+ /** Fully expanded refs whose expansion did not cut a cycle, with their size in nodes. */
129
+ memo: Map<string, { nodes: number; schema: SpecRecord | undefined }>
130
+ nodes: number
131
+ }
132
+
133
+ function charge(state: InlineState, nodes: number): void {
134
+ state.nodes += nodes
135
+ if (state.nodes > MAX_INLINED_NODES) {
136
+ throw new Error(`MCP codegen: inlined tool schema exceeds ${MAX_INLINED_NODES} nodes (deeply shared $refs)`)
83
137
  }
84
- if (cur === undefined) return undefined
85
- /* recurse — resolved schema may itself be a ref */
86
- return resolveSchema(spec, cur as SpecRecord)
87
138
  }
88
139
 
89
140
  function deepResolveSchema(
90
141
  spec: SpecRecord,
91
142
  schema: SpecRecord | undefined,
92
143
  seen: Set<string> = new Set(),
93
- ): SpecRecord | undefined {
94
- if (!schema) return undefined
95
- if (schema.$ref) {
96
- const ref = schema.$ref as string
97
- if (seen.has(ref)) return { type: "object" }
144
+ state: InlineState = { memo: new Map(), nodes: 0 },
145
+ ): { cut: boolean; schema: SpecRecord | undefined } {
146
+ if (!schema) return { cut: false, schema: undefined }
147
+ if (typeof schema.$ref === "string") {
148
+ const ref = schema.$ref
149
+ /* a self-referential schema becomes an open object at the point it recurs */
150
+ if (seen.has(ref)) {
151
+ charge(state, 1)
152
+ return { cut: true, schema: { type: "object" } }
153
+ }
154
+ /* a memoized expansion is emitted again in full, so it costs its full size again */
155
+ const memo = state.memo.get(ref)
156
+ if (memo) {
157
+ charge(state, memo.nodes)
158
+ return { cut: false, schema: memo.schema }
159
+ }
98
160
  const next = new Set(seen)
99
161
  next.add(ref)
100
- return deepResolveSchema(spec, resolveSchema(spec, schema), next)
162
+ const before = state.nodes
163
+ const result = deepResolveSchema(spec, resolveSchema(spec, schema), next, state)
164
+ if (!result.cut) state.memo.set(ref, { nodes: state.nodes - before, schema: result.schema })
165
+ return result
101
166
  }
167
+ charge(state, 1)
168
+ let cut = false
102
169
  const out: SpecRecord = {}
103
170
  for (const [k, v] of Object.entries(schema)) {
104
171
  if (v === null || v === undefined) {
105
172
  out[k] = v
106
173
  } else if (Array.isArray(v)) {
107
- out[k] = v.map((item) =>
108
- item !== null && typeof item === "object" ? deepResolveSchema(spec, item as SpecRecord, seen) : item,
109
- )
174
+ out[k] = v.map((item) => {
175
+ if (item === null || typeof item !== "object") return item
176
+ const r = deepResolveSchema(spec, item as SpecRecord, seen, state)
177
+ cut ||= r.cut
178
+ return r.schema
179
+ })
110
180
  } else if (typeof v === "object") {
111
- out[k] = deepResolveSchema(spec, v as SpecRecord, seen)
181
+ const r = deepResolveSchema(spec, v as SpecRecord, seen, state)
182
+ cut ||= r.cut
183
+ out[k] = r.schema
112
184
  } else {
113
185
  out[k] = v
114
186
  }
115
187
  }
116
- return out
188
+ return { cut, schema: out }
117
189
  }
118
190
 
119
- function extractJsonBodySchema(op: SpecRecord): SpecRecord | undefined {
120
- const requestBody = op.requestBody as SpecRecord | undefined
121
- const content = requestBody?.content as Record<string, SpecRecord> | undefined
122
- return content?.["application/json"]?.schema as SpecRecord | undefined
191
+ function inline(spec: SpecRecord, schema: SpecRecord | undefined): SpecRecord | undefined {
192
+ return deepResolveSchema(spec, schema).schema
193
+ }
194
+
195
+ /** Declared parameters of an operation: its own, then the path item's it does not override. */
196
+ function declaredParameters(op: SpecRecord, pathItem: SpecRecord, spec: SpecRecord): SpecRecord[] {
197
+ const own = ((op.parameters as unknown[] | undefined) ?? []).map((p) => resolveSchema(spec, p as SpecRecord) ?? {})
198
+ const shared = ((pathItem.parameters as unknown[] | undefined) ?? []).map(
199
+ (p) => resolveSchema(spec, p as SpecRecord) ?? {},
200
+ )
201
+ const out = [...own]
202
+ for (const p of shared) if (!out.some((d) => d.name === p.name && d.in === p.in)) out.push(p)
203
+ return out
123
204
  }
124
205
 
125
206
  function collectMCPOps(spec: OpenApiSpecInput): MCPOp[] {
126
- const paths = spec.paths as Record<string, SpecRecord> | undefined
127
- if (!paths) return []
207
+ /* the ids, tree and member names the TypeScript SDK derives; its schemas are not needed here */
208
+ const ir = toIR(spec, { deriveOperationIds: true, duplicateOperationIds: "throw" })
209
+ const members = sdkMemberPaths(ir)
210
+ const specRec = spec as unknown as SpecRecord
128
211
  const ops: MCPOp[] = []
129
212
 
130
- for (const [path, pathItem] of Object.entries(paths)) {
131
- for (const method of HTTP_METHODS) {
132
- const op = pathItem[method] as SpecRecord | undefined
133
- if (!op) continue
134
- if (op["x-mcp"] !== true) continue
135
- /* skip websocket / realtime / SSE operations — MCP is request/response only */
136
- if (op["x-websocket"] === true) continue
137
- if (op["x-realtime"] === true) continue
138
- if (hasSSEResponse(op)) continue
139
-
140
- const operationId = op.operationId as string | undefined
141
- if (!operationId) continue
142
-
143
- ops.push({
144
- bodyRequired: (op.requestBody as SpecRecord | undefined)?.required === true,
145
- bodySchema: extractJsonBodySchema(op),
146
- description: op.description as string | undefined,
147
- method: method.toUpperCase(),
148
- operationId,
149
- parameters: (op.parameters as Array<SpecRecord> | undefined) ?? [],
150
- path,
151
- pathSegments: operationId.split("."),
152
- summary: op.summary as string | undefined,
153
- toolName: "",
154
- })
155
- }
213
+ for (const irOp of ir.operations) {
214
+ const ext = irOp.extensions
215
+ if (ext.mcp !== true) continue
216
+ /* skip websocket / realtime / SSE operations — MCP is request/response only */
217
+ if (ext.websocket || ext.realtime || ext.sse) continue
218
+
219
+ const pathItem = (spec.paths?.[irOp.path] ?? {}) as SpecRecord
220
+ const op = (pathItem[irOp.method.toLowerCase()] ?? {}) as SpecRecord
221
+ const requestBody = resolveSchema(specRec, op.requestBody as SpecRecord | undefined)
222
+ const content = requestBody?.content as Record<string, SpecRecord> | undefined
223
+ /* the JSON body the SDK's `json` input sends: the first JSON media type, as the SDK picks it */
224
+ const jsonBody = bodiesOf(irOp).find((b) => b.kind === "raw" && isJsonMedia(b.contentType))
225
+
226
+ ops.push({
227
+ bodyRequired: jsonBody?.required === true,
228
+ bodySchema: jsonBody ? (content?.[jsonBody.contentType]?.schema as SpecRecord | undefined) : undefined,
229
+ description: irOp.description,
230
+ method: irOp.method,
231
+ operationId: irOp.id,
232
+ parameters: declaredParameters(op, pathItem, specRec),
233
+ path: irOp.path,
234
+ pathSegments: members.get(irOp.id) ?? irOp.id.split("."),
235
+ summary: irOp.summary,
236
+ toolName: "",
237
+ })
156
238
  }
157
239
 
158
240
  return ops
@@ -160,6 +242,8 @@ function collectMCPOps(spec: OpenApiSpecInput): MCPOp[] {
160
242
 
161
243
  type ParamGroup = { props: SpecRecord; required: string[] }
162
244
 
245
+ const FORBIDDEN_HEADER_ARGS = new Set(["authorization", "cookie", "proxy-authorization"])
246
+
163
247
  function emptyParamGroup(): ParamGroup {
164
248
  return { props: {}, required: [] }
165
249
  }
@@ -184,12 +268,15 @@ function buildToolInputSchema(op: MCPOp, spec: OpenApiSpecInput): SpecRecord {
184
268
  const header = emptyParamGroup()
185
269
  const groupByLoc: Record<string, ParamGroup> = { header, path, query }
186
270
 
187
- for (const p of op.parameters) {
271
+ for (const raw of op.parameters) {
272
+ const p = resolveSchema(specRec, raw) ?? {}
188
273
  const name = p.name as string
189
274
  const inLoc = p.in as string
190
- const group = groupByLoc[inLoc]
191
- if (!group) continue
192
- group.props[name] = deepResolveSchema(specRec, (p.schema ?? {}) as SpecRecord) ?? {}
275
+ const group = Object.hasOwn(groupByLoc, inLoc) ? groupByLoc[inLoc] : undefined
276
+ if (!group || typeof name !== "string") continue
277
+ /* credentials come from the server's config, never from tool arguments */
278
+ if (inLoc === "header" && FORBIDDEN_HEADER_ARGS.has(name.toLowerCase())) continue
279
+ group.props[name] = inline(specRec, (p.schema ?? {}) as SpecRecord) ?? {}
193
280
  if (p.required === true) group.required.push(name)
194
281
  }
195
282
 
@@ -198,7 +285,7 @@ function buildToolInputSchema(op: MCPOp, spec: OpenApiSpecInput): SpecRecord {
198
285
  assignGroup(properties, required, "headers", header)
199
286
 
200
287
  if (op.bodySchema) {
201
- properties.json = deepResolveSchema(specRec, op.bodySchema) ?? { type: "object" }
288
+ properties.json = inline(specRec, op.bodySchema) ?? { type: "object" }
202
289
  if (op.bodyRequired) required.push("json")
203
290
  }
204
291
 
@@ -207,51 +294,60 @@ function buildToolInputSchema(op: MCPOp, spec: OpenApiSpecInput): SpecRecord {
207
294
  return schema
208
295
  }
209
296
 
297
+ /** Keys a tool may forward to the SDK, per argument group; everything else is dropped. */
298
+ function allowedArgs(inputSchema: SpecRecord): Record<string, string[] | true> {
299
+ const out: Record<string, string[] | true> = {}
300
+ const props = inputSchema.properties as Record<string, SpecRecord>
301
+ for (const group of ["params", "search", "headers"]) {
302
+ const g = props[group]
303
+ if (g) out[group] = Object.keys((g.properties as SpecRecord | undefined) ?? {}).sort()
304
+ }
305
+ if (props.json) out.json = true
306
+ return out
307
+ }
308
+
309
+ /** Text safe inside a block comment. */
310
+ function commentText(text: string): string {
311
+ return text.replace(/\*\//g, "*\\/").replace(/[\r\n]+/g, " ")
312
+ }
313
+
210
314
  function buildToolsGen(ops: MCPOp[], spec: OpenApiSpecInput, projectName: string): string {
211
315
  const l: string[] = []
212
316
  l.push(`/* Generated by honey codegen-mcp.ts — do not edit by hand. */`)
213
317
  l.push(``)
318
+ l.push(`import { callTool, type AllowedArgs } from "./_runtime"`)
214
319
  l.push(`import type { Tool } from "./types"`)
215
320
  l.push(``)
216
321
  l.push(`export function buildTools(sdk: Record<string, unknown>): Tool[] {`)
322
+ /* callTool validates the arguments against inputSchema, forwards only declared keys, and
323
+ walks the SDK by operationId segments: ["checkout", "sessions", "create"]. */
324
+ l.push(
325
+ `\tconst tool = (name: string, description: string | undefined, inputSchema: Record<string, unknown>, segments: string[], allowed: AllowedArgs): Tool => ({`,
326
+ )
327
+ l.push(`\t\tdescription,`)
328
+ l.push(`\t\thandler: (args) => callTool(sdk, segments, args, inputSchema, allowed),`)
329
+ l.push(`\t\tinputSchema,`)
330
+ l.push(`\t\tname,`)
331
+ l.push(`\t})`)
217
332
  l.push(`\treturn [`)
218
333
 
219
334
  for (const op of ops) {
220
335
  const desc = op.description ?? op.summary ?? ""
221
336
  const inputSchema = buildToolInputSchema(op, spec)
222
- l.push(`\t\t{`)
223
- l.push(`\t\t\tname: ${JSON.stringify(op.toolName)},`)
224
- if (desc.length > 0) {
225
- l.push(`\t\t\tdescription: ${JSON.stringify(desc)},`)
226
- }
227
- l.push(`\t\t\tinputSchema: ${JSON.stringify(inputSchema)},`)
228
- /* handler dispatches by walking all path segments; pass args verbatim.
229
- * arguments shape already matches TS SDK method signature: { params?, search?, headers?, json? }. */
230
- const callExpr = op.pathSegments.reduce(
231
- (acc, seg, i) =>
232
- i === 0
233
- ? `(sdk as Record<string, unknown>)[${JSON.stringify(seg)}]`
234
- : `(${acc} as Record<string, unknown>)[${JSON.stringify(seg)}]`,
235
- "",
236
- )
237
- l.push(`\t\t\thandler: async (args) => {`)
238
- l.push(`\t\t\t\tconst method = ${callExpr}`)
239
- l.push(`\t\t\t\tif (typeof method !== "function") {`)
240
- l.push(
241
- `\t\t\t\t\treturn { content: [{ type: "text", text: JSON.stringify({ message: "SDK missing method ${op.operationId}" }) }], isError: true }`,
242
- )
243
- l.push(`\t\t\t\t}`)
244
- l.push(`\t\t\t\tconst result = await method.call(sdk, args)`)
245
- l.push(`\t\t\t\treturn { content: [{ type: "text", text: JSON.stringify(result) }] }`)
246
- l.push(`\t\t\t},`)
247
- l.push(`\t\t},`)
337
+ l.push(`\t\ttool(`)
338
+ l.push(`\t\t\t${JSON.stringify(op.toolName)},`)
339
+ l.push(`\t\t\t${desc.length > 0 ? JSON.stringify(desc) : "undefined"},`)
340
+ l.push(`\t\t\t${JSON.stringify(inputSchema)},`)
341
+ l.push(`\t\t\t${JSON.stringify(op.pathSegments)},`)
342
+ l.push(`\t\t\t${JSON.stringify(allowedArgs(inputSchema))},`)
343
+ l.push(`\t\t),`)
248
344
  }
249
345
 
250
346
  l.push(`\t]`)
251
347
  l.push(`}`)
252
348
  l.push(``)
253
349
  /* project name embedded for tool-naming contract visibility — consumed by tests */
254
- l.push(`/* project: ${projectName} */`)
350
+ l.push(`/* project: ${commentText(projectName)} */`)
255
351
  l.push(``)
256
352
  return l.join("\n")
257
353
  }
@@ -264,7 +360,6 @@ function buildServerEntry(
264
360
  version: string,
265
361
  ): string {
266
362
  const { apiKey: envVar, baseUrl: baseUrlEnvVar } = envVarNames(projectName)
267
- const defaultBaseUrl = `https://api.${projectName}.com`
268
363
  const l: string[] = []
269
364
  l.push(`/* Generated by honey codegen-mcp.ts — do not edit by hand. */`)
270
365
  l.push(``)
@@ -273,7 +368,14 @@ function buildServerEntry(
273
368
  l.push(`import { buildTools } from "./tools.gen"`)
274
369
  l.push(``)
275
370
  l.push(`const apiKey = process.env[${JSON.stringify(envVar)}] ?? ""`)
276
- l.push(`const baseURL = process.env[${JSON.stringify(baseUrlEnvVar)}] ?? ${JSON.stringify(defaultBaseUrl)}`)
371
+ /* No guessed default: the API key must never be sent to a host nobody configured. */
372
+ l.push(`const baseURL = process.env[${JSON.stringify(baseUrlEnvVar)}] ?? ""`)
373
+ l.push(`if (baseURL.length === 0) {`)
374
+ l.push(
375
+ `\tprocess.stderr.write(${JSON.stringify(`${baseUrlEnvVar} is required (the API base URL, e.g. https://api.example.com)\n`)})`,
376
+ )
377
+ l.push(`\tprocess.exit(1)`)
378
+ l.push(`}`)
277
379
  l.push(``)
278
380
  l.push(`const sdk = new ${sdkClassName}({`)
279
381
  l.push(`\tbaseURL,`)
@@ -317,7 +419,6 @@ function buildTsconfig(): string {
317
419
  }
318
420
 
319
421
  export function generateMCPServer(spec: OpenApiSpecInput, options: MCPOptions): MCPResult {
320
- toIR(spec)
321
422
  const { projectName, sdkClassName, sdkPackageName } = options
322
423
  const version = options.version ?? "0.1.0"
323
424
 
@@ -325,9 +426,7 @@ export function generateMCPServer(spec: OpenApiSpecInput, options: MCPOptions):
325
426
  if (ops.length === 0) {
326
427
  throw new Error("No operations marked x-mcp: true; nothing to emit")
327
428
  }
328
- for (const op of ops) {
329
- op.toolName = `${projectName}_${toSnakeCase(op.operationId)}`
330
- }
429
+ assignToolNames(ops, projectName)
331
430
 
332
431
  const info = (spec as { info?: { title?: string } }).info ?? {}
333
432
  const serverName = info.title ?? `@${projectName}/mcp-server`