@lovrozagar/honey 0.1.0 → 0.2.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 (263) hide show
  1. package/README.md +1596 -6
  2. package/dist/accepts.d.ts +6 -0
  3. package/dist/accepts.d.ts.map +1 -0
  4. package/dist/body-limit.d.ts +22 -0
  5. package/dist/body-limit.d.ts.map +1 -0
  6. package/dist/build/index.d.ts +42 -0
  7. package/dist/build/index.d.ts.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/client/error.d.ts +14 -0
  11. package/dist/client/error.d.ts.map +1 -0
  12. package/dist/client/http.d.ts +88 -0
  13. package/dist/client/http.d.ts.map +1 -0
  14. package/dist/client/index.d.ts +22 -0
  15. package/dist/client/index.d.ts.map +1 -0
  16. package/dist/client/sdk.d.ts +34 -0
  17. package/dist/client/sdk.d.ts.map +1 -0
  18. package/dist/client/sse.d.ts +10 -0
  19. package/dist/client/sse.d.ts.map +1 -0
  20. package/dist/client/types.d.ts +124 -0
  21. package/dist/client/types.d.ts.map +1 -0
  22. package/dist/client/ws.d.ts +15 -0
  23. package/dist/client/ws.d.ts.map +1 -0
  24. package/dist/client-mcp/server.d.ts +10 -0
  25. package/dist/client-mcp/server.d.ts.map +1 -0
  26. package/dist/client-mcp/types.d.ts +16 -0
  27. package/dist/client-mcp/types.d.ts.map +1 -0
  28. package/dist/cloudflare/realtime.d.ts +30 -0
  29. package/dist/cloudflare/realtime.d.ts.map +1 -0
  30. package/dist/codegen-go-cli.d.ts +22 -0
  31. package/dist/codegen-go-cli.d.ts.map +1 -0
  32. package/dist/codegen-go.d.ts +29 -0
  33. package/dist/codegen-go.d.ts.map +1 -0
  34. package/dist/codegen-hash.d.ts +3 -0
  35. package/dist/codegen-hash.d.ts.map +1 -0
  36. package/dist/codegen-ir.d.ts +123 -0
  37. package/dist/codegen-ir.d.ts.map +1 -0
  38. package/dist/codegen-loaders.d.ts +12 -0
  39. package/dist/codegen-loaders.d.ts.map +1 -0
  40. package/dist/codegen-mcp.d.ts +13 -0
  41. package/dist/codegen-mcp.d.ts.map +1 -0
  42. package/dist/codegen-python.d.ts +21 -0
  43. package/dist/codegen-python.d.ts.map +1 -0
  44. package/dist/codegen-rust.d.ts +18 -0
  45. package/dist/codegen-rust.d.ts.map +1 -0
  46. package/dist/codegen-sanitize.d.ts +3 -0
  47. package/dist/codegen-sanitize.d.ts.map +1 -0
  48. package/dist/codegen-schema-naming.d.ts +22 -0
  49. package/dist/codegen-schema-naming.d.ts.map +1 -0
  50. package/dist/codegen.d.ts +178 -0
  51. package/dist/codegen.d.ts.map +1 -0
  52. package/dist/context.d.ts +56 -0
  53. package/dist/context.d.ts.map +1 -0
  54. package/dist/cookie-sign.d.ts +3 -0
  55. package/dist/cookie-sign.d.ts.map +1 -0
  56. package/dist/cookie.d.ts +12 -0
  57. package/dist/cookie.d.ts.map +1 -0
  58. package/dist/cors.d.ts +13 -0
  59. package/dist/cors.d.ts.map +1 -0
  60. package/dist/crypto.d.ts +2 -0
  61. package/dist/crypto.d.ts.map +1 -0
  62. package/dist/csrf.d.ts +9 -0
  63. package/dist/csrf.d.ts.map +1 -0
  64. package/dist/curl-logger.d.ts +33 -0
  65. package/dist/curl-logger.d.ts.map +1 -0
  66. package/dist/detect-runtime.d.ts +16 -0
  67. package/dist/detect-runtime.d.ts.map +1 -0
  68. package/dist/error.d.ts +21 -0
  69. package/dist/error.d.ts.map +1 -0
  70. package/dist/errors.d.ts +40 -0
  71. package/dist/errors.d.ts.map +1 -0
  72. package/dist/etag.d.ts +9 -0
  73. package/dist/etag.d.ts.map +1 -0
  74. package/dist/feature-load.d.ts +3 -0
  75. package/dist/feature-load.d.ts.map +1 -0
  76. package/dist/go-type-emitter.d.ts +33 -0
  77. package/dist/go-type-emitter.d.ts.map +1 -0
  78. package/dist/honey-response.d.ts +82 -0
  79. package/dist/honey-response.d.ts.map +1 -0
  80. package/dist/i18n-slot.d.ts +7 -0
  81. package/dist/i18n-slot.d.ts.map +1 -0
  82. package/dist/i18n.d.ts +26 -0
  83. package/dist/i18n.d.ts.map +1 -0
  84. package/dist/index.d.ts +470 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/init.d.ts +7 -0
  87. package/dist/init.d.ts.map +1 -0
  88. package/dist/input.d.ts +6 -0
  89. package/dist/input.d.ts.map +1 -0
  90. package/dist/ip-restrict.d.ts +12 -0
  91. package/dist/ip-restrict.d.ts.map +1 -0
  92. package/dist/logger.d.ts +45 -0
  93. package/dist/logger.d.ts.map +1 -0
  94. package/dist/meta-spec.d.ts +81 -0
  95. package/dist/meta-spec.d.ts.map +1 -0
  96. package/dist/middleware.d.ts +60 -0
  97. package/dist/middleware.d.ts.map +1 -0
  98. package/dist/node-request.d.ts +59 -0
  99. package/dist/node-request.d.ts.map +1 -0
  100. package/dist/node.d.ts +13 -0
  101. package/dist/node.d.ts.map +1 -0
  102. package/dist/openapi/register.d.ts +3 -0
  103. package/dist/openapi/register.d.ts.map +1 -0
  104. package/dist/openapi/scalar.d.ts +12 -0
  105. package/dist/openapi/scalar.d.ts.map +1 -0
  106. package/dist/openapi/spec-factory.d.ts +31 -0
  107. package/dist/openapi/spec-factory.d.ts.map +1 -0
  108. package/dist/openapi/spec.d.ts +19 -0
  109. package/dist/openapi/spec.d.ts.map +1 -0
  110. package/dist/openapi/swagger.d.ts +12 -0
  111. package/dist/openapi/swagger.d.ts.map +1 -0
  112. package/dist/plugin.d.ts +167 -0
  113. package/dist/plugin.d.ts.map +1 -0
  114. package/dist/powered-by.d.ts +7 -0
  115. package/dist/powered-by.d.ts.map +1 -0
  116. package/dist/pretty-json.d.ts +10 -0
  117. package/dist/pretty-json.d.ts.map +1 -0
  118. package/dist/proxy.d.ts +51 -0
  119. package/dist/proxy.d.ts.map +1 -0
  120. package/dist/python-type-emitter.d.ts +11 -0
  121. package/dist/python-type-emitter.d.ts.map +1 -0
  122. package/dist/realtime/buffer.d.ts +18 -0
  123. package/dist/realtime/buffer.d.ts.map +1 -0
  124. package/dist/realtime/bus.d.ts +11 -0
  125. package/dist/realtime/bus.d.ts.map +1 -0
  126. package/dist/realtime/longpoll.d.ts +23 -0
  127. package/dist/realtime/longpoll.d.ts.map +1 -0
  128. package/dist/realtime/protocol.d.ts +50 -0
  129. package/dist/realtime/protocol.d.ts.map +1 -0
  130. package/dist/realtime/route.d.ts +42 -0
  131. package/dist/realtime/route.d.ts.map +1 -0
  132. package/dist/realtime/runtime.d.ts +74 -0
  133. package/dist/realtime/runtime.d.ts.map +1 -0
  134. package/dist/request-id.d.ts +12 -0
  135. package/dist/request-id.d.ts.map +1 -0
  136. package/dist/request-to-curl.d.ts +9 -0
  137. package/dist/request-to-curl.d.ts.map +1 -0
  138. package/dist/response.d.ts +57 -0
  139. package/dist/response.d.ts.map +1 -0
  140. package/dist/rust-type-emitter.d.ts +32 -0
  141. package/dist/rust-type-emitter.d.ts.map +1 -0
  142. package/dist/secure-headers.d.ts +16 -0
  143. package/dist/secure-headers.d.ts.map +1 -0
  144. package/dist/serve-register.d.ts +2 -0
  145. package/dist/serve-register.d.ts.map +1 -0
  146. package/dist/serve-slot.d.ts +6 -0
  147. package/dist/serve-slot.d.ts.map +1 -0
  148. package/dist/serve.d.ts +21 -0
  149. package/dist/serve.d.ts.map +1 -0
  150. package/dist/server-timing.d.ts +9 -0
  151. package/dist/server-timing.d.ts.map +1 -0
  152. package/dist/static.d.ts +12 -0
  153. package/dist/static.d.ts.map +1 -0
  154. package/dist/telemetry/otel.d.ts +59 -0
  155. package/dist/telemetry/otel.d.ts.map +1 -0
  156. package/dist/testing.d.ts +24 -0
  157. package/dist/testing.d.ts.map +1 -0
  158. package/dist/timeout.d.ts +7 -0
  159. package/dist/timeout.d.ts.map +1 -0
  160. package/dist/tree.d.ts +90 -0
  161. package/dist/tree.d.ts.map +1 -0
  162. package/dist/ts-type-emitter.d.ts +4 -0
  163. package/dist/ts-type-emitter.d.ts.map +1 -0
  164. package/dist/type-emitter.d.ts +8 -0
  165. package/dist/type-emitter.d.ts.map +1 -0
  166. package/dist/type-extractor.d.ts +39 -0
  167. package/dist/type-extractor.d.ts.map +1 -0
  168. package/dist/types.d.ts +451 -0
  169. package/dist/types.d.ts.map +1 -0
  170. package/dist/validation.d.ts +18 -0
  171. package/dist/validation.d.ts.map +1 -0
  172. package/dist/ws/bun.d.ts +28 -0
  173. package/dist/ws/bun.d.ts.map +1 -0
  174. package/dist/ws/cloudflare.d.ts +55 -0
  175. package/dist/ws/cloudflare.d.ts.map +1 -0
  176. package/dist/ws/deno.d.ts +13 -0
  177. package/dist/ws/deno.d.ts.map +1 -0
  178. package/dist/ws/node.d.ts +10 -0
  179. package/dist/ws/node.d.ts.map +1 -0
  180. package/dist/yaml.d.ts +4 -0
  181. package/dist/yaml.d.ts.map +1 -0
  182. package/docs/api-ref/go.md +82 -82
  183. package/docs/api-ref/python.md +82 -82
  184. package/docs/api-ref/rust.md +82 -82
  185. package/docs/api-ref/typescript.md +82 -82
  186. package/docs/invalidate-spec.md +13 -13
  187. package/docs/meta-spec.md +513 -0
  188. package/docs/packaging.md +85 -0
  189. package/docs/sdk.md +87 -73
  190. package/package.json +195 -51
  191. package/src/body-limit.ts +2 -1
  192. package/src/build/index.ts +2 -9
  193. package/src/cli.ts +2 -3
  194. package/src/client/http.ts +204 -223
  195. package/src/client/index.ts +6 -14
  196. package/src/client/sdk.ts +24 -17
  197. package/src/client/types.ts +4 -9
  198. package/src/client/ws.ts +3 -5
  199. package/src/client-mcp/server.ts +1 -4
  200. package/src/cloudflare/realtime.ts +8 -10
  201. package/src/codegen-go-cli.ts +74 -67
  202. package/src/codegen-go.ts +71 -51
  203. package/src/codegen-ir.ts +16 -27
  204. package/src/codegen-loaders.ts +5 -8
  205. package/src/codegen-mcp.ts +9 -27
  206. package/src/codegen-python.ts +47 -27
  207. package/src/codegen-rust.ts +110 -66
  208. package/src/codegen-sanitize.ts +1 -7
  209. package/src/codegen-schema-naming.ts +8 -2
  210. package/src/codegen.ts +299 -196
  211. package/src/context.ts +91 -95
  212. package/src/cookie-sign.ts +5 -13
  213. package/src/cookie.ts +1 -2
  214. package/src/cors.ts +4 -6
  215. package/src/crypto.ts +1 -4
  216. package/src/csrf.ts +3 -3
  217. package/src/curl-logger.ts +14 -32
  218. package/src/detect-runtime.ts +1 -3
  219. package/src/errors.ts +1 -3
  220. package/src/etag.ts +3 -4
  221. package/src/go-type-emitter.ts +45 -40
  222. package/src/honey-response.ts +1 -3
  223. package/src/i18n.ts +3 -12
  224. package/src/index.ts +1168 -1412
  225. package/src/ip-restrict.ts +2 -1
  226. package/src/logger.ts +13 -13
  227. package/src/meta-spec.ts +0 -0
  228. package/src/middleware.ts +111 -79
  229. package/src/node-request.ts +2 -1
  230. package/src/node.ts +9 -10
  231. package/src/openapi/register.ts +1 -2
  232. package/src/openapi/scalar.ts +9 -9
  233. package/src/openapi/spec-factory.ts +2 -2
  234. package/src/openapi/spec.ts +26 -19
  235. package/src/openapi/swagger.ts +9 -9
  236. package/src/plugin.ts +226 -256
  237. package/src/powered-by.ts +2 -1
  238. package/src/pretty-json.ts +2 -1
  239. package/src/proxy.ts +1 -3
  240. package/src/python-type-emitter.ts +37 -12
  241. package/src/realtime/route.ts +1 -1
  242. package/src/realtime/runtime.ts +9 -12
  243. package/src/request-id.ts +3 -4
  244. package/src/request-to-curl.ts +1 -4
  245. package/src/response.ts +150 -199
  246. package/src/rust-type-emitter.ts +66 -25
  247. package/src/secure-headers.ts +2 -1
  248. package/src/serve.ts +3 -12
  249. package/src/server-timing.ts +2 -1
  250. package/src/static.ts +3 -4
  251. package/src/telemetry/otel.ts +1 -6
  252. package/src/testing.ts +2 -11
  253. package/src/timeout.ts +2 -1
  254. package/src/tree.ts +12 -27
  255. package/src/ts-type-emitter.ts +71 -15
  256. package/src/type-emitter.ts +226 -237
  257. package/src/type-extractor.ts +260 -334
  258. package/src/types.ts +168 -68
  259. package/src/validation.ts +7 -30
  260. package/src/ws/bun.ts +2 -9
  261. package/src/ws/cloudflare.ts +13 -16
  262. package/src/ws/deno.ts +31 -40
  263. package/src/ws/node.ts +4 -19
