@lovrozagar/honey 0.6.8 → 0.7.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 (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 +776 -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 +562 -424
  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
package/dist/index.d.ts CHANGED
@@ -1,19 +1,29 @@
1
1
  import { HoneyContext } from "./context.ts";
2
+ import { type TrustSetting } from "./client-info.ts";
3
+ import type { TrustProxy } from "./trust.ts";
2
4
  import { HoneyError } from "./error.ts";
3
5
  import { ERROR_META } from "./errors.ts";
4
- import type { MiddlewareFn, RuntimeMiddleware } from "./middleware.ts";
6
+ import type { ChainErrorConverter, MiddlewareFn, RuntimeMiddleware } from "./middleware.ts";
5
7
  import type { ProxyConfig } from "./proxy.ts";
6
8
  import type { CustomErrorFormatter, ErrorFormatter, ResponseOptions, TypedResponse } from "./response.ts";
7
9
  import { type HoneyRes } from "./response.ts";
8
- import type { RouteHandler, RouteTree, TreeNode } from "./tree.ts";
10
+ import type { RouteId, Segment } from "./pattern.ts";
11
+ import type { RouteEntry, RouteHandler, RouteTree, TreeNode, WSRouteHandler } from "./tree.ts";
9
12
  import type { RealtimeBus } from "./realtime/bus.ts";
10
- import type { RealtimeRouteOpts } from "./realtime/route.ts";
11
- import type { ComputeErrorsByStatus, DefaultMeta, ExtractSchemas, HttpMethod, InferInputMap, InferOutput, HoneyMetaSpec, InputSchemasDef, MergePath, MergeRoute, MetaSpecConfig, OutputSchemaDef, ParamsFromPath, StandardSchemaLike, TapContext } from "./types.ts";
13
+ import type { RealtimeConfig, RealtimeRouteOpts } from "./realtime/route.ts";
14
+ import type { RealtimePublisher } from "./realtime/server.ts";
15
+ import type { ComputeErrorsByStatus, DefaultMeta, ExtractSchemas, HttpMethod, InferInputMap, InferOutput, HoneyMetaSpec, InputSchemasDef, MergePath, MergeRoute, MetaSpecConfig, OutputSchemaDef, ParamsFromPath, PrefixRoutes, StandardSchemaLike, TapContext } from "./types.ts";
12
16
  import type { WSAdapter, WSHandler } from "./ws/cloudflare.ts";
17
+ import { type WSOriginPolicy } from "./ws-origin.ts";
18
+ import type { MetaSpecSource } from "./meta-spec-merge.ts";
13
19
  import type { HoneyServeOptions, ServeHandle } from "./serve.ts";
14
- export { HoneyContext } from "./context.ts";
20
+ export { clientInfo, HoneyContext } from "./context.ts";
21
+ export { toFetchRequest } from "./fetch-request.ts";
22
+ export type { WSOriginPolicy } from "./ws-origin.ts";
23
+ export type { ClientInfo } from "./client-info.ts";
24
+ export type { TrustProxy } from "./trust.ts";
15
25
  /** HoneyContext without internal backing fields — use this for consumer-facing types */
16
- export type HoneyCtx<TEnv = Record<string, unknown>> = Omit<import("./context.ts").HoneyContext<TEnv>, "_errorToResponse" | "_isErrorResponse" | "_lzCookies" | "_lzHeaders" | "_lzSearch" | "_lzSearchAll" | "_lzUrlFn" | "_setErrors">;
26
+ export type HoneyCtx<TEnv = Record<string, unknown>> = Omit<import("./context.ts").HoneyContext<TEnv>, "_errorToResponse" | "_isErrorResponse" | "_lzClient" | "_lzCookies" | "_lzHeaders" | "_lzSearch" | "_lzSearchAll" | "_lzUrlFn" | "_rq" | "_setErrors">;
17
27
  export { HoneyError } from "./error.ts";
18
28
  export { defineErrors, ERROR_META } from "./errors.ts";
19
29
  export type { ErrorMetaEntry } from "./errors.ts";
@@ -24,9 +34,10 @@ export type { PendingTap, TapContext, TapHandler } from "./types.ts";
24
34
  export type { CookieOptions, CustomErrorFormatter, ErrorFormatter, ResponseOptions, SSEEvent, SSEOptions, SSEStream, TypedResponse, } from "./response.ts";
25
35
  export { createErrorResponse, HoneyRes } from "./response.ts";
26
36
  export { mergeTree } from "./tree.ts";
27
- export type { DefaultMeta, HoneyCodegen, HoneyMeta, InferBasePath, InferCtx, InferEnv, InferErrorFactory, InferInputMap, InferMeta, InferMethods, InferOutput, InferRouteCtx, InferRouteErrors, InferRouteInput, InferRouteMeta, InferRouteMethods, InferRouteOutput, InferRoutePaths, InferRoutes, InputSchemasDef, MergePath, HoneyMetaSpec, MetaSpecConfig, MetaSpecContext, MetaSpecEntry, MetaSpecMergeConflict, MetaSpecExpand, MetaSpecProfile, MetaSpecSchemaEntry, MetaSpecSchemaSearch, MetaSpecSchemaSource, MetaSpecSingle, MetaSpecStrictness, MetaSpecTarget, OpenApiMeta, OutputSchemaDef, Overwrite, ComputeErrorsByStatus, RouteRecord, StandardSchemaLike, StatusKey, SuccessStatusKey, } from "./types.ts";
28
- export type { WSAdapter, WSContext, WSHandler, WSPreUpgrade } from "./ws/cloudflare.ts";
29
- export type { ConnContext, RealtimeRouteOpts } from "./realtime/route.ts";
37
+ export type { DefaultMeta, HoneyCodegen, HoneyMeta, InferBasePath, InferCtx, InferEnv, InferErrorFactory, InferInputMap, InferMeta, InferMethods, InferOutput, InferRouteCtx, InferRouteErrors, InferRouteInput, InferRouteMeta, InferRouteMethods, InferRouteOutput, InferRoutePaths, InferRoutes, InputSchemasDef, MergePath, PrefixRoutes, HoneyMetaSpec, MetaSpecConfig, MetaSpecContext, MetaSpecEntry, MetaSpecMergeConflict, MetaSpecExpand, MetaSpecProfile, MetaSpecSchemaEntry, MetaSpecSchemaSearch, MetaSpecSchemaSource, MetaSpecSingle, MetaSpecStrictness, MetaSpecTarget, OpenApiMeta, OutputSchemaDef, Overwrite, ComputeErrorsByStatus, RouteRecord, StandardSchemaLike, StatusKey, SuccessStatusKey, } from "./types.ts";
38
+ export type { WSAdapter, WSAdapterOptions, WSContext, WSHandler, WSPreUpgrade } from "./ws/cloudflare.ts";
39
+ export type { ConnContext, RealtimeLimits, RealtimeRouteOpts } from "./realtime/route.ts";
40
+ export type { RealtimePublisher } from "./realtime/server.ts";
30
41
  export type { RealtimeBus } from "./realtime/bus.ts";
31
42
  export type { HoneyServeOptions, ServeHandle } from "./serve.ts";
32
43
  export type { ServeRuntime } from "./detect-runtime.ts";
@@ -38,10 +49,12 @@ type TelemetryAdapter = {
38
49
  method: string;
39
50
  path: string;
40
51
  }): void;
