ts-procedures 5.13.0 → 5.15.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 (249) hide show
  1. package/agent_config/claude-code/agents/ts-procedures-architect.md +0 -1
  2. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +0 -25
  3. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +26 -4
  4. package/agent_config/claude-code/skills/ts-procedures/patterns.md +2 -1
  5. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/client.md +3 -0
  6. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-api.md +1 -1
  7. package/agent_config/copilot/copilot-instructions.md +2 -2
  8. package/agent_config/cursor/cursorrules +2 -2
  9. package/build/codegen/bin/cli.d.ts +2 -0
  10. package/build/codegen/bin/cli.js +11 -0
  11. package/build/codegen/bin/cli.js.map +1 -1
  12. package/build/codegen/bin/cli.test.js +30 -0
  13. package/build/codegen/bin/cli.test.js.map +1 -1
  14. package/build/codegen/index.d.ts +1 -0
  15. package/build/codegen/index.js +1 -0
  16. package/build/codegen/index.js.map +1 -1
  17. package/build/codegen/pipeline.d.ts +1 -0
  18. package/build/codegen/pipeline.js +8 -2
  19. package/build/codegen/pipeline.js.map +1 -1
  20. package/build/codegen/pipeline.test.js +34 -1
  21. package/build/codegen/pipeline.test.js.map +1 -1
  22. package/build/implementations/http/hono-api/index.d.ts +15 -3
  23. package/build/implementations/http/hono-api/index.js +3 -32
  24. package/build/implementations/http/hono-api/index.js.map +1 -1
  25. package/build/implementations/http/hono-api/index.test.js +6 -6
  26. package/build/implementations/http/hono-api/index.test.js.map +1 -1
  27. package/docs/client-and-codegen.md +2 -0
  28. package/package.json +2 -3
  29. package/src/codegen/bin/cli.test.ts +35 -0
  30. package/src/codegen/bin/cli.ts +11 -0
  31. package/src/codegen/index.ts +2 -0
  32. package/src/codegen/pipeline.test.ts +46 -1
  33. package/src/codegen/pipeline.ts +9 -2
  34. package/src/implementations/http/README.md +2 -0
  35. package/src/implementations/http/hono-api/index.test.ts +6 -6
  36. package/src/implementations/http/hono-api/index.ts +17 -36
  37. package/build/src/client/call.d.ts +0 -14
  38. package/build/src/client/call.js +0 -47
  39. package/build/src/client/call.js.map +0 -1
  40. package/build/src/client/call.test.d.ts +0 -1
  41. package/build/src/client/call.test.js +0 -124
  42. package/build/src/client/call.test.js.map +0 -1
  43. package/build/src/client/errors.d.ts +0 -25
  44. package/build/src/client/errors.js +0 -33
  45. package/build/src/client/errors.js.map +0 -1
  46. package/build/src/client/errors.test.d.ts +0 -1
  47. package/build/src/client/errors.test.js +0 -41
  48. package/build/src/client/errors.test.js.map +0 -1
  49. package/build/src/client/fetch-adapter.d.ts +0 -12
  50. package/build/src/client/fetch-adapter.js +0 -156
  51. package/build/src/client/fetch-adapter.js.map +0 -1
  52. package/build/src/client/fetch-adapter.test.d.ts +0 -1
  53. package/build/src/client/fetch-adapter.test.js +0 -271
  54. package/build/src/client/fetch-adapter.test.js.map +0 -1
  55. package/build/src/client/hooks.d.ts +0 -17
  56. package/build/src/client/hooks.js +0 -40
  57. package/build/src/client/hooks.js.map +0 -1
  58. package/build/src/client/hooks.test.d.ts +0 -1
  59. package/build/src/client/hooks.test.js +0 -163
  60. package/build/src/client/hooks.test.js.map +0 -1
  61. package/build/src/client/index.d.ts +0 -22
  62. package/build/src/client/index.js +0 -67
  63. package/build/src/client/index.js.map +0 -1
  64. package/build/src/client/index.test.d.ts +0 -1
  65. package/build/src/client/index.test.js +0 -231
  66. package/build/src/client/index.test.js.map +0 -1
  67. package/build/src/client/request-builder.d.ts +0 -13
  68. package/build/src/client/request-builder.js +0 -53
  69. package/build/src/client/request-builder.js.map +0 -1
  70. package/build/src/client/request-builder.test.d.ts +0 -1
  71. package/build/src/client/request-builder.test.js +0 -160
  72. package/build/src/client/request-builder.test.js.map +0 -1
  73. package/build/src/client/stream.d.ts +0 -27
  74. package/build/src/client/stream.js +0 -118
  75. package/build/src/client/stream.js.map +0 -1
  76. package/build/src/client/stream.test.d.ts +0 -1
  77. package/build/src/client/stream.test.js +0 -228
  78. package/build/src/client/stream.test.js.map +0 -1
  79. package/build/src/client/types.d.ts +0 -78
  80. package/build/src/client/types.js +0 -3
  81. package/build/src/client/types.js.map +0 -1
  82. package/build/src/codegen/bin/cli.d.ts +0 -45
  83. package/build/src/codegen/bin/cli.js +0 -246
  84. package/build/src/codegen/bin/cli.js.map +0 -1
  85. package/build/src/codegen/bin/cli.test.d.ts +0 -1
  86. package/build/src/codegen/bin/cli.test.js +0 -220
  87. package/build/src/codegen/bin/cli.test.js.map +0 -1
  88. package/build/src/codegen/constants.d.ts +0 -1
  89. package/build/src/codegen/constants.js +0 -2
  90. package/build/src/codegen/constants.js.map +0 -1
  91. package/build/src/codegen/e2e.test.d.ts +0 -1
  92. package/build/src/codegen/e2e.test.js +0 -464
  93. package/build/src/codegen/e2e.test.js.map +0 -1
  94. package/build/src/codegen/emit-client-runtime.d.ts +0 -9
  95. package/build/src/codegen/emit-client-runtime.js +0 -99
  96. package/build/src/codegen/emit-client-runtime.js.map +0 -1
  97. package/build/src/codegen/emit-client-runtime.test.d.ts +0 -1
  98. package/build/src/codegen/emit-client-runtime.test.js +0 -78
  99. package/build/src/codegen/emit-client-runtime.test.js.map +0 -1
  100. package/build/src/codegen/emit-client-types.d.ts +0 -8
  101. package/build/src/codegen/emit-client-types.js +0 -25
  102. package/build/src/codegen/emit-client-types.js.map +0 -1
  103. package/build/src/codegen/emit-client-types.test.d.ts +0 -1
  104. package/build/src/codegen/emit-client-types.test.js +0 -33
  105. package/build/src/codegen/emit-client-types.test.js.map +0 -1
  106. package/build/src/codegen/emit-errors.d.ts +0 -19
  107. package/build/src/codegen/emit-errors.js +0 -59
  108. package/build/src/codegen/emit-errors.js.map +0 -1
  109. package/build/src/codegen/emit-errors.test.d.ts +0 -1
  110. package/build/src/codegen/emit-errors.test.js +0 -175
  111. package/build/src/codegen/emit-errors.test.js.map +0 -1
  112. package/build/src/codegen/emit-index.d.ts +0 -12
  113. package/build/src/codegen/emit-index.js +0 -41
  114. package/build/src/codegen/emit-index.js.map +0 -1
  115. package/build/src/codegen/emit-index.test.d.ts +0 -1
  116. package/build/src/codegen/emit-index.test.js +0 -106
  117. package/build/src/codegen/emit-index.test.js.map +0 -1
  118. package/build/src/codegen/emit-scope.d.ts +0 -15
  119. package/build/src/codegen/emit-scope.js +0 -299
  120. package/build/src/codegen/emit-scope.js.map +0 -1
  121. package/build/src/codegen/emit-scope.test.d.ts +0 -1
  122. package/build/src/codegen/emit-scope.test.js +0 -559
  123. package/build/src/codegen/emit-scope.test.js.map +0 -1
  124. package/build/src/codegen/emit-types.d.ts +0 -43
  125. package/build/src/codegen/emit-types.js +0 -111
  126. package/build/src/codegen/emit-types.js.map +0 -1
  127. package/build/src/codegen/emit-types.test.d.ts +0 -1
  128. package/build/src/codegen/emit-types.test.js +0 -184
  129. package/build/src/codegen/emit-types.test.js.map +0 -1
  130. package/build/src/codegen/group-routes.d.ts +0 -23
  131. package/build/src/codegen/group-routes.js +0 -46
  132. package/build/src/codegen/group-routes.js.map +0 -1
  133. package/build/src/codegen/group-routes.test.d.ts +0 -1
  134. package/build/src/codegen/group-routes.test.js +0 -131
  135. package/build/src/codegen/group-routes.test.js.map +0 -1
  136. package/build/src/codegen/index.d.ts +0 -15
  137. package/build/src/codegen/index.js +0 -16
  138. package/build/src/codegen/index.js.map +0 -1
  139. package/build/src/codegen/naming.d.ts +0 -7
  140. package/build/src/codegen/naming.js +0 -21
  141. package/build/src/codegen/naming.js.map +0 -1
  142. package/build/src/codegen/naming.test.d.ts +0 -1
  143. package/build/src/codegen/naming.test.js +0 -40
  144. package/build/src/codegen/naming.test.js.map +0 -1
  145. package/build/src/codegen/pipeline.d.ts +0 -17
  146. package/build/src/codegen/pipeline.js +0 -78
  147. package/build/src/codegen/pipeline.js.map +0 -1
  148. package/build/src/codegen/pipeline.test.d.ts +0 -1
  149. package/build/src/codegen/pipeline.test.js +0 -269
  150. package/build/src/codegen/pipeline.test.js.map +0 -1
  151. package/build/src/codegen/resolve-envelope.d.ts +0 -7
  152. package/build/src/codegen/resolve-envelope.js +0 -46
  153. package/build/src/codegen/resolve-envelope.js.map +0 -1
  154. package/build/src/codegen/resolve-envelope.test.d.ts +0 -1
  155. package/build/src/codegen/resolve-envelope.test.js +0 -69
  156. package/build/src/codegen/resolve-envelope.test.js.map +0 -1
  157. package/build/src/errors.d.ts +0 -33
  158. package/build/src/errors.js +0 -91
  159. package/build/src/errors.js.map +0 -1
  160. package/build/src/errors.test.d.ts +0 -1
  161. package/build/src/errors.test.js +0 -122
  162. package/build/src/errors.test.js.map +0 -1
  163. package/build/src/exports.d.ts +0 -7
  164. package/build/src/exports.js +0 -8
  165. package/build/src/exports.js.map +0 -1
  166. package/build/src/implementations/http/doc-registry.d.ts +0 -12
  167. package/build/src/implementations/http/doc-registry.js +0 -114
  168. package/build/src/implementations/http/doc-registry.js.map +0 -1
  169. package/build/src/implementations/http/doc-registry.test.d.ts +0 -1
  170. package/build/src/implementations/http/doc-registry.test.js +0 -347
  171. package/build/src/implementations/http/doc-registry.test.js.map +0 -1
  172. package/build/src/implementations/http/express-rpc/index.d.ts +0 -94
  173. package/build/src/implementations/http/express-rpc/index.js +0 -185
  174. package/build/src/implementations/http/express-rpc/index.js.map +0 -1
  175. package/build/src/implementations/http/express-rpc/index.test.d.ts +0 -1
  176. package/build/src/implementations/http/express-rpc/index.test.js +0 -684
  177. package/build/src/implementations/http/express-rpc/index.test.js.map +0 -1
  178. package/build/src/implementations/http/express-rpc/types.d.ts +0 -11
  179. package/build/src/implementations/http/express-rpc/types.js +0 -2
  180. package/build/src/implementations/http/express-rpc/types.js.map +0 -1
  181. package/build/src/implementations/http/hono-api/index.d.ts +0 -102
  182. package/build/src/implementations/http/hono-api/index.js +0 -341
  183. package/build/src/implementations/http/hono-api/index.js.map +0 -1
  184. package/build/src/implementations/http/hono-api/index.test.d.ts +0 -1
  185. package/build/src/implementations/http/hono-api/index.test.js +0 -992
  186. package/build/src/implementations/http/hono-api/index.test.js.map +0 -1
  187. package/build/src/implementations/http/hono-api/types.d.ts +0 -13
  188. package/build/src/implementations/http/hono-api/types.js +0 -2
  189. package/build/src/implementations/http/hono-api/types.js.map +0 -1
  190. package/build/src/implementations/http/hono-rpc/index.d.ts +0 -92
  191. package/build/src/implementations/http/hono-rpc/index.js +0 -161
  192. package/build/src/implementations/http/hono-rpc/index.js.map +0 -1
  193. package/build/src/implementations/http/hono-rpc/index.test.d.ts +0 -1
  194. package/build/src/implementations/http/hono-rpc/index.test.js +0 -803
  195. package/build/src/implementations/http/hono-rpc/index.test.js.map +0 -1
  196. package/build/src/implementations/http/hono-rpc/types.d.ts +0 -11
  197. package/build/src/implementations/http/hono-rpc/types.js +0 -2
  198. package/build/src/implementations/http/hono-rpc/types.js.map +0 -1
  199. package/build/src/implementations/http/hono-stream/index.d.ts +0 -120
  200. package/build/src/implementations/http/hono-stream/index.js +0 -309
  201. package/build/src/implementations/http/hono-stream/index.js.map +0 -1
  202. package/build/src/implementations/http/hono-stream/index.test.d.ts +0 -1
  203. package/build/src/implementations/http/hono-stream/index.test.js +0 -1356
  204. package/build/src/implementations/http/hono-stream/index.test.js.map +0 -1
  205. package/build/src/implementations/http/hono-stream/types.d.ts +0 -15
  206. package/build/src/implementations/http/hono-stream/types.js +0 -2
  207. package/build/src/implementations/http/hono-stream/types.js.map +0 -1
  208. package/build/src/implementations/types.d.ts +0 -142
  209. package/build/src/implementations/types.js +0 -2
  210. package/build/src/implementations/types.js.map +0 -1
  211. package/build/src/index.d.ts +0 -165
  212. package/build/src/index.js +0 -253
  213. package/build/src/index.js.map +0 -1
  214. package/build/src/index.test.d.ts +0 -1
  215. package/build/src/index.test.js +0 -890
  216. package/build/src/index.test.js.map +0 -1
  217. package/build/src/schema/compute-schema.d.ts +0 -35
  218. package/build/src/schema/compute-schema.js +0 -41
  219. package/build/src/schema/compute-schema.js.map +0 -1
  220. package/build/src/schema/compute-schema.test.d.ts +0 -1
  221. package/build/src/schema/compute-schema.test.js +0 -107
  222. package/build/src/schema/compute-schema.test.js.map +0 -1
  223. package/build/src/schema/extract-json-schema.d.ts +0 -2
  224. package/build/src/schema/extract-json-schema.js +0 -12
  225. package/build/src/schema/extract-json-schema.js.map +0 -1
  226. package/build/src/schema/extract-json-schema.test.d.ts +0 -1
  227. package/build/src/schema/extract-json-schema.test.js +0 -23
  228. package/build/src/schema/extract-json-schema.test.js.map +0 -1
  229. package/build/src/schema/parser.d.ts +0 -28
  230. package/build/src/schema/parser.js +0 -170
  231. package/build/src/schema/parser.js.map +0 -1
  232. package/build/src/schema/parser.test.d.ts +0 -1
  233. package/build/src/schema/parser.test.js +0 -120
  234. package/build/src/schema/parser.test.js.map +0 -1
  235. package/build/src/schema/resolve-schema-lib.d.ts +0 -12
  236. package/build/src/schema/resolve-schema-lib.js +0 -11
  237. package/build/src/schema/resolve-schema-lib.js.map +0 -1
  238. package/build/src/schema/resolve-schema-lib.test.d.ts +0 -1
  239. package/build/src/schema/resolve-schema-lib.test.js +0 -17
  240. package/build/src/schema/resolve-schema-lib.test.js.map +0 -1
  241. package/build/src/schema/types.d.ts +0 -8
  242. package/build/src/schema/types.js +0 -2
  243. package/build/src/schema/types.js.map +0 -1
  244. package/build/src/stack-utils.d.ts +0 -25
  245. package/build/src/stack-utils.js +0 -95
  246. package/build/src/stack-utils.js.map +0 -1
  247. package/build/src/stack-utils.test.d.ts +0 -1
  248. package/build/src/stack-utils.test.js +0 -80
  249. package/build/src/stack-utils.test.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { mkdir, writeFile } from 'node:fs/promises'