package/docs/sdk.md CHANGED
@@ -19,24 +19,24 @@ The rest of this page is the capability matrix and "how to do X" snippets. All s
19
19
 
20
20
  ## Capability matrix
21
21
 
22
- | § | Capability | TS | Python | Go | Rust |
23
- | --- | ------------------------------------------------------ | --- | ------ | --- | ---- |
24
- | 1 | Typed operations (request, response, params, bodies) | ✓ | ✓ | ✓ | ✓ |
25
- | 2 | Typed error hierarchy + `.data` typed payload | ✓ | ✓ | ✓ | ✓ |
26
- | 3 | `onAuthExpired` callback + 1x 401 retry | ✓ | ✓ | ✓ | ✓ |
27
- | 4 | Cancellation (idiomatic per lang) | ✓ | ✓ | ✓ | ✓ |
28
- | 5 | Per-call timeout override | ✓ | ✓ | ✓ | ✓ |
29
- | 6 | Per-call headers merge | ✓ | ✓ | ✓ | ✓ |
30
- | 7 | `onRequest` / `onResponse` hook chain | ✓ | ✓ | ✓ | ✓ |
31
- | 8 | Invalidation + `isStale` | ✓ | ✓ | ✓ | ✓ |
32
- | 9 | SSE iteration | ✓ | ✓ | ✓ | ✓ |
33
- | 10 | Realtime (`x-realtime`) + `TransportAdapter` fallback | ✓ | ✓ | ✓ | ✓ |
34
- | 11 | WebSocket (`x-websocket`) bidi | ✓ | ✓ | ✓ | ✓ |
35
- | 12 | Streaming request body | ✓ | ✓ | ✓ | ✓ |
36
- | 13 | Sync runtime | — | ✓ | — | ✓ |
37
- | 14 | `onLog` lifecycle hook | ✓ | ✓ | ✓ | ✓ |
38
- | 15 | `x-deprecated` | ✓ | ✓ | ✓ | ✓ |
39
- | 16 | `x-idempotency-key` | ✓ | ✓ | ✓ | ✓ |
22
+ | § | Capability | TS | Python | Go | Rust |
23
+ | --- | ----------------------------------------------------- | --- | ------ | --- | ---- |
24
+ | 1 | Typed operations (request, response, params, bodies) | ✓ | ✓ | ✓ | ✓ |
25
+ | 2 | Typed error hierarchy + `.data` typed payload | ✓ | ✓ | ✓ | ✓ |
26
+ | 3 | `onAuthExpired` callback + 1x 401 retry | ✓ | ✓ | ✓ | ✓ |
27
+ | 4 | Cancellation (idiomatic per lang) | ✓ | ✓ | ✓ | ✓ |
28
+ | 5 | Per-call timeout override | ✓ | ✓ | ✓ | ✓ |
29
+ | 6 | Per-call headers merge | ✓ | ✓ | ✓ | ✓ |
30
+ | 7 | `onRequest` / `onResponse` hook chain | ✓ | ✓ | ✓ | ✓ |
31
+ | 8 | Invalidation + `isStale` | ✓ | ✓ | ✓ | ✓ |
32
+ | 9 | SSE iteration | ✓ | ✓ | ✓ | ✓ |
33
+ | 10 | Realtime (`x-realtime`) + `TransportAdapter` fallback | ✓ | ✓ | ✓ | ✓ |
34
+ | 11 | WebSocket (`x-websocket`) bidi | ✓ | ✓ | ✓ | ✓ |
35
+ | 12 | Streaming request body | ✓ | ✓ | ✓ | ✓ |
36
+ | 13 | Sync runtime | — | ✓ | — | ✓ |
37
+ | 14 | `onLog` lifecycle hook | ✓ | ✓ | ✓ | ✓ |
38
+ | 15 | `x-deprecated` | ✓ | ✓ | ✓ | ✓ |
39
+ | 16 | `x-idempotency-key` | ✓ | ✓ | ✓ | ✓ |
40
40
 
