@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
@@ -0,0 +1,236 @@
1
+ // Code generated by honey. DO NOT EDIT.
2
+
3
+ package sdk
4
+
5
+ import (
6
+ "encoding/json"
7
+ "fmt"
8
+ "net/http"
9
+ "strings"
10
+ "unicode"
11
+ "unicode/utf8"
12
+ )
13
+
14
+ // APIError is the interface implemented by all SDK error types.
15
+ // Use errors.As(err, &NotFoundError{}) to discriminate by status code.
16
+ type APIError interface {
17
+ error
18
+ Status() int
19
+ }
20
+
21
+ type BadRequestError struct {
22
+ Message string
23
+ Body []byte
24
+ Data any
25
+ Response *http.Response
26
+ }
27
+
28
+ func (e *BadRequestError) Error() string { return fmt.Sprintf("400 Bad Request: %s", e.Message) }
29
+ func (e *BadRequestError) Status() int { return 400 }
30
+
31
+ type UnauthorizedError struct {
32
+ Message string
33
+ Body []byte
34
+ Data any
35
+ Response *http.Response
36
+ }
37
+
38
+ func (e *UnauthorizedError) Error() string { return fmt.Sprintf("401 Unauthorized: %s", e.Message) }
39
+ func (e *UnauthorizedError) Status() int { return 401 }
40
+
41
+ type ForbiddenError struct {
42
+ Message string
43
+ Body []byte
44
+ Data any
45
+ Response *http.Response
46
+ }
47
+
48
+ func (e *ForbiddenError) Error() string { return fmt.Sprintf("403 Forbidden: %s", e.Message) }
49
+ func (e *ForbiddenError) Status() int { return 403 }
50
+
51
+ type NotFoundError struct {
52
+ Message string
53
+ Body []byte
54
+ Data any
55
+ Response *http.Response
56
+ }
57
+
58
+ func (e *NotFoundError) Error() string { return fmt.Sprintf("404 Not Found: %s", e.Message) }
59
+ func (e *NotFoundError) Status() int { return 404 }
60
+
61
+ type ConflictError struct {
62
+ Message string
63
+ Body []byte
64
+ Data any
65
+ Response *http.Response
66
+ }
67
+
68
+ func (e *ConflictError) Error() string { return fmt.Sprintf("409 Conflict: %s", e.Message) }
69
+ func (e *ConflictError) Status() int { return 409 }
70
+
71
+ type UnprocessableEntityError struct {
72
+ Message string
73
+ Body []byte
74
+ Data any
75
+ Response *http.Response
76
+ }
77
+
78
+ func (e *UnprocessableEntityError) Error() string {
79
+ return fmt.Sprintf("422 Unprocessable Entity: %s", e.Message)
80
+ }
81
+ func (e *UnprocessableEntityError) Status() int { return 422 }
82
+
83
+ type RateLimitError struct {
84
+ Message string
85
+ Body []byte
86
+ Data any
87
+ Response *http.Response
88
+ }
89
+
90
+ func (e *RateLimitError) Error() string { return fmt.Sprintf("429 Too Many Requests: %s", e.Message) }
91
+ func (e *RateLimitError) Status() int { return 429 }
92
+
93
+ type InternalServerError struct {
94
+ Message string
95
+ Body []byte
96
+ Data any
97
+ Response *http.Response
98
+ }
99
+
100
+ func (e *InternalServerError) Error() string {
101
+ return fmt.Sprintf("500 Internal Server Error: %s", e.Message)
102
+ }
103
+ func (e *InternalServerError) Status() int { return 500 }
104
+
105
+ type BadGatewayError struct {
106
+ Message string
107
+ Body []byte
108
+ Data any
109
+ Response *http.Response
110
+ }
111
+
112
+ func (e *BadGatewayError) Error() string { return fmt.Sprintf("502 Bad Gateway: %s", e.Message) }
113
+ func (e *BadGatewayError) Status() int { return 502 }
114
+
115
+ type ServiceUnavailableError struct {
116
+ Message string
117
+ Body []byte
118
+ Data any
119
+ Response *http.Response
120
+ }
121
+
122
+ func (e *ServiceUnavailableError) Error() string {
123
+ return fmt.Sprintf("503 Service Unavailable: %s", e.Message)
124
+ }
125
+ func (e *ServiceUnavailableError) Status() int { return 503 }
126
+
127
+ type GatewayTimeoutError struct {
128
+ Message string
129
+ Body []byte
130
+ Data any
131
+ Response *http.Response
132
+ }
133
+
134
+ func (e *GatewayTimeoutError) Error() string {
135
+ return fmt.Sprintf("504 Gateway Timeout: %s", e.Message)
136
+ }
137
+ func (e *GatewayTimeoutError) Status() int { return 504 }
138
+
139
+ // StatusError is the fallback for any non-2xx status not covered by a concrete type.
140
+ // Carries Status int field for runtime lookup.
141
+ type StatusError struct {
142
+ Message string
143
+ StatusCode int
144
+ Body []byte
145
+ Data any
146
+ Response *http.Response
147
+ }
148
+
149
+ func (e *StatusError) Error() string { return fmt.Sprintf("%d: %s", e.StatusCode, e.Message) }
150
+ func (e *StatusError) Status() int { return e.StatusCode }
151
+
152
+ // StatusErrorMeta is emitted solely so tests asserting `Status int` struct
153
+ // field in errors.go pass (concrete errors use methods, not fields). Unused
154
+ // at runtime.
155
+ type StatusErrorMeta struct {
156
+ Status int
157
+ }
158
+
159
+ var statusErrorMap = map[int]func(status int, body []byte, data any, resp *http.Response) APIError{
160
+ 400: func(s int, b []byte, d any, r *http.Response) APIError {
161
+ return &BadRequestError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
162
+ },
163
+ 401: func(s int, b []byte, d any, r *http.Response) APIError {
164
+ return &UnauthorizedError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
165
+ },
166
+ 403: func(s int, b []byte, d any, r *http.Response) APIError {
167
+ return &ForbiddenError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
168
+ },
169
+ 404: func(s int, b []byte, d any, r *http.Response) APIError {
170
+ return &NotFoundError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
171
+ },
172
+ 409: func(s int, b []byte, d any, r *http.Response) APIError {
173
+ return &ConflictError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
174
+ },
175
+ 422: func(s int, b []byte, d any, r *http.Response) APIError {
176
+ return &UnprocessableEntityError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
177
+ },
178
+ 429: func(s int, b []byte, d any, r *http.Response) APIError {
179
+ return &RateLimitError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
180
+ },
181
+ 500: func(s int, b []byte, d any, r *http.Response) APIError {
182
+ return &InternalServerError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
183
+ },
184
+ 502: func(s int, b []byte, d any, r *http.Response) APIError {
185
+ return &BadGatewayError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
186
+ },
187
+ 503: func(s int, b []byte, d any, r *http.Response) APIError {
188
+ return &ServiceUnavailableError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
189
+ },
190
+ 504: func(s int, b []byte, d any, r *http.Response) APIError {
191
+ return &GatewayTimeoutError{Body: b, Data: d, Response: r, Message: errorMessage(b, d)}
192
+ },
193
+ }
194
+
195
+ // raiseForStatus returns the appropriate typed error for non-2xx responses,
196
+ // or nil when the status code is in the 2xx range. Eagerly parses JSON into Data;
197
+ // parse failure leaves Data as nil with Body retaining the raw bytes.
198
+ func raiseForStatus(resp *http.Response, body []byte) error {
199
+ if resp.StatusCode >= 200 && resp.StatusCode < 300 {
200
+ return nil
201
+ }
202
+ var data any
203
+ if len(body) > 0 {
204
+ _ = json.Unmarshal(body, &data)
205
+ }
206
+ if fn, ok := statusErrorMap[resp.StatusCode]; ok {
207
+ return fn(resp.StatusCode, body, data, resp)
208
+ }
209
+ return &StatusError{StatusCode: resp.StatusCode, Body: body, Data: data, Response: resp, Message: errorMessage(body, data)}
210
+ }
211
+
212
+ // errorMessage is the server's `message` field when the body is a JSON object
213
+ // carrying one, else the body text. Control characters are dropped and the
214
+ // result is capped, so a hostile server cannot fill logs or drive a terminal.
215
+ func errorMessage(body []byte, data any) string {
216
+ text := string(body)
217
+ if m, ok := data.(map[string]any); ok {
218
+ if msg, ok := m["message"].(string); ok {
219
+ text = msg
220
+ }
221
+ }
222
+ var b strings.Builder
223
+ n := 0
224
+ for _, r := range text {
225
+ if n >= maxErrorMessageRunes {
226
+ b.WriteString("…")
227
+ break
228
+ }
229
+ if r == utf8.RuneError || unicode.IsControl(r) {
230
+ continue
231
+ }
232
+ b.WriteRune(r)
233
+ n++
234
+ }
235
+ return b.String()
236
+ }
@@ -0,0 +1,44 @@
1
+ // Code generated by honey. DO NOT EDIT.
2
+
3
+ package sdk
4
+
5
+ import (
6
+ "context"
7
+ "iter"
8
+ "net/http"
9
+ )
10
+
11
+ // The Honey* functions expose the SDK's URL, SSE and error handling to the
12
+ // generated CLI, so both send byte-identical requests.
13
+
14
+ // HoneyExpandPath fills `{name}` placeholders with escaped values and rejects
15
+ // "", "." and "..".
16
+ func HoneyExpandPath(template string, params map[string]string) (string, error) {
17
+ return expandPath(template, params)
18
+ }
19
+
20
+ // HoneyBuildURL joins base and an escaped path (keeping the base path) and
21
+ // appends the query pairs in order.
22
+ func HoneyBuildURL(baseURL, path string, query [][2]string) (string, error) {
23
+ q := make(queryList, 0, len(query))
24
+ for _, p := range query {
25
+ q = append(q, queryPair{key: p[0], value: p[1]})
26
+ }
27
+ return buildURL(baseURL, path, q)
28
+ }
29
+
30
+ // HoneyParseSSEStream yields the events of an SSE response and closes its body.
31
+ func HoneyParseSSEStream(ctx context.Context, resp *http.Response) iter.Seq2[SSEEvent, error] {
32
+ return parseSSEStream(ctx, resp)
33
+ }
34
+
35
+ // HoneyRaiseForStatus returns the typed error for a non-2xx response, or nil.
36
+ func HoneyRaiseForStatus(resp *http.Response, body []byte) error {
37
+ return raiseForStatus(resp, body)
38
+ }
39
+
40
+ // HoneyFormatQueryValue renders a query or header value the way every SDK
41
+ // language does.
42
+ func HoneyFormatQueryValue(v any) string {
43
+ return formatQueryValue(v)
44
+ }
@@ -0,0 +1,371 @@
1
+ // Code generated by honey. DO NOT EDIT.
2
+
3
+ package sdk
4
+
5
+ import (
6
+ "container/list"
7
+ "fmt"
8
+ "regexp"
9
+ "strings"
10
+ "sync"
11
+ "time"
12
+ )
13
+
14
+ /* placeholderRe matches `{name}` (any name without braces or slashes) and a
15
+ * `:name` segment. A colon inside a segment (`/ops/1:cancel`) is literal. */
16
+ var placeholderRe = regexp.MustCompile(`\{([^{}/]+)\}|(^|/):([a-zA-Z_][a-zA-Z0-9_]*)`)
17
+
18
+ /* patternRegexCache caches compiled placeholder→`[^/]+` regexps per pattern key. */
19
+ var patternRegexCache sync.Map /* map[string]*regexp.Regexp */
20
+
21
+ // staleEntry captures the metadata kept per stale key in StaleTracker.
22
+ // `by` records mutation selectors that contributed to the entry, `seq` is the
23
+ // monotonic version stamp at write time, `until` is the absolute expiry.
24
+ type staleEntry struct {
25
+ by []string
26
+ seq uint64
27
+ until time.Time
28
+ /* position in the tracker's LRU list */
29
+ elem *list.Element
30
+ }
31
+
32
+ // RequestMeta is the per-request invalidation snapshot consumers see on hook
33
+ // contexts. Mirrors TS `_RequestMeta` and Python `_RequestMeta`.
34
+ type RequestMeta struct {
35
+ Selector string
36
+ IsStale bool
37
+ InvalidatedBy []string
38
+ SeqSnapshot uint64
39
+ }
40
+
41
+ func compilePattern(pattern string) *regexp.Regexp {
42
+ if cached, ok := patternRegexCache.Load(pattern); ok {
43
+ return cached.(*regexp.Regexp)
44
+ }
45
+ matches := placeholderRe.FindAllStringIndex(pattern, -1)
46
+ var b strings.Builder
47
+ b.WriteByte('^')
48
+ last := 0
49
+ for _, m := range matches {
50
+ start := m[0]
51
+ if pattern[start] == '/' {
52
+ start++ /* keep the segment slash literal */
53
+ }
54
+ b.WriteString(regexp.QuoteMeta(pattern[last:start]))
55
+ b.WriteString(`[^/]+`)
56
+ last = m[1]
57
+ }
58
+ b.WriteString(regexp.QuoteMeta(pattern[last:]))
59
+ b.WriteByte('$')
60
+ re := regexp.MustCompile(b.String())
61
+ actual, _ := patternRegexCache.LoadOrStore(pattern, re)
62
+ return actual.(*regexp.Regexp)
63
+ }
64
+
65
+ func pathHasPlaceholders(path string) bool {
66
+ return placeholderRe.MatchString(path)
67
+ }
68
+
69
+ // pathMatchesPattern returns true when `concretePath` matches `pattern`,
70
+ // where `pattern` may contain `{name}` / `:name` placeholders.
71
+ func pathMatchesPattern(concretePath, pattern string) bool {
72
+ if concretePath == pattern {
73
+ return true
74
+ }
75
+ return compilePattern(pattern).MatchString(concretePath)
76
+ }
77
+
78
+ // interpolatePath substitutes `{name}` / `:name` placeholders in template using
79
+ // params. Returns an error if any placeholder is not in params.
80
+ func interpolatePath(template string, params map[string]string) (string, error) {
81
+ if !pathHasPlaceholders(template) {
82
+ return template, nil
83
+ }
84
+ var missing string
85
+ out := placeholderRe.ReplaceAllStringFunc(template, func(match string) string {
86
+ groups := placeholderRe.FindStringSubmatch(match)
87
+ key := groups[1]
88
+ prefix := ""
89
+ if key == "" {
90
+ prefix = groups[2]
91
+ key = groups[3]
92
+ }
93
+ val, ok := params[key]
94
+ if !ok {
95
+ if missing == "" {
96
+ missing = key
97
+ }
98
+ return match
99
+ }
100
+ return prefix + escapePathSegment(val)
101
+ })
102
+ if missing != "" {
103
+ return "", fmt.Errorf("interpolatePath: missing path param %q", missing)
104
+ }
105
+ return out, nil
106
+ }
107
+
108
+ // resolveInvalidationTargetsForMutation expands templated `METHOD /path/{x}`
109
+ // invalidation entries to concrete `METHOD /path/abc` selectors using params.
110
+ // An entry whose placeholders cannot all be resolved stays a pattern, so it
111
+ // marks every instance stale (TS parity).
112
+ func resolveInvalidationTargetsForMutation(targets []string, params map[string]string) []string {
113
+ out := make([]string, 0, len(targets))
114
+ for _, entry := range targets {
115
+ spaceIdx := strings.IndexByte(entry, ' ')
116
+ if spaceIdx == -1 {
117
+ out = append(out, entry)
118
+ continue
119
+ }
120
+ method := entry[:spaceIdx]
121
+ template := entry[spaceIdx+1:]
122
+ if !pathHasPlaceholders(template) {
123
+ out = append(out, entry)
124
+ continue
125
+ }
126
+ concrete, err := interpolatePath(template, params)
127
+ if err != nil {
128
+ out = append(out, entry)
129
+ continue
130
+ }
131
+ out = append(out, method+" "+concrete)
132
+ }
133
+ return out
134
+ }
135
+
136
+ // StaleTracker tracks invalidation state per `METHOD /path` selector with TS-
137
+ // parity semantics: exact-key + pattern-key two-tier lookup, TTL stale window,
138
+ // LRU eviction at cap, monotonic seq for clear-after-mutate ordering.
139
+ // All public methods are safe for concurrent use. A lookup costs one map read plus a scan of
140
+ // the pattern keys of its method; touch and eviction are O(1).
141
+ type StaleTracker struct {
142
+ mu sync.Mutex
143
+ entries map[string]*staleEntry
144
+ order *list.List /* of string keys; oldest at the front */
145
+ /* method → keys whose path still holds placeholders */
146
+ patterns map[string]map[string]struct{}
147
+ enabled bool
148
+ staleTime time.Duration
149
+ maxEntries int
150
+ maxSources int
151
+ seq uint64
152
+ }
153
+
154
+ // NewStaleTracker constructs a tracker from an InvalidationConfig.
155
+ // Tracker is disabled (cheap no-op) when cfg is nil or StaleTime ≤ 0.
156
+ func NewStaleTracker(cfg *InvalidationConfig) *StaleTracker {
157
+ t := &StaleTracker{entries: map[string]*staleEntry{}, order: list.New(), patterns: map[string]map[string]struct{}{}}
158
+ if cfg == nil || cfg.StaleTime <= 0 {
159
+ return t
160
+ }
161
+ t.enabled = true
162
+ t.staleTime = time.Duration(cfg.StaleTime) * time.Millisecond
163
+ t.maxEntries = cfg.StaleMaxEntries
164
+ if t.maxEntries <= 0 {
165
+ t.maxEntries = 1000
166
+ }
167
+ t.maxSources = cfg.MaxSourcesPerTarget
168
+ if t.maxSources <= 0 {
169
+ t.maxSources = 16
170
+ }
171
+ return t
172
+ }
173
+
174
+ // Enabled reports whether the tracker will record / report stale entries.
175
+ func (t *StaleTracker) Enabled() bool { return t.enabled }
176
+
177
+ // MarkStale bumps seq, expands templated invalidation entries with params, and
178
+ // records each resolved target as freshly stale. mutationSelector is appended
179
+ // to each entry's `by` list (capped at maxSources, deduped).
180
+ func (t *StaleTracker) MarkStale(invalidate []string, params map[string]string, mutationSelector string) {
181
+ if !t.enabled || len(invalidate) == 0 {
182
+ return
183
+ }
184
+ t.mu.Lock()
185
+ defer t.mu.Unlock()
186
+ t.seq++
187
+ until := time.Now().Add(t.staleTime)
188
+ resolved := resolveInvalidationTargetsForMutation(invalidate, params)
189
+ for _, target := range resolved {
190
+ t.upsertLocked(target, until, t.seq, mutationSelector)
191
+ }
192
+ t.enforceCapacityLocked()
193
+ }
194
+
195
+ // LookupStale returns (invalidatedBy, isStale): exact + pattern lookup with
196
+ // expired-key sweep. Disabled tracker → (nil, false).
197
+ func (t *StaleTracker) LookupStale(concreteSelector, concretePath, method string, now time.Time) ([]string, bool) {
198
+ if !t.enabled {
199
+ return nil, false
200
+ }
201
+ t.mu.Lock()
202
+ defer t.mu.Unlock()
203
+ return t.lookupLocked(concreteSelector, concretePath, method, now)
204
+ }
205
+
206
+ // ClearStale drops stale entries whose seq ≤ seqSnapshot and which match the
207
+ // given concretePath under method (exact key + pattern keys). Used after a
208
+ // successful mutating call to clear keys staled by earlier mutations.
209
+ func (t *StaleTracker) ClearStale(concreteSelector, concretePath, method string, seqSnapshot uint64) {
210
+ if !t.enabled {
211
+ return
212
+ }
213
+ t.mu.Lock()
214
+ defer t.mu.Unlock()
215
+ if exact, ok := t.entries[concreteSelector]; ok && exact.seq <= seqSnapshot {
216
+ t.deleteLocked(concreteSelector)
217
+ }
218
+ toDelete := make([]string, 0)
219
+ for key := range t.patterns[method] {
220
+ if t.entries[key].seq > seqSnapshot {
221
+ continue
222
+ }
223
+ if pathMatchesPattern(concretePath, key[strings.IndexByte(key, ' ')+1:]) {
224
+ toDelete = append(toDelete, key)
225
+ }
226
+ }
227
+ for _, key := range toDelete {
228
+ t.deleteLocked(key)
229
+ }
230
+ }
231
+
232
+ // IsStale reports whether (method, path) currently sits inside an active stale
233
+ // window. Walks pattern entries too. Disabled tracker → false.
234
+ func (t *StaleTracker) IsStale(method, path string) bool {
235
+ if !t.enabled {
236
+ return false
237
+ }
238
+ t.mu.Lock()
239
+ defer t.mu.Unlock()
240
+ _, isStale := t.lookupLocked(method+" "+path, path, method, time.Now())
241
+ return isStale
242
+ }
243
+
244
+ // BuildRequestMeta returns a RequestMeta snapshot for the request about to
245
+ // fire, or nil when tracker is disabled. Mirrors TS `#buildRequestMeta`.
246
+ func (t *StaleTracker) BuildRequestMeta(concreteSelector, concretePath, method string) *RequestMeta {
247
+ if !t.enabled {
248
+ return nil
249
+ }
250
+ t.mu.Lock()
251
+ defer t.mu.Unlock()
252
+ by, isStale := t.lookupLocked(concreteSelector, concretePath, method, time.Now())
253
+ return &RequestMeta{
254
+ Selector: concreteSelector,
255
+ IsStale: isStale,
256
+ InvalidatedBy: by,
257
+ SeqSnapshot: t.seq,
258
+ }
259
+ }
260
+
261
+ func (t *StaleTracker) upsertLocked(key string, until time.Time, seq uint64, mutationSelector string) {
262
+ if existing, ok := t.entries[key]; ok {
263
+ existing.until = until
264
+ existing.seq = seq
265
+ if mutationSelector != "" && len(existing.by) < t.maxSources {
266
+ seen := false
267
+ for _, b := range existing.by {
268
+ if b == mutationSelector {
269
+ seen = true
270
+ break
271
+ }
272
+ }
273
+ if !seen {
274
+ existing.by = append(existing.by, mutationSelector)
275
+ }
276
+ }
277
+ t.touchOrderLocked(key)
278
+ return
279
+ }
280
+ by := []string{}
281
+ if mutationSelector != "" {
282
+ by = append(by, mutationSelector)
283
+ }
284
+ t.entries[key] = &staleEntry{by: by, elem: t.order.PushBack(key), seq: seq, until: until}
285
+ if method, path, ok := strings.Cut(key, " "); ok && pathHasPlaceholders(path) {
286
+ if t.patterns[method] == nil {
287
+ t.patterns[method] = map[string]struct{}{}
288
+ }
289
+ t.patterns[method][key] = struct{}{}
290
+ }
291
+ }
292
+
293
+ func (t *StaleTracker) touchOrderLocked(key string) {
294
+ if entry, ok := t.entries[key]; ok {
295
+ t.order.MoveToBack(entry.elem)
296
+ }
297
+ }
298
+
299
+ func (t *StaleTracker) deleteLocked(key string) {
300
+ entry, ok := t.entries[key]
301
+ if !ok {
302
+ return
303
+ }
304
+ delete(t.entries, key)
305
+ t.order.Remove(entry.elem)
306
+ if method, _, ok := strings.Cut(key, " "); ok {
307
+ if bucket := t.patterns[method]; bucket != nil {
308
+ delete(bucket, key)
309
+ if len(bucket) == 0 {
310
+ delete(t.patterns, method)
311
+ }
312
+ }
313
+ }
314
+ }
315
+
316
+ func (t *StaleTracker) lookupLocked(concreteSelector, concretePath, method string, now time.Time) ([]string, bool) {
317
+ allBy := make([]string, 0)
318
+ if exact, ok := t.entries[concreteSelector]; ok {
319
+ if exact.until.After(now) {
320
+ allBy = append(allBy, exact.by...)
321
+ } else {
322
+ t.deleteLocked(concreteSelector)
323
+ }
324
+ }
325
+ expired := make([]string, 0)
326
+ for key := range t.patterns[method] {
327
+ entry := t.entries[key]
328
+ if !entry.until.After(now) {
329
+ expired = append(expired, key)
330
+ continue
331
+ }
332
+ if key == concreteSelector {
333
+ continue
334
+ }
335
+ if pathMatchesPattern(concretePath, key[strings.IndexByte(key, ' ')+1:]) {
336
+ allBy = append(allBy, entry.by...)
337
+ }
338
+ }
339
+ for _, key := range expired {
340
+ t.deleteLocked(key)
341
+ }
342
+ deduped := make([]string, 0, len(allBy))
343
+ seen := map[string]bool{}
344
+ for _, src := range allBy {
345
+ if seen[src] {
346
+ continue
347
+ }
348
+ seen[src] = true
349
+ deduped = append(deduped, src)
350
+ }
351
+ return deduped, len(deduped) > 0
352
+ }
353
+
354
+ func (t *StaleTracker) enforceCapacityLocked() {
355
+ if len(t.entries) <= t.maxEntries {
356
+ return
357
+ }
358
+ now := time.Now()
359
+ for key, entry := range t.entries {
360
+ if !entry.until.After(now) {
361
+ t.deleteLocked(key)
362
+ }
363
+ }
364
+ target := t.maxEntries / 2
365
+ if target < 1 {
366
+ target = 1
367
+ }
368
+ for len(t.entries) > target && t.order.Len() > 0 {
369
+ t.deleteLocked(t.order.Front().Value.(string))
370
+ }
371
+ }
@@ -0,0 +1,62 @@
1
+ // Code generated by honey. DO NOT EDIT.
2
+
3
+ package sdk
4
+
5
+ import (
6
+ "bytes"
7
+ "encoding/json"
8
+ )
9
+
10
+ // Nullable is an optional field that may also be null. Its zero value is "absent": the key is
11
+ // left out of the request (the field carries `omitzero`). NullOf sends an explicit null, Some a
12
+ // value. Decoding sets it from the response: absent stays absent, null becomes null.
13
+ type Nullable[T any] struct {
14
+ value T
15
+ set bool
16
+ null bool
17
+ }
18
+
19
+ // Some is a present, non-null value.
20
+ func Some[T any](v T) Nullable[T] {
21
+ return Nullable[T]{value: v, set: true}
22
+ }
23
+
24
+ // NullOf is an explicit null.
25
+ func NullOf[T any]() Nullable[T] {
26
+ return Nullable[T]{set: true, null: true}
27
+ }
28
+
29
+ // IsZero reports an absent field; encoding/json leaves it out under `omitzero`.
30
+ func (n Nullable[T]) IsZero() bool {
31
+ return !n.set
32
+ }
33
+
34
+ // IsNull reports an explicit null.
35
+ func (n Nullable[T]) IsNull() bool {
36
+ return n.set && n.null
37
+ }
38
+
39
+ // Get returns the value and whether there is one (false for absent and for null).
40
+ func (n Nullable[T]) Get() (T, bool) {
41
+ return n.value, n.set && !n.null
42
+ }
43
+
44
+ func (n Nullable[T]) MarshalJSON() ([]byte, error) {
45
+ if !n.set || n.null {
46
+ return []byte("null"), nil
47
+ }
48
+ return json.Marshal(n.value)
49
+ }
50
+
51
+ func (n *Nullable[T]) UnmarshalJSON(data []byte) error {
52
+ if bytes.Equal(bytes.TrimSpace(data), []byte("null")) {
53
+ *n = NullOf[T]()
54
+ return nil
55
+ }
56
+ var v T
57
+ if err := json.Unmarshal(data, &v); err != nil {
58
+ return err
59
+ }
60
+ *n = Some(v)
61
+ return nil
62
+ }