52
+ /** `path` is the request path; `route` the matched pattern (`/users/:id`). */
41
53
  onHandler?(ctx: {
42
54
  duration: number;
43
55
  method: string;
44
56
  path: string;
57
+ route: string;
45
58
  status: number;
46
59
  }): void;
47
60
  onMethodNotAllowed?(ctx: {
@@ -64,16 +77,19 @@ type TelemetryAdapter = {
64
77
  env: unknown;
65
78
  req: Request;
66
79
  }): void;
80
+ /** Fires exactly once per request that fired `onRequest`, whichever way it exits. */
67
81
  onResponse?(ctx: {
68
82
  duration: number;
69
83
  req: Request;
70
84
  status: number;
71
85
  }): void;
86
+ /** `path` is the request path; `route` the matched pattern (`/users/:id`). */
72
87
  onRoute?(ctx: {
73
88
  method: string;
74
89
  params: Record<string, string>;
75
90
  path: string;
76
91
  req: Request;
92
+ route: string;
77
93
  }): void;
78
94
  };
79
95
  type ErrorI18nConfig<TEnv> = {
@@ -92,13 +108,144 @@ type ErrorI18nConfig<TEnv> = {
92
108
  type Logger = {
93
109
  warn?(objOrMsg: Record<string, unknown> | string, msg?: string): void;
94
110
  };
111
+ type ErrorCtx<TEnv> = {
112
+ env: TEnv;
113
+ jsonFromError: (err: HoneyError) => Response;
114
+ req: Request;
115
+ };
116
+ type OnErrorFn<TEnv> = (error: unknown, ctx: ErrorCtx<TEnv>) => HoneyError | Response | Promise<HoneyError | Response | undefined | void> | undefined | void;
117
+ type OnMethodNotAllowedFn<TEnv> = (ctx: ErrorCtx<TEnv> & {
118
+ allowed: string[];
119
+ }) => Response | Promise<Response>;
120
+ type OnNotFoundFn<TEnv> = (ctx: ErrorCtx<TEnv>) => Response | Promise<Response>;
121
+ type TapFn<TEnv> = (ctx: TapContext<TEnv>, payload: unknown) => void | Promise<void>;
122
+ type ErrorFactoryRecord = Record<string, (...args: never[]) => unknown>;
123
+ type OutputValidationMode = "always" | "dev" | "off";
124
+ /**
125
+ * Settings of one app — shared by every handle derived from it (`use()`, `basePath()`,
126
+ * `context()`, `meta()`), so a setter called on any handle applies to all of them and
127
+ * serving any handle behaves the same. Records point at the settings of the app they were
128
+ * registered on, so a mounted sub-app's routes keep their own error factory, default errors,
129
+ * boundary and output validation.
130
+ */
131
+ type AppSettings<TEnv = unknown> = {
132
+ customErrorFormatter: CustomErrorFormatter | null;
133
+ customErrorSchema: StandardSchemaLike | null;
134
+ defaultBoundaryKey: string | null;
135
+ defaultErrorKeys: Set<string>;
136
+ errorFactory: ErrorFactoryRecord | null;
137
+ errorFormatter: ErrorFormatterFn;
138
+ errorI18n: ErrorI18nConfig<TEnv> | null;
139
+ errorSchema: StandardSchemaLike | null;
140
+ logger: Logger | null;
141
+ onError: OnErrorFn<TEnv> | null;
142
+ onMethodNotAllowed: OnMethodNotAllowedFn<TEnv> | null;
143
+ onNotFound: OnNotFoundFn<TEnv> | null;
144
+ /** null = never set: a mounted route follows the mounting app's mode */
145
+ outputValidation: OutputValidationMode | null;
146
+ stripPrefix: string | null;
147
+ taps: Map<string, TapFn<TEnv>> | null;
148
+ telemetry: TelemetryAdapter | null;
149
+ trailingSlash: "enforce" | "ignore" | "strip";
150
+ encodedSlashes: "allow" | "reject";
151
+ trust: TrustSetting;
152
+ wsAdapter: WSAdapter | null;
153
+ };
154
+ /**
155
+ * Everything a matched route runs, compiled once at finalize: the record (with its resolved
156
+ * error keys, meta and chain) and one function that runs chain + handler and never rejects.
157
+ */
158
+ type Plan = {
159
+ /** `.context()` values copied onto each request context */
160
+ cv: Record<string, unknown> | null;
161
+ /** declared error keys are enforced (the route, its middleware or the app declared any) */
162
+ enf: boolean;
163
+ /** preflight runner — chain without input validation or handler; compiled on first preflight */
164
+ pf: CompiledChain | null;
165
+ /** what the preflight runner runs */
166
+ pfChain: RuntimeMiddleware[];
167
+ r: RouteHandler | WSRouteHandler;
168
+ /** realtime route config when this is a realtime route */
169
+ rt: RealtimeConfig | null;
170
+ run: CompiledChain;
171
+ /** taps of the serving app, plus those of the app the route came from */
172
+ taps: Map<string, TapFn<unknown>> | null;
173
+ };
174
+ type CompiledChain = (ctx: object) => Response | Promise<Response>;
175
+ /** What one app graph serves, resolved at finalize from records and the loaded tree. */
176
+ type FinalTable = {
177
+ byId: Map<RouteId, RouteHandler>;
178
+ convert: ChainErrorConverter;
179
+ epoch: number;
180
+ /** 404 / 405: the middleware every route runs, plus the scopes covering the request path */
181
+ miss: Plan;
182
+ plans: Map<RouteId, Plan>;
183
+ /** `METHOD /path` → plan, for routes without params or wildcards */
184
+ statics: Record<string, Plan>;
185
+ wsById: Map<RouteId, WSRouteHandler>;
186
+ wsPlans: Map<RouteId, Plan>;
187
+ };
188
+ /** One `app.use(mw)` — the handle it returns has to register a route, or `mw` runs nowhere. */
189
+ type ChainNode = {
190
+ mw: RuntimeMiddleware;
191
+ parent: ChainNode | null;
192
+ used: boolean;
193
+ };
194
+ /** A route builder still waiting for `.handler()` — reported at finalize. */
195
+ type PendingRoute = {
196
+ id: string;
197
+ };
198
+ /** @internal — runtime entry for a scoped middleware */
199
+ type ScopedEntry = {
200
+ /** cached from mw.errors at registration; undefined when none */
201
+ errors: readonly string[] | undefined;
202
+ /** the middleware behind a request-path check, for routes the scope covers only partly */
203
+ guard: RuntimeMiddleware;
204
+ mw: RuntimeMiddleware;
205
+ /** canonical full-path pattern (already rebased against basePath at .use time) */
206
+ prefix: string;
207
+ segs: Segment[];
208
+ };
209
+ /**
210
+ * One app graph — shared by every handle derived with `use()`, `basePath()`, `context()`,
211
+ * `meta()`. Records are per graph, keyed by `RouteId`; the tree holds ids only, so a loaded
212
+ * (shared, frozen) tree never carries another app's handlers.
213
+ */
95
214
  type HoneyGraph = {
96
- handlerMap: Record<string, RouteHandler> | null;
97
- hasRouteTree: boolean;
98
- /** Codegen-time meta → OpenAPI policy. Never read on the request path */
215
+ /** metaSpec policies of mounted sub-apps, merged under `metaSpec` when codegen reads it */
216
+ absorbedMetaSpecs: MetaSpecSource[];
217
+ /** gateway catch-alls by method — root wildcards registered over a loaded tree that lacks them */
218
+ catchAll: Map<string, RouteHandler>;
219
+ /** every `use(mw)` handle — one that never registers a route is reported at finalize */
220
+ chains: ChainNode[];
221
+ /** bumped by every registration; finalize re-runs when it moves */
222
+ epoch: number;
223
+ final: FinalTable | null;
224
+ /** app-wide middleware that runs before every chain (serve({ cors })), keyed so a re-serve replaces it */
225
+ global: Map<string, RuntimeMiddleware>;
226
+ hasWs: boolean;
227
+ /** route data of the loaded tree (per-graph copies) — null when no tree was loaded */
228
+ loaded: Map<RouteId, RouteEntry> | null;
229
+ /** Codegen-time meta → OpenAPI policy declared on this app. Never read on the request path */
99
230
  metaSpec: MetaSpecConfig | null;
231
+ /** route builders still waiting for `.handler()` */
232
+ pending: Set<PendingRoute>;
100
233
  realtimeBus: RealtimeBus | null;
234
+ /** `ctx.realtime`, shared by every request of this graph */
235
+ realtimeCtx: RealtimePublisher | null;
236
+ realtimeRoutes: Map<string, RealtimeConfig>;
237
+ records: Map<RouteId, RouteHandler>;
101
238
  root: TreeNode;
239
+ /** root is a loaded tree (frozen, possibly shared by other apps) — copy before inserting */
240
+ rootShared: boolean;
241
+ /** path-scoped middleware, in registration order */
242
+ scoped: ScopedEntry[];
243
+ /** chains of the handles that served a request — decide what 404 and 405 run when there are no routes */
244
+ served: Set<RuntimeMiddleware[]>;
245
+ settings: AppSettings<unknown>;
246
+ /** registered after routeTree() with no leaf in the loaded tree — stale generated file */
247
+ unexpected: Set<RouteId>;
248
+ wsRecords: Map<RouteId, WSRouteHandler>;
102
249
  };
103
250
  type ErrorFormatterFn = ErrorFormatter;
104
251
  export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta = never, TErrorFactory = never, TDefaultErrors extends string = never, TBasePath extends string = "/", TTaps extends Record<string, unknown> = {}, TScopedMw extends readonly ScopedMwEntry[] = []> {
@@ -110,111 +257,108 @@ export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta
110
257
  readonly $routes: TRoutes;
111
258
  readonly $taps: TTaps;
112
259
  private _basePath;
113
- private _defaultBoundaryKey;
114
- private _defaultErrorKeys;
115
- private _errorFactory;
116
- private _errorSchema;
117
- private _customErrorFormatter;
118
- private _customErrorSchema;
260
+ private _chain;
119
261
  private _chainMeta;
120
- private _chainMiddlewares;
121
- private _scopedMiddlewares;
122
262
  private _contextValues;
123
- private _errorFormatter;
124
- private _errorI18n;
125
- private _globalMiddlewares;
126
263
  private _graph;
127
- private _hasWsRoutes;
128
- private _logger;
129
- private _outputValidation;
130
- private _staticRoutes;
131
- private _stripPrefix;
132
- private _trailingSlash;
133
- private _wsAdapter;
134
- private _openApiCache;
135
- private _openApiYamlCache;
136
- private _manifestCache;
137
- private _onError;
138
- private _onMethodNotAllowed;
139
- private _onNotFound;
140
- private _taps;
141
- private _telemetry;
142
- private _realtimeRoutes;
264
+ /** the `use(mw)` call that created this chain — null on the root handle */
265
+ private _node;
143
266
  constructor(opts?: {
144
- chainMiddlewares?: RuntimeMiddleware[];
145
- defaultErrorKeys?: Set<string>;
146
- globalMiddlewares?: RuntimeMiddleware[];
147
267
  graph?: HoneyGraph;
148
- handlerMap?: Record<string, RouteHandler> | null;
149
- root?: TreeNode;
150
- scopedMiddlewares?: ScopedEntry[];
151
268
  });
152
- private get _handlerMap();
153
- private set _handlerMap(value);
154
- private get _hasRouteTree();
155
- private set _hasRouteTree(value);
156
- /** @internal — read by codegen */
157
- private get _metaSpec();
158
- private set _metaSpec(value);
269
+ private get _s();
270
+ /**
271
+ * @internal — read by codegen through `metaSpecOf()`: the declared policy and every mounted
272
+ * sub-app's, unmerged. Merged on read, so `metaSpec()` may come before or after `route(sub)`;
273
+ * the merge lives with codegen so a served app never loads it.
274
+ */
275
+ private get _metaSpecSource();
276
+ /** @internal — read by codegen and OpenAPI */
277
+ get _errorFactory(): ErrorFactoryRecord | null;
278
+ set _errorFactory(factory: ErrorFactoryRecord | null);
279
+ /** @internal — read by OpenAPI */
280
+ get _errorSchema(): StandardSchemaLike | null;
281
+ /** @internal — read by OpenAPI */
282
+ get _customErrorSchema(): StandardSchemaLike | null;
159
283
  private get _root();
160
- private set _root(value);
161
- /** @internal — used by codegen */
162
- private get _tree();
163
284
  private get _realtimeBus();
164
- private set _realtimeBus(value);
165
- /** @internal — mark that this app has WS routes */
166
- _markWsRoutes(): void;
167
- /** @internal — register a static route for O(1) lookup */
168
- _registerStatic(key: string, handler: RouteHandler): void;
285
+ /** A new handle on the same graph, carrying this handle's view. */
286
+ private _derive;
287
+ /** This handle registers, mounts or serves — every `use()` on its way here is in use. */
288
+ private _markUsed;
169
289
  /** @internal — used by RouteBuilder for pre-filtered error factory */
170
290
  get _factory(): unknown;
171
291
  /** @internal — used by runtime error boundary */
172
292
  get _boundaryKey(): string | null;
173
- /** Convert unknown thrown value to error Response — used in WS, 404, 405 catch blocks */
293
+ /** Convert an unknown thrown value to a plain error Response — no boundary, no onError. */
174
294
  private _toErrorResponse;
175
295
  private _createBoundaryError;
176
296
  private _createError;
177
- /** Apply error keys from a single scoped entry to every matching handler currently in the tree */
178
- private _applyScopedEntryErrors;
179
297
  /**
180
- * Meta contributed by every middleware that will run for `routePath`, in runtime order:
181
- * global, chain, then scoped entries matching the path. Route-level `.use()` is folded in
182
- * later, by the builder. Resolved here — at registration — because the precompiled route
183
- * tree bakes `mt` as a literal, so a per-request derivation would diverge from it.
298
+ * The i18n-resolved copy of `honeyError`: message from the locale's template for its
299
+ * errorKey, field paths from the locale's field names. Returns `honeyError` itself when
300
+ * i18n is not configured or nothing matches. Never mutates it: an error instance can be
301
+ * thrown again, on another request, in another locale.
184
302
  */
185
- private _contributedMetaFor;
303
+ private _resolveI18n;
186
304
  /**
187
- * Back-fill meta from one scoped entry onto handlers already in the tree. Mirrors
188
- * `_applyScopedEntryErrors` — `.use("/prefix", mw)` may be registered after the routes it
189
- * covers, and a tag missing where enforcement happens is the worst failure direction.
190
- * `mt` is frozen at registration, so this replaces the object rather than mutating it.
305
+ * The error boundary of every `next()`: turns what a handler or middleware threw into the
306
+ * Response that replaces it, so every middleware around it sees a Response. Never rejects.
191
307
  */
192
- private _applyScopedEntryMeta;
193
- /** Apply error keys from every scoped entry on this chain to every matching handler in the tree */
194
- private _applyAllScopedErrors;
195
- /** Return scoped middleware functions that match the given route path */
196
- private _filterScopedForPath;
197
- /** Mutates `honeyError.message` in-place with the i18n-resolved template for its errorKey.
198
- * No-op when i18n is not configured or when no template matches. */
199
- private _resolveI18n;
308
+ private _convertError;
309
+ /** Last resort when even the configured formatter throws. */
310
+ private _safeErrorResponse;
200
311
  /**
201
- * Convert thrown value into an error Response — resolves boundary wrapping,
202
- * i18n translation, onError callback, and telemetry.
203
- * Called from the handler wrapper so errors flow back through middleware.
312
+ * Convert thrown value into an error Response — resolves boundary wrapping, i18n
313
+ * translation, the onError callback, and error telemetry. `onResponse` telemetry is not
314
+ * fired here: the request fires it exactly once, on the way out.
204
315
  */
205
316
  private _resolveErrorResponse;
206
317
  basePath<P extends string>(prefix: P): Honey<TEnv, TCtx, TRoutes, TMeta, TErrorFactory, TDefaultErrors, MergePath<TBasePath, P>, TTaps, TScopedMw>;
207
318
  context<TAdds extends Record<string, unknown>>(values: TAdds): Honey<TEnv, TCtx & Readonly<TAdds>, TRoutes, TMeta, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
208
319
  logger(logger: Logger): this;
209
- outputValidation(mode: "always" | "dev" | "off"): this;
320
+ outputValidation(mode: OutputValidationMode): this;
210
321
  trailingSlash(mode: "enforce" | "ignore" | "strip"): this;
322
+ /**
323
+ * Request paths containing an encoded `/` or `\` (`%2F`, `%5C`) answer 400 by default.
324
+ * `"allow"` keeps them encoded in the path, so they decode into a param value
325
+ * (`/repos/:id` with `/repos/group%2Fproject` gives `id === "group/project"`). Only allow
326
+ * them when nothing downstream (a `proxy()` upstream, a file resolver) treats a decoded
327
+ * slash as a separator.
328
+ */
329
+ encodedSlashes(mode: "allow" | "reject"): this;
330
+ /**
331
+ * Which reverse proxies in front of the app to believe. Decides `ctx.ip`, `clientInfo()`,
332
+ * `ipRestrict`, and every other feature that needs the client's address, scheme or host.
333
+ *
334
+ * - `false` (default): the peer address the runtime reports is the client; `X-Forwarded-*`
335
+ * headers are ignored, since any client can send them.
336
+ * - a hop count: exactly that many proxies, each appending its peer to `X-Forwarded-For`
337
+ * (nginx `$proxy_add_x_forwarded_for`, most load balancers). The client is the entry the
338
+ * outermost proxy wrote.
339
+ * - addresses and CIDR ranges of your proxies: hops from those addresses are skipped; the
340
+ * first other address is the client.
341
+ *
342
+ * A hop count or list needs `import "@lovrozagar/honey/trust"` in the app entry.
343
+ */
344
+ trustProxy(value: TrustProxy): this;
211
345
  /** Strip a URL path prefix before route matching — boundary-safe (won't strip partial segments), paths without the prefix pass through unchanged */
212
346
  stripPrefix(prefix: string): this;
213
347
  wsAdapter(adapter: WSAdapter): this;
348
+ /**
349
+ * Serve this app's OpenAPI document at `${path}.json`, `.yaml` and `.yml` (default
350
+ * `/openapi`), and optionally a docs UI. Each call serves its own document: two calls with
351
+ * different options (say an internal and a public profile) never share a cache. Documents
352
+ * are generated once per route change, serialized once, and sent with an `ETag` and
353
+ * `Cache-Control: no-cache`. Pass `enabled: false` (for example in production) to mount
354
+ * nothing while keeping the call in place.
355
+ */
214
356
  openapi(options: {
215
357
  description?: string;
216
358
  docs?: "scalar" | "swagger";
217
359
  docsPath?: string;
360
+ /** Mount the document and docs routes. Default `true`. */
361
+ enabled?: boolean;
218
362
  filterRoutes?: (route: {
219
363
  meta: unknown;
220
364
  method: string;
@@ -227,40 +371,135 @@ export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta
227
371
  title: string;
228
372
  version: string;
229
373
  }): this;
374
+ /**
375
+ * Serve the route manifest at `path` (default `/manifest.json`), filtered by the same
376
+ * visibility policy as the OpenAPI document. Cached per route change, sent with an `ETag`.
377
+ * `enabled: false` mounts nothing.
378
+ */
230
379
  manifest(options?: {
380
+ enabled?: boolean;
231
381
  path?: string;
232
382
  }): this;
383
+ /** Mount a served document; a path another route or an earlier call owns is an error. */
384
+ private _mountArtifact;
233
385
  serve(options?: HoneyServeOptions): Promise<ServeHandle>;
234
- private _lookupGet;
235
- /** Mount an internal GET. Returns false when a user route already owns the path. */
386
+ /**
387
+ * Mount an internal GET (spec, docs, manifest). Reports who owns the path when it cannot:
388
+ * a user route (`"user"`) or an earlier internal mount (`"internal"`). Only an exact leaf
389
+ * counts: a `/:slug` or `/*rest` route does not block a static internal path, which wins
390
+ * over it on precedence, with backtracking, in both the runtime and a loaded tree.
391
+ */
236
392
  private _mountInternalGet;
393
+ private _bumpEpoch;
394
+ /** Place `id` at every leaf of `segments`, copying a shared (loaded) root first. */
395
+ private _placeLeaves;
396
+ /**
397
+ * @internal — register one route record. Over a loaded tree the record binds to the leaf
398
+ * the tree already holds for its id; a root wildcard the tree lacks becomes the gateway
399
+ * catch-all; any other unknown route marks the tree as stale (reported at finalize).
400
+ */
401
+ _addRoute(method: string, segments: readonly Segment[], record: RouteHandler): void;
402
+ /** @internal — register one websocket (or realtime) route record. */
403
+ _addWsRoute(segments: readonly Segment[], record: WSRouteHandler): void;
404
+ /**
405
+ * Resolve what this graph serves: registered records, live records carried by a loaded
406
+ * snapshot, and delegated leaves the gateway catch-all serves. Then resolve every record —
407
+ * its full chain (`chain → scoped → route → input validation`), error keys, meta and error
408
+ * factory — and compile it once. Re-runs whenever the graph's epoch moved. Throws, naming
409
+ * every route, when a loaded tree and the registered routes disagree (the generated file is
410
+ * stale), and when a `use(mw)` handle or a route builder was left unused (the middleware or
411
+ * route would silently be missing).
412
+ */
413
+ _finalize(): FinalTable;
414
+ /** `use(mw)` handles that never registered, mounted or served, and builders without `.handler()`. */
415
+ private _assertNothingDiscarded;
416
+ /**
417
+ * Resolve a record against this graph: chain = captured chain, the scopes that cover its
418
+ * pattern (behind a request-path check where only some of its paths are inside), then its
419
+ * route middleware. Error keys and contributed meta come from that chain, in run order.
420
+ * The error factory, default errors and boundary come from the app the route was
421
+ * registered on when that app has a factory, else from this one.
422
+ */
423
+ private _resolve;
424
+ /** Wrap each middleware for `telemetry.onMiddleware`, once per finalize. */
425
+ private _timed;
426
+ private _planRoute;
427
+ private _planWs;
428
+ /**
429
+ * 404 and 405 run through the same pipeline as a route: the middleware every route of this
430
+ * graph starts with (with no routes: every handle that served a request), then every scope
431
+ * (behind its request-path check), then the 404/405 answer. So a logger or CORS policy on the whole app also covers unknown paths, and a
432
+ * scope's guard answers before "not found" leaks what exists under it.
433
+ */
434
+ private _planMiss;
435
+ /**
436
+ * @internal — every served route as one entry per leaf (an optional param yields two
437
+ * paths), in tree order. Codegen and OpenAPI read routes through this.
438
+ */
439
+ _collectRoutes(includeSkipped?: boolean): Array<{
440
+ handler: RouteHandler;
441
+ method: string;
442
+ path: string;
443
+ }>;
444
+ /** @internal — websocket routes, one entry per leaf. */
445
+ _collectWsRoutes(): Array<{
446
+ handler: WSRouteHandler;
447
+ path: string;
448
+ }>;
449
+ /** @internal — the route-graph epoch; served documents cache against it. */
450
+ get _epoch(): number;
237
451
  defaultErrorFormatter<TSchema extends StandardSchemaLike>(schema: TSchema, fn: (error: HoneyError) => InferOutput<TSchema>): this;
238
452
  defaultErrorFormatter(fn: ErrorFormatterFn): this;
239
453
  customErrorFormatter<TSchema extends StandardSchemaLike>(schema: TSchema, fn: (error: HoneyError, data: Record<string, unknown>) => InferOutput<TSchema>): this;
240
454
  customErrorFormatter(fn: CustomErrorFormatter): this;
241
455
  errorI18n(config: ErrorI18nConfig<TEnv>): this;
242
- onError(handler: (error: unknown, ctx: {
243
- env: TEnv;
244
- jsonFromError: (err: HoneyError) => Response;
245
- req: Request;
246
- }) => HoneyError | Response | Promise<HoneyError | Response | undefined | void> | undefined | void): this;
247
- onMethodNotAllowed(handler: (ctx: {
248
- allowed: string[];
249
- env: TEnv;
250
- jsonFromError: (err: HoneyError) => Response;
251
- req: Request;
252
- }) => Response | Promise<Response>): this;
253
- onNotFound(handler: (ctx: {
254
- env: TEnv;
255
- jsonFromError: (err: HoneyError) => Response;
256
- req: Request;
257
- }) => Response | Promise<Response>): this;
456
+ onError(handler: OnErrorFn<TEnv>): this;
457
+ onMethodNotAllowed(handler: OnMethodNotAllowedFn<TEnv>): this;
458
+ onNotFound(handler: OnNotFoundFn<TEnv>): this;
258
459
  /** Register a tap handler keyed by name — fires after successful handler response */
259
460
  tap<K extends string>(key: K, handler: (ctx: TapContext<TEnv>, payload: K extends keyof TTaps ? TTaps[K] : unknown) => void | Promise<void>): this;
260
461
  telemetry(adapter: TelemetryAdapter): this;
462
+ /**
463
+ * Load a route tree — a generated `routes.gen.ts`, an `app.toRouteTree()` snapshot, or a
464
+ * `mergeTree()` of either. The tree supplies the router topology; what each route runs
465
+ * comes from the routes this app registers afterwards (bound by `RouteId`), from live
466
+ * records in a snapshot, or — for leaves with neither — from a root wildcard the app
467
+ * registers as its gateway catch-all. Must be called before any route is registered.
468
+ */
261
469
  routeTree(tree: RouteTree): this;
470
+ /**
471
+ * Snapshot this app's routes as a tree: a copy of the topology plus, per route, its data
472
+ * and its live record. Internal routes (spec, docs, manifest) are left out. Loading the
473
+ * snapshot into another app serves these records; nothing in it is shared with this app.
474
+ * Each record keeps this app's settings (error factory, defaults, boundary) and context
475
+ * values, and carries the scoped middleware that covers it here as part of its chain —
476
+ * scopes themselves do not travel in a tree.
477
+ */
262
478
  toRouteTree(): RouteTree;
479
+ /** A resolved record as a standalone source: its resolved chain minus route middleware becomes its chain. */
480
+ private _bake;
481
+ /**
482
+ * @internal — generate-time: copy input/output schemas from `source` onto this app's
483
+ * routes that lack them (a gateway serves its generated tree, which carries none).
484
+ */
485
+ _overlaySchemas(source: RouteTree): void;
486
+ /**
487
+ * @internal — generate-time: the route tree a gateway serves. `source` is the merged
488
+ * downstream tree (`codegen.mergeTree`); the gateway's own registered routes join it as
489
+ * ordinary leaves, while its root wildcards stay out of the tree — they are the catch-all
490
+ * the downstream leaves delegate to. An own route that is also a downstream route, or
491
+ * whose topology conflicts with one, throws here instead of at request time. The app is
492
+ * rebound to the result, so codegen that runs next (OpenAPI, manifest) sees what it serves.
493
+ */
494
+ _gatewayTree(source: RouteTree): RouteTree;
495
+ /** @internal — swap the loaded tree, re-binding every registered route to it. */
496
+ _replaceLoadedTree(tree: RouteTree): void;
497
+ /**
498
+ * Set the app's error factory. Like every app setting it applies to every handle of this
499
+ * app, whenever it is called; routes mounted from another app keep that app's factory.
500
+ */
263
501
  errorFactory<TFactory extends Record<string, (...args: never[]) => unknown>>(factory: TFactory): Honey<TEnv, TCtx, TRoutes, TMeta, TFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
502
+ /** Error keys every route of this app declares — applies to routes registered before and after the call. */
264
503
  defaultErrors<TKeys extends ([TErrorFactory] extends [never] ? never : keyof TErrorFactory & string)>(...keys: TKeys[]): Honey<TEnv, TCtx, TRoutes, TMeta, TErrorFactory, TDefaultErrors | TKeys, TBasePath, TTaps, TScopedMw>;
265
504
  defaultBoundary<TKey extends ([TErrorFactory] extends [never] ? never : keyof TErrorFactory & string)>(key: TKey): Honey<TEnv, TCtx, TRoutes, TMeta, TErrorFactory, TDefaultErrors | TKey, TBasePath, TTaps, TScopedMw>;
266
505
  /** Phantom overload — constrains what route-level .meta() accepts */
@@ -274,19 +513,6 @@ export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta
274
513
  * Codegen-time only — never consulted on the request path. See docs/meta-spec.md.
275
514
  */
276
515
  metaSpec<TSpec extends HoneyMetaSpec<TMeta>>(spec: TSpec): this;
277
- /**
278
- * Merge a mounted sub-app's policy into this one.
279
- *
280
- * The parent wins on conflict, so one gateway keeps one answer for its aggregate document —
281
- * with a single exception. A sub entry of `false` wins over anything the parent says, because
282
- * hiding is a safety claim and the strictest claim has to survive composition: a worker that
283
- * declares a field unpublishable must not have the gateway publish it. Wrongly hidden is a
284
- * visible gap; wrongly published is a leak.
285
- *
286
- * Every other disagreement is recorded and reported at codegen. Silently dropping a sub's
287
- * entry is how someone ends up diffing two documents to find out why they differ.
288
- */
289
- private _absorbMetaSpec;
290
516
  /** Declare tap payload types — auto-extends meta with Partial<T> for meta-driven taps */
291
517
  taps<TNewTaps extends Record<string, unknown>>(): Honey<TEnv, Omit<TCtx, "tap"> & {
292
518
  tap<K extends keyof TNewTaps>(key: K, payload: TNewTaps[K]): void;
@@ -298,8 +524,26 @@ export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta
298
524
  readonly path: MergePath<TBasePath, TPath>;
299
525
  readonly adds: TAdds;
300
526
  }]>;
301
- route<TSubRoutes, TSubMeta, TSubErrorFactory, TSubDefaultErrors extends string, TSubBasePath extends string>(sub: Honey<TEnv, TCtx, TSubRoutes, TSubMeta, TSubErrorFactory, TSubDefaultErrors, TSubBasePath>): Honey<TEnv, TCtx, TRoutes & TSubRoutes, TMeta, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
527
+ /**
528
+ * Mount a sub-app: its routes are served under this handle's basePath (and under `prefix`
529
+ * when given — `app.route("/v1", sub)` is `app.basePath("/v1").route(sub)`), and this
530
+ * handle's chain runs before theirs. The sub's own basePath stays part of each path.
531
+ */
532
+ route<TSubRoutes, TSubMeta, TSubErrorFactory, TSubDefaultErrors extends string, TSubBasePath extends string>(sub: Honey<TEnv, TCtx, TSubRoutes, TSubMeta, TSubErrorFactory, TSubDefaultErrors, TSubBasePath>): Honey<TEnv, TCtx, TRoutes & PrefixRoutes<TBasePath, TSubRoutes>, TMeta, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
533
+ route<const TPrefix extends string, TSubRoutes, TSubMeta, TSubErrorFactory, TSubDefaultErrors extends string, TSubBasePath extends string>(prefix: TPrefix, sub: Honey<TEnv, TCtx, TSubRoutes, TSubMeta, TSubErrorFactory, TSubDefaultErrors, TSubBasePath>): Honey<TEnv, TCtx, TRoutes & PrefixRoutes<MergePath<TBasePath, TPrefix>, TSubRoutes>, TMeta, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
534
+ private _mount;
535
+ private _setBus;
302
536
  private _registerRoute;
537
+ /** @internal — set (or clear, with null) one app-wide middleware; used by `serve()` */
538
+ _setGlobal(key: string, mw: RuntimeMiddleware | null): void;
539
+ /** @internal — what a route registered through this handle captures */
540
+ _view(): {
541
+ chain: RuntimeMiddleware[];
542
+ cv: Record<string, unknown> | null;
543
+ own: AppSettings<unknown>;
544
+ };
545
+ /** @internal — a builder got its handler (or was abandoned on purpose) */
546
+ _settle(pending: PendingRoute): void;
303
547
  on<const TPath extends string, const TMethods extends readonly [HttpMethod | "ALL", ...(HttpMethod | "ALL")[]]>(methods: TMethods, path: TPath): BuilderChain<TEnv, TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>, {}, never, {}, MergePath<TBasePath, TPath>, TMethods[number], TRoutes, never, TCtx, TMeta, InitAccMeta<TMeta>, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
304
548
  all<const TPath extends string>(path: TPath): BuilderChain<TEnv, TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>, {}, never, {}, MergePath<TBasePath, TPath>, "ALL", TRoutes, never, TCtx, TMeta, InitAccMeta<TMeta>, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
305
549
  delete<const TPath extends string>(path: TPath): BuilderChain<TEnv, TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>, {}, never, {}, MergePath<TBasePath, TPath>, "DELETE", TRoutes, never, TCtx, TMeta, InitAccMeta<TMeta>, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
@@ -310,7 +554,7 @@ export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta
310
554
  post<const TPath extends string>(path: TPath): BuilderChain<TEnv, TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>, {}, never, {}, MergePath<TBasePath, TPath>, "POST", TRoutes, never, TCtx, TMeta, InitAccMeta<TMeta>, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
311
555
  put<const TPath extends string>(path: TPath): BuilderChain<TEnv, TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>, {}, never, {}, MergePath<TBasePath, TPath>, "PUT", TRoutes, never, TCtx, TMeta, InitAccMeta<TMeta>, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
312
556
  ws<const TPath extends string>(path: TPath): WSRouteBuilder<TEnv, TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>, {}, never, Honey<TEnv, TCtx, TRoutes, TMeta, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>>;
313
- realtime(path: string, opts: RealtimeRouteOpts): this;
557
+ realtime<const TPath extends string>(path: TPath, opts: RealtimeRouteOpts<TCtx & ApplyScoped<TScopedMw, MergePath<TBasePath, TPath>>>): this;
314
558
  /**
315
559
  * Deno must call `Deno.upgradeWebSocket` in the same turn as the serve
316
560
  * callback. When the adapter implements `preUpgrade`, we do that here
@@ -319,21 +563,44 @@ export declare class Honey<TEnv, TCtx = HoneyContext<TEnv>, TRoutes = {}, TMeta
319
563
  fetch(request: Request, env: TEnv, executionCtx?: {
320
564
  waitUntil?: (p: Promise<unknown>) => void;
321
565
  }): Response | Promise<Response>;
322
- private pathFromRequest;
566
+ /** @internal 400 for a request path the normalization policy rejects (see `normalizePath`), or an invalid `Host`. */
567
+ _badRequestTarget(): Response;
323
568
  private trailingSlashRedirects;
324
569
  private pathAfterPrefix;
325
570
  private _doFetch;
571
+ private _route;
572
+ private _matchWs;
573
+ private _dispatchRecord;
326
574
  private _makeErrorCtx;
575
+ /** A request context for `plan`: route data, context values, `ctx.errors`, `ctx.realtime`. */
576
+ private _newCtx;
327
577
  private _handleWs;
328
- private _handleRealtime;
329
- private _handle404;
330
- private _preflightFallbackMethod;
331
- /** Run the existing method's middleware for a CORS preflight. Do not invoke the route handler. */
332
- private _handleCorsPreflight;
333
- private _handle405;
578
+ /** Reject a cross-origin upgrade the route's origin policy does not allow (403). */
579
+ /** The websocket session runtime; a cross-origin upgrade the route does not allow is a 403. */
580
+ private _wsSession;
581
+ private _wsUpgrade;
582
+ /** Terminal of a realtime route's chain: identify, upgrade, and attach the connection to the bus. */
583
+ private _realtimeUpgrade;
584
+ /**
585
+ * 404 (`allowed === null`) and 405: one pipeline with a synthetic record — full context,
586
+ * the app-wide middleware and the scopes covering the path run once, telemetry fires once.
587
+ */
588
+ private _handleMiss;
589
+ /** Fire `onResponse` once for the request's one exit and return. A dispatch that rejects
590
+ * (an adapter failure past every error boundary) still ends the request: it reports 500. */
591
+ private _withOnResponse;
592
+ private _make404;
593
+ private _make405;
594
+ /**
595
+ * CORS preflight for a path that has no OPTIONS route: run the chain of the route the
596
+ * preflight asks about (`Access-Control-Request-Method`) — chain, scoped and route
597
+ * middleware, never input validation or the handler. Middleware that answers the
598
+ * preflight (cors) short-circuits; otherwise the answer is the 405 with `Allow`.
599
+ */
600
+ private _handlePreflight;
334
601
  private _handleMatched;
335
- private _afterMatched;
336
- private _validateThenFinish;
602
+ /** Output validation, inside the chain: an invalid body becomes an error response the middleware sees. */
603
+ private _validateOutput;
337
604
  private _finishMatched;
338
605
  }
339
606
  /**
@@ -384,14 +651,6 @@ type ApplyScoped<TScopedMw extends readonly ScopedMwEntry[], TFullPath extends s
384
651
  infer Head extends ScopedMwEntry,
385
652
  ...infer Rest extends readonly ScopedMwEntry[]
386
653
  ] ? (string extends Head["path"] ? {} : TFullPath extends Head["path"] ? Head["adds"] : TFullPath extends `${Head["path"] & string}/${string}` ? Head["adds"] : {}) & ApplyScoped<Rest, TFullPath> : {};
387
- /** @internal — runtime entry for a scoped middleware */
388
- type ScopedEntry = {
389
- /** merged full-path prefix (already rebased against basePath at .use time) */
390
- prefix: string;
391
- mw: RuntimeMiddleware;
392
- /** cached from mw.errors at registration; undefined when none */
393
- errors: readonly string[] | undefined;
394
- };
395
654
  /** Apply typed params — override params with specific keys when route has :param segments */
396
655
  type ApplyParams<TCtx, TParams> = [keyof TParams] extends [string] ? string extends keyof TParams ? TCtx : TCtx & {
397
656
  readonly params: TParams;
@@ -415,20 +674,21 @@ type HandlerCtx<TCtx, TInput, TOutput, TParams, TAccMeta = {}, TErrorFactory = n
415
674
  }) & TypedTap<TTaps>, TOutput>;
416
675
  type RouteBuilderState<TParent> = {
417
676
  boundaryErrorKey: string | null;
677
+ /** keys the route declares itself (`.errors()`, `.boundary()`) */
418
678
  errorKeys: Set<string>;
419
679
  extraMethods: (HttpMethod | "ALL")[] | null;
420
- handlerMap: Record<string, RouteHandler> | null;
421
680
  inputSchemas: InputSchemasDef | null;
681
+ /** explicit meta — chain `.meta()` overlaid by route `.meta()` */
422
682
  meta: Record<string, unknown> | null;
423
- /** meta contributed by middleware — kept apart so explicit .meta() always outranks it */
424
- mwMeta: Record<string, unknown> | null;
425
683
  method: HttpMethod | "ALL";
684
+ /** route-level middleware */
426
685
  middlewares: RuntimeMiddleware[];
427
686
  outputSchemas: OutputSchemaDef | null;
428
687
  parent: TParent;
429
- parentMiddlewares: RuntimeMiddleware[];
688
+ /** canonical full pattern */
430
689
  path: string;
431
- root: TreeNode;
690
+ /** reported at finalize until `.handler()` runs */
691
+ pending: PendingRoute;
432
692
  };
433
693
  /** Honey.TMeta defaults to never; never & X is never, so start acc meta at {}. */
434
694
  type InitAccMeta<TMeta> = [TMeta] extends [never] ? {} : TMeta;
@@ -454,28 +714,28 @@ declare class RouteBuilder<TEnv, TCtx, TInput = {}, _TErrorKeys extends string =
454
714
  use<TAdds>(mw: MiddlewareFn<TCtx, TAdds>): BuilderChain<TEnv, TCtx & TAdds, TInput, _TErrorKeys, TOutput, TPath, TMethod, TRoutes, TUsed, TBaseCtx, TMeta, TAccMeta, TErrorFactory, TDefaultErrors, TBasePath, TTaps, TScopedMw>;
455
715
  }
456
716
  type WSRouteBuilderState<TParent> = {
457
- mwMeta?: Record<string, unknown> | null;
458
- boundaryErrorKey: string | null;
459
717
  errorKeys: Set<string>;
460
718
  inputSchemas: InputSchemasDef | null;
719
+ origins: WSOriginPolicy | null;
461
720
  meta: Record<string, unknown> | null;
462
721
  middlewares: RuntimeMiddleware[];
463
722
  parent: TParent;
464
- parentMiddlewares: RuntimeMiddleware[];
465
723
  path: string;
466
- root: TreeNode;
724
+ pending: PendingRoute;
467
725
  };
468
- declare class WSRouteBuilder<TEnv, TCtx, TInput = {}, _TErrorKeys extends string = never, TParent extends {
469
- _markWsRoutes(): void;
470
- } = {
471
- _markWsRoutes(): void;
472
- }> {
726
+ declare class WSRouteBuilder<TEnv, TCtx, TInput = {}, _TErrorKeys extends string = never, TParent = unknown> {
473
727
  private _s;
474
728
  constructor(state: WSRouteBuilderState<TParent>);
475
729
  errors<TFactory extends Record<string, (...args: never[]) => unknown>>(factory: TFactory, ...keys: Array<keyof TFactory & string>): WSRouteBuilder<TEnv, TCtx, TInput, _TErrorKeys | (keyof TFactory & string), TParent>;
476
730
  handler(wsHandler: WSHandler<TCtx>): TParent;
477
731
  input<TSchemas extends Pick<InputSchemasDef, "cookies" | "headers" | "search">>(schemas: TSchemas): WSRouteBuilder<TEnv, TCtx, TInput & InferInputMap<TSchemas>, _TErrorKeys, TParent>;
478
732
  meta(meta: Record<string, unknown>): this;
733
+ /**
734
+ * Browser origins allowed to open this socket: `"*"`, a list of origins
735
+ * (`https://app.example.com`), or a predicate. Same-origin always passes. Without it, a
736
+ * cross-origin upgrade that carries `Cookie` or `Authorization` gets 403.
737
+ */
738
+ origins(policy: WSOriginPolicy): WSRouteBuilder<TEnv, TCtx, TInput, _TErrorKeys, TParent>;
479
739
  use<TAdds>(mw: MiddlewareFn<TCtx, TAdds>): WSRouteBuilder<TEnv, TCtx & TAdds, TInput, _TErrorKeys, TParent>;
480
740
  }
481
741
  export declare function honey<TEnv>(): Honey<TEnv>;