41
41
  Sync runtime is not idiomatic in TS (no sync HTTP in browsers or workerd) or Go (goroutines + `context.Context` are the async model). Python and Rust ship dual async + sync generation.
42
42
 
@@ -50,14 +50,14 @@ Config is mechanism, not policy. You pick retry, logging, auth refresh, and inva
50
50
 
51
51
  ```ts
52
52
  const sdk = new MockSDK({
53
- baseURL: BASE_URL,
54
- headers: { Authorization: "Bearer expired-token" },
55
- onAuthExpired: () => Promise.resolve("valid-token"),
56
- onLog: (entry) => console.debug(entry.event, entry.operation, entry.duration_ms, entry.status),
57
- onRequest: [addTrace, addApp],
58
- onResponse: [inspect5xx],
59
- throwOnError: true,
60
- timeout: 10_000,
53
+ baseURL: BASE_URL,
54
+ headers: { Authorization: "Bearer expired-token" },
55
+ onAuthExpired: () => Promise.resolve("valid-token"),
56
+ onLog: (entry) => console.debug(entry.event, entry.operation, entry.duration_ms, entry.status),
57
+ onRequest: [addTrace, addApp],
58
+ onResponse: [inspect5xx],
59
+ throwOnError: true,
60
+ timeout: 10_000,
61
61
  })
62
62
  ```
