@redocly/client-generator 0.3.8 → 0.4.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 (617) hide show
  1. package/README.md +32 -54
  2. package/eject-assets/AGENTS.md +137 -0
  3. package/eject-assets/generators/cli/docs.ts +224 -0
  4. package/eject-assets/generators/cli/engine-source.ts +21 -0
  5. package/eject-assets/generators/cli/index.ts +90 -0
  6. package/eject-assets/generators/cli/render.ts +348 -0
  7. package/eject-assets/generators/go/client.ts +57 -0
  8. package/eject-assets/generators/go/descriptor.ts +41 -0
  9. package/eject-assets/generators/go/index.ts +336 -0
  10. package/eject-assets/generators/go/models.ts +179 -0
  11. package/eject-assets/generators/go/naming.ts +49 -0
  12. package/eject-assets/generators/go/operations.ts +296 -0
  13. package/eject-assets/generators/go/pagination.ts +194 -0
  14. package/eject-assets/generators/go/types.ts +60 -0
  15. package/eject-assets/generators/mock/faker.ts +214 -0
  16. package/eject-assets/generators/mock/index.ts +35 -0
  17. package/eject-assets/generators/mock/render.ts +282 -0
  18. package/eject-assets/generators/mock/sample.ts +316 -0
  19. package/eject-assets/generators/mock/values.ts +63 -0
  20. package/eject-assets/generators/php/client.ts +63 -0
  21. package/eject-assets/generators/php/descriptor.ts +58 -0
  22. package/eject-assets/generators/php/index.ts +237 -0
  23. package/eject-assets/generators/php/models.ts +275 -0
  24. package/eject-assets/generators/php/naming.ts +51 -0
  25. package/eject-assets/generators/php/operations.ts +232 -0
  26. package/eject-assets/generators/php/pagination.ts +133 -0
  27. package/eject-assets/generators/php/types.ts +148 -0
  28. package/eject-assets/generators/python/client.ts +123 -0
  29. package/eject-assets/generators/python/descriptor.ts +52 -0
  30. package/eject-assets/generators/python/index.ts +251 -0
  31. package/eject-assets/generators/python/models.ts +242 -0
  32. package/eject-assets/generators/python/naming.ts +46 -0
  33. package/eject-assets/generators/python/operations.ts +147 -0
  34. package/eject-assets/generators/python/pagination.ts +128 -0
  35. package/eject-assets/generators/python/types.ts +54 -0
  36. package/eject-assets/generators/swr/index.ts +37 -0
  37. package/eject-assets/generators/swr/render.ts +78 -0
  38. package/eject-assets/generators/tanstack-query/index.ts +48 -0
  39. package/eject-assets/generators/tanstack-query/render.ts +346 -0
  40. package/eject-assets/generators/transformers/index.ts +46 -0
  41. package/eject-assets/generators/transformers/render.ts +506 -0
  42. package/eject-assets/generators/typescript/banner.ts +35 -0
  43. package/eject-assets/generators/typescript/client.ts +254 -0
  44. package/eject-assets/generators/typescript/descriptor.ts +137 -0
  45. package/eject-assets/generators/typescript/index.ts +101 -0
  46. package/eject-assets/generators/typescript/inline-runtime.ts +135 -0
  47. package/eject-assets/generators/typescript/operation-signature.ts +62 -0
  48. package/eject-assets/generators/typescript/operation-types.ts +17 -0
  49. package/eject-assets/generators/typescript/operations.ts +524 -0
  50. package/eject-assets/generators/typescript/response-headers.ts +74 -0
  51. package/eject-assets/generators/typescript/type-guards.ts +159 -0
  52. package/eject-assets/generators/typescript/types.ts +172 -0
  53. package/eject-assets/generators/zod/index.ts +32 -0
  54. package/eject-assets/generators/zod/schemas.ts +456 -0
  55. package/eject-assets/skills/cli-generator/SKILL.md +121 -0
  56. package/eject-assets/skills/client-generators/SKILL.md +142 -0
  57. package/eject-assets/skills/go-generator/SKILL.md +96 -0
  58. package/eject-assets/skills/mock-generator/SKILL.md +50 -0
  59. package/eject-assets/skills/php-generator/SKILL.md +112 -0
  60. package/eject-assets/skills/python-generator/SKILL.md +110 -0
  61. package/eject-assets/skills/swr-generator/SKILL.md +50 -0
  62. package/eject-assets/skills/tanstack-query-generator/SKILL.md +55 -0
  63. package/eject-assets/skills/transformers-generator/SKILL.md +47 -0
  64. package/eject-assets/skills/typescript-generator/SKILL.md +95 -0
  65. package/eject-assets/skills/zod-generator/SKILL.md +54 -0
  66. package/lib/authoring/index.d.ts +11 -0
  67. package/lib/authoring/index.d.ts.map +1 -0
  68. package/lib/authoring/index.js +42 -0
  69. package/lib/authoring/index.js.map +1 -0
  70. package/lib/authoring/naming.d.ts +34 -0
  71. package/lib/authoring/naming.d.ts.map +1 -0
  72. package/lib/authoring/naming.js +104 -0
  73. package/lib/authoring/naming.js.map +1 -0
  74. package/lib/authoring/operation.d.ts +47 -0
  75. package/lib/authoring/operation.d.ts.map +1 -0
  76. package/lib/authoring/operation.js +86 -0
  77. package/lib/authoring/operation.js.map +1 -0
  78. package/lib/authoring/options.d.ts +9 -0
  79. package/lib/authoring/options.d.ts.map +1 -0
  80. package/lib/authoring/options.js +5 -0
  81. package/lib/authoring/options.js.map +1 -0
  82. package/lib/authoring/pagination.d.ts +19 -0
  83. package/lib/authoring/pagination.d.ts.map +1 -0
  84. package/lib/authoring/pagination.js +45 -0
  85. package/lib/authoring/pagination.js.map +1 -0
  86. package/lib/authoring/printer.d.ts +16 -0
  87. package/lib/authoring/printer.d.ts.map +1 -0
  88. package/lib/authoring/printer.js +36 -0
  89. package/lib/authoring/printer.js.map +1 -0
  90. package/lib/authoring/reference-page.d.ts +31 -0
  91. package/lib/authoring/reference-page.d.ts.map +1 -0
  92. package/lib/authoring/reference-page.js +160 -0
  93. package/lib/authoring/reference-page.js.map +1 -0
  94. package/lib/authoring/schema.d.ts +51 -0
  95. package/lib/authoring/schema.d.ts.map +1 -0
  96. package/lib/authoring/schema.js +190 -0
  97. package/lib/authoring/schema.js.map +1 -0
  98. package/lib/cli-contract.d.ts +126 -0
  99. package/lib/cli-contract.d.ts.map +1 -0
  100. package/lib/cli-contract.js +25 -0
  101. package/lib/cli-contract.js.map +1 -0
  102. package/lib/{emitters/wrapper-support.d.ts → contracts/typescript.d.ts} +13 -24
  103. package/lib/contracts/typescript.d.ts.map +1 -0
  104. package/lib/contracts/typescript.js +87 -0
  105. package/lib/contracts/typescript.js.map +1 -0
  106. package/lib/generate.d.ts +10 -10
  107. package/lib/generate.d.ts.map +1 -1
  108. package/lib/generate.js +25 -106
  109. package/lib/generate.js.map +1 -1
  110. package/lib/generators/cli/docs.d.ts +19 -0
  111. package/lib/generators/cli/docs.d.ts.map +1 -0
  112. package/lib/generators/cli/docs.js +187 -0
  113. package/lib/generators/cli/docs.js.map +1 -0
  114. package/lib/generators/cli/engine-source.d.ts +5 -0
  115. package/lib/generators/cli/engine-source.d.ts.map +1 -0
  116. package/lib/generators/cli/engine-source.js +12 -0
  117. package/lib/generators/cli/engine-source.js.map +1 -0
  118. package/lib/generators/cli/index.d.ts +18 -0
  119. package/lib/generators/cli/index.d.ts.map +1 -0
  120. package/lib/generators/cli/index.js +67 -0
  121. package/lib/generators/cli/index.js.map +1 -0
  122. package/lib/generators/cli/render.d.ts +39 -0
  123. package/lib/generators/cli/render.d.ts.map +1 -0
  124. package/lib/generators/cli/render.js +281 -0
  125. package/lib/generators/cli/render.js.map +1 -0
  126. package/lib/generators/cli/runtime/cli.d.ts +42 -0
  127. package/lib/generators/cli/runtime/cli.d.ts.map +1 -0
  128. package/lib/generators/cli/runtime/cli.js +582 -0
  129. package/lib/generators/cli/runtime/cli.js.map +1 -0
  130. package/lib/generators/compatibility.d.ts +10 -0
  131. package/lib/generators/compatibility.d.ts.map +1 -0
  132. package/lib/generators/compatibility.js +45 -0
  133. package/lib/generators/compatibility.js.map +1 -0
  134. package/lib/generators/go/client.d.ts +5 -0
  135. package/lib/generators/go/client.d.ts.map +1 -0
  136. package/lib/generators/go/client.js +34 -0
  137. package/lib/generators/go/client.js.map +1 -0
  138. package/lib/generators/go/descriptor.d.ts +6 -0
  139. package/lib/generators/go/descriptor.d.ts.map +1 -0
  140. package/lib/generators/go/descriptor.js +26 -0
  141. package/lib/generators/go/descriptor.js.map +1 -0
  142. package/lib/generators/go/index.d.ts +14 -0
  143. package/lib/generators/go/index.d.ts.map +1 -0
  144. package/lib/generators/go/index.js +240 -0
  145. package/lib/generators/go/index.js.map +1 -0
  146. package/lib/generators/go/models.d.ts +4 -0
  147. package/lib/generators/go/models.d.ts.map +1 -0
  148. package/lib/generators/go/models.js +125 -0
  149. package/lib/generators/go/models.js.map +1 -0
  150. package/lib/generators/go/naming.d.ts +15 -0
  151. package/lib/generators/go/naming.d.ts.map +1 -0
  152. package/lib/generators/go/naming.js +36 -0
  153. package/lib/generators/go/naming.js.map +1 -0
  154. package/lib/generators/go/operations.d.ts +16 -0
  155. package/lib/generators/go/operations.d.ts.map +1 -0
  156. package/lib/generators/go/operations.js +200 -0
  157. package/lib/generators/go/operations.js.map +1 -0
  158. package/lib/generators/go/pagination.d.ts +5 -0
  159. package/lib/generators/go/pagination.d.ts.map +1 -0
  160. package/lib/generators/go/pagination.js +93 -0
  161. package/lib/generators/go/pagination.js.map +1 -0
  162. package/lib/generators/go/types.d.ts +4 -0
  163. package/lib/generators/go/types.d.ts.map +1 -0
  164. package/lib/generators/go/types.js +48 -0
  165. package/lib/generators/go/types.js.map +1 -0
  166. package/lib/generators/index.d.ts +2 -3
  167. package/lib/generators/index.d.ts.map +1 -1
  168. package/lib/generators/index.js +31 -53
  169. package/lib/generators/index.js.map +1 -1
  170. package/lib/generators/meta.d.ts +13 -0
  171. package/lib/generators/meta.d.ts.map +1 -0
  172. package/lib/generators/meta.js +157 -0
  173. package/lib/generators/meta.js.map +1 -0
  174. package/lib/{emitters → generators/mock}/faker.d.ts +4 -5
  175. package/lib/generators/mock/faker.d.ts.map +1 -0
  176. package/lib/generators/mock/faker.js +180 -0
  177. package/lib/generators/mock/faker.js.map +1 -0
  178. package/lib/generators/{mock.d.ts → mock/index.d.ts} +2 -2
  179. package/lib/generators/mock/index.d.ts.map +1 -0
  180. package/lib/generators/{mock.js → mock/index.js} +8 -8
  181. package/lib/generators/mock/index.js.map +1 -0
  182. package/lib/{emitters/mock.d.ts → generators/mock/render.d.ts} +2 -3
  183. package/lib/generators/mock/render.d.ts.map +1 -0
  184. package/lib/generators/mock/render.js +228 -0
  185. package/lib/generators/mock/render.js.map +1 -0
  186. package/lib/{emitters → generators/mock}/sample.d.ts +1 -2
  187. package/lib/generators/mock/sample.d.ts.map +1 -0
  188. package/lib/generators/mock/sample.js.map +1 -0
  189. package/lib/generators/mock/values.d.ts +33 -0
  190. package/lib/generators/mock/values.d.ts.map +1 -0
  191. package/lib/generators/mock/values.js +46 -0
  192. package/lib/generators/mock/values.js.map +1 -0
  193. package/lib/generators/options.d.ts +7 -0
  194. package/lib/generators/options.d.ts.map +1 -0
  195. package/lib/generators/options.js +74 -0
  196. package/lib/generators/options.js.map +1 -0
  197. package/lib/generators/php/client.d.ts +5 -0
  198. package/lib/generators/php/client.d.ts.map +1 -0
  199. package/lib/generators/php/client.js +38 -0
  200. package/lib/generators/php/client.js.map +1 -0
  201. package/lib/generators/php/descriptor.d.ts +7 -0
  202. package/lib/generators/php/descriptor.d.ts.map +1 -0
  203. package/lib/generators/php/descriptor.js +42 -0
  204. package/lib/generators/php/descriptor.js.map +1 -0
  205. package/lib/generators/php/index.d.ts +14 -0
  206. package/lib/generators/php/index.d.ts.map +1 -0
  207. package/lib/generators/php/index.js +166 -0
  208. package/lib/generators/php/index.js.map +1 -0
  209. package/lib/generators/php/models.d.ts +8 -0
  210. package/lib/generators/php/models.d.ts.map +1 -0
  211. package/lib/generators/php/models.js +200 -0
  212. package/lib/generators/php/models.js.map +1 -0
  213. package/lib/generators/php/naming.d.ts +16 -0
  214. package/lib/generators/php/naming.d.ts.map +1 -0
  215. package/lib/generators/php/naming.js +31 -0
  216. package/lib/generators/php/naming.js.map +1 -0
  217. package/lib/generators/php/operations.d.ts +21 -0
  218. package/lib/generators/php/operations.d.ts.map +1 -0
  219. package/lib/generators/php/operations.js +156 -0
  220. package/lib/generators/php/operations.js.map +1 -0
  221. package/lib/generators/php/pagination.d.ts +5 -0
  222. package/lib/generators/php/pagination.d.ts.map +1 -0
  223. package/lib/generators/php/pagination.js +68 -0
  224. package/lib/generators/php/pagination.js.map +1 -0
  225. package/lib/generators/php/types.d.ts +27 -0
  226. package/lib/generators/php/types.d.ts.map +1 -0
  227. package/lib/generators/php/types.js +128 -0
  228. package/lib/generators/php/types.js.map +1 -0
  229. package/lib/generators/python/client.d.ts +6 -0
  230. package/lib/generators/python/client.d.ts.map +1 -0
  231. package/lib/generators/python/client.js +80 -0
  232. package/lib/generators/python/client.js.map +1 -0
  233. package/lib/generators/python/descriptor.d.ts +9 -0
  234. package/lib/generators/python/descriptor.d.ts.map +1 -0
  235. package/lib/generators/python/descriptor.js +38 -0
  236. package/lib/generators/python/descriptor.js.map +1 -0
  237. package/lib/generators/python/index.d.ts +15 -0
  238. package/lib/generators/python/index.d.ts.map +1 -0
  239. package/lib/generators/python/index.js +197 -0
  240. package/lib/generators/python/index.js.map +1 -0
  241. package/lib/generators/python/models.d.ts +31 -0
  242. package/lib/generators/python/models.d.ts.map +1 -0
  243. package/lib/generators/python/models.js +203 -0
  244. package/lib/generators/python/models.js.map +1 -0
  245. package/lib/generators/python/naming.d.ts +22 -0
  246. package/lib/generators/python/naming.d.ts.map +1 -0
  247. package/lib/generators/python/naming.js +28 -0
  248. package/lib/generators/python/naming.js.map +1 -0
  249. package/lib/generators/python/operations.d.ts +4 -0
  250. package/lib/generators/python/operations.d.ts.map +1 -0
  251. package/lib/generators/python/operations.js +108 -0
  252. package/lib/generators/python/operations.js.map +1 -0
  253. package/lib/generators/python/pagination.d.ts +5 -0
  254. package/lib/generators/python/pagination.d.ts.map +1 -0
  255. package/lib/generators/python/pagination.js +95 -0
  256. package/lib/generators/python/pagination.js.map +1 -0
  257. package/lib/generators/python/types.d.ts +4 -0
  258. package/lib/generators/python/types.d.ts.map +1 -0
  259. package/lib/generators/python/types.js +45 -0
  260. package/lib/generators/python/types.js.map +1 -0
  261. package/lib/generators/resolve.d.ts.map +1 -1
  262. package/lib/generators/resolve.js +92 -13
  263. package/lib/generators/resolve.js.map +1 -1
  264. package/lib/generators/{swr.d.ts → swr/index.d.ts} +3 -3
  265. package/lib/generators/swr/index.d.ts.map +1 -0
  266. package/lib/generators/{swr.js → swr/index.js} +7 -10
  267. package/lib/generators/swr/index.js.map +1 -0
  268. package/lib/{emitters/swr.d.ts → generators/swr/render.d.ts} +2 -4
  269. package/lib/generators/swr/render.d.ts.map +1 -0
  270. package/lib/generators/swr/render.js +57 -0
  271. package/lib/generators/swr/render.js.map +1 -0
  272. package/lib/generators/{tanstack-query.d.ts → tanstack-query/index.d.ts} +3 -3
  273. package/lib/generators/tanstack-query/index.d.ts.map +1 -0
  274. package/lib/generators/{tanstack-query.js → tanstack-query/index.js} +11 -10
  275. package/lib/generators/tanstack-query/index.js.map +1 -0
  276. package/lib/{emitters/tanstack-query.d.ts → generators/tanstack-query/render.d.ts} +6 -5
  277. package/lib/generators/tanstack-query/render.d.ts.map +1 -0
  278. package/lib/{emitters/tanstack-query.js → generators/tanstack-query/render.js} +33 -21
  279. package/lib/generators/tanstack-query/render.js.map +1 -0
  280. package/lib/generators/{transformers.d.ts → transformers/index.d.ts} +2 -2
  281. package/lib/generators/transformers/index.d.ts.map +1 -0
  282. package/lib/generators/{transformers.js → transformers/index.js} +11 -8
  283. package/lib/generators/transformers/index.js.map +1 -0
  284. package/lib/{emitters/transformers.d.ts → generators/transformers/render.d.ts} +2 -2
  285. package/lib/generators/transformers/render.d.ts.map +1 -0
  286. package/lib/{emitters/transformers.js → generators/transformers/render.js} +125 -165
  287. package/lib/generators/transformers/render.js.map +1 -0
  288. package/lib/generators/types.d.ts +190 -12
  289. package/lib/generators/types.d.ts.map +1 -1
  290. package/lib/generators/typescript/banner.d.ts +12 -0
  291. package/lib/generators/typescript/banner.d.ts.map +1 -0
  292. package/lib/{emitters/emit-options.js → generators/typescript/banner.js} +2 -3
  293. package/lib/generators/typescript/banner.js.map +1 -0
  294. package/lib/generators/typescript/client.d.ts +25 -0
  295. package/lib/generators/typescript/client.d.ts.map +1 -0
  296. package/lib/generators/typescript/client.js +207 -0
  297. package/lib/generators/typescript/client.js.map +1 -0
  298. package/lib/generators/typescript/descriptor.d.ts +11 -0
  299. package/lib/generators/typescript/descriptor.d.ts.map +1 -0
  300. package/lib/generators/typescript/descriptor.js +97 -0
  301. package/lib/generators/typescript/descriptor.js.map +1 -0
  302. package/lib/generators/typescript/index.d.ts +20 -0
  303. package/lib/generators/typescript/index.d.ts.map +1 -0
  304. package/lib/generators/typescript/index.js +80 -0
  305. package/lib/generators/typescript/index.js.map +1 -0
  306. package/lib/generators/typescript/inline-runtime.d.ts +21 -0
  307. package/lib/generators/typescript/inline-runtime.d.ts.map +1 -0
  308. package/lib/generators/typescript/inline-runtime.js +114 -0
  309. package/lib/generators/typescript/inline-runtime.js.map +1 -0
  310. package/lib/generators/typescript/operation-signature.d.ts +23 -0
  311. package/lib/generators/typescript/operation-signature.d.ts.map +1 -0
  312. package/lib/generators/typescript/operation-signature.js +41 -0
  313. package/lib/generators/typescript/operation-signature.js.map +1 -0
  314. package/lib/generators/typescript/operation-types.d.ts +9 -0
  315. package/lib/generators/typescript/operation-types.d.ts.map +1 -0
  316. package/lib/generators/typescript/operation-types.js +11 -0
  317. package/lib/generators/typescript/operation-types.js.map +1 -0
  318. package/lib/generators/typescript/operations.d.ts +60 -0
  319. package/lib/generators/typescript/operations.d.ts.map +1 -0
  320. package/lib/generators/typescript/operations.js +386 -0
  321. package/lib/generators/typescript/operations.js.map +1 -0
  322. package/lib/generators/typescript/response-headers.d.ts +12 -0
  323. package/lib/generators/typescript/response-headers.d.ts.map +1 -0
  324. package/lib/generators/typescript/response-headers.js +40 -0
  325. package/lib/generators/typescript/response-headers.js.map +1 -0
  326. package/lib/generators/typescript/runtime/auth.d.ts.map +1 -0
  327. package/lib/generators/typescript/runtime/auth.js.map +1 -0
  328. package/lib/{runtime → generators/typescript/runtime}/create-client.d.ts +7 -2
  329. package/lib/generators/typescript/runtime/create-client.d.ts.map +1 -0
  330. package/lib/{runtime → generators/typescript/runtime}/create-client.js +84 -30
  331. package/lib/generators/typescript/runtime/create-client.js.map +1 -0
  332. package/lib/generators/typescript/runtime/errors.d.ts.map +1 -0
  333. package/lib/generators/typescript/runtime/errors.js.map +1 -0
  334. package/lib/generators/typescript/runtime/index.d.ts.map +1 -0
  335. package/lib/generators/typescript/runtime/index.js.map +1 -0
  336. package/lib/generators/typescript/runtime/multipart.d.ts.map +1 -0
  337. package/lib/generators/typescript/runtime/multipart.js.map +1 -0
  338. package/lib/{runtime → generators/typescript/runtime}/paginate.d.ts +2 -2
  339. package/lib/generators/typescript/runtime/paginate.d.ts.map +1 -0
  340. package/lib/{runtime → generators/typescript/runtime}/paginate.js +12 -12
  341. package/lib/generators/typescript/runtime/paginate.js.map +1 -0
  342. package/lib/generators/typescript/runtime/parse.d.ts.map +1 -0
  343. package/lib/generators/typescript/runtime/parse.js.map +1 -0
  344. package/lib/generators/typescript/runtime/retry.d.ts.map +1 -0
  345. package/lib/generators/typescript/runtime/retry.js.map +1 -0
  346. package/lib/generators/typescript/runtime/send.d.ts.map +1 -0
  347. package/lib/generators/typescript/runtime/send.js.map +1 -0
  348. package/lib/generators/typescript/runtime/setup.d.ts.map +1 -0
  349. package/lib/generators/typescript/runtime/setup.js.map +1 -0
  350. package/lib/generators/typescript/runtime/sse.d.ts.map +1 -0
  351. package/lib/generators/typescript/runtime/sse.js.map +1 -0
  352. package/lib/{runtime → generators/typescript/runtime}/types.d.ts +17 -95
  353. package/lib/generators/typescript/runtime/types.d.ts.map +1 -0
  354. package/lib/generators/typescript/runtime/types.js.map +1 -0
  355. package/lib/generators/typescript/runtime/url.d.ts.map +1 -0
  356. package/lib/generators/typescript/runtime/url.js.map +1 -0
  357. package/lib/generators/typescript/type-guards.d.ts +4 -0
  358. package/lib/generators/typescript/type-guards.d.ts.map +1 -0
  359. package/lib/{emitters → generators/typescript}/type-guards.js +18 -52
  360. package/lib/generators/typescript/type-guards.js.map +1 -0
  361. package/lib/generators/typescript/types.d.ts +8 -0
  362. package/lib/generators/typescript/types.d.ts.map +1 -0
  363. package/lib/generators/typescript/types.js +132 -0
  364. package/lib/generators/typescript/types.js.map +1 -0
  365. package/lib/generators/{zod.d.ts → zod/index.d.ts} +2 -2
  366. package/lib/generators/zod/index.d.ts.map +1 -0
  367. package/lib/generators/{zod.js → zod/index.js} +5 -7
  368. package/lib/generators/zod/index.js.map +1 -0
  369. package/lib/{emitters/zod.d.ts → generators/zod/schemas.d.ts} +4 -5
  370. package/lib/generators/zod/schemas.d.ts.map +1 -0
  371. package/lib/{emitters/zod.js → generators/zod/schemas.js} +118 -154
  372. package/lib/generators/zod/schemas.js.map +1 -0
  373. package/lib/index.d.ts +8 -3
  374. package/lib/index.d.ts.map +1 -1
  375. package/lib/index.js +18 -11
  376. package/lib/index.js.map +1 -1
  377. package/lib/intermediate-representation/build.d.ts +8 -1
  378. package/lib/intermediate-representation/build.d.ts.map +1 -1
  379. package/lib/intermediate-representation/build.js +59 -4
  380. package/lib/intermediate-representation/build.js.map +1 -1
  381. package/lib/intermediate-representation/model.d.ts +26 -1
  382. package/lib/intermediate-representation/model.d.ts.map +1 -1
  383. package/lib/intermediate-representation/model.js.map +1 -1
  384. package/lib/intermediate-representation/sanitize-identifiers.d.ts +1 -10
  385. package/lib/intermediate-representation/sanitize-identifiers.d.ts.map +1 -1
  386. package/lib/intermediate-representation/sanitize-identifiers.js +37 -38
  387. package/lib/intermediate-representation/sanitize-identifiers.js.map +1 -1
  388. package/lib/{emitters/pagination.d.ts → pagination.d.ts} +39 -15
  389. package/lib/pagination.d.ts.map +1 -0
  390. package/lib/{emitters/pagination.js → pagination.js} +13 -52
  391. package/lib/pagination.js.map +1 -0
  392. package/lib/pipeline.d.ts +17 -0
  393. package/lib/pipeline.d.ts.map +1 -0
  394. package/lib/pipeline.js +244 -0
  395. package/lib/pipeline.js.map +1 -0
  396. package/lib/plugin.d.ts +4 -4
  397. package/lib/plugin.d.ts.map +1 -1
  398. package/lib/plugin.js +12 -9
  399. package/lib/plugin.js.map +1 -1
  400. package/lib/printers/go.d.ts +33 -0
  401. package/lib/printers/go.d.ts.map +1 -0
  402. package/lib/printers/go.js +209 -0
  403. package/lib/printers/go.js.map +1 -0
  404. package/lib/printers/index.d.ts +5 -0
  405. package/lib/printers/index.d.ts.map +1 -0
  406. package/lib/printers/index.js +9 -0
  407. package/lib/printers/index.js.map +1 -0
  408. package/lib/printers/php.d.ts +21 -0
  409. package/lib/printers/php.d.ts.map +1 -0
  410. package/lib/printers/php.js +68 -0
  411. package/lib/printers/php.js.map +1 -0
  412. package/lib/printers/python.d.ts +31 -0
  413. package/lib/printers/python.d.ts.map +1 -0
  414. package/lib/printers/python.js +101 -0
  415. package/lib/printers/python.js.map +1 -0
  416. package/lib/printers/typescript.d.ts +82 -0
  417. package/lib/printers/typescript.d.ts.map +1 -0
  418. package/lib/printers/typescript.js +268 -0
  419. package/lib/printers/typescript.js.map +1 -0
  420. package/lib/reserved-names.d.ts +8 -0
  421. package/lib/reserved-names.d.ts.map +1 -0
  422. package/lib/{emitters/reserved-names.js → reserved-names.js} +16 -27
  423. package/lib/reserved-names.js.map +1 -0
  424. package/lib/runtime-contract.d.ts +62 -2
  425. package/lib/runtime-contract.d.ts.map +1 -1
  426. package/lib/runtime-contract.js +3 -3
  427. package/lib/runtime-contract.js.map +1 -1
  428. package/lib/runtime-sources/go.d.ts +2 -0
  429. package/lib/runtime-sources/go.d.ts.map +1 -0
  430. package/lib/runtime-sources/go.js +3 -0
  431. package/lib/runtime-sources/go.js.map +1 -0
  432. package/lib/runtime-sources/php.d.ts +2 -0
  433. package/lib/runtime-sources/php.d.ts.map +1 -0
  434. package/lib/runtime-sources/php.js +3 -0
  435. package/lib/runtime-sources/php.js.map +1 -0
  436. package/lib/runtime-sources/python.d.ts +12 -0
  437. package/lib/runtime-sources/python.d.ts.map +1 -0
  438. package/lib/runtime-sources/python.js +12 -0
  439. package/lib/runtime-sources/python.js.map +1 -0
  440. package/lib/runtime-sources/typescript.d.ts +36 -0
  441. package/lib/runtime-sources/typescript.d.ts.map +1 -0
  442. package/lib/runtime-sources/typescript.js +152 -0
  443. package/lib/runtime-sources/typescript.js.map +1 -0
  444. package/lib/runtime-sources.d.ts +5 -0
  445. package/lib/runtime-sources.d.ts.map +1 -0
  446. package/lib/runtime-sources.js +10 -0
  447. package/lib/runtime-sources.js.map +1 -0
  448. package/lib/setup-bake.d.ts.map +1 -0
  449. package/lib/{emitters/setup-bake.js → setup-bake.js} +11 -2
  450. package/lib/setup-bake.js.map +1 -0
  451. package/lib/types.d.ts +38 -8
  452. package/lib/types.d.ts.map +1 -1
  453. package/package.json +40 -4
  454. package/lib/emitters/auth.d.ts +0 -14
  455. package/lib/emitters/auth.d.ts.map +0 -1
  456. package/lib/emitters/auth.js +0 -30
  457. package/lib/emitters/auth.js.map +0 -1
  458. package/lib/emitters/client-assembly.d.ts +0 -15
  459. package/lib/emitters/client-assembly.d.ts.map +0 -1
  460. package/lib/emitters/client-assembly.js +0 -358
  461. package/lib/emitters/client-assembly.js.map +0 -1
  462. package/lib/emitters/descriptor.d.ts +0 -22
  463. package/lib/emitters/descriptor.d.ts.map +0 -1
  464. package/lib/emitters/descriptor.js +0 -199
  465. package/lib/emitters/descriptor.js.map +0 -1
  466. package/lib/emitters/emit-options.d.ts +0 -67
  467. package/lib/emitters/emit-options.d.ts.map +0 -1
  468. package/lib/emitters/emit-options.js.map +0 -1
  469. package/lib/emitters/faker.d.ts.map +0 -1
  470. package/lib/emitters/faker.js +0 -221
  471. package/lib/emitters/faker.js.map +0 -1
  472. package/lib/emitters/identifier.d.ts +0 -34
  473. package/lib/emitters/identifier.d.ts.map +0 -1
  474. package/lib/emitters/identifier.js +0 -104
  475. package/lib/emitters/identifier.js.map +0 -1
  476. package/lib/emitters/inline-runtime.d.ts +0 -11
  477. package/lib/emitters/inline-runtime.d.ts.map +0 -1
  478. package/lib/emitters/inline-runtime.js +0 -99
  479. package/lib/emitters/inline-runtime.js.map +0 -1
  480. package/lib/emitters/jsdoc.d.ts +0 -9
  481. package/lib/emitters/jsdoc.d.ts.map +0 -1
  482. package/lib/emitters/jsdoc.js +0 -83
  483. package/lib/emitters/jsdoc.js.map +0 -1
  484. package/lib/emitters/mock.d.ts.map +0 -1
  485. package/lib/emitters/mock.js +0 -265
  486. package/lib/emitters/mock.js.map +0 -1
  487. package/lib/emitters/operation-aliases.d.ts +0 -27
  488. package/lib/emitters/operation-aliases.d.ts.map +0 -1
  489. package/lib/emitters/operation-aliases.js +0 -150
  490. package/lib/emitters/operation-aliases.js.map +0 -1
  491. package/lib/emitters/operation-signature.d.ts +0 -24
  492. package/lib/emitters/operation-signature.d.ts.map +0 -1
  493. package/lib/emitters/operation-signature.js +0 -42
  494. package/lib/emitters/operation-signature.js.map +0 -1
  495. package/lib/emitters/operation-types.d.ts +0 -32
  496. package/lib/emitters/operation-types.d.ts.map +0 -1
  497. package/lib/emitters/operation-types.js +0 -117
  498. package/lib/emitters/operation-types.js.map +0 -1
  499. package/lib/emitters/operations.d.ts +0 -41
  500. package/lib/emitters/operations.d.ts.map +0 -1
  501. package/lib/emitters/operations.js +0 -35
  502. package/lib/emitters/operations.js.map +0 -1
  503. package/lib/emitters/pagination.d.ts.map +0 -1
  504. package/lib/emitters/pagination.js.map +0 -1
  505. package/lib/emitters/reserved-names.d.ts +0 -5
  506. package/lib/emitters/reserved-names.d.ts.map +0 -1
  507. package/lib/emitters/reserved-names.js.map +0 -1
  508. package/lib/emitters/response-headers.d.ts +0 -14
  509. package/lib/emitters/response-headers.d.ts.map +0 -1
  510. package/lib/emitters/response-headers.js +0 -91
  511. package/lib/emitters/response-headers.js.map +0 -1
  512. package/lib/emitters/runtime-sources.d.ts +0 -16
  513. package/lib/emitters/runtime-sources.d.ts.map +0 -1
  514. package/lib/emitters/runtime-sources.js +0 -16
  515. package/lib/emitters/runtime-sources.js.map +0 -1
  516. package/lib/emitters/sample.d.ts.map +0 -1
  517. package/lib/emitters/sample.js.map +0 -1
  518. package/lib/emitters/setup-bake.d.ts.map +0 -1
  519. package/lib/emitters/setup-bake.js.map +0 -1
  520. package/lib/emitters/sse.d.ts +0 -10
  521. package/lib/emitters/sse.d.ts.map +0 -1
  522. package/lib/emitters/sse.js +0 -46
  523. package/lib/emitters/sse.js.map +0 -1
  524. package/lib/emitters/support.d.ts +0 -18
  525. package/lib/emitters/support.d.ts.map +0 -1
  526. package/lib/emitters/support.js +0 -37
  527. package/lib/emitters/support.js.map +0 -1
  528. package/lib/emitters/swr.d.ts.map +0 -1
  529. package/lib/emitters/swr.js +0 -88
  530. package/lib/emitters/swr.js.map +0 -1
  531. package/lib/emitters/tanstack-query.d.ts.map +0 -1
  532. package/lib/emitters/tanstack-query.js.map +0 -1
  533. package/lib/emitters/transformers.d.ts.map +0 -1
  534. package/lib/emitters/transformers.js.map +0 -1
  535. package/lib/emitters/ts.d.ts +0 -42
  536. package/lib/emitters/ts.d.ts.map +0 -1
  537. package/lib/emitters/ts.js +0 -116
  538. package/lib/emitters/ts.js.map +0 -1
  539. package/lib/emitters/type-guards.d.ts +0 -21
  540. package/lib/emitters/type-guards.d.ts.map +0 -1
  541. package/lib/emitters/type-guards.js.map +0 -1
  542. package/lib/emitters/types.d.ts +0 -15
  543. package/lib/emitters/types.d.ts.map +0 -1
  544. package/lib/emitters/types.js +0 -125
  545. package/lib/emitters/types.js.map +0 -1
  546. package/lib/emitters/wrapper-support.d.ts.map +0 -1
  547. package/lib/emitters/wrapper-support.js +0 -127
  548. package/lib/emitters/wrapper-support.js.map +0 -1
  549. package/lib/emitters/zod.d.ts.map +0 -1
  550. package/lib/emitters/zod.js.map +0 -1
  551. package/lib/generators/anchor.d.ts +0 -9
  552. package/lib/generators/anchor.d.ts.map +0 -1
  553. package/lib/generators/anchor.js +0 -10
  554. package/lib/generators/anchor.js.map +0 -1
  555. package/lib/generators/mock.d.ts.map +0 -1
  556. package/lib/generators/mock.js.map +0 -1
  557. package/lib/generators/sdk.d.ts +0 -12
  558. package/lib/generators/sdk.d.ts.map +0 -1
  559. package/lib/generators/sdk.js +0 -26
  560. package/lib/generators/sdk.js.map +0 -1
  561. package/lib/generators/swr.d.ts.map +0 -1
  562. package/lib/generators/swr.js.map +0 -1
  563. package/lib/generators/tanstack-query.d.ts.map +0 -1
  564. package/lib/generators/tanstack-query.js.map +0 -1
  565. package/lib/generators/transformers.d.ts.map +0 -1
  566. package/lib/generators/transformers.js.map +0 -1
  567. package/lib/generators/zod.d.ts.map +0 -1
  568. package/lib/generators/zod.js.map +0 -1
  569. package/lib/runtime/auth.d.ts.map +0 -1
  570. package/lib/runtime/auth.js.map +0 -1
  571. package/lib/runtime/create-client.d.ts.map +0 -1
  572. package/lib/runtime/create-client.js.map +0 -1
  573. package/lib/runtime/errors.d.ts.map +0 -1
  574. package/lib/runtime/errors.js.map +0 -1
  575. package/lib/runtime/index.d.ts.map +0 -1
  576. package/lib/runtime/index.js.map +0 -1
  577. package/lib/runtime/multipart.d.ts.map +0 -1
  578. package/lib/runtime/multipart.js.map +0 -1
  579. package/lib/runtime/paginate.d.ts.map +0 -1
  580. package/lib/runtime/paginate.js.map +0 -1
  581. package/lib/runtime/parse.d.ts.map +0 -1
  582. package/lib/runtime/parse.js.map +0 -1
  583. package/lib/runtime/retry.d.ts.map +0 -1
  584. package/lib/runtime/retry.js.map +0 -1
  585. package/lib/runtime/send.d.ts.map +0 -1
  586. package/lib/runtime/send.js.map +0 -1
  587. package/lib/runtime/setup.d.ts.map +0 -1
  588. package/lib/runtime/setup.js.map +0 -1
  589. package/lib/runtime/sse.d.ts.map +0 -1
  590. package/lib/runtime/sse.js.map +0 -1
  591. package/lib/runtime/types.d.ts.map +0 -1
  592. package/lib/runtime/types.js.map +0 -1
  593. package/lib/runtime/url.d.ts.map +0 -1
  594. package/lib/runtime/url.js.map +0 -1
  595. /package/lib/{emitters → generators/mock}/sample.js +0 -0
  596. /package/lib/{runtime → generators/typescript/runtime}/auth.d.ts +0 -0
  597. /package/lib/{runtime → generators/typescript/runtime}/auth.js +0 -0
  598. /package/lib/{runtime → generators/typescript/runtime}/errors.d.ts +0 -0
  599. /package/lib/{runtime → generators/typescript/runtime}/errors.js +0 -0
  600. /package/lib/{runtime → generators/typescript/runtime}/index.d.ts +0 -0
  601. /package/lib/{runtime → generators/typescript/runtime}/index.js +0 -0
  602. /package/lib/{runtime → generators/typescript/runtime}/multipart.d.ts +0 -0
  603. /package/lib/{runtime → generators/typescript/runtime}/multipart.js +0 -0
  604. /package/lib/{runtime → generators/typescript/runtime}/parse.d.ts +0 -0
  605. /package/lib/{runtime → generators/typescript/runtime}/parse.js +0 -0
  606. /package/lib/{runtime → generators/typescript/runtime}/retry.d.ts +0 -0
  607. /package/lib/{runtime → generators/typescript/runtime}/retry.js +0 -0
  608. /package/lib/{runtime → generators/typescript/runtime}/send.d.ts +0 -0
  609. /package/lib/{runtime → generators/typescript/runtime}/send.js +0 -0
  610. /package/lib/{runtime → generators/typescript/runtime}/setup.d.ts +0 -0
  611. /package/lib/{runtime → generators/typescript/runtime}/setup.js +0 -0
  612. /package/lib/{runtime → generators/typescript/runtime}/sse.d.ts +0 -0
  613. /package/lib/{runtime → generators/typescript/runtime}/sse.js +0 -0
  614. /package/lib/{runtime → generators/typescript/runtime}/types.js +0 -0
  615. /package/lib/{runtime → generators/typescript/runtime}/url.d.ts +0 -0
  616. /package/lib/{runtime → generators/typescript/runtime}/url.js +0 -0
  617. /package/lib/{emitters/setup-bake.d.ts → setup-bake.d.ts} +0 -0
