@lovrozagar/honey 0.6.5 → 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 +410 -149
  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 +1893 -1761
  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 +271 -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,147 @@
1
+ /**
2
+ * Detects which optional honey features (`openapi`, `i18n`, `serve`) app code uses, so build
3
+ * tooling can import their entries ahead of the app. A bundle cannot follow the lazy, opaque
4
+ * feature imports honey uses at run time. Not a package export.
5
+ */
6
+
7
+ export type HoneyFeature = "i18n" | "openapi" | "serve"
8
+
9
+ export const FEATURES: readonly HoneyFeature[] = ["i18n", "openapi", "serve"]
10
+
11
+ const FEATURE_ENTRY: Record<HoneyFeature, { enable: string; specifier: string }> = {
12
+ i18n: { enable: "enableI18n", specifier: "@lovrozagar/honey/i18n" },
13
+ openapi: { enable: "enableOpenApi", specifier: "@lovrozagar/honey/openapi" },
14
+ serve: { enable: "enableServe", specifier: "@lovrozagar/honey/serve" },
15
+ }
16
+
17
+ const METHOD_FEATURE: Record<string, HoneyFeature> = {
18
+ errorI18n: "i18n",
19
+ manifest: "openapi",
20
+ openapi: "openapi",
21
+ serve: "serve",
22
+ }
23
+
24
+ /** Globals whose `.serve()` is the runtime's own server, not `Honey.serve()`. */
25
+ const RUNTIME_SERVE_OWNERS = new Set(["Bun", "Deno"])
26
+
27
+ function blank(s: string): string {
28
+ return s.replace(/[^\n]/g, " ")
29
+ }
30
+
31
+ /**
32
+ * Replaces comments and string, template and regex literal contents with spaces, keeping every
33
+ * newline so offsets and line numbers still line up. A scanner, not a parser; it is only accurate
34
+ * enough to keep `// app.serve(` in a comment from counting as a call.
35
+ */
36
+ export function stripCommentsAndStrings(code: string): string {
37
+ let out = ""
38
+ let i = 0
39
+ while (i < code.length) {
40
+ const ch = code[i] as string
41
+ const next = code[i + 1]
42
+ if (ch === "/" && next === "/") {
43
+ const end = code.indexOf("\n", i)
44
+ const stop = end === -1 ? code.length : end
45
+ out += blank(code.slice(i, stop))
46
+ i = stop
47
+ } else if (ch === "/" && next === "*") {
48
+ const end = code.indexOf("*/", i + 2)
49
+ const stop = end === -1 ? code.length : end + 2
50
+ out += blank(code.slice(i, stop))
51
+ i = stop
52
+ } else if (ch === '"' || ch === "'" || ch === "`") {
53
+ let j = i + 1
54
+ while (j < code.length && code[j] !== ch) {
55
+ if (code[j] === "\\") j++
56
+ else if (ch !== "`" && code[j] === "\n") break
57
+ j++
58
+ }
59
+ const stop = Math.min(j + 1, code.length)
60
+ out += ch + blank(code.slice(i + 1, stop - 1)) + (stop - 1 > i ? (code[stop - 1] ?? "") : "")
61
+ i = stop
62
+ } else {
63
+ out += ch
64
+ i++
65
+ }
66
+ }
67
+ return out
68
+ }
69
+
70
+ /** Feature calls in source text, ignoring comments and strings. */
71
+ export function detectFeaturesInSource(code: string): Set<HoneyFeature> {
72
+ const text = stripCommentsAndStrings(code)
73
+ const found = new Set<HoneyFeature>()
74
+ const re = /(\b[A-Za-z_$][\w$]*\s*)?\.\s*(openapi|manifest|errorI18n|serve)\s*\(/g
75
+ for (const m of text.matchAll(re)) {
76
+ const owner = m[1]?.trim()
77
+ const method = m[2] as string
78
+ if (method === "serve" && owner && RUNTIME_SERVE_OWNERS.has(owner)) continue
79
+ found.add(METHOD_FEATURE[method] as HoneyFeature)
80
+ }
81
+ return found
82
+ }
83
+
84
+ type AstNode = { [key: string]: unknown; type: string }
85
+
86
+ function isNode(value: unknown): value is AstNode {
87
+ return value !== null && typeof value === "object" && typeof (value as { type?: unknown }).type === "string"
88
+ }
89
+
90
+ /** Feature calls and import specifiers of an ESTree program. */
91
+ export function scanProgram(program: unknown): { features: Set<HoneyFeature>; imports: string[] } {
92
+ const features = new Set<HoneyFeature>()
93
+ const imports: string[] = []
94
+ const stack: unknown[] = [program]
95
+ while (stack.length > 0) {
96
+ const node = stack.pop()
97
+ if (Array.isArray(node)) {
98
+ stack.push(...node)
99
+ continue
100
+ }
101
+ if (!isNode(node)) continue
102
+ switch (node.type) {
103
+ case "ImportDeclaration":
104
+ case "ExportAllDeclaration":
105
+ case "ExportNamedDeclaration":
106
+ case "ImportExpression": {
107
+ const source = node.source as { type?: string; value?: unknown } | null | undefined
108
+ if (source && typeof source.value === "string") imports.push(source.value)
109
+ break
110
+ }
111
+ case "CallExpression": {
112
+ const callee = node.callee as AstNode | undefined
113
+ if (callee?.type === "MemberExpression" && !callee.computed) {
114
+ const property = callee.property as { name?: unknown }
115
+ const feature = typeof property.name === "string" ? METHOD_FEATURE[property.name] : undefined
116
+ const object = callee.object as { name?: unknown; type?: string }
117
+ const runtimeOwned =
118
+ property.name === "serve" && object.type === "Identifier" && RUNTIME_SERVE_OWNERS.has(String(object.name))
119
+ if (feature && !runtimeOwned) features.add(feature)
120
+ }
121
+ break
122
+ }
123
+ }
124
+ for (const key in node) {
125
+ if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range") continue
126
+ const value = node[key]
127
+ if (value !== null && typeof value === "object") stack.push(value)
128
+ }
129
+ }
130
+ return { features, imports }
131
+ }
132
+
133
+ /** `import { enableX } from "…"; enableX();` for each feature, on one line. */
134
+ export function featurePrelude(features: Iterable<HoneyFeature>): string {
135
+ const parts: string[] = []
136
+ for (const feature of FEATURES) {
137
+ if (![...features].includes(feature)) continue
138
+ const { enable, specifier } = FEATURE_ENTRY[feature]
139
+ parts.push(`import { ${enable} } from ${JSON.stringify(specifier)}; ${enable}();`)
140
+ }
141
+ return parts.join(" ")
142
+ }
143
+
144
+ /** True when `code` already imports the entry for `feature`. */
145
+ export function importsFeatureEntry(code: string, feature: HoneyFeature): boolean {
146
+ return code.includes(FEATURE_ENTRY[feature].specifier)
147
+ }
@@ -0,0 +1,70 @@
1
+ import type { createProxyHandler } from "./proxy.ts"
2
+ import type { createBus } from "./realtime/bus.ts"
3
+ import type { resolveRealtimeConfig } from "./realtime/route.ts"
4
+ import type { createRealtimePublisher, createRealtimeSession } from "./realtime/server.ts"
5
+ import type { compileTrust } from "./trust.ts"
6
+ import type { originAllowed } from "./ws-origin.ts"
7
+ import type { createWsSession } from "./ws/session.ts"
8
+
9
+ /**
10
+ * Runtime features a builder method needs but most apps never call. The core imports none of
11
+ * them, so a bundle of an app that does not use them leaves them out; each feature's entry
12
+ * registers itself when imported. A builder method that finds its feature missing throws at
13
+ * registration, naming the import.
14
+ */
15
+ export type FeatureSlots = {
16
+ proxy: { createProxyHandler: typeof createProxyHandler }
17
+ realtime: {
18
+ createBus: typeof createBus
19
+ createRealtimePublisher: typeof createRealtimePublisher
20
+ createRealtimeSession: typeof createRealtimeSession
21
+ resolveRealtimeConfig: typeof resolveRealtimeConfig
22
+ }
23
+ trust: { compileTrust: typeof compileTrust }
24
+ ws: { createWsSession: typeof createWsSession; originAllowed: typeof originAllowed }
25
+ }
26
+
27
+ export type FeatureName = keyof FeatureSlots
28
+
29
+ const ENTRY: Record<FeatureName, string> = {
30
+ proxy: "@lovrozagar/honey/proxy",
31
+ realtime: "@lovrozagar/honey/realtime",
32
+ trust: "@lovrozagar/honey/trust",
33
+ ws: "@lovrozagar/honey/ws/session",
34
+ }
35
+
36
+ const slots: { [K in FeatureName]?: FeatureSlots[K] } = {}
37
+
38
+ export function registerFeature<K extends FeatureName>(name: K, impl: FeatureSlots[K]): void {
39
+ slots[name] = impl
40
+ }
41
+
42
+ /** Tests only: forget a registered feature. */
43
+ export function resetFeature(name: FeatureName): void {
44
+ delete slots[name]
45
+ }
46
+
47
+ /** The registered feature, or a throw that names the import `caller` needs. */
48
+ export function requireFeature<K extends FeatureName>(name: K, caller: string): FeatureSlots[K] {
49
+ const impl = slots[name]
50
+ if (impl === undefined) {
51
+ throw new Error(`honey: ${caller} requires \`import "${ENTRY[name]}"\` in the app entry.`)
52
+ }
53
+ return impl as FeatureSlots[K]
54
+ }
55
+
56
+ /**
57
+ * The registered feature, importing its entry first when nothing registered it yet. Works where
58
+ * modules load at run time (Node, Bun, Deno from `node_modules`); a bundle cannot follow the
59
+ * opaque specifier, so there the entry must be imported (honey's WebSocket adapters do).
60
+ */
61
+ export async function loadFeature<K extends FeatureName>(name: K, caller: string): Promise<FeatureSlots[K]> {
62
+ const impl = slots[name]
63
+ if (impl !== undefined) return impl as FeatureSlots[K]
64
+ try {
65
+ await import(/* @vite-ignore */ ENTRY[name])
66
+ } catch {
67
+ /* reported below, naming the import */
68
+ }
69
+ return requireFeature(name, caller)
70
+ }
@@ -0,0 +1,13 @@
1
+ /** A Request-shaped object (Honey's Node shim) that can hand over the real Fetch `Request` behind it. */
2
+ export const TO_FETCH_REQUEST = Symbol.for("honey.toFetchRequest")
3
+
4
+ /**
5
+ * The Fetch `Request` for `req`. On Bun, Deno and Workers that is `req` itself. On Node, `ctx.req`
6
+ * is a lighter view of the incoming message, so `new Request(ctx.req)`, `fetch(ctx.req)` and
7
+ * `ctx.req instanceof Request` need this first; it builds the real Request once, and it then owns
8
+ * the body (read the body through either, not both).
9
+ */
10
+ export function toFetchRequest(req: Request): Request {
11
+ const own = (req as unknown as { [TO_FETCH_REQUEST]?: () => Request })[TO_FETCH_REQUEST]
12
+ return typeof own === "function" ? own.call(req) : req
13
+ }
@@ -0,0 +1,42 @@
1
+ /** Runs `honey generate` in a child process. Not a package export. */
2
+ import { spawn } from "node:child_process"
3
+ import { createRequire } from "node:module"
4
+ import { dirname, extname, join } from "node:path"
5
+ import { fileURLToPath, pathToFileURL } from "node:url"
6
+
7
+ const isBun = typeof (globalThis as { Bun?: unknown }).Bun !== "undefined"
8
+
9
+ /**
10
+ * argv that starts this package's CLI on the current runtime. Bun and a compiled install run the
11
+ * CLI directly. Source under Node (this repository's tests) goes through jiti's loader, with the
12
+ * `honey-source` condition so the app resolves the package to the same source.
13
+ */
14
+ export function cliInvocation(): string[] {
15
+ const self = fileURLToPath(import.meta.url)
16
+ const ext = extname(self)
17
+ const cli = join(dirname(self), `cli${ext}`)
18
+ if (ext !== ".ts" || isBun) return [process.execPath, cli]
19
+ const jitiDir = dirname(createRequire(import.meta.url).resolve("jiti/package.json"))
20
+ const register = pathToFileURL(join(jitiDir, "lib", "jiti-register.mjs")).href
21
+ return [process.execPath, "--conditions=honey-source", "--import", register, cli]
22
+ }
23
+
24
+ /**
25
+ * Runs `honey <args>` in `cwd` and resolves when it exits 0. Each run gets a fresh module graph,
26
+ * so edits to any file the app imports are seen, and app side effects die with the child.
27
+ */
28
+ export function runCli(args: string[], options: { cwd: string; env?: Record<string, string> }): Promise<void> {
29
+ const [cmd, ...pre] = cliInvocation() as [string, ...string[]]
30
+ return new Promise((resolvePromise, reject) => {
31
+ const child = spawn(cmd, [...pre, ...args], {
32
+ cwd: options.cwd,
33
+ env: { ...process.env, ...options.env },
34
+ stdio: ["ignore", "inherit", "inherit"],
35
+ })
36
+ child.on("error", reject)
37
+ child.on("exit", (code, signal) => {
38
+ if (code === 0) resolvePromise()
39
+ else reject(new Error(`honey ${args[0] ?? ""} failed (${signal ?? `exit ${code}`})`))
40
+ })
41
+ })
42
+ }
@@ -0,0 +1,127 @@
1
+ import { createHash, randomBytes } from "node:crypto"
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmdirSync, rmSync, writeFileSync } from "node:fs"
3
+ import { dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path"
4
+ import { toYaml } from "./yaml.ts"
5
+
6
+ /** Lists what one generator run wrote into an output directory, so the next run can delete leftovers. */
7
+ export const OUTPUT_MANIFEST = ".honey-generated.json"
8
+
9
+ /**
10
+ * Writes `content` unless the file already holds exactly that. The write goes to a temp file in
11
+ * the same directory and is renamed over the target, so a crash never leaves a truncated file.
12
+ * Returns true when the file was written.
13
+ */
14
+ export function writeFileIfChanged(filePath: string, content: string): boolean {
15
+ if (existsSync(filePath)) {
16
+ try {
17
+ if (readFileSync(filePath, "utf-8") === content) return false
18
+ } catch {
19
+ /* unreadable — overwrite */
20
+ }
21
+ }
22
+ mkdirSync(dirname(filePath), { recursive: true })
23
+ const tmp = `${filePath}.${randomBytes(6).toString("hex")}.tmp`
24
+ writeFileSync(tmp, content, "utf-8")
25
+ try {
26
+ renameSync(tmp, filePath)
27
+ } catch (err) {
28
+ rmSync(tmp, { force: true })
29
+ throw err
30
+ }
31
+ return true
32
+ }
33
+
34
+ function checksum(text: string): string {
35
+ return createHash("sha256").update(text).digest("hex").slice(0, 12)
36
+ }
37
+
38
+ /** Source file with a `@generated` header. Compares the full content, not only the header checksum. */
39
+ export function writeGenFile(filePath: string, body: string, generator: string): boolean {
40
+ const normalized = body.replace(/\n*$/, "\n")
41
+ const ext = filePath.endsWith(".d.ts") ? ".d.ts" : extname(filePath)
42
+ const hash = checksum(normalized)
43
+ const header =
44
+ ext === ".sql"
45
+ ? `-- @generated by ${generator} — do not edit. checksum: ${hash}`
46
+ : `/* @generated by ${generator} — do not edit. checksum: ${hash} */`
47
+ return writeFileIfChanged(filePath, `${header}\n${normalized}`)
48
+ }
49
+
50
+ /** `x-generated` marker: an extension key, so the document stays valid OpenAPI. */
51
+ function withMarker(data: unknown, generator: string): Record<string, unknown> {
52
+ const hash = checksum(JSON.stringify(data, null, 2))
53
+ return { "x-generated": `${generator} checksum:${hash}`, ...(data as Record<string, unknown>) }
54
+ }
55
+
56
+ export function writeGenJsonFile(filePath: string, data: unknown, generator: string): boolean {
57
+ return writeFileIfChanged(filePath, `${JSON.stringify(withMarker(data, generator), null, 2)}\n`)
58
+ }
59
+
60
+ export function writeGenYamlFile(filePath: string, data: unknown, generator: string): boolean {
61
+ return writeFileIfChanged(filePath, toYaml(withMarker(data, generator)))
62
+ }
63
+
64
+ /**
65
+ * Writes a generated directory (an SDK port, the Go CLI) and deletes the files the previous run
66
+ * wrote that this run no longer produces. Only files listed in the previous manifest are ever
67
+ * deleted, so hand-written files next to generated ones survive. Paths must stay inside `outDir`.
68
+ */
69
+ export function writeOutputDir(outDir: string, files: Record<string, string>): void {
70
+ const root = resolve(outDir)
71
+ const written = new Set<string>()
72
+ for (const [rel, content] of Object.entries(files)) {
73
+ const abs = resolveInside(root, rel)
74
+ writeFileIfChanged(abs, content)
75
+ written.add(toPosix(relative(root, abs)))
76
+ }
77
+
78
+ for (const stale of readOutputManifest(root)) {
79
+ if (written.has(stale)) continue
80
+ const abs = resolveInside(root, stale)
81
+ rmSync(abs, { force: true })
82
+ removeEmptyParents(dirname(abs), root)
83
+ }
84
+
85
+ const manifest = `${JSON.stringify({ files: [...written].sort(compareCodeUnits) }, null, 2)}\n`
86
+ writeFileIfChanged(join(root, OUTPUT_MANIFEST), manifest)
87
+ }
88
+
89
+ function readOutputManifest(root: string): string[] {
90
+ const path = join(root, OUTPUT_MANIFEST)
91
+ if (!existsSync(path)) return []
92
+ try {
93
+ const parsed = JSON.parse(readFileSync(path, "utf-8")) as { files?: unknown }
94
+ return Array.isArray(parsed.files) ? parsed.files.filter((f): f is string => typeof f === "string") : []
95
+ } catch {
96
+ return []
97
+ }
98
+ }
99
+
100
+ function resolveInside(root: string, rel: string): string {
101
+ const abs = resolve(root, rel)
102
+ if (isAbsolute(rel) || (abs !== root && !abs.startsWith(root + sep))) {
103
+ throw new Error(`generated file path escapes its output directory: ${rel}`)
104
+ }
105
+ if (abs === root) throw new Error(`generated file path is the output directory itself: ${rel}`)
106
+ return abs
107
+ }
108
+
109
+ function removeEmptyParents(dir: string, root: string): void {
110
+ let current = dir
111
+ while (current !== root && current.startsWith(root + sep)) {
112
+ /* a directory the user already deleted counts as removed; keep walking up */
113
+ if (existsSync(current)) {
114
+ if (readdirSync(current).length > 0) return
115
+ rmdirSync(current)
116
+ }
117
+ current = dirname(current)
118
+ }
119
+ }
120
+
121
+ function toPosix(p: string): string {
122
+ return p.split(sep).join("/")
123
+ }
124
+
125
+ function compareCodeUnits(a: string, b: string): number {
126
+ return a < b ? -1 : a > b ? 1 : 0
127
+ }
package/src/glob.ts ADDED
@@ -0,0 +1,109 @@
1
+ import { isAbsolute, relative } from "node:path"
2
+
3
+ /**
4
+ * Glob → RegExp for `watch` patterns, matched against a path relative to the project root.
5
+ * Supports `**` (any number of segments), `*` and `?` (within a segment), `{a,b}` alternation and
6
+ * `[...]` classes (`[!...]` negates). A pattern is anchored at the root, so `src/**` never matches
7
+ * `node_modules/x/src/a.ts`.
8
+ */
9
+ export function globToRegExp(pattern: string): RegExp {
10
+ const normalized = pattern.replaceAll("\\", "/").replace(/^(\.\/)+/, "")
11
+ const segments = normalized.split("/")
12
+ let re = "^"
13
+ segments.forEach((segment, i) => {
14
+ const last = i === segments.length - 1
15
+ if (segment === "**") {
16
+ re += last ? ".*" : "(?:[^/]*/)*"
17
+ return
18
+ }
19
+ re += segmentToRegExp(segment)
20
+ if (!last) re += "/"
21
+ })
22
+ return new RegExp(`${re}$`)
23
+ }
24
+
25
+ function segmentToRegExp(segment: string): string {
26
+ let out = ""
27
+ for (let i = 0; i < segment.length; i++) {
28
+ const ch = segment[i] as string
29
+ if (ch === "*") {
30
+ /* a stray `**` inside a segment means the same as `*` */
31
+ while (segment[i + 1] === "*") i++
32
+ out += "[^/]*"
33
+ } else if (ch === "?") {
34
+ out += "[^/]"
35
+ } else if (ch === "[") {
36
+ const close = segment.indexOf("]", i + 2)
37
+ if (close === -1) {
38
+ out += "\\["
39
+ continue
40
+ }
41
+ let body = segment.slice(i + 1, close)
42
+ if (body.startsWith("!")) body = `^${body.slice(1)}`
43
+ out += `[${body.replaceAll("\\", "\\\\").replaceAll("/", "")}]`
44
+ i = close
45
+ } else if (ch === "{") {
46
+ const close = matchingBrace(segment, i)
47
+ if (close === -1) {
48
+ out += "\\{"
49
+ continue
50
+ }
51
+ const alternatives = splitTopLevel(segment.slice(i + 1, close))
52
+ out += `(?:${alternatives.map(segmentToRegExp).join("|")})`
53
+ i = close
54
+ } else {
55
+ out += ch.replace(/[.+^${}()|[\]\\]/g, "\\$&")
56
+ }
57
+ }
58
+ return out
59
+ }
60
+
61
+ function matchingBrace(s: string, open: number): number {
62
+ let depth = 0
63
+ for (let i = open; i < s.length; i++) {
64
+ if (s[i] === "{") depth++
65
+ else if (s[i] === "}" && --depth === 0) return i
66
+ }
67
+ return -1
68
+ }
69
+
70
+ function splitTopLevel(body: string): string[] {
71
+ const parts: string[] = []
72
+ let depth = 0
73
+ let start = 0
74
+ for (let i = 0; i < body.length; i++) {
75
+ if (body[i] === "{") depth++
76
+ else if (body[i] === "}") depth--
77
+ else if (body[i] === "," && depth === 0) {
78
+ parts.push(body.slice(start, i))
79
+ start = i + 1
80
+ }
81
+ }
82
+ parts.push(body.slice(start))
83
+ return parts
84
+ }
85
+
86
+ /**
87
+ * A matcher for `patterns`, compiled once: true when `file` (absolute, or relative to `root`)
88
+ * matches any pattern. Files outside `root` never match.
89
+ */
90
+ export function compileGlobs(patterns: readonly string[]): (file: string, root: string) => boolean {
91
+ const regexps = patterns.map(globToRegExp)
92
+ return (file, root) => {
93
+ const rel = (isAbsolute(file) ? relative(root, file) : file).replaceAll("\\", "/")
94
+ if (rel === "" || rel.startsWith("../") || rel === ".." || isAbsolute(rel)) return false
95
+ return regexps.some((re) => re.test(rel))
96
+ }
97
+ }
98
+
99
+ /** True when `file` (absolute, or relative to `root`) matches any pattern. Files outside `root` never match. */
100
+ export function matchesGlob(file: string, patterns: readonly string[], root: string): boolean {
101
+ return compileGlobs(patterns)(file, root)
102
+ }
103
+
104
+ /**
105
+ * Paths a watch never regenerates for: generated files (`_gen/` and the `_gen` directory itself,
106
+ * `*.gen.*`), dependencies, and the `<file>.<hex>.tmp` files an atomic write renames into place. Shared by `honey generate --watch`
107
+ * and the Vite plugin.
108
+ */
109
+ export const WATCH_IGNORE_RE = /(^|[/\\])_gen([/\\]|$)|\.gen\.(tsx?|json|ya?ml|d\.ts)$|[/\\]node_modules[/\\]|\.tmp$/