63
63
 
@@ -138,15 +138,15 @@ Every SDK emits the unified taxonomy: `BadRequestError`, `UnauthorizedError`, `N
138
138
 
139
139
  ```ts
140
140
  try {
141
- await sdk.createUser({ json: input })
141
+ await sdk.createUser({ json: input })
142
142
  } catch (e) {
143
- if (e instanceof BadRequestError) console.error("400", e.status)
144
- else if (e instanceof UnauthorizedError) console.error("401")
145
- else if (e instanceof NotFoundError) console.error("404")
146
- else if (e instanceof RateLimitError) console.error("429")
147
- else if (e instanceof InternalServerError) console.error("500")
148
- else if (isClientError(e)) console.error("unknown:", e.status)
149
- else throw e
143
+ if (e instanceof BadRequestError) console.error("400", e.status)
144
+ else if (e instanceof UnauthorizedError) console.error("401")
145
+ else if (e instanceof NotFoundError) console.error("404")
146
+ else if (e instanceof RateLimitError) console.error("429")
147
+ else if (e instanceof InternalServerError) console.error("500")
148
+ else if (isClientError(e)) console.error("unknown:", e.status)
149
+ else throw e
150
150
  }
151
151
  ```
152
152
 
@@ -203,11 +203,11 @@ When an operation declares a `4xx` response schema in OpenAPI, the parsed payloa
203
203
 
204
204
  ```ts