@@ -0,0 +1,456 @@
1
+ // Ejected from @redocly/client-generator@0.4.0 — the built-in "zod" generator.
2
+ // This file is yours: edit freely; the generated client stays machine-owned and is
3
+ // rebuilt by `redocly generate-client`. Newer generator versions merge in with
4
+ // `redocly eject-generator zod --update`.
5
+ // Emits Zod schemas from the IR. Each named schema becomes an
6
+ // `export const <Name>Schema = z.<…>;` — source-text templates mirroring the
7
+ // type renderer (`typescript/types.ts`) but targeting runtime validators instead of types.
8
+ // Operations with a JSON request or response body additionally land in the
9
+ // `operationSchemas` map, which powers the `zodValidation` client middleware.
10
+ //
11
+ // Only the refinement methods stable across zod 3.23 and 4 are emitted
12
+ // (`.min/.max/.int/.gt/.lt/.regex`); format helpers (`.email/.uuid/.url`) diverge
13
+ // between major versions and are deferred. Refs become `z.lazy(() => …Schema)`,
14
+ // which sidesteps declaration ordering and recursion uniformly.
15
+
16
+ import {
17
+ allOperations,
18
+ type ApiModel,
19
+ type PropertyModel,
20
+ type ScalarKind,
21
+ type SchemaMetadata,
22
+ type SchemaModel,
23
+ } from '@redocly/client-generator';
24
+ import { codeLiteral, pascalCase, safeIdent } from '@redocly/client-generator/printers/typescript';
25
+
26
+ const INDENT = ' ';
27
+
28
+ /** `<Name>Schema` — the const identifier a named schema is bound to. */
29
+ function schemaConstName(name: string): string {
30
+ return `${pascalCase(name)}Schema`;
31
+ }
32
+
33
+ type SchemaByName = ReadonlyMap<string, SchemaModel>;
34
+
35
+ const NO_SCHEMAS: SchemaByName = new Map();
36
+
37
+ /** Map an IR schema to the Zod expression (source text) that validates it. */
38
+ export function schemaToZodExpression(
39
+ schema: SchemaModel,
40
+ byName: SchemaByName = NO_SCHEMAS,
41
+ indent = ''
42
+ ): string {
43
+ return withRefinements(baseExpression(schema, byName, indent), schema);
44
+ }
45
+
46
+ function baseExpression(schema: SchemaModel, byName: SchemaByName, indent: string): string {
47
+ switch (schema.kind) {
48
+ case 'scalar':
49
+ return scalarExpression(schema.scalar, schema.metadata);
50
+ case 'object':
51
+ return objectExpression(schema.properties, byName, indent);
52
+ case 'array':
53
+ return `z.array(${schemaToZodExpression(schema.items, byName, indent)})`;
54
+ case 'record':
55
+ return `z.record(z.string(), ${schemaToZodExpression(schema.value, byName, indent)})`;
56
+ case 'ref':
57
+ return `z.lazy(() => ${schemaConstName(schema.name)})`;
58
+ case 'literal':
59
+ return `z.literal(${codeLiteral(schema.value)})`;
60
+ case 'enum':
61
+ return enumExpression(schema.values);
62
+ case 'union':
63
+ return unionExpression(schema.members, byName, indent);
64
+ case 'intersection':
65
+ return schema.members
66
+ .map((member) => schemaToZodExpression(member, byName, indent))
67
+ .reduce((acc, next) => `${acc}.and(${next})`);
68
+ case 'null':
69
+ return 'z.null()';
70
+ case 'unknown':
71
+ return 'z.unknown()';
72
+ case 'omit':
73
+ return omitExpression(schema.base, schema.keys, byName, indent);
74
+ }
75
+ }
76
+
77
+ function scalarExpression(scalar: ScalarKind, metadata?: SchemaMetadata): string {
78
+ switch (scalar) {
79
+ case 'string':
80
+ // `format: binary` is typed as `Blob` (see typescript/types.ts); validate it as one so the
81
+ // zod schema agrees with the generated type instead of expecting a string.
82
+ return metadata?.format === 'binary' ? 'z.instanceof(Blob)' : 'z.string()';
83
+ case 'integer':
84
+ return 'z.number().int()';
85
+ case 'number':
86
+ return 'z.number()';
87
+ case 'boolean':
88
+ return 'z.boolean()';
89
+ }
90
+ }
91
+
92
+ /** A bare identifier key when valid, a quoted key otherwise. */
93
+ function propertyKeyText(name: string): string {
94
+ return safeIdent(name) === name ? name : JSON.stringify(name);
95
+ }
96
+
97
+ /** `z.object({ <key>: <expr>(.optional() when !required), … })` — multiline when non-empty. */
98
+ function objectExpression(
99
+ properties: PropertyModel[],
100
+ byName: SchemaByName,
101
+ indent: string
102
+ ): string {
103
+ if (properties.length === 0) return 'z.object({})';
104
+ const inner = indent + INDENT;
105
+ const lines = properties.map((property, index) => {
106
+ const expr = schemaToZodExpression(property.schema, byName, inner);
107
+ const value = property.required ? expr : `${expr}.optional()`;
108
+ const comma = index === properties.length - 1 ? '' : ',';
109
+ return `${inner}${propertyKeyText(property.name)}: ${value}${comma}`;
110
+ });
111
+ return `z.object({\n${lines.join('\n')}\n${indent}})`;
112
+ }
113
+
114
+ /** All-string values → `z.enum([…])`; otherwise → a union of literals. */
115
+ function enumExpression(values: Array<string | number | boolean>): string {
116
+ if (values.every((value) => typeof value === 'string')) {
117
+ return `z.enum([${values.map((value) => JSON.stringify(value)).join(', ')}])`;
118
+ }
119
+ return `z.union([${values.map((value) => `z.literal(${codeLiteral(value)})`).join(', ')}])`;
120
+ }
121
+
122
+ /** `z.union([…])`; a single member collapses to that member's expression. */
123
+ function unionExpression(members: SchemaModel[], byName: SchemaByName, indent: string): string {
124
+ const exprs = members.map((member) => schemaToZodExpression(member, byName, indent));
125
+ if (exprs.length === 1) return exprs[0];
126
+ return `z.union([${exprs.join(', ')}])`;
127
+ }
128
+
129
+ /**
130
+ * `<Base>Schema.omit({ k1: true, … })` when the base is a plain object schema.
131
+ * `.omit` exists only on `ZodObject` — for any other base (an `allOf` intersection,
132
+ * a union, …) the omission is distributed into the base's object members instead.
133
+ */
134
+ function omitExpression(
135
+ base: string,
136
+ keys: string[],
137
+ byName: SchemaByName,
138
+ indent: string
139
+ ): string {
140
+ const target = byName.get(base);
141
+ if (target && target.kind !== 'object') {
142
+ return schemaToZodExpression(applyOmit(target, keys, byName, new Set([base])), byName, indent);
143
+ }
144
+ const mask = keys.map((key) => `${propertyKeyText(key)}: true`).join(', ');
145
+ return `${schemaConstName(base)}.omit({ ${mask} })`;
146
+ }
147
+
148
+ /**
149
+ * Remove `keys` from a schema that is not a plain object: objects drop the properties,
150
+ * union/intersection members recurse, and a ref to an object becomes `<Ref>Schema.omit`
151
+ * with only the keys that exist on it (zod's mask rejects unknown keys at the type
152
+ * level). Cycles and non-object leaves return unchanged — there is nothing to omit.
153
+ */
154
+ function applyOmit(
155
+ schema: SchemaModel,
156
+ keys: string[],
157
+ byName: SchemaByName,
158
+ seen: Set<string>
159
+ ): SchemaModel {
160
+ switch (schema.kind) {
161
+ case 'object':
162
+ return { ...schema, properties: schema.properties.filter((p) => !keys.includes(p.name)) };
163
+ case 'union':
164
+ case 'intersection':
165
+ return {
166
+ ...schema,
167
+ members: schema.members.map((member) => applyOmit(member, keys, byName, seen)),
168
+ };
169
+ case 'ref': {
170
+ if (seen.has(schema.name)) return schema;
171
+ const target = byName.get(schema.name);
172
+ if (!target) return schema;
173
+ if (target.kind === 'object') {
174
+ const present = keys.filter((key) =>
175
+ target.properties.some((property) => property.name === key)
176
+ );
177
+ return present.length > 0 ? { kind: 'omit', base: schema.name, keys: present } : schema;
178
+ }
179
+ return applyOmit(target, keys, byName, new Set([...seen, schema.name]));
180
+ }
181
+ default:
182
+ return schema;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Chain the stable-subset metadata refinements onto `expr`. Order: numeric/length
188
+ * bounds, then `.regex` (the `.int()` for integers is already on the base).
189
+ * `.optional()` is NOT applied here — optionality is a property-level concern
190
+ * handled in `objectExpression`, so a top-level schema is never spuriously optional.
191
+ */
192
+ function withRefinements(expr: string, schema: SchemaModel): string {
193
+ const m = schema.metadata;
194
+ if (!m) return expr;
195
+ let out = expr;
196
+ if (schema.kind === 'scalar' && schema.scalar === 'string') {
197
+ if (m.minLength !== undefined) out = `${out}.min(${m.minLength})`;
198
+ if (m.maxLength !== undefined) out = `${out}.max(${m.maxLength})`;
199
+ if (m.pattern !== undefined) out = `${out}.regex(new RegExp(${JSON.stringify(m.pattern)}))`;
200
+ }
201
+ if (schema.kind === 'scalar' && (schema.scalar === 'number' || schema.scalar === 'integer')) {
202
+ if (m.minimum !== undefined) out = `${out}.min(${m.minimum})`;
203
+ if (m.maximum !== undefined) out = `${out}.max(${m.maximum})`;
204
+ if (m.exclusiveMinimum !== undefined) out = `${out}.gt(${m.exclusiveMinimum})`;
205
+ if (m.exclusiveMaximum !== undefined) out = `${out}.lt(${m.exclusiveMaximum})`;
206
+ }
207
+ if (schema.kind === 'array') {
208
+ if (m.minItems !== undefined) out = `${out}.min(${m.minItems})`;
209
+ if (m.maxItems !== undefined) out = `${out}.max(${m.maxItems})`;
210
+ }
211
+ return out;
212
+ }
213
+
214
+ /**
215
+ * `<opName>: { request?: <expr>, response?: <expr> }` for every non-SSE operation with a
216
+ * JSON request or response body — the operation's validators, keyed by the same id the
217
+ * middleware sees at runtime (`ctx.operation.id`). SSE, binary, text, and void bodies
218
+ * have no JSON payload to validate and are skipped.
219
+ */
220
+ type OperationSchemaEntry = { name: string; request?: string; response?: string };
221
+
222
+ function operationSchemaEntries(model: ApiModel, byName: SchemaByName): OperationSchemaEntry[] {
223
+ const entries: OperationSchemaEntry[] = [];
224
+ for (const op of allOperations(model.services)) {
225
+ if (op.sse !== undefined) continue;
226
+ const requestBody = op.requestBody;
227
+ const request =
228
+ requestBody && requestBody.contentType.toLowerCase().includes('json')
229
+ ? schemaToZodExpression(requestBody.schema, byName, INDENT)
230
+ : undefined;
231
+ const jsonResponse = op.successResponses.find((response) =>
232
+ response.contentType.toLowerCase().includes('json')
233
+ );
234
+ const response = jsonResponse
235
+ ? schemaToZodExpression(jsonResponse.schema, byName, INDENT)
236
+ : undefined;
237
+ if (!request && !response) continue;
238
+ // The SPEC operationId — the middleware looks entries up by `ctx.operation.id`,
239
+ // which stays the spec id even when the emitted function name was renamed.
240
+ entries.push({ name: op.specName ?? op.name, request, response });
241
+ }
242
+ return entries;
243
+ }
244
+
245
+ function operationSchemasBlock(entries: OperationSchemaEntry[]): string {
246
+ // The explicit `z.ZodType` annotation keeps the declaration-emit size proportional to
247
+ // the operation count: the inferred type would serialize every schema's zod generics
248
+ // and overflow tsc's limit (TS7056) on large APIs under `declaration: true`.
249
+ const typeLines = entries.flatMap((entry) => [
250
+ `${INDENT}${propertyKeyText(entry.name)}: {`,
251
+ ...(entry.request ? [`${INDENT}${INDENT}request: z.ZodType;`] : []),
252
+ ...(entry.response ? [`${INDENT}${INDENT}response: z.ZodType;`] : []),
253
+ `${INDENT}};`,
254
+ ]);
255
+ const valueLines = entries.map((entry, index) => {
256
+ const fields = [
257
+ ...(entry.request ? [`request: ${entry.request}`] : []),
258
+ ...(entry.response ? [`response: ${entry.response}`] : []),
259
+ ].join(', ');
260
+ const comma = index === entries.length - 1 ? '' : ',';
261
+ return `${INDENT}${propertyKeyText(entry.name)}: { ${fields} }${comma}`;
262
+ });
263
+ return [
264
+ '/**',
265
+ ' * Request/response validators by operationId — powers `zodValidation`, or import one directly.',
266
+ ' */',
267
+ 'export const operationSchemas: {',
268
+ ...typeLines,
269
+ '} = {',
270
+ ...valueLines,
271
+ '};',
272
+ ].join('\n');
273
+ }
274
+
275
+ // The validation middleware, spliced verbatim after the schemas (matches the printer's
276
+ // double-quote/4-space style). Structurally compatible with the client's `Middleware`
277
+ // without importing it, so the zod module keeps its single `zod` dependency.
278
+ const VALIDATION_SUPPORT = `/** \`request\`/\`response\` validators for one operation (an absent side is not validated). */
279
+ export type OperationSchemaSet = { request?: z.ZodType; response?: z.ZodType };
280
+
281
+ const schemaIndex: Partial<Record<string, OperationSchemaSet>> = operationSchemas;
282
+
283
+ /** One flattened validation problem: the full nested path and a short preview of the value. */
284
+ export type ZodViolation = { path: string; message: string; received: string };
285
+
286
+ /** A request or response payload failed validation. Requests throw it; response handling is configurable. */
287
+ export class ZodValidationError extends Error {
288
+ // Declared and assigned in the body, NOT as constructor parameter properties: those
289
+ // need a transform, so they break \`node --experimental-strip-types\` for anything
290
+ // importing this module (the generated CLI runs that way).
291
+ readonly operationId: string;
292
+ readonly direction: "request" | "response";
293
+ readonly issues: z.ZodError["issues"];
294
+ readonly violations: ZodViolation[];
295
+
296
+ constructor(
297
+ operationId: string,
298
+ direction: "request" | "response",
299
+ issues: z.ZodError["issues"],
300
+ violations: ZodViolation[]
301
+ ) {
302
+ const detail = violations
303
+ .slice(0, 5)
304
+ .map((violation) => \`\${violation.path || "(root)"}: \${violation.message} (received \${violation.received})\`)
305
+ .join("; ");
306
+ const more = violations.length > 5 ? \`; …and \${violations.length - 5} more\` : "";
307
+ super(\`\${direction === "request" ? "Request" : "Response"} validation failed for operation "\${operationId}": \${detail}\${more}\`);
308
+ this.operationId = operationId;
309
+ this.direction = direction;
310
+ this.issues = issues;
311
+ this.violations = violations;
312
+ this.name = "ZodValidationError";
313
+ }
314
+ }
315
+
316
+ // Flatten zod issues into leaf violations. Union branches (zod 3 \`unionErrors\`, zod 4
317
+ // nested \`errors\`) are recursed into, so the message names the actual failing fields
318
+ // instead of just the union root ("Invalid input").
319
+ function flattenIssues(
320
+ issues: z.ZodError["issues"],
321
+ value: unknown,
322
+ base: PropertyKey[] = []
323
+ ): ZodViolation[] {
324
+ const violations: ZodViolation[] = [];
325
+ for (const issue of issues) {
326
+ const path = [...base, ...issue.path];
327
+ const nested = nestedIssueLists(issue);
328
+ if (nested.length > 0) {
329
+ for (const sub of nested) violations.push(...flattenIssues(sub, value, path));
330
+ } else {
331
+ violations.push({
332
+ path: path.map(String).join("."),
333
+ message: issue.message,
334
+ received: preview(valueAt(value, path)),
335
+ });
336
+ }
337
+ }
338
+ return violations;
339
+ }
340
+
341
+ /** The nested issue lists of a union-ish issue, across zod 3 (\`unionErrors\`) and zod 4 (\`errors\`). */
342
+ function nestedIssueLists(issue: unknown): Array<z.ZodError["issues"]> {
343
+ const candidate = issue as {
344
+ unionErrors?: Array<{ issues: z.ZodError["issues"] }>;
345
+ errors?: Array<z.ZodError["issues"]>;
346
+ };
347
+ if (Array.isArray(candidate.unionErrors)) return candidate.unionErrors.map((error) => error.issues);
348
+ if (Array.isArray(candidate.errors)) return candidate.errors;
349
+ return [];
350
+ }
351
+
352
+ function valueAt(value: unknown, path: PropertyKey[]): unknown {
353
+ let current = value;
354
+ for (const key of path) {
355
+ if (current === null || typeof current !== "object") return undefined;
356
+ current = (current as Record<PropertyKey, unknown>)[key];
357
+ }
358
+ return current;
359
+ }
360
+
361
+ /** A short single-line preview of the offending value. NOTE: validation output can surface
362
+ * payload data — route \`onViolation\` to a scrubbed logger when responses may carry secrets. */
363
+ function preview(value: unknown): string {
364
+ let text: string;
365
+ try {
366
+ text = JSON.stringify(value) ?? String(value);
367
+ } catch {
368
+ text = String(value);
369
+ }
370
+ return text.length > 80 ? \`\${text.slice(0, 77)}…\` : text;
371
+ }
372
+
373
+ export type ZodValidationOptions = {
374
+ /** Validate request bodies before any network call; a failure THROWS (it is the caller's own bug). Default: true. */
375
+ request?: boolean;
376
+ /** Replace the outgoing body with the parsed result, dropping keys the schema does not declare
377
+ * (for strict-DTO servers that 400 on excess properties). Runs request validation. Default: false. */
378
+ stripRequestBodies?: boolean;
379
+ /** Response drift handling: \`"warn"\` (default) reports via \`onViolation\` and lets the call
380
+ * succeed — a server drifting from its description should not crash the consumer;
381
+ * \`"throw"\` fails the call (even on result-mode clients); \`false\` skips response validation. */
382
+ response?: "warn" | "throw" | false;
383
+ /** Sink for \`"warn"\` mode. Default: \`console.warn\` with the error message. */
384
+ onViolation?: (error: ZodValidationError) => void;
385
+ };
386
+
387
+ /**
388
+ * Schema-validation middleware for the generated client: \`use(zodValidation())\`.
389
+ * Request bodies are validated before any network call and throw on failure; successful
390
+ * JSON responses are validated against the operation's response schema and WARN by
391
+ * default (see \`ZodValidationOptions.response\`). Operations without a schema pass
392
+ * through untouched. Payloads are never mutated unless \`stripRequestBodies\` is set.
393
+ */
394
+ export function zodValidation(options: ZodValidationOptions = {}) {
395
+ const { request = true, stripRequestBodies = false, response = "warn", onViolation } = options;
396
+ const report = onViolation ?? ((error: ZodValidationError) => console.warn(error.message));
397
+ return {
398
+ onRequest(context: { body?: unknown; operation: { id: string } }): void {
399
+ if ((!request && !stripRequestBodies) || context.body === undefined) return;
400
+ const schema = schemaIndex[context.operation.id]?.request;
401
+ if (!schema) return;
402
+ const result = schema.safeParse(context.body);
403
+ if (!result.success) {
404
+ throw new ZodValidationError(
405
+ context.operation.id,
406
+ "request",
407
+ result.error.issues,
408
+ flattenIssues(result.error.issues, context.body)
409
+ );
410
+ }
411
+ // zod object schemas drop undeclared keys during parsing, so the parsed value
412
+ // IS the declared shape (intersections keep their own zod semantics).
413
+ if (stripRequestBodies) context.body = result.data;
414
+ },
415
+ async onResponse(incoming: Response, context: { operation: { id: string } }): Promise<void> {
416
+ if (response === false || !incoming.ok) return;
417
+ const schema = schemaIndex[context.operation.id]?.response;
418
+ if (!schema) return;
419
+ const contentType = (incoming.headers.get("content-type") ?? "").toLowerCase();
420
+ if (!contentType.includes("json")) return;
421
+ const payload: unknown = await incoming.clone().json();
422
+ const result = schema.safeParse(payload);
423
+ if (!result.success) {
424
+ const error = new ZodValidationError(
425
+ context.operation.id,
426
+ "response",
427
+ result.error.issues,
428
+ flattenIssues(result.error.issues, payload)
429
+ );
430
+ if (response === "throw") throw error;
431
+ report(error);
432
+ }
433
+ },
434
+ };
435
+ }`;
436
+
437
+ /**
438
+ * Render the full zod module source: the component schemas, then — when any operation
439
+ * has a JSON body — the `operationSchemas` map and the `zodValidation` middleware.
440
+ * `''` when there is nothing to emit.
441
+ */
442
+ export function renderZodModule(model: ApiModel): string {
443
+ const byName: SchemaByName = new Map(model.schemas.map((named) => [named.name, named.schema]));
444
+ const entries = operationSchemaEntries(model, byName);
445
+ if (model.schemas.length === 0 && entries.length === 0) return '';
446
+ const blocks = [
447
+ 'import { z } from "zod";',
448
+ ...model.schemas.map(
449
+ (named) =>
450
+ `export const ${schemaConstName(named.name)} = ${schemaToZodExpression(named.schema, byName)};`
451
+ ),
452
+ ];
453
+ if (entries.length === 0) return blocks.join('\n\n');
454
+ blocks.push(operationSchemasBlock(entries));
455
+ return `${blocks.join('\n\n')}\n${VALIDATION_SUPPORT}\n`;
456
+ }
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: cli-generator
3
+ description: Design of the ejected Redocly `cli` client generator. Read it, and update it, before changing generators/cli/.
4
+ ---
5
+
6
+ # The `cli` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `cli` generator (`generators/cli/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/cli/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ A bin-ready `<stem>.cli.ts`: one command per operation over the sdk's instance client,
15
+ with `--help`, a `schema <op>` introspection command, and `--dry-run`.
16
+
17
+ With `client.docs` (or `--docs`), the `docs` hook also writes `<stem>.cli.md`: the usage
18
+ line, the global flags, the credential variables, the exit-code table, and one section per
19
+ command with its positionals and flags.
20
+
21
+ ## Design decisions that must hold
22
+
23
+ - **Argument shape:** path params positional, query params typed `--kebab-name` flags,
24
+ JSON bodies via `--json '<json>' | @file | @-` (stdin).
25
+ - **Help is the whole interface.** A flag that exists but isn't in `--help` doesn't exist
26
+ to the user, so the top-level help carries a `Global flags:` section (`--server-url`,
27
+ `--format`, `--dry-run`, `--page-all`, `--output`, `--token`, `--json`) plus the
28
+ credential environment variables. Descriptions are collapsed to ONE line — an OpenAPI
29
+ description with newlines otherwise breaks the alignment of every following flag. The
30
+ footer names the form that actually works for a grouped API
31
+ (`<bin> <group> <command> --help`).
32
+ - **Commands are addressable the way a shell allows.** A group slug is kebab-cased so a
33
+ multi-word OpenAPI tag can be typed without quoting, while help shows the original tag.
34
+ A bare operationId resolves to its grouped command when unambiguous.
35
+ - **Exit codes are a contract:** 0 ok, 1 API error, 2 auth, 3 validation, 4 usage.
36
+ Errors print ONE JSON object to stderr so stdout stays pipeable.
37
+ - **The CLI names itself from `process.argv[1]`.** Only the operator's `bin` field decides
38
+ what the command is called, so help reads the invoked name back instead of printing a
39
+ name from generation that may not exist on the machine.
40
+ - **Credentials come from the environment** — `wiring.envPrefix`, the constant-cased output
41
+ stem (`CLIENT_TOKEN`), which a composed entry sets per api alias — or explicit flags;
42
+ `--dry-run` prints the prepared request with credentials REDACTED. The prefix is fixed at
43
+ generation on purpose: a renamed binary must keep reading the variables a published CLI
44
+ already documents. Help lists only the credentials the description declares, and an
45
+ unusable `--token` is a usage error, never silently dropped.
46
+ - **Validation is on by default.** The generator declares `requires: ['typescript', 'zod']` and
47
+ the pipeline pulls prerequisites in automatically, so `--generator cli` alone produces a
48
+ validating CLI — a user shouldn't have to know which other generator provides it. The
49
+ consequence is a zod peer dependency at run time, which the docs state.
50
+ - Throw-mode only — the exit-code mapping reads thrown `ApiError`s.
51
+ - **Runs under `node --experimental-strip-types` with no build step**, including the
52
+ modules it imports (the sdk and the zod module). Anything emitted must be erasable
53
+ TypeScript; a parameter property anywhere in that import graph breaks the zero-build
54
+ runner.
55
+ - **The generated module is a library as well as a binary.** It exports `COMMANDS`,
56
+ `wiring`, and `run`, and self-executes only when it is the process entry — a REALPATH
57
+ comparison of `import.meta.url` against `argv[1]`, because some runners resolve
58
+ symlinks in one but not the other (macOS temp dirs, installed bin symlinks), and a
59
+ plain URL comparison silently runs nothing. `import.meta.main` would be cleaner but is
60
+ absent from our Node floors. Importing the module must be side-effect-safe:
61
+ module-level wiring (zod validation) touches only the module's OWN client, never a
62
+ global.
63
+ - **Behavior that is not in the description is composed, never generated.** A custom
64
+ command (`login`, anything) is the operation-command data shape plus a `handler`, so it
65
+ inherits help, parsing, `schema`, and the exit-code contract; `runCli` dispatches it
66
+ instead of the client. The generator itself never learns what such a command does —
67
+ credentials files, login flows, and profiles are user land (or a future satellite),
68
+ by design.
69
+ - **One binary can span several descriptions.** `runCli` also accepts sources — each a
70
+ command list plus, optionally, its OWN wiring (own base URL, schemes, credentials)
71
+ behind a namespace, so colliding operationIds across descriptions are simply different
72
+ commands (`cafe shop createOrder`, `cafe kitchen createOrder`). A namespace-less source
73
+ puts commands at the root (`cafe login`); a root command whose name matches a namespace
74
+ is rejected at startup, never shadowed. A source WITHOUT wiring inherits the first
75
+ wired source's — a root `login` shares the composed binary's identity, which is the
76
+ whole point of composing it there.
77
+ - **The composed entry is generated, not hand-rolled.** A top-level `client.cliOutput`
78
+ makes `redocly generate-client` (no api argument) emit one entry over every api that
79
+ selected `cli`: the namespace is the api ALIAS from `apis:`, and the credential prefix
80
+ defaults to `<BINNAME>_<ALIAS>` (`CAFE_SHOP_TOKEN`) via `wiring.envPrefix` — which
81
+ exists precisely so the display name and the credential prefix can differ. The composed
82
+ entry exports its `SOURCES` so an adopter layers custom commands around it without
83
+ editing a generated file. Without `cliOutput`, nothing changes.
84
+
85
+ - **The CLI documents itself.** The page is this generator's `docs` hook, not a separate
86
+ generator: nothing else knows this tool's commands, and a reader who ejects `cli` gets
87
+ the page layout with it. The page renders from `commandData` — the same table `runCli`
88
+ dispatches on — so it cannot describe a tool other than the one beside it. A capability
89
+ reaches the page only by being in that table. The page is Markdown that survives a
90
+ linter (ATX headings, a blank line around every block, no hard tabs, one sentence per
91
+ line) and it escapes what descriptions contain, because a summary is arbitrary text.
92
+
93
+ ## The stage files
94
+
95
+ `render.ts` derives `commandData` from the IR and renders the module and the composed
96
+ entry; `docs.ts` renders the reference page from the same command table;
97
+ `engine-source.ts` supplies the cli engine's source text — the engine itself (`runCli`,
98
+ the parser, help, dispatch) ships inside the package and arrives through
99
+ `@redocly/client-generator/runtime-sources` (in this repo it lives in `runtime/cli.ts`
100
+ beside these files). `index.ts` is the entry. The sdk calling convention comes from
101
+ `@redocly/client-generator/contracts/typescript`.
102
+
103
+ ## Ejecting it
104
+
105
+ `redocly eject-generator cli` copies this generator's TypeScript source folder to
106
+ `generators/cli/`, exactly as we wrote it, importing `@redocly/client-generator`,
107
+ `@redocly/client-generator/contracts/typescript`,
108
+ `@redocly/client-generator/runtime-sources` (the embedded cli engine), and
109
+ `@redocly/openapi-core`. Running a `.ts` generator uses Node's type stripping (Node
110
+ 22.18, 23.6, or newer); newer built-in versions merge in per file with `--update`. Change
111
+ the command surface, the help layout, or the exit-code mapping, and regenerate. The exit
112
+ codes are a contract for scripts, so change them only deliberately.
113
+
114
+ ## The modify loop
115
+
116
+ 1. Edit this skill: state the new behavior or decision.
117
+ 2. Make `generators/cli/` match it.
118
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
119
+ generated files are never hand-edited.
120
+
121
+ Newer built-in versions merge in with `redocly eject-generator cli --update`.