@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
@@ -30,9 +30,7 @@ export { createTypedWebSocket } from "./ws.ts"
30
30
 
31
31
  const HTTP_METHODS = new Set(["delete", "get", "patch", "post", "put"])
32
32
 
33
- export function createClient<T>(
34
- config: ClientConfig & { throwOnError: true },
35
- ): HoneyClient<InferRoutes<T>, true>
33
+ export function createClient<T>(config: ClientConfig & { throwOnError: true }): HoneyClient<InferRoutes<T>, true>
36
34
  export function createClient<T>(
37
35
  config: Omit<ClientConfig, "throwOnError"> & { throwOnError?: false },
38
36
  ): HoneyClient<InferRoutes<T>, false>
@@ -49,17 +47,13 @@ export function createClient<T, TThrow extends boolean = false>(
49
47
  if (prop === "$isClientError") return isClientError
50
48
 
51
49
  if (prop === "$url") {
52
- return (
53
- path: string,
54
- input?: { params?: Record<string, string>; search?: Record<string, unknown> },
55
- ) => http.buildUrl(path, input ?? {})
50
+ return (path: string, input?: { params?: Record<string, string>; search?: Record<string, unknown> }) =>
51
+ http.buildUrl(path, input ?? {})
56
52
  }
57
53
 
58
54
  if (prop === "$path") {
59
- return (
60
- path: string,
61
- input?: { params?: Record<string, string>; search?: Record<string, unknown> },
62
- ) => http.buildPath(path, input ?? {})
55
+ return (path: string, input?: { params?: Record<string, string>; search?: Record<string, unknown> }) =>
56
+ http.buildPath(path, input ?? {})
63
57
  }
64
58
 
65
59
  if (prop === "ws") {
@@ -97,9 +91,7 @@ export function createClient<T, TThrow extends boolean = false>(
97
91
  let restPromise: Promise<unknown> | undefined
98
92
  const lazyRest = (): Promise<unknown> => {
99
93
  if (!restPromise) {
100
- restPromise = shouldThrow
101
- ? http.request(method, path, opts)
102
- : http.requestSafe(method, path, opts)
94
+ restPromise = shouldThrow ? http.request(method, path, opts) : http.requestSafe(method, path, opts)
103
95
  }
104
96
  return restPromise
105
97
  }
package/src/client/sdk.ts CHANGED
@@ -39,14 +39,20 @@ export function resolveInvalidationTargets(
39
39
  ): string[] {
40
40
  const resolved: string[] = []
41
41
  for (const target of targets) {
42
- if (!params || !target.includes(":")) { resolved.push(target); continue }
42
+ if (!params || !target.includes(":")) {
43
+ resolved.push(target)
44
+ continue
45
+ }
43
46
  const spaceIdx = target.indexOf(" ")
44
47
  const targetMethod = target.slice(0, spaceIdx)
45
48
  const targetPath = target.slice(spaceIdx + 1)
46
49
  let hasUnresolved = false
47
50
  const replaced = targetPath.replace(/:(\w+)/g, (match, key: string) => {
48
51
  const val = params[key]
49
- if (val === undefined) { hasUnresolved = true; return match }
52
+ if (val === undefined) {
53
+ hasUnresolved = true
54
+ return match
55
+ }
50
56
  return encodeURIComponent(val)
51
57
  })
52
58
  if (hasUnresolved) continue
@@ -64,9 +70,7 @@ export function pathMatchesPattern(concretePath: string, pattern: string): boole
64
70
  if (!re) {
65
71
  /* split on :param placeholders, escape each literal segment's metachars, rejoin with [^/]+ */
66
72
  const parts = pattern.split(/:[^/]+/g)
67
- const escaped = parts
68
- .map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
69
- .join("[^/]+")
73
+ const escaped = parts.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("[^/]+")
70
74
  re = new RegExp(`^${escaped}$`)
71
75
  patternRegexCache.set(pattern, re)
72
76
  }
@@ -75,12 +79,12 @@ export function pathMatchesPattern(concretePath: string, pattern: string): boole
75
79
 
76
80
  /* two-tier stale lookup: exact concrete match, then pattern fallback; sweeps expired entries in one pass */
77
81
  export function lookupStale(
78
- staleMap: Map<string, { by: string[], seq: number, until: number }>,
82
+ staleMap: Map<string, { by: string[]; seq: number; until: number }>,
79
83
  concreteSelector: string,
80
84
  concretePath: string,
81
85
  method: string,
82
86
  now: number,
83
- ): { by: string[], isStale: boolean } {
87
+ ): { by: string[]; isStale: boolean } {
84
88
  const allBy: string[] = []
85
89
  const expired: string[] = []
86
90
 
@@ -89,7 +93,10 @@ export function lookupStale(
89
93
  else if (exact) expired.push(concreteSelector)
90
94
 
91
95
  for (const [key, entry] of staleMap) {
92
- if (entry.until <= now) { expired.push(key); continue }
96
+ if (entry.until <= now) {
97
+ expired.push(key)
98
+ continue
99
+ }
93
100
  if (!key.includes(":")) continue
94
101
  const spaceIdx = key.indexOf(" ")
95
102
  const keyMethod = key.slice(0, spaceIdx)
@@ -111,9 +118,7 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
111
118
  const http = new HTTPClient(config)
112
119
  const staleTime = config.invalidation?.staleTime ?? 0
113
120
  const hasInvalidation = staleTime > 0
114
- const staleUntil = hasInvalidation
115
- ? new Map<string, { by: string[], seq: number, until: number }>()
116
- : null
121
+ const staleUntil = hasInvalidation ? new Map<string, { by: string[]; seq: number; until: number }>() : null
117
122
 
118
123
  let invalidationSeq = 0
119
124
 
@@ -156,14 +161,16 @@ export function createSDK<T = Record<string, Record<string, (...args: unknown[])
156
161
  requestMeta = { invalidatedBy: by, isStale, selector: concreteSelector, seqSnapshot: invalidationSeq }
157
162
  }
158
163
 
159
- const result = config.throwOnError === true
160
- ? await http.request(method, path, opts, requestMeta)
161
- : await http.requestSafe(method, path, opts, requestMeta)
164
+ const result =
165
+ config.throwOnError === true
166
+ ? await http.request(method, path, opts, requestMeta)
167
+ : await http.requestSafe(method, path, opts, requestMeta)
162
168
 
163
169
  if (staleUntil) {
164
- const isSuccess = config.throwOnError === true
165
- ? true
166
- : ((result as { status: number }).status >= 200 && (result as { status: number }).status < 300)
170
+ const isSuccess =
171
+ config.throwOnError === true
172
+ ? true
173
+ : (result as { status: number }).status >= 200 && (result as { status: number }).status < 300
167
174
 
168
175
  if (isSuccess) {
169
176
  if (entry.invalidate && entry.invalidate.length > 0) {
@@ -57,11 +57,7 @@ export type OutputFor<TRoutes, P extends string, M extends string> =
57
57
 
58
58
  /** Check if a route returns SSE (text/event-stream in output) */
59
59
  export type IsSSE<TRoutes, P extends string, M extends string> =
60
- OutputDefFor<TRoutes, P, M> extends infer O
61
- ? O extends { "text/event-stream": unknown }
62
- ? true
63
- : false
64
- : false
60
+ OutputDefFor<TRoutes, P, M> extends infer O ? (O extends { "text/event-stream": unknown } ? true : false) : false
65
61
 
66
62
  /** Extract errorsByStatus from route record if available */
67
63
  type ErrorsByStatusFor<TRoutes, P extends string, M extends string> = P extends keyof TRoutes
@@ -109,8 +105,8 @@ type ErrorVariants<TErrorsByStatus> = {
109
105
  export type ClientResult<TData, TErrorsByStatus = never> =
110
106
  | { data: TData; error: null; response: Response; status: number }
111
107
  | (HasStatusErrors<TErrorsByStatus> extends false
112
- ? { data: null; error: unknown; response: Response; status: number }
113
- : ErrorVariants<TErrorsByStatus>)
108
+ ? { data: null; error: unknown; response: Response; status: number }
109
+ : ErrorVariants<TErrorsByStatus>)
114
110
 
115
111
  /** Resolve return type based on transport + throw mode */
116
112
  export type ReturnFor<TRoutes, P extends string, M extends string, TThrow extends boolean = true> =
@@ -121,8 +117,7 @@ export type ReturnFor<TRoutes, P extends string, M extends string, TThrow extend
121
117
  : Promise<ClientResult<OutputFor<TRoutes, P, M>, ErrorsByStatusFor<TRoutes, P, M>>>
122
118
 
123
119
  /** Build the client input type — merge route input with params from path */
124
- export type ClientInput<TRoutes, P extends string, M extends string> = InputFor<TRoutes, P, M> &
125
- ParamsInput<P>
120
+ export type ClientInput<TRoutes, P extends string, M extends string> = InputFor<TRoutes, P, M> & ParamsInput<P>
126
121
 
127
122
  /** Extract params input if path has params */
128
123
  type ParamsInput<P extends string> =
package/src/client/ws.ts CHANGED
@@ -55,10 +55,7 @@ export function createTypedWebSocket(
55
55
  break
56
56
  case "close":
57
57
  wrapped = (e: Event) =>
58
- (handler as (code: number, reason: string) => void)(
59
- (e as CloseEvent).code,
60
- (e as CloseEvent).reason,
61
- )
58
+ (handler as (code: number, reason: string) => void)((e as CloseEvent).code, (e as CloseEvent).reason)
62
59
  break
63
60
  case "error":
64
61
  wrapped = (e: Event) => (handler as (error: unknown) => void)(e)
@@ -80,7 +77,8 @@ export function createTypedWebSocket(
80
77
 
81
78
  function toWsData(data: ArrayBuffer | ArrayBufferView | string): string | Uint8Array<ArrayBuffer> {
82
79
  if (typeof data === "string") return data
83
- const view = data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
80
+ const view =
81
+ data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
84
82
  const copy = new Uint8Array(view.byteLength)
85
83
  copy.set(view)
86
84
  return copy
@@ -11,10 +11,7 @@
11
11
  /* eslint-disable @typescript-eslint/no-deprecated */
12
12
  import { Server } from "@modelcontextprotocol/sdk/server/index.js"
13
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
14
- import {
15
- CallToolRequestSchema,
16
- ListToolsRequestSchema,
17
- } from "@modelcontextprotocol/sdk/types.js"
14
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"
18
15
  import type { Tool, ToolResult } from "./types.ts"
19
16
 
20
17
  type ServerError = Error & { status?: number; body?: unknown; data?: unknown }
@@ -42,9 +42,7 @@ type Attachment = {
42
42
  const DEFAULT_BUFFER_SIZE = 100
43
43
  const BUFFER_TTL_MS = 30_000
44
44
 
45
- export function createRealtimeHandlers<TEnv = unknown>(
46
- config: RealtimeHandlerConfig<TEnv>,
47
- ): RealtimeHandlers {
45
+ export function createRealtimeHandlers<TEnv = unknown>(config: RealtimeHandlerConfig<TEnv>): RealtimeHandlers {
48
46
  const bufferSize = config.reconnectBuffer ?? DEFAULT_BUFFER_SIZE
49
47
  const buffer = new ReconnectBuffer({ size: bufferSize })
50
48
  const bus = createBus()
@@ -70,7 +68,7 @@ export function createRealtimeHandlers<TEnv = unknown>(
70
68
  }
71
69
 
72
70
  function sendFrame(ws: WebSocket, frame: ServerFrame): void {
73
- (ws as unknown as { send(data: string): void }).send(encodeServerFrame(frame))
71
+ ;(ws as unknown as { send(data: string): void }).send(encodeServerFrame(frame))
74
72
  }
75
73
 
76
74
  function getRouteHandler(): ((c: unknown, conn: ConnContext) => void | Promise<void>) | null {
@@ -85,7 +83,7 @@ export function createRealtimeHandlers<TEnv = unknown>(
85
83
  return createConnContext({
86
84
  bus,
87
85
  closeFn: (reason) => {
88
- (ws as unknown as { close(code?: number, reason?: string): void }).close(1000, reason ?? "")
86
+ ;(ws as unknown as { close(code?: number, reason?: string): void }).close(1000, reason ?? "")
89
87
  },
90
88
  id: attachment.connId,
91
89
  sendFn: (payload) => {
@@ -109,7 +107,9 @@ export function createRealtimeHandlers<TEnv = unknown>(
109
107
  userId = await config.onAuth(req)
110
108
  }
111
109
 
112
- const pair = new (globalThis as unknown as { WebSocketPair: new () => { 0: WebSocket; 1: WebSocket } }).WebSocketPair()
110
+ const pair = new (
111
+ globalThis as unknown as { WebSocketPair: new () => { 0: WebSocket; 1: WebSocket } }
112
+ ).WebSocketPair()
113
113
  const client = pair[0]
114
114
  const server = pair[1]
115
115
 
@@ -120,9 +120,7 @@ export function createRealtimeHandlers<TEnv = unknown>(
120
120
  knownTokens.add(reconnectToken)
121
121
 
122
122
  const attachment: Attachment = { connId, reconnectToken, userId }
123
- ;(server as unknown as { serializeAttachment(data: string): void }).serializeAttachment(
124
- JSON.stringify(attachment),
125
- )
123
+ ;(server as unknown as { serializeAttachment(data: string): void }).serializeAttachment(JSON.stringify(attachment))
126
124
 
127
125
  sendFrame(server, { reconnectToken, t: "ready" })
128
126
 
@@ -215,7 +213,7 @@ export function createRealtimeHandlers<TEnv = unknown>(
215
213
 
216
214
  function handleError(ws: WebSocket, _err: unknown): Promise<void> {
217
215
  try {
218
- (ws as unknown as { close(code?: number, reason?: string): void }).close(1011, "internal error")
216
+ ;(ws as unknown as { close(code?: number, reason?: string): void }).close(1011, "internal error")
219
217
  } catch {
220
218
  /* swallow — ws may already be closed */
221
219
  }
@@ -82,11 +82,11 @@ type BodyShape =
82
82
  | { kind: "json-flat"; scalars: BodyScalarInfo[]; required: boolean }
83
83
  | { kind: "json-complex"; required: boolean }
84
84
  | {
85
- kind: "multipart"
86
- binaryFields: { name: string; required: boolean }[]
87
- scalarFields: BodyScalarInfo[]
88
- useGenericFileFlag: boolean
89
- }
85
+ kind: "multipart"
86
+ binaryFields: { name: string; required: boolean }[]
87
+ scalarFields: BodyScalarInfo[]
88
+ useGenericFileFlag: boolean
89
+ }
90
90
 
91
91
  type CommandInfo = {
92
92
  opId: string
@@ -163,16 +163,7 @@ let runtimeCache: Map<string, string> | null = null
163
163
  /** Reads static .go runtime files from ./cli-go/ and caches them. */
164
164
  export function loadGoCliRuntimeTemplates(): Map<string, string> {
165
165
  if (runtimeCache) return runtimeCache
166
- const names = [
167
- "config.go",
168
- "auth.go",
169
- "output.go",
170
- "errors.go",
171
- "stream.go",
172
- "multipart.go",
173
- "version.go",
174
- "root.go",
175
- ]
166
+ const names = ["config.go", "auth.go", "output.go", "errors.go", "stream.go", "multipart.go", "version.go", "root.go"]
176
167
  const cache = new Map<string, string>()
177
168
  for (const name of names) {
178
169
  const filePath = fileURLToPath(new URL(`./cli-go/${name}`, import.meta.url))
@@ -190,10 +181,7 @@ export function loadGoCliRuntimeTemplates(): Map<string, string> {
190
181
 
191
182
  /* ── param + body helpers ── */
192
183
 
193
- function getPathParams(
194
- op: Record<string, unknown>,
195
- rawPath: string,
196
- ): ParamInfo[] {
184
+ function getPathParams(op: Record<string, unknown>, rawPath: string): ParamInfo[] {
197
185
  const declared = extractOpenApiPathParams(rawPath)
198
186
  const byName = new Map<string, Record<string, unknown>>()
199
187
  const parameters = (op.parameters as Array<Record<string, unknown>> | undefined) ?? []
@@ -333,9 +321,11 @@ function hasJsonResponse(op: Record<string, unknown>): boolean {
333
321
 
334
322
  /* ── command collection ── */
335
323
 
336
- function collectCLIMethods(
337
- spec: Record<string, unknown>,
338
- ): { groups: Map<string, ResourceGroup>; skipped: string[]; serviceMap: Record<string, Record<string, unknown>> } {
324
+ function collectCLIMethods(spec: Record<string, unknown>): {
325
+ groups: Map<string, ResourceGroup>
326
+ skipped: string[]
327
+ serviceMap: Record<string, Record<string, unknown>>
328
+ } {
339
329
  toIR(spec as Parameters<typeof toIR>[0])
340
330
  const { serviceMap } = collectSDKMethods(spec as Parameters<typeof collectSDKMethods>[0])
341
331
  const resolved = resolveRefs(spec as Parameters<typeof resolveRefs>[0]) as unknown as OpenApiSpec
@@ -609,12 +599,7 @@ function emitResourceFile(group: ResourceGroup, options: GoCLIOptions): string {
609
599
  }
610
600
 
611
601
  /** Emits var declarations for every flag-backing Go variable + the cobra.Command literal. */
612
- function emitCommand(
613
- l: string[],
614
- group: ResourceGroup,
615
- cmd: CommandInfo,
616
- options: GoCLIOptions,
617
- ): void {
602
+ function emitCommand(l: string[], group: ResourceGroup, cmd: CommandInfo, options: GoCLIOptions): void {
618
603
  /* flag-backing vars */
619
604
  for (const p of cmd.pathParams) {
620
605
  l.push(`var ${cmd.cmdVarName}${goPascal(p.name)}Var string`)
@@ -689,7 +674,9 @@ function emitFlagRegistrations(l: string[], cmd: CommandInfo): void {
689
674
  const v = `${cmd.cmdVarName}${goPascal(p.name)}Var`
690
675
  /* flag docstring references original param name for discoverability */
691
676
  l.push(`\t/* Path flag — Use: ${JSON.stringify(p.name)} */`)
692
- l.push(`\t${cmd.cmdVarName}.Flags().StringVar(&${v}, ${JSON.stringify(p.flagName)}, "", ${JSON.stringify(`Path parameter ${p.name}`)})`)
677
+ l.push(
678
+ `\t${cmd.cmdVarName}.Flags().StringVar(&${v}, ${JSON.stringify(p.flagName)}, "", ${JSON.stringify(`Path parameter ${p.name}`)})`,
679
+ )
693
680
  l.push(`\t${cmd.cmdVarName}.MarkFlagRequired(${JSON.stringify(p.flagName)})`)
694
681
  }
695
682
  for (const q of cmd.queryParams) {
@@ -697,7 +684,9 @@ function emitFlagRegistrations(l: string[], cmd: CommandInfo): void {
697
684
  emitQueryFlag(l, cmd, q)
698
685
  }
699
686
  if (cmd.body.kind === "json-flat" || cmd.body.kind === "json-complex") {
700
- l.push(`\t${cmd.cmdVarName}.Flags().StringVar(&${cmd.cmdVarName}DataVar, "data", "", "Request body: JSON literal, @file, or - for stdin")`)
687
+ l.push(
688
+ `\t${cmd.cmdVarName}.Flags().StringVar(&${cmd.cmdVarName}DataVar, "data", "", "Request body: JSON literal, @file, or - for stdin")`,
689
+ )
701
690
  }
702
691
  if (cmd.body.kind === "json-flat") {
703
692
  for (const s of cmd.body.scalars) {
@@ -717,7 +706,9 @@ function emitFlagRegistrations(l: string[], cmd: CommandInfo): void {
717
706
  } else {
718
707
  for (const f of cmd.body.binaryFields) {
719
708
  const v = `${cmd.cmdVarName}${goPascal(f.name)}Var`
720
- l.push(`\t${cmd.cmdVarName}.Flags().StringVar(&${v}, ${JSON.stringify(toFlagName(f.name))}, "", ${JSON.stringify(`Path to ${f.name} file`)})`)
709
+ l.push(
710
+ `\t${cmd.cmdVarName}.Flags().StringVar(&${v}, ${JSON.stringify(toFlagName(f.name))}, "", ${JSON.stringify(`Path to ${f.name} file`)})`,
711
+ )
721
712
  if (f.required) {
722
713
  l.push(`\t${cmd.cmdVarName}.MarkFlagRequired(${JSON.stringify(toFlagName(f.name))})`)
723
714
  }
@@ -725,16 +716,17 @@ function emitFlagRegistrations(l: string[], cmd: CommandInfo): void {
725
716
  }
726
717
  }
727
718
  if (cmd.hasLastEventId) {
728
- l.push(`\t${cmd.cmdVarName}.Flags().StringVar(&${cmd.cmdVarName}LastEventIDVar, "last-event-id", "", "SSE Last-Event-ID resume token")`)
719
+ l.push(
720
+ `\t${cmd.cmdVarName}.Flags().StringVar(&${cmd.cmdVarName}LastEventIDVar, "last-event-id", "", "SSE Last-Event-ID resume token")`,
721
+ )
729
722
  }
730
723
  }
731
724
 
732
725
  function emitQueryFlag(l: string[], cmd: CommandInfo, q: ParamInfo): void {
733
726
  const v = `${cmd.cmdVarName}${goPascal(q.name)}Var`
734
727
  const t = q.schema.type
735
- const help = q.enumValues.length > 0
736
- ? `Query param ${q.name} (one of: ${q.enumValues.join(", ")})`
737
- : `Query param ${q.name}`
728
+ const help =
729
+ q.enumValues.length > 0 ? `Query param ${q.name} (one of: ${q.enumValues.join(", ")})` : `Query param ${q.name}`
738
730
  const helpStr = JSON.stringify(help)
739
731
 
740
732
  if (t === "integer") {
@@ -745,14 +737,18 @@ function emitQueryFlag(l: string[], cmd: CommandInfo, q: ParamInfo): void {
745
737
  l.push(`\t${cmd.cmdVarName}.Flags().Float64Var(&${v}, ${JSON.stringify(q.flagName)}, ${def}, ${helpStr})`)
746
738
  } else if (t === "boolean") {
747
739
  const def = q.defaultValue === true
748
- l.push(`\t${cmd.cmdVarName}.Flags().BoolVar(&${v}, ${JSON.stringify(q.flagName)}, ${def ? "true" : "false"}, ${helpStr})`)
740
+ l.push(
741
+ `\t${cmd.cmdVarName}.Flags().BoolVar(&${v}, ${JSON.stringify(q.flagName)}, ${def ? "true" : "false"}, ${helpStr})`,
742
+ )
749
743
  } else if (t === "array") {
750
744
  const defArr = Array.isArray(q.defaultValue) ? q.defaultValue : []
751
745
  const defStr = `[]string{${defArr.map((x) => JSON.stringify(String(x))).join(", ")}}`
752
746
  l.push(`\t${cmd.cmdVarName}.Flags().StringSliceVar(&${v}, ${JSON.stringify(q.flagName)}, ${defStr}, ${helpStr})`)
753
747
  } else {
754
748
  const def = typeof q.defaultValue === "string" ? q.defaultValue : ""
755
- l.push(`\t${cmd.cmdVarName}.Flags().StringVar(&${v}, ${JSON.stringify(q.flagName)}, ${JSON.stringify(def)}, ${helpStr})`)
749
+ l.push(
750
+ `\t${cmd.cmdVarName}.Flags().StringVar(&${v}, ${JSON.stringify(q.flagName)}, ${JSON.stringify(def)}, ${helpStr})`,
751
+ )
756
752
  }
757
753
  if (q.required) {
758
754
  l.push(`\t${cmd.cmdVarName}.MarkFlagRequired(${JSON.stringify(q.flagName)})`)
@@ -761,9 +757,10 @@ function emitQueryFlag(l: string[], cmd: CommandInfo, q: ParamInfo): void {
761
757
 
762
758
  function emitBodyScalarFlag(l: string[], cmd: CommandInfo, s: BodyScalarInfo): void {
763
759
  const v = `${cmd.cmdVarName}${goPascal(s.propName)}Var`
764
- const help = s.enumValues.length > 0
765
- ? `Body field ${s.propName} (one of: ${s.enumValues.join(", ")})`
766
- : `Body field ${s.propName}`
760
+ const help =
761
+ s.enumValues.length > 0
762
+ ? `Body field ${s.propName} (one of: ${s.enumValues.join(", ")})`
763
+ : `Body field ${s.propName}`
767
764
  const helpStr = JSON.stringify(help)
768
765
  if (s.schemaType === "integer") {
769
766
  l.push(`\t${cmd.cmdVarName}.Flags().Int64Var(&${v}, ${JSON.stringify(s.flagName)}, 0, ${helpStr})`)
@@ -809,7 +806,9 @@ function emitPreRunE(cmd: CommandInfo): string[] {
809
806
  if (s.schemaType !== "string") continue
810
807
  const v = `${cmd.cmdVarName}${goPascal(s.propName)}Var`
811
808
  const values = s.enumValues.map((x) => JSON.stringify(x)).join(", ")
812
- lines.push(`if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) && !slices.Contains([]string{${values}}, ${v}) {`)
809
+ lines.push(
810
+ `if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) && !slices.Contains([]string{${values}}, ${v}) {`,
811
+ )
813
812
  lines.push(`\treturn fmt.Errorf("--${s.flagName} must be one of: ${s.enumValues.join(", ")}")`)
814
813
  lines.push(`}`)
815
814
  }
@@ -858,12 +857,16 @@ function emitRunE(l: string[], cmd: CommandInfo, _options: GoCLIOptions): void {
858
857
  l.push(`${ind}\tdataBytes, derr := cli.ReadDataFlag(${cmd.cmdVarName}DataVar)`)
859
858
  l.push(`${ind}\tif derr != nil { return derr }`)
860
859
  l.push(`${ind}\tif len(dataBytes) > 0 {`)
861
- l.push(`${ind}\t\tif jerr := json.Unmarshal(dataBytes, &merged); jerr != nil { return fmt.Errorf("parse --data: %w", jerr) }`)
860
+ l.push(
861
+ `${ind}\t\tif jerr := json.Unmarshal(dataBytes, &merged); jerr != nil { return fmt.Errorf("parse --data: %w", jerr) }`,
862
+ )
862
863
  l.push(`${ind}\t}`)
863
864
  l.push(`${ind}}`)
864
865
  for (const s of cmd.body.scalars) {
865
866
  const v = `${cmd.cmdVarName}${goPascal(s.propName)}Var`
866
- l.push(`${ind}if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) { merged[${JSON.stringify(s.propName)}] = ${v} }`)
867
+ l.push(
868
+ `${ind}if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) { merged[${JSON.stringify(s.propName)}] = ${v} }`,
869
+ )
867
870
  }
868
871
  l.push(`${ind}bodyBytes, merr := json.Marshal(merged)`)
869
872
  l.push(`${ind}if merr != nil { return merr }`)
@@ -879,15 +882,21 @@ function emitRunE(l: string[], cmd: CommandInfo, _options: GoCLIOptions): void {
879
882
  for (const s of cmd.body.scalarFields) {
880
883
  const v = `${cmd.cmdVarName}${goPascal(s.propName)}Var`
881
884
  if (s.schemaType === "string") {
882
- l.push(`${ind}if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) { fields[${JSON.stringify(s.propName)}] = ${v} }`)
885
+ l.push(
886
+ `${ind}if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) { fields[${JSON.stringify(s.propName)}] = ${v} }`,
887
+ )
883
888
  } else {
884
- l.push(`${ind}if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) { fields[${JSON.stringify(s.propName)}] = fmt.Sprint(${v}) }`)
889
+ l.push(
890
+ `${ind}if cmd.Flags().Changed(${JSON.stringify(s.flagName)}) { fields[${JSON.stringify(s.propName)}] = fmt.Sprint(${v}) }`,
891
+ )
885
892
  }
886
893
  }
887
894
  l.push(`${ind}files := map[string]string{}`)
888
895
  if (cmd.body.useGenericFileFlag) {
889
896
  const bin = cmd.body.binaryFields[0]
890
- l.push(`${ind}if ${cmd.cmdVarName}FileVar != "" { files[${JSON.stringify(bin.name)}] = ${cmd.cmdVarName}FileVar }`)
897
+ l.push(
898
+ `${ind}if ${cmd.cmdVarName}FileVar != "" { files[${JSON.stringify(bin.name)}] = ${cmd.cmdVarName}FileVar }`,
899
+ )
891
900
  } else {
892
901
  for (const f of cmd.body.binaryFields) {
893
902
  const v = `${cmd.cmdVarName}${goPascal(f.name)}Var`
@@ -908,7 +917,9 @@ function emitRunE(l: string[], cmd: CommandInfo, _options: GoCLIOptions): void {
908
917
  l.push(`${ind}req.Header.Set("Accept", "text/event-stream")`)
909
918
  l.push(`${ind}if apiKey != "" { req.Header.Set("Authorization", "Bearer "+apiKey) }`)
910
919
  if (cmd.hasLastEventId) {
911
- l.push(`${ind}if ${cmd.cmdVarName}LastEventIDVar != "" { req.Header.Set("Last-Event-ID", ${cmd.cmdVarName}LastEventIDVar) }`)
920
+ l.push(
921
+ `${ind}if ${cmd.cmdVarName}LastEventIDVar != "" { req.Header.Set("Last-Event-ID", ${cmd.cmdVarName}LastEventIDVar) }`,
922
+ )
912
923
  }
913
924
  l.push(`${ind}resp, herr := httpClient.Do(req)`)
914
925
  l.push(`${ind}if herr != nil { return herr }`)
@@ -941,7 +952,9 @@ function emitRunE(l: string[], cmd: CommandInfo, _options: GoCLIOptions): void {
941
952
  l.push(`${ind}body, berr := io.ReadAll(resp.Body)`)
942
953
  l.push(`${ind}if berr != nil { return berr }`)
943
954
  l.push(`${ind}if resp.StatusCode >= 400 {`)
944
- l.push(`${ind}\treturn &sdk.StatusError{StatusCode: resp.StatusCode, Body: body, Response: resp, Message: string(body)}`)
955
+ l.push(
956
+ `${ind}\treturn &sdk.StatusError{StatusCode: resp.StatusCode, Body: body, Response: resp, Message: string(body)}`,
957
+ )
945
958
  l.push(`${ind}}`)
946
959
  if (cmd.has204) {
947
960
  l.push(`${ind}if resp.StatusCode == http.StatusNoContent { return nil }`)
@@ -970,11 +983,16 @@ function buildPathExpr(cmd: CommandInfo): string {
970
983
  function querySetStmt(q: ParamInfo, v: string): string {
971
984
  const name = JSON.stringify(q.name)
972
985
  switch (q.schema.type) {
973
- case "integer": return `q.Set(${name}, fmt.Sprintf("%d", ${v}))`
974
- case "number": return `q.Set(${name}, fmt.Sprintf("%g", ${v}))`
975
- case "boolean": return `q.Set(${name}, fmt.Sprintf("%t", ${v}))`
976
- case "array": return `for _, v := range ${v} { q.Add(${name}, v) }`
977
- default: return `q.Set(${name}, ${v})`
986
+ case "integer":
987
+ return `q.Set(${name}, fmt.Sprintf("%d", ${v}))`
988
+ case "number":
989
+ return `q.Set(${name}, fmt.Sprintf("%g", ${v}))`
990
+ case "boolean":
991
+ return `q.Set(${name}, fmt.Sprintf("%t", ${v}))`
992
+ case "array":
993
+ return `for _, v := range ${v} { q.Add(${name}, v) }`
994
+ default:
995
+ return `q.Set(${name}, ${v})`
978
996
  }
979
997
  }
980
998
 
@@ -1087,11 +1105,7 @@ function emitReadme(spec: OpenApiSpec, options: GoCLIOptions): string {
1087
1105
 
1088
1106
  /* ── embedded SDK copy ── */
1089
1107
 
1090
- function copyEmbeddedSDK(
1091
- spec: Record<string, unknown>,
1092
- options: GoCLIOptions,
1093
- outFiles: Record<string, string>,
1094
- ): void {
1108
+ function copyEmbeddedSDK(spec: Record<string, unknown>, options: GoCLIOptions, outFiles: Record<string, string>): void {
1095
1109
  const sdkModule = `${resolveModulePath(options)}/internal/sdk`
1096
1110
  const sdkGen = generateGoSDK(spec, { modulePath: sdkModule })
1097
1111
  for (const [name, content] of Object.entries(sdkGen.files)) {
@@ -1107,11 +1121,7 @@ function copyEmbeddedSDK(
1107
1121
  * When embedding, add a small sse_export.go into internal/sdk/.
1108
1122
  * When using external SDK, we still need the same symbol — emit an adapter file. */
1109
1123
 
1110
- function emitSSEExportShim(
1111
- options: GoCLIOptions,
1112
- files: Record<string, string>,
1113
- hasEmbedded: boolean,
1114
- ): void {
1124
+ function emitSSEExportShim(options: GoCLIOptions, files: Record<string, string>, hasEmbedded: boolean): void {
1115
1125
  const shim = [
1116
1126
  `// Code generated by honey. DO NOT EDIT.`,
1117
1127
  `package sdk`,
@@ -1137,10 +1147,7 @@ function emitSSEExportShim(
1137
1147
 
1138
1148
  /* ── public entrypoint ── */
1139
1149
 
1140
- export function generateGoCLI(
1141
- spec: Record<string, unknown>,
1142
- options: GoCLIOptions,
1143
- ): GeneratedGoCLI {
1150
+ export function generateGoCLI(spec: Record<string, unknown>, options: GoCLIOptions): GeneratedGoCLI {
1144
1151
  const resolved = resolveRefs(spec as Parameters<typeof resolveRefs>[0]) as unknown as OpenApiSpec
1145
1152
  const { groups, skipped, serviceMap } = collectCLIMethods(spec)
1146
1153