205
205
  try {
206
- await sdk.createUser({ json: bad })
206
+ await sdk.createUser({ json: bad })
207
207
  } catch (e) {
208
- if (e instanceof BadRequestError) {
209
- console.error("400 data:", e.data, "body:", e.body)
210
- }
208
+ if (e instanceof BadRequestError) {
209
+ console.error("400 data:", e.data, "body:", e.body)
210
+ }
211
211
  }
212
212
  ```
213
213
 
@@ -266,9 +266,9 @@ Each SDK uses the language's native cancellation primitive. Cancellation propaga
266
266
  const ctrl = new AbortController()
267
267
  setTimeout(() => ctrl.abort(), 25)
268
268
  try {
269
- await sdk.slow({ search: { ms: 500 }, signal: ctrl.signal })
269
+ await sdk.slow({ search: { ms: 500 }, signal: ctrl.signal })
270
270
  } catch (e) {
271
- console.error("cancelled:", (e as Error).name)
271
+ console.error("cancelled:", (e as Error).name)
272
272
  }
273
273
  ```
274
274
 
@@ -335,8 +335,8 @@ Per-call headers merge over config headers; per-call wins per key. Useful for re
335
335
 
336
336
  ```ts
337
337
  await sdk.getUser({
338
- headers: { "X-Both": "call-wins" },
339
- params: { id: "u1" },
338
+ headers: { "X-Both": "call-wins" },
339
+ params: { id: "u1" },
340
340
  })
341
341
  ```
342
342
 
@@ -478,8 +478,8 @@ Operations with `produces: text/event-stream` return a typed async iterable of e
478
478
 
479
479
  ```ts
480
480
  for await (const ev of sdk.streamEvents()) {
481
- console.log("sse event:", ev)
482
- break
481
+ console.log("sse event:", ev)
482
+ break
483
483
  }
484
484
  ```
485
485
 
@@ -513,10 +513,12 @@ Operations with `x-websocket: true` yield a typed bidirectional channel: `Send`
513
513
 
514
514
  ```ts
515
515
  const ws = sdk.connectWs()
516
- await new Promise<void>((resolve) => { ws.on("open", () => resolve()) })
516
+ await new Promise<void>((resolve) => {
517
+ ws.on("open", () => resolve())
518
+ })
517
519
  ws.on("message", (data: string) => {
518
- console.log("ws recv:", data)
519
- ws.close(1000, "done")
520
+ console.log("ws recv:", data)
521
+ ws.close(1000, "done")
520
522
  })
521
523
  ws.send("hello")
522
524
  ```
@@ -555,27 +557,36 @@ ws.close(1000, "done").await?;
555
557
 
556
558
  ```ts
557
559
  function makeCustomAdapter(): TransportAdapter {
558
- return {
559
- connect(_url, _opts): TransportConnection {
560
- let onFrame: (f: ServerFrame) => void = () => {}
561
- const conn: TransportConnection = {
562
- close() {},
563
- onClose: () => {}, onError: () => {},
564
- get onFrame() { return onFrame }, set onFrame(cb) { onFrame = cb },
565
- send(_data) {},
566
- }
567
- queueMicrotask(() => onFrame({ data: { kind: "tick" }, id: 1, t: "msg" }))
568
- return conn
569
- },
570
- }
560
+ return {
561
+ connect(_url, _opts): TransportConnection {
562
+ let onFrame: (f: ServerFrame) => void = () => {}
563
+ const conn: TransportConnection = {
564
+ close() {},
565
+ onClose: () => {},
566
+ onError: () => {},
567
+ get onFrame() {
568
+ return onFrame
569
+ },
570
+ set onFrame(cb) {
571
+ onFrame = cb
572
+ },
573
+ send(_data) {},
574
+ }
575
+ queueMicrotask(() => onFrame({ data: { kind: "tick" }, id: 1, t: "msg" }))
576
+ return conn
577
+ },
578
+ }
571
579
  }
572
580
  const rc = createResumableConnection({
573
- maxReconnectAttempts: 5,
574
- reconnectDelayMs: 100,
575
- transports: [makeCustomAdapter()],
576
- url: `${BASE_URL}/rt`,
581
+ maxReconnectAttempts: 5,
582
+ reconnectDelayMs: 100,
583
+ transports: [makeCustomAdapter()],
584
+ url: `${BASE_URL}/rt`,
577
585
  })
578
- for await (const ev of rc) { console.log("rt:", ev); break }
586
+ for await (const ev of rc) {
587
+ console.log("rt:", ev)
588
+ break
589
+ }
579
590
  rc.close()
580
591
  ```
581
592
 
@@ -632,12 +643,15 @@ Binary or multipart uploads flow as a stream. No buffering — the SDK pipes the
632
643
 