1
+ import { mkdir, rm, writeFile } from 'node:fs/promises'
2
2
  import { join } from 'node:path'
3
3
  import { createHash } from 'node:crypto'
4
4
  import type { DocEnvelope } from '../implementations/types.js'
@@ -20,6 +20,7 @@ export interface PipelineOptions {
20
20
  namespaceTypes?: boolean
21
21
  selfContained?: boolean
22
22
  serviceName?: string
23
+ cleanOutDir?: boolean
23
24
  }
24
25
 
25
26
  export interface GeneratedFile {
@@ -28,7 +29,7 @@ export interface GeneratedFile {
28
29
  }
29
30
 
30
31
  export async function runPipeline(options: PipelineOptions): Promise<GeneratedFile[]> {
31
- const { envelope, outDir, ajsc: ajscOpts, dryRun = false, namespaceTypes = false, selfContained = false } = options
32
+ const { envelope, outDir, ajsc: ajscOpts, dryRun = false, namespaceTypes = false, selfContained = false, cleanOutDir = false } = options
32
33
  const serviceName = options.serviceName ?? 'Api'
33
34
  validateServiceName(serviceName)
34
35
  const clientImportPath = selfContained ? './_types' : options.clientImportPath
@@ -92,11 +93,17 @@ export async function runPipeline(options: PipelineOptions): Promise<GeneratedFi
92
93
  }
93
94
 
94
95
  if (dryRun) {
96
+ if (cleanOutDir) {
97
+ console.log(`[dry-run] Would clean outDir: ${outDir}`)
98
+ }
95
99
  for (const file of files) {
96
100
  const bytes = Buffer.byteLength(file.code, 'utf-8')
97
101
  console.log(`[dry-run] Would write: ${file.path} (${bytes} bytes)`)
98
102
  }
99
103
  } else {
104
+ if (cleanOutDir) {
105
+ await rm(outDir, { recursive: true, force: true })
106
+ }
100
107
  await mkdir(outDir, { recursive: true })
101
108
  for (const file of files) {
102
109
  await writeFile(file.path, file.code, 'utf-8')
@@ -298,6 +298,8 @@ apiBuilder.register(factory, (c) => ctx, {
298
298
 
299
299
  **Self-contained mode:** Use `--self-contained` to emit `_types.ts` (all client type definitions) and `_client.ts` (runtime: `createClient`, `createFetchAdapter`, hooks, errors) into the output directory. All scope files and `index.ts` will import from `./_types` instead of `ts-procedures/client`, so consumers have no runtime dependency on `ts-procedures`. With this flag, `ts-procedures` can be a devDependency only.
300
300
 
301
+ **Clean output directory:** Use `--clean-out-dir` (or `cleanOutDir: true` in the programmatic API) to recursively remove the output directory before writing, so scope files left over from deleted or renamed scopes are pruned. Skipped under `--dry-run`.
302
+
301
303
  ## Framework Comparison
302
304
 
303
305
  | Aspect | Express | Hono |
@@ -881,7 +881,7 @@ describe('HonoAPIAppBuilder', () => {
881
881
  )
882
882
 
883
883
  builder.register(API, () => ({}))
884
- await expect(builder.build()).rejects.toThrow(/pathParams is not defined/)
884
+ expect(() => builder.build()).toThrow(/pathParams is not defined/)
885
885
  })
886
886
 
887
887
  test('throws when schema.input.pathParams defined but path has no params', async () => {
@@ -903,7 +903,7 @@ describe('HonoAPIAppBuilder', () => {
903
903
  )
904
904
 
905
905
  builder.register(API, () => ({}))
906
- await expect(builder.build()).rejects.toThrow(/has no path parameters/)
906
+ expect(() => builder.build()).toThrow(/has no path parameters/)
907
907
  })
908
908
 
909
909
  test('no error when path has params and pathParams schema matches', async () => {
@@ -925,7 +925,7 @@ describe('HonoAPIAppBuilder', () => {
925
925
  )
926
926
 
927
927
  builder.register(API, () => ({}))
928
- await expect(builder.build()).resolves.toBeDefined()
928
+ expect(builder.build()).toBeDefined()
929
929
  })
930
930
 
931
931
  test('throws when pathParams schema keys do not match path param names', async () => {
@@ -948,7 +948,7 @@ describe('HonoAPIAppBuilder', () => {
948
948
  )
949
949
 
950
950
  builder.register(API, () => ({}))
951
- await expect(builder.build()).rejects.toThrow(/Path param mismatch/)
951
+ expect(() => builder.build()).toThrow(/Path param mismatch/)
952
952
  })
953
953
 
954
954
  test('throws when path has multiple params and schema is missing one', async () => {
@@ -971,7 +971,7 @@ describe('HonoAPIAppBuilder', () => {
971
971
  )
972
972
 
973
973
  builder.register(API, () => ({}))
974
- await expect(builder.build()).rejects.toThrow(/commentId/)
974
+ expect(() => builder.build()).toThrow(/commentId/)
975
975
  })
976
976
 
977
977
  test('no validation when schema.input is not used', async () => {
@@ -989,7 +989,7 @@ describe('HonoAPIAppBuilder', () => {
989
989
  )
990
990
 
991
991
  builder.register(API, () => ({}))
992
- await expect(builder.build()).resolves.toBeDefined()
992
+ expect(builder.build()).toBeDefined()
993
993
  })
994
994
  })
995
995
 
@@ -19,22 +19,7 @@ export type { APIConfig, APIHttpRouteDoc, APIInput, HttpMethod }
19
19
 
20
20
  export type QueryParser = (queryString: string) => Record<string, unknown>
21
21
 
22
- /** Lazy-loaded qs module (optional peer dependency) */
23
- let _qsModule: { parse: (str: string, opts?: any) => any } | false | undefined
24
-
25
- async function loadQs(): Promise<{ parse: (str: string, opts?: any) => any } | undefined> {
26
- if (_qsModule === undefined) {
27
- try {
28
- const mod = await import('qs')
29
- _qsModule = mod.default ?? mod
30
- } catch {
31
- _qsModule = false
32
- }
33
- }
34
- return _qsModule || undefined
35
- }
36
-
37
- /** Fallback query parser using native URLSearchParams */
22
+ /** Default query parser using native URLSearchParams. */
38
23
  function parseQueryNative(queryString: string): Record<string, unknown> {
39
24
  const searchParams = new URLSearchParams(queryString)
40
25
  const result: Record<string, unknown> = {}
@@ -45,21 +30,6 @@ function parseQueryNative(queryString: string): Record<string, unknown> {
45
30
  return result
46
31
  }
47
32
 
48
- /**
49
- * Resolves the query parser once. Called during build() so handlers use a sync parser.
50
- * Priority: custom queryParser > qs (optional peer dep) > native URLSearchParams
51
- */
52
- async function resolveQueryParser(custom?: QueryParser): Promise<QueryParser> {
53
- if (custom) return custom
54
-
55
- const qs = await loadQs()
56
- if (qs) {
57
- return (raw: string) => qs.parse(raw) as Record<string, unknown>
58
- }
59
-
60
- return parseQueryNative
61
- }
62
-
63
33
  /** Extract path parameter names from a route pattern (e.g., '/users/:id' → ['id']) */
64
34
  function extractPathParamNames(path: string): string[] {
65
35
  const matches = path.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)
@@ -104,7 +74,20 @@ export type HonoAPIAppBuilderConfig = {
104
74
  pathPrefix?: string
105
75
  /**
106
76
  * Custom query string parser. Receives the raw query string (without '?').
107
- * Default: uses `qs` (optional peer dependency) if available, otherwise native URLSearchParams.
77
+ *
78
+ * Default: native `URLSearchParams`. The default handles:
79
+ * - flat keys: `?page=2&limit=10` → `{ page: '2', limit: '10' }`
80
+ * - repeated keys: `?tag=a&tag=b` → `{ tag: ['a', 'b'] }`
81
+ *
82
+ * The default does NOT parse any of these — the bracket/dot syntax is kept
83
+ * as part of the literal key name, not interpreted:
84
+ * - bracket objects: `?user[name]=John` → `{ 'user[name]': 'John' }`
85
+ * - bracket arrays: `?tags[]=a&tags[]=b` → `{ 'tags[]': ['a', 'b'] }`
86
+ * - dot paths: `?user.name=John` → `{ 'user.name': 'John' }`
87
+ * - comma-split arrays: `?tags=a,b,c` → `{ tags: 'a,b,c' }`
88
+ *
89
+ * For any of the above, install `qs` and opt in explicitly:
90
+ * `queryParser: (raw) => qs.parse(raw) as Record<string, unknown>`
108
91
  */
109
92
  queryParser?: QueryParser
110
93
  onRequestStart?: (c: Context) => void
@@ -216,11 +199,9 @@ export class HonoAPIAppBuilder {
216
199
 
217
200
  /**
218
201
  * Builds and returns the Hono application with registered API routes.
219
- * Async because it resolves the query parser (qs optional peer dep) once at build time.
220
202
  */
221
- async build(): Promise<Hono> {
222
- // Resolve query parser once so handlers use it synchronously
223
- const queryParser = await resolveQueryParser(this.config?.queryParser)
203
+ build(): Hono {
204
+ const queryParser = this.config?.queryParser ?? parseQueryNative
224
205
 
225
206
  this.factories.forEach(({ factory, factoryContext, extendProcedureDoc }) => {
226
207
  factory.getProcedures().map((procedure: TProcedureRegistration<any, APIConfig>) => {
@@ -1,14 +0,0 @@
1
- import type { ClientAdapter, ClientHooks, CallDescriptor } from './types.js';
2
- /**
3
- * Executes a single procedure call through the adapter.
4
- *
5
- * Flow:
6
- * 1. Build AdapterRequest from descriptor
7
- * 2. Run onBeforeRequest hooks (global then local)
8
- * 3. Call adapter.request()
9
- * 4. On adapter error: run onError hooks, re-throw
10
- * 5. Run onAfterResponse hooks (hooks may mutate response.status)
11
- * 6. If response status is non-2xx: throw ClientRequestError
12
- * 7. Return response.body as TResponse
13
- */
14
- export declare function executeCall<TResponse>(descriptor: CallDescriptor, basePath: string, adapter: ClientAdapter, globalHooks: ClientHooks, localHooks: ClientHooks | undefined): Promise<TResponse>;
@@ -1,47 +0,0 @@
1
- import { buildAdapterRequest } from './request-builder.js';
2
- import { runBeforeRequest, runAfterResponse, runOnError } from './hooks.js';
3
- import { ClientRequestError } from './errors.js';
4
- /**
5
- * Executes a single procedure call through the adapter.
6
- *
7
- * Flow:
8
- * 1. Build AdapterRequest from descriptor
9
- * 2. Run onBeforeRequest hooks (global then local)
10
- * 3. Call adapter.request()
11
- * 4. On adapter error: run onError hooks, re-throw
12
- * 5. Run onAfterResponse hooks (hooks may mutate response.status)
13
- * 6. If response status is non-2xx: throw ClientRequestError
14
- * 7. Return response.body as TResponse
15
- */
16
- export async function executeCall(descriptor, basePath, adapter, globalHooks, localHooks) {
17
- // 1. Build the initial request
18
- let request = buildAdapterRequest(descriptor, basePath);
19
- // 2. Run before-request hooks — they may mutate the request
20
- const beforeCtx = await runBeforeRequest({ procedureName: descriptor.name, scope: descriptor.scope, request }, globalHooks, localHooks);
21
- request = beforeCtx.request;
22
- // 3. Call the adapter
23
- let response;
24
- try {
25
- response = await adapter.request(request);
26
- }
27
- catch (err) {
28
- // 4. On adapter error: run error hooks, re-throw
29
- await runOnError({ procedureName: descriptor.name, scope: descriptor.scope, request, error: err }, globalHooks, localHooks);
30
- throw err;
31
- }
32
- // 5. Run after-response hooks — they may mutate response.status to swallow errors
33
- await runAfterResponse({ procedureName: descriptor.name, scope: descriptor.scope, request, response }, globalHooks, localHooks);
34
- // 6. Check status AFTER hooks (hooks may have swallowed the error by mutating status)
35
- if (response.status < 200 || response.status >= 300) {
36
- throw new ClientRequestError({
37
- status: response.status,
38
- headers: response.headers,
39
- body: response.body,
40
- procedureName: descriptor.name,
41
- scope: descriptor.scope,
42
- });
43
- }
44
- // 7. Return the body
45
- return response.body;
46
- }
47
- //# sourceMappingURL=call.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"call.js","sourceRoot":"","sources":["../../../src/client/call.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAOhD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,UAA0B,EAC1B,QAAgB,EAChB,OAAsB,EACtB,WAAwB,EACxB,UAAmC;IAEnC,+BAA+B;IAC/B,IAAI,OAAO,GAAG,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IAEvD,4DAA4D;IAC5D,MAAM,SAAS,GAAG,MAAM,gBAAgB,CACtC,EAAE,aAAa,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,EACpE,WAAW,EACX,UAAU,CACX,CAAA;IACD,OAAO,GAAG,SAAS,CAAC,OAAO,CAAA;IAE3B,sBAAsB;IACtB,IAAI,QAAQ,CAAA;IACZ,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,iDAAiD;QACjD,MAAM,UAAU,CACd,EAAE,aAAa,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAChF,WAAW,EACX,UAAU,CACX,CAAA;QACD,MAAM,GAAG,CAAA;IACX,CAAC;IAED,kFAAkF;IAClF,MAAM,gBAAgB,CACpB,EAAE,aAAa,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAC9E,WAAW,EACX,UAAU,CACX,CAAA;IAED,sFAAsF;IACtF,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QACpD,MAAM,IAAI,kBAAkB,CAAC;YAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,aAAa,EAAE,UAAU,CAAC,IAAI;YAC9B,KAAK,EAAE,UAAU,CAAC,KAAK;SACxB,CAAC,CAAA;IACJ,CAAC;IAED,qBAAqB;IACrB,OAAO,QAAQ,CAAC,IAAiB,CAAA;AACnC,CAAC"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,124 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { executeCall } from './call.js';
3
- import { ClientRequestError } from './errors.js';
4
- // ── helpers ───────────────────────────────────────────────
5
- function makeDescriptor(overrides) {
6
- return {
7
- name: 'GetUser',
8
- scope: 'users',
9
- path: '/users',
10
- method: 'GET',
11
- kind: 'rpc',
12
- params: { id: '42' },
13
- ...overrides,
14
- };
15
- }
16
- function makeAdapter(response) {
17
- return {
18
- request: vi.fn(async (_req) => ({
19
- status: 200,
20
- headers: {},
21
- body: { id: '42', name: 'Alice' },
22
- ...response,
23
- })),
24
- stream: vi.fn(async () => {
25
- throw new Error('stream not expected in call tests');
26
- }),
27
- };
28
- }
29
- // ── executeCall ───────────────────────────────────────────
30
- describe('executeCall', () => {
31
- it('calls adapter.request and returns body', async () => {
32
- const adapter = makeAdapter({ body: { id: '1', name: 'Bob' } });
33
- const result = await executeCall(makeDescriptor(), 'https://api.example.com', adapter, {}, undefined);
34
- expect(adapter.request).toHaveBeenCalledOnce();
35
- expect(result).toEqual({ id: '1', name: 'Bob' });
36
- });
37
- it('throws ClientRequestError on 4xx response', async () => {
38
- const adapter = makeAdapter({ status: 404, body: { message: 'Not Found' } });
39
- await expect(executeCall(makeDescriptor(), 'https://api.example.com', adapter, {}, undefined)).rejects.toThrow(ClientRequestError);
40
- });
41
- it('throws ClientRequestError on 5xx response', async () => {
42
- const adapter = makeAdapter({ status: 500, body: { message: 'Server Error' } });
43
- await expect(executeCall(makeDescriptor(), 'https://api.example.com', adapter, {}, undefined)).rejects.toThrow(ClientRequestError);
44
- });
45
- it('throws ClientRequestError on 199 response (below 200)', async () => {
46
- const adapter = makeAdapter({ status: 199, body: null });
47
- await expect(executeCall(makeDescriptor(), 'https://api.example.com', adapter, {}, undefined)).rejects.toThrow(ClientRequestError);
48
- });
49
- it('does not throw on 2xx boundary responses (200, 201, 299)', async () => {
50
- for (const status of [200, 201, 204, 299]) {
51
- const adapter = makeAdapter({ status, body: null });
52
- await expect(executeCall(makeDescriptor(), 'https://api.example.com', adapter, {}, undefined)).resolves.not.toThrow();
53
- }
54
- });
55
- it('runs onBeforeRequest before calling adapter (headers are modified)', async () => {
56
- const capturedHeaders = [];
57
- const adapter = {
58
- request: vi.fn(async (req) => {
59
- capturedHeaders.push(req.headers ?? {});
60
- return { status: 200, headers: {}, body: {} };
61
- }),
62
- stream: vi.fn(async () => { throw new Error('not expected'); }),
63
- };
64
- const globalHooks = {
65
- onBeforeRequest: (ctx) => ({
66
- ...ctx,
67
- request: {
68
- ...ctx.request,
69
- headers: { ...ctx.request.headers, 'x-auth': 'token-123' },
70
- },
71
- }),
72
- };
73
- await executeCall(makeDescriptor(), 'https://api.example.com', adapter, globalHooks, undefined);
74
- expect(capturedHeaders[0]?.['x-auth']).toBe('token-123');
75
- });
76
- it('runs onAfterResponse after adapter returns', async () => {
77
- const order = [];
78
- const adapter = {
79
- request: vi.fn(async () => {
80
- order.push('adapter');
81
- return { status: 200, headers: {}, body: {} };
82
- }),
83
- stream: vi.fn(async () => { throw new Error('not expected'); }),
84
- };
85
- const globalHooks = {
86
- onAfterResponse: () => { order.push('afterResponse'); },
87
- };
88
- await executeCall(makeDescriptor(), 'https://api.example.com', adapter, globalHooks, undefined);
89
- expect(order).toEqual(['adapter', 'afterResponse']);
90
- });
91
- it('does not throw when onAfterResponse swallows non-2xx by mutating status', async () => {
92
- const adapter = makeAdapter({ status: 401, body: { message: 'Unauthorized' } });
93
- const globalHooks = {
94
- onAfterResponse: (ctx) => {
95
- // Swallow the error by setting status to 200
96
- ctx.response.status = 200;
97
- },
98
- };
99
- await expect(executeCall(makeDescriptor(), 'https://api.example.com', adapter, globalHooks, undefined)).resolves.not.toThrow();
100
- });
101
- it('runs onError on adapter failure and re-throws', async () => {
102
- const adapterError = new Error('Network failure');
103
- const adapter = {
104
- request: vi.fn(async () => { throw adapterError; }),
105
- stream: vi.fn(async () => { throw new Error('not expected'); }),
106
- };
107
- const receivedErrors = [];
108
- const globalHooks = {
109
- onError: (ctx) => { receivedErrors.push(ctx.error); },
110
- };
111
- await expect(executeCall(makeDescriptor(), 'https://api.example.com', adapter, globalHooks, undefined)).rejects.toThrow('Network failure');
112
- expect(receivedErrors[0]).toBe(adapterError);
113
- });
114
- it('passes per-procedure hooks as local hooks', async () => {
115
- const adapter = makeAdapter();
116
- const localOrder = [];
117
- const localHooks = {
118
- onBeforeRequest: (ctx) => { localOrder.push('local-before'); return ctx; },
119
- };
120
- await executeCall(makeDescriptor(), 'https://api.example.com', adapter, {}, localHooks);
121
- expect(localOrder).toContain('local-before');
122
- });
123
- });
124
- //# sourceMappingURL=call.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"call.test.js","sourceRoot":"","sources":["../../../src/client/call.test.ts"],"names":[],"mappings":"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"}
@@ -1,25 +0,0 @@
1
- export declare class ClientRequestError extends Error {
2
- readonly name = "ClientRequestError";
3
- readonly status: number;
4
- readonly headers: Record<string, string>;
5
- readonly body: unknown;
6
- readonly procedureName: string;
7
- readonly scope: string;
8
- constructor(opts: {
9
- status: number;
10
- headers: Record<string, string>;
11
- body: unknown;
12
- procedureName: string;
13
- scope: string;
14
- });
15
- }
16
- export declare class ClientPathParamError extends Error {
17
- readonly name = "ClientPathParamError";
18
- constructor(param: string, path: string, procedureName: string);
19
- }
20
- export declare class ClientStreamError extends Error {
21
- readonly name = "ClientStreamError";
22
- readonly procedureName: string;
23
- readonly scope: string;
24
- constructor(message: string, procedureName: string, scope: string);
25
- }
@@ -1,33 +0,0 @@
1
- export class ClientRequestError extends Error {
2
- name = 'ClientRequestError';
3
- status;
4
- headers;
5
- body;
6
- procedureName;
7
- scope;
8
- constructor(opts) {
9
- super(`${opts.procedureName} (${opts.scope}) failed with status ${opts.status}`);
10
- this.status = opts.status;
11
- this.headers = opts.headers;
12
- this.body = opts.body;
13
- this.procedureName = opts.procedureName;
14
- this.scope = opts.scope;
15
- }
16
- }
17
- export class ClientPathParamError extends Error {
18
- name = 'ClientPathParamError';
19
- constructor(param, path, procedureName) {
20
- super(`Missing path parameter "${param}" in "${path}" for procedure ${procedureName}`);
21
- }
22
- }
23
- export class ClientStreamError extends Error {
24
- name = 'ClientStreamError';
25
- procedureName;
26
- scope;
27
- constructor(message, procedureName, scope) {
28
- super(message);
29
- this.procedureName = procedureName;
30
- this.scope = scope;
31
- }
32
- }
33
- //# sourceMappingURL=errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/client/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,GAAG,oBAAoB,CAAA;IAC3B,MAAM,CAAQ;IACd,OAAO,CAAwB;IAC/B,IAAI,CAAS;IACb,aAAa,CAAQ;IACrB,KAAK,CAAQ;IAEtB,YAAY,IAMX;QACC,KAAK,CAAC,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,KAAK,wBAAwB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QAChF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAA;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IACzB,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,IAAI,GAAG,sBAAsB,CAAA;IAEtC,YAAY,KAAa,EAAE,IAAY,EAAE,aAAqB;QAC5D,KAAK,CAAC,2BAA2B,KAAK,SAAS,IAAI,mBAAmB,aAAa,EAAE,CAAC,CAAA;IACxF,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,GAAG,mBAAmB,CAAA;IAC1B,aAAa,CAAQ;IACrB,KAAK,CAAQ;IAEtB,YAAY,OAAe,EAAE,aAAqB,EAAE,KAAa;QAC/D,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,41 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { ClientRequestError, ClientPathParamError, ClientStreamError } from './errors.js';
3
- describe('ClientRequestError', () => {
4
- it('includes status, headers, and body', () => {
5
- const err = new ClientRequestError({
6
- status: 401,
7
- headers: { 'x-request-id': 'abc' },
8
- body: { message: 'Unauthorized' },
9
- procedureName: 'GetUser',
10
- scope: 'users',
11
- });
12
- expect(err).toBeInstanceOf(Error);
13
- expect(err.name).toBe('ClientRequestError');
14
- expect(err.status).toBe(401);
15
- expect(err.headers['x-request-id']).toBe('abc');
16
- expect(err.body).toEqual({ message: 'Unauthorized' });
17
- expect(err.procedureName).toBe('GetUser');
18
- expect(err.scope).toBe('users');
19
- expect(err.message).toBe('GetUser (users) failed with status 401');
20
- });
21
- });
22
- describe('ClientPathParamError', () => {
23
- it('reports missing param', () => {
24
- const err = new ClientPathParamError('id', '/users/:id', 'GetUser');
25
- expect(err).toBeInstanceOf(Error);
26
- expect(err.name).toBe('ClientPathParamError');
27
- expect(err.message).toContain('id');
28
- expect(err.message).toContain('/users/:id');
29
- });
30
- });
31
- describe('ClientStreamError', () => {
32
- it('includes procedure context', () => {
33
- const err = new ClientStreamError('stream interrupted', 'Watch', 'events');
34
- expect(err).toBeInstanceOf(Error);
35
- expect(err.name).toBe('ClientStreamError');
36
- expect(err.procedureName).toBe('Watch');
37
- expect(err.scope).toBe('events');
38
- expect(err.message).toBe('stream interrupted');
39
- });
40
- });
41
- //# sourceMappingURL=errors.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../../../src/client/errors.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEzF,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,GAAG,GAAG,IAAI,kBAAkB,CAAC;YACjC,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE;YAClC,IAAI,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE;YACjC,aAAa,EAAE,SAAS;YACxB,KAAK,EAAE,OAAO;SACf,CAAC,CAAA;QACF,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;QAC3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC5B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAA;QACrD,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACzC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,GAAG,GAAG,IAAI,oBAAoB,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAA;QACnE,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;QAC7C,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,oBAAoB,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;QAC1E,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QACjC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAC1C,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAChC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1,12 +0,0 @@
1
- import type { ClientAdapter } from './types.js';
2
- export interface FetchAdapterConfig {
3
- headers?: Record<string, string>;
4
- }
5
- /**
6
- * Creates a fetch-based ClientAdapter.
7
- *
8
- * - `config.headers` are default headers applied to every request.
9
- * - Per-request headers override config headers (spread order).
10
- * - Works in Node.js 18+ and browsers (uses standard fetch + ReadableStream).
11
- */
12
- export declare function createFetchAdapter(config?: FetchAdapterConfig): ClientAdapter;