633
644
  ```ts
634
645
  const stream = new ReadableStream<Uint8Array>({
635
- pull(controller) {
636
- if (sent >= TOTAL) { controller.close(); return }
637
- const chunk = new Uint8Array(Math.min(CHUNK, TOTAL - sent))
638
- sent += chunk.length
639
- controller.enqueue(chunk)
640
- },
646
+ pull(controller) {
647
+ if (sent >= TOTAL) {
648
+ controller.close()
649
+ return
650
+ }
651
+ const chunk = new Uint8Array(Math.min(CHUNK, TOTAL - sent))
652
+ sent += chunk.length
653
+ controller.enqueue(chunk)
654
+ },
641
655
  })
642
656
  const uploaded = await sdk.uploadBlob({ body: stream })
643
657
  console.log("uploaded:", uploaded.size, uploaded.hash)
@@ -671,8 +685,8 @@ println!("uploaded: {} {}", uploaded.size, uploaded.hash);
671
685
  Operations marked `x-idempotency-key: true` auto-send an `Idempotency-Key` header with a UUID when the caller doesn't supply one. Precedence: `headers["Idempotency-Key"]` wins over the explicit opts field, which wins over the auto UUID.
672
686
 
673
687
  ```ts
674
- const auto = await sdk.idempotentCreate()
675
- const explicit = await sdk.idempotentCreate({ idempotencyKey: "user-supplied-123" })
688
+ const auto = await sdk.idempotentCreate()
689
+ const explicit = await sdk.idempotentCreate({ idempotencyKey: "user-supplied-123" })
676
690
  const viaHeader = await sdk.idempotentCreate({ headers: { "Idempotency-Key": "header-wins-456" } })
677
691
  ```
678
692
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovrozagar/honey",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Type-safe API framework built on Web Standards. Builder-pattern DX, precompiled radix tree in production.",
5
5
  "keywords": [
6
6
  "api",
@@ -11,18 +11,22 @@
11
11
  "type-safe",
12
12
  "web-standards"
13
13
  ],
14
+ "homepage": "https://github.com/lovrozagar/honey#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/lovrozagar/honey/issues"
17
+ },
14
18
  "license": "MIT",
19
+ "author": "lovrozagar",
15
20
  "repository": {
16
21
  "type": "git",
17
- "url": "https://github.com/lovrozagar/honey"
18
- },
19
- "publishConfig": {
20
- "access": "public"
22
+ "url": "git+https://github.com/lovrozagar/honey.git",
23
+ "directory": "packages/core"
21
24
  },
22
25
  "bin": {
23
26
  "honey": "./src/cli.ts"
24
27
  },
25
28
  "files": [
29
+ "dist",
26
30
  "docs",
27
31
  "src"
28
32
  ],
@@ -33,53 +37,193 @@
33
37
  "./src/serve-register.ts"
34
38
  ],
35
39
  "exports": {
36
- ".": "./src/index.ts",
37
- "./accepts": "./src/accepts.ts",
38
- "./body-limit": "./src/body-limit.ts",
39
- "./build": "./src/build/index.ts",
40
- "./cli": "./src/cli.ts",
41
- "./client": "./src/client/index.ts",
42
- "./client/sdk": "./src/client/sdk.ts",
43
- "./codegen": "./src/codegen.ts",
44
- "./codegen-go-cli": "./src/codegen-go-cli.ts",
45
- "./codegen/extract": "./src/type-extractor.ts",
46
- "./cookie": "./src/cookie.ts",
47
- "./cookie-sign": "./src/cookie-sign.ts",
48
- "./cors": "./src/cors.ts",
49
- "./crypto": "./src/crypto.ts",
50
- "./curl-logger": "./src/curl-logger.ts",
51
- "./csrf": "./src/csrf.ts",
52
- "./errors": "./src/errors.ts",
53
- "./etag": "./src/etag.ts",
54
- "./i18n": "./src/i18n.ts",
55
- "./input": "./src/input.ts",
56
- "./ip-restrict": "./src/ip-restrict.ts",
57
- "./logger": "./src/logger.ts",
58
- "./node": "./src/node.ts",
59
- "./openapi": "./src/openapi/register.ts",
60
- "./openapi/spec": "./src/openapi/spec.ts",
61
- "./openapi/scalar": "./src/openapi/scalar.ts",
62
- "./openapi/swagger": "./src/openapi/swagger.ts",
63
- "./plugin": "./src/plugin.ts",
64
- "./powered-by": "./src/powered-by.ts",
65
- "./pretty-json": "./src/pretty-json.ts",
66
- "./proxy": "./src/proxy.ts",
67
- "./request-to-curl": "./src/request-to-curl.ts",
68
- "./request-id": "./src/request-id.ts",
69
- "./secure-headers": "./src/secure-headers.ts",
70
- "./serve": "./src/serve-register.ts",
71
- "./server-timing": "./src/server-timing.ts",
72
- "./static": "./src/static.ts",
73
- "./telemetry/otel": "./src/telemetry/otel.ts",
74
- "./testing": "./src/testing.ts",
75
- "./timeout": "./src/timeout.ts",
76
- "./tree": "./src/tree.ts",
77
- "./ws/bun": "./src/ws/bun.ts",
78
- "./ws/cloudflare": "./src/ws/cloudflare.ts",
79
- "./ws/deno": "./src/ws/deno.ts",
80
- "./ws/node": "./src/ws/node.ts"
40
+ ".": {
41
+ "types": "./dist/index.d.ts",
42
+ "default": "./src/index.ts"
43
+ },
44
+ "./accepts": {
45
+ "types": "./dist/accepts.d.ts",
46
+ "default": "./src/accepts.ts"
47
+ },
48
+ "./body-limit": {
49
+ "types": "./dist/body-limit.d.ts",
50
+ "default": "./src/body-limit.ts"
51
+ },
52
+ "./build": {
53
+ "types": "./dist/build/index.d.ts",
54
+ "default": "./src/build/index.ts"
55
+ },
56
+ "./cli": {
57
+ "types": "./dist/cli.d.ts",
58
+ "default": "./src/cli.ts"
59
+ },
60
+ "./client": {
61
+ "types": "./dist/client/index.d.ts",
62
+ "default": "./src/client/index.ts"
63
+ },
64
+ "./client/sdk": {
65
+ "types": "./dist/client/sdk.d.ts",
66
+ "default": "./src/client/sdk.ts"
67
+ },
68
+ "./codegen": {
69
+ "types": "./dist/codegen.d.ts",
70
+ "default": "./src/codegen.ts"
71
+ },
72
+ "./codegen-go-cli": {
73
+ "types": "./dist/codegen-go-cli.d.ts",
74
+ "default": "./src/codegen-go-cli.ts"
75
+ },
76
+ "./codegen/extract": {
77
+ "types": "./dist/type-extractor.d.ts",
78
+ "default": "./src/type-extractor.ts"
79
+ },
80
+ "./cookie": {
81
+ "types": "./dist/cookie.d.ts",
82
+ "default": "./src/cookie.ts"
83
+ },
84
+ "./cookie-sign": {
85
+ "types": "./dist/cookie-sign.d.ts",
86
+ "default": "./src/cookie-sign.ts"
87
+ },
88
+ "./cors": {
89
+ "types": "./dist/cors.d.ts",
90
+ "default": "./src/cors.ts"
91
+ },
92
+ "./crypto": {
93
+ "types": "./dist/crypto.d.ts",
94
+ "default": "./src/crypto.ts"
95
+ },
96
+ "./curl-logger": {
97
+ "types": "./dist/curl-logger.d.ts",
98
+ "default": "./src/curl-logger.ts"
99
+ },
100
+ "./csrf": {
101
+ "types": "./dist/csrf.d.ts",
102
+ "default": "./src/csrf.ts"
103
+ },
104
+ "./errors": {
105
+ "types": "./dist/errors.d.ts",
106
+ "default": "./src/errors.ts"
107
+ },
108
+ "./etag": {
109
+ "types": "./dist/etag.d.ts",
110
+ "default": "./src/etag.ts"
111
+ },
112
+ "./i18n": {
113
+ "types": "./dist/i18n.d.ts",
114
+ "default": "./src/i18n.ts"
115
+ },
116
+ "./input": {
117
+ "types": "./dist/input.d.ts",
118
+ "default": "./src/input.ts"
119
+ },
120
+ "./ip-restrict": {
121
+ "types": "./dist/ip-restrict.d.ts",
122
+ "default": "./src/ip-restrict.ts"
123
+ },
124
+ "./logger": {
125
+ "types": "./dist/logger.d.ts",
126
+ "default": "./src/logger.ts"
127
+ },
128
+ "./node": {
129
+ "types": "./dist/node.d.ts",
130
+ "default": "./src/node.ts"
131
+ },
132
+ "./openapi": {
133
+ "types": "./dist/openapi/register.d.ts",
134
+ "default": "./src/openapi/register.ts"
135
+ },
136
+ "./openapi/spec": {
137
+ "types": "./dist/openapi/spec.d.ts",
138
+ "default": "./src/openapi/spec.ts"
139
+ },
140
+ "./openapi/scalar": {
141
+ "types": "./dist/openapi/scalar.d.ts",
142
+ "default": "./src/openapi/scalar.ts"
143
+ },
144
+ "./openapi/swagger": {
145
+ "types": "./dist/openapi/swagger.d.ts",
146
+ "default": "./src/openapi/swagger.ts"
147
+ },
148
+ "./plugin": {
149
+ "types": "./dist/plugin.d.ts",
150
+ "default": "./src/plugin.ts"
151
+ },
152
+ "./powered-by": {
153
+ "types": "./dist/powered-by.d.ts",
154
+ "default": "./src/powered-by.ts"
155
+ },
156
+ "./pretty-json": {
157
+ "types": "./dist/pretty-json.d.ts",
158
+ "default": "./src/pretty-json.ts"
159
+ },
160
+ "./proxy": {
161
+ "types": "./dist/proxy.d.ts",
162
+ "default": "./src/proxy.ts"
163
+ },
164
+ "./request-to-curl": {
165
+ "types": "./dist/request-to-curl.d.ts",
166
+ "default": "./src/request-to-curl.ts"
167
+ },
168
+ "./request-id": {
169
+ "types": "./dist/request-id.d.ts",
170
+ "default": "./src/request-id.ts"
171
+ },
172
+ "./secure-headers": {
173
+ "types": "./dist/secure-headers.d.ts",
174
+ "default": "./src/secure-headers.ts"
175
+ },
176
+ "./serve": {
177
+ "types": "./dist/serve-register.d.ts",
178
+ "default": "./src/serve-register.ts"
179
+ },
180
+ "./server-timing": {
181
+ "types": "./dist/server-timing.d.ts",
182
+ "default": "./src/server-timing.ts"
183
+ },
184
+ "./static": {
185
+ "types": "./dist/static.d.ts",
186
+ "default": "./src/static.ts"
187
+ },
188
+ "./telemetry/otel": {
189
+ "types": "./dist/telemetry/otel.d.ts",
190
+ "default": "./src/telemetry/otel.ts"
191
+ },
192
+ "./testing": {
193
+ "types": "./dist/testing.d.ts",
194
+ "default": "./src/testing.ts"
195
+ },
196
+ "./timeout": {
197
+ "types": "./dist/timeout.d.ts",
198
+ "default": "./src/timeout.ts"
199
+ },
200
+ "./tree": {
201
+ "types": "./dist/tree.d.ts",
202
+ "default": "./src/tree.ts"
203
+ },
204
+ "./ws/bun": {
205
+ "types": "./dist/ws/bun.d.ts",
206
+ "default": "./src/ws/bun.ts"
207
+ },
208
+ "./ws/cloudflare": {
209
+ "types": "./dist/ws/cloudflare.d.ts",
210
+ "default": "./src/ws/cloudflare.ts"
211
+ },
212
+ "./ws/deno": {
213
+ "types": "./dist/ws/deno.d.ts",
214
+ "default": "./src/ws/deno.ts"
215
+ },
216
+ "./ws/node": {
217
+ "types": "./dist/ws/node.d.ts",
218
+ "default": "./src/ws/node.ts"
219
+ }
220
+ },
221
+ "publishConfig": {
222
+ "access": "public"
81
223
  },
82
224
  "scripts": {
225
+ "build:types": "tsc -p tsconfig.dts.json",
226
+ "prepack": "tsc -p tsconfig.dts.json",
83
227
  "test": "vitest run",
84
228
  "test:all": "vitest run --config vitest.all.config.ts",
85
229
  "test:harness": "vitest run --config vitest.harness.config.ts",
@@ -93,8 +237,8 @@
93
237
  "jiti": "2.7.0"
94
238
  },
95
239
  "devDependencies": {
96
- "@honey/e2e-surface": "workspace:*",
97
240
  "@honey/e2e-kitchen": "workspace:*",
241
+ "@honey/e2e-surface": "workspace:*",
98
242
  "@modelcontextprotocol/sdk": "^1.29.0",
99
243
  "@total-typescript/ts-reset": "catalog:",
100
244
  "@types/node": "catalog:",
package/src/body-limit.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { namedMiddleware } from "./middleware.ts"
1
2
  import { HoneyError } from "./error.ts"
2
3
  import type { MiddlewareFn } from "./middleware.ts"
3
4
  import { EK, SK } from "./types.ts"
@@ -96,5 +97,5 @@ export function bodyLimit(opts: BodyLimitOptions): MiddlewareFn<{ req: Request }
96
97
  return next()
97
98
  }
98
99
 
99
- return mw
100
+ return namedMiddleware("bodyLimit", mw)
100
101
  }
@@ -108,10 +108,7 @@ const RESOLVED_BUILD_ENTRY = `\0${VIRTUAL_BUILD_ENTRY}`
108
108
 
109
109
  /* ---- Build plugin factory ---- */
110
110
 
111
- export function createBuildPlugin(
112
- buildConfig: HoneyBuildConfig,
113
- shared: { entry: string; export: string },
114
- ) {
111
+ export function createBuildPlugin(buildConfig: HoneyBuildConfig, shared: { entry: string; export: string }) {
115
112
  const adapter = adapters[buildConfig.target]
116
113
  const resolvedConfig: ResolvedBuildConfig = {
117
114
  entry: shared.entry,
@@ -131,11 +128,7 @@ export function createBuildPlugin(
131
128
  minify: buildConfig.minify ?? true,
132
129
  outDir: buildConfig.outDir ?? "./dist",
133
130
  rolldownOptions: {
134
- external: [
135
- ...builtinModules,
136
- ...builtinModules.map((m) => `node:${m}`),
137
- ...(buildConfig.external ?? []),
138
- ],
131
+ external: [...builtinModules, ...builtinModules.map((m) => `node:${m}`), ...(buildConfig.external ?? [])],
139
132
  input: VIRTUAL_BUILD_ENTRY,
140
133
  output: { entryFileNames: "index.js" },
141
134
  },
package/src/cli.ts CHANGED
@@ -6,8 +6,7 @@ import type { HoneyGoCliConfig, HoneyVitePluginConfig } from "./plugin.ts"
6
6
  import { generateAndWrite, type getLastHoneyConfig, resolveHoneyConfig } from "./plugin.ts"
7
7
 
8
8
  const USAGE =
9
- "Usage: honey generate [--watch] [--config <path>] [--app <path>] [flags]\n" +
10
- " honey init [--cf] [--force]"
9
+ "Usage: honey generate [--watch] [--config <path>] [--app <path>] [flags]\n" + " honey init [--cf] [--force]"
11
10
 
12
11
  type CliFlags = {
13
12
  app?: string
@@ -74,7 +73,7 @@ async function loadConfigFromVite(configPath: string): Promise<HoneyVitePluginCo
74
73
  await jiti.import(configPath)
75
74
 
76
75
  /* read stashed config from the same module graph */
77
- const pluginMod = (await jiti.import("honey/plugin")) as Record<string, unknown>
76
+ const pluginMod = (await jiti.import("@lovrozagar/honey/plugin")) as Record<string, unknown>
78
77
  const getter = pluginMod.getLastHoneyConfig as typeof getLastHoneyConfig | undefined
79
78
  return getter?.()
80
79
  }