@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,142 @@
1
+ ---
2
+ name: client-generators
3
+ description: Write or change a Redocly client generator — the API model, the language-neutral helper toolkit, and the edit → regenerate → diff loop.
4
+ ---
5
+
6
+ # Writing custom client generators
7
+
8
+ A generator is a plain module: `(input) => GeneratedFile[]`. It receives the
9
+ language-agnostic API model and returns files — in ANY output language. It runs
10
+ in the same pass as the built-ins; select it by path in `redocly.yaml`:
11
+
12
+ ```yaml
13
+ client:
14
+ generators: [typescript, ./generators/my-generator.mjs]
15
+ ```
16
+
17
+ ## The contract
18
+
19
+ ```js
20
+ /** @type {import('@redocly/client-generator').CustomGenerator} */
21
+ export default {
22
+ name: 'my-generator',
23
+ run({ model, output, outputMode, emit }) {
24
+ return [{ path: output.path.replace(/\.ts$/, '.mine.txt'), content: '…' }];
25
+ },
26
+ // Optional: one idiomatic call snippet per operation for docs (x-codeSamples),
27
+ // collected into an overlay file when `client.codeSamples: true` is set.
28
+ sample(operation, { model, emit }) {
29
+ return { lang: 'python', source: '…' };
30
+ },
31
+ // Optional: the reference page for what `run` emits, written when `client.docs` (or
32
+ // --docs) is on. Same `{ path, content }` shape as `run`; `renderReferencePage` gives
33
+ // the standard layout and takes `sample` for its snippets. A generator documents itself.
34
+ docs({ model, output, emit }) {
35
+ return [{ path: output.path.replace(/\.ts$/, '.mine.md'), content: '…' }];
36
+ },
37
+ };
38
+ ```
39
+
40
+ ## Declaring options
41
+
42
+ A generator that needs configuration declares it as a schema; `run` then receives
43
+ `options` already validated, with defaults applied:
44
+
45
+ ```js
46
+ export default {
47
+ name: 'permissions-matrix',
48
+ options: {
49
+ type: 'object',
50
+ properties: { groupBy: { enum: ['tag', 'path'], default: 'tag' } },
51
+ additionalProperties: false,
52
+ },
53
+ run({ model, output, options }) {
54
+ return [
55
+ { path: output.path.replace(/\.ts$/, '.permissions.md'), content: render(options.groupBy) },
56
+ ];
57
+ },
58
+ };
59
+ ```
60
+
61
+ Users set them per generator name:
62
+
63
+ ```yaml
64
+ client:
65
+ generators: [typescript, ./generators/permissions-matrix.mjs]
66
+ options:
67
+ permissions-matrix:
68
+ groupBy: path
69
+ ```
70
+
71
+ The supported subset is a top-level `type: 'object'` with `properties`, `required`, and
72
+ `additionalProperties`; each property is a scalar (`string`/`number`/`boolean`), an
73
+ `enum`, or an array of scalars, and may carry a `default` and a `description`. Don't
74
+ validate options inside `run` — an unknown key, a wrong type, a value outside an `enum`,
75
+ or a missing `required` key already fails generation before `run` is called.
76
+
77
+ Rules: output is deterministic (same description → same bytes); never add
78
+ dependencies to the generated client; **never hand-edit generated output** —
79
+ edit this generator and regenerate. Emitted file paths must stay inside the
80
+ `--output` directory (subdirectories are fine) — escapes are rejected.
81
+ Optionally declare `requiresGenerator` — the `@redocly/client-generator` version
82
+ range you wrote this against (`'^1.2.0'`, `'~1.2.0'`, `'>=1.2.0'`, or an exact
83
+ version). A CLI outside the range then fails with the fix path instead of feeding
84
+ your generator an unexpected model shape. Ejected generators carry it
85
+ automatically; hand-written ones without it are taken as current.
86
+
87
+ ## The model (IR)
88
+
89
+ `model.services[].operations[]` — each operation carries `name`, `specName`,
90
+ `method`, `path`, `tags`, `pathParams`/`queryParams`/`headerParams`/`cookieParams`,
91
+ `requestBody`, `successResponses`/`errorResponses` (each with a `schema`), and
92
+ `security`. `model.schemas` holds the named schemas. Every schema is a
93
+ discriminated union on `kind`: `scalar`, `array`, `object`, `record`, `ref`,
94
+ `literal`, `enum`, `union` (optionally with a discriminator), `intersection`
95
+ (allOf), `null`, `unknown`, `omit`.
96
+
97
+ ## Helpers (import from '@redocly/client-generator')
98
+
99
+ | Helper | Use |
100
+ | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
101
+ | `flattenAllOf(schema, model)` | The merged property view of allOf compositions — languages without intersection types render this. |
102
+ | `deref(schema, model)` | Follow a `ref` chain to the schema it names (cycle-guarded). |
103
+ | `jsonSuccessSchema(op)` / `sseResponse(op)` | The primary JSON success schema; the `text/event-stream` response when the operation streams. |
104
+ | `isMultipartBody(op)` | Whether the request body is multipart. |
105
+ | `serverUrlParts(server)` | A server-URL template as literal/variable parts, ready for any concatenation syntax. |
106
+ | `securityRequirements(op, model)` | The operation's security as OR-alternatives of AND-sets, denormalized against the declared schemes. |
107
+ | `paginationItemSchema(pageSchema, itemsPointer, model)` | The raw element schema behind a pagination rule's `items` pointer — a `ref` element keeps its name. |
108
+ | `discriminatorCases(schema, model)` | `{ property, cases }` dispatch table for discriminated unions. |
109
+ | `isNullable(schema)` / `unwrapNullable(schema)` | Detect and strip `null` union members (`Optional[T]`, pointers, `Option<T>`). |
110
+ | `enumValues(schema)` | Values plus SCREAMING_SNAKE member-name suggestions. |
111
+ | `headerCoerceType(schema, model)` | Response-header coerce hint (`integer`/`number`/`boolean`/`string`) through refs, nullables, and allOf wrappers. |
112
+ | `casing` / `identifierFor(name, { style, reserved })` | camel/pascal/snake/screaming; keyword-safe identifiers (`RESERVED_WORDS.python/go/typescript` shipped). |
113
+ | `uniqueIdentifiers(names, { style, reserved, taken })` | The same, made unique among themselves and among names you already took — for a signature that takes one argument per parameter. |
114
+ | `Printer` | Indentation-aware text builder — no manual whitespace bookkeeping. |
115
+ | `docText(description)` | Description as trimmed lines for any comment syntax. |
116
+ | `schemaAtPointer(schema, pointer, model)` | Resolve an RFC 6901 JSON pointer over a schema (through refs and allOf) — e.g. a pagination `items` pointer to its element type. |
117
+ | `paginationRuleFor(op, config)` | The pagination rule that applies to an operation (per-op config > extension > fitting convention), normalized. |
118
+ | `renderReferencePage(model, options)` | The Markdown reference page a generator's `docs` hook returns — your `sample` hook supplies its call snippets. |
119
+ | `NotSupportedError` | Throw it to reject an option the generator can't honor — the CLI prints the message as a user error, not a crash. |
120
+ | `AUTHORING_HELPER_NAMES` | The list of the above (introspection). |
121
+
122
+ Worked example: the built-in `python` generator
123
+ (`packages/client-generator/src/generators/python/index.ts` in the Redocly CLI repo) is
124
+ authored with exactly this toolkit and nothing else — models via `flattenAllOf`/
125
+ `enumValues`/`discriminatorCases`, all code through `Printer`, every name through
126
+ `identifierFor(..., RESERVED_WORDS.python)`.
127
+
128
+ A generator that emits TypeScript may additionally use the source-text renderers from
129
+ `@redocly/client-generator/generate` — `tsType` (schema → type), `tsJsdoc`, `codeLiteral`,
130
+ `operationSignature`, `pascalCase`, `safeIdent`. There is no AST toolkit and no
131
+ `typescript` dependency: every generator prints text through `Printer`.
132
+
133
+ ## The loop
134
+
135
+ 1. Edit the generator.
136
+ 2. Run `redocly generate-client`.
137
+ 3. Inspect `git diff` of the generated output.
138
+ 4. Repeat. Generated files are never hand-edited.
139
+
140
+ If you had to work around a **missing helper** or a wrong default, tell the user
141
+ and suggest filing an issue at https://github.com/Redocly/redocly-cli/issues —
142
+ include the generator snippet and the helper you expected to exist.
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: go-generator
3
+ description: Design of the ejected Redocly `go` client generator. Read it, and update it, before changing generators/go/.
4
+ ---
5
+
6
+ # The `go` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `go` generator (`generators/go/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/go/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ One self-contained `<stem>.go` (`package client`): structs with `json` tags, a `Client`
15
+ with one `(T, error)` method per operation taking a `context.Context`, and the embedded
16
+ runtime. Go ≥ 1.21, standard library only — zero dependencies.
17
+
18
+ ## Design decisions that must hold
19
+
20
+ - **Models are structs**: required fields by value, optionals as pointers with
21
+ `,omitempty`; the `json` tag always carries the exact wire name.
22
+ - **Package clause:** `package client` by default, `goPackage` to override — a generated
23
+ file usually lands in a package the consumer already owns. The value is checked against
24
+ Go's own rule (lowercase letters, digits, `_`, no leading digit, not a keyword) and an
25
+ invalid one fails generation: silently rewriting a publisher's package name would be
26
+ worse than saying no.
27
+ - **Doc comments are gofmt's shape**, not the description's: a blank line prints as `//`
28
+ (never `// `, which gofmt strips), and CONSECUTIVE blank lines collapse to one — gofmt
29
+ rewrites `//\n//` to a single `//`, so emitting both means our output is not
30
+ gofmt-clean. Descriptions with a double blank line are common in real specs.
31
+ - **Every parameter is its own argument, so their names share one namespace** with the
32
+ arguments the method declares itself (`ctx`, `body`, `params`, and the receiver). Build them with
33
+ `uniqueIdentifiers(..., { taken: … })`: OpenAPI lets one operation use a name in two
34
+ locations (`id` in the path AND in the query), and Go rejects a duplicate parameter. The
35
+ wire name is untouched, so the request is unchanged.
36
+ - **Naming:** exported PascalCase via `identifierFor` + an `N` prefix for digit-leading
37
+ names (`3ds` → `N3ds` — an `_`-prefixed field is unexported and invisible to
38
+ `encoding/json`); `+1`/`-1` become `Plus1`/`Minus1`.
39
+ - **Enums** are typed consts (`type Status string` + `StatusInProgress Status = …`);
40
+ **discriminated unions** are `type X = any` plus a generated `UnmarshalX([]byte)`
41
+ dispatcher; **allOf** is flattened.
42
+ - **Errors:** `(T, error)` returns ARE the error mode — `errorMode` does not change the
43
+ output (the generator declares `errorModes: ['throw']`, so `result` fails fast).
44
+ Non-2xx → `*APIError`; timeouts → `*TimeoutError`.
45
+ - **Dates:** `dateType: Date` maps `format: date-time` to `time.Time` (encoding/json
46
+ handles RFC 3339 natively) and `date` to the runtime's `Date` wrapper, which
47
+ marshals as `2006-01-02`. Query values format explicitly, never via `String()`.
48
+ - **Response headers:** an operation that DECLARES success-response headers gains a
49
+ `<Op>WithHeaders(ctx, …) (T, <Op>Headers, error)` variant; `<Op>Headers` is a
50
+ generated struct with pointer fields (nil when absent or unparsable), coerced to
51
+ int64/bool/string. Operations without declared headers get no variant, and the
52
+ base method stays `(T, error)`.
53
+ - **Servers:** when the description declares servers, one `<Name>URL(...)` function per
54
+ server is emitted (named from the server description); server VARIABLES become string
55
+ parameters (Go has no defaults — the doc comment states the spec default), so templated
56
+ base URLs need no manual string building. The client's baked default stays `servers[0]`
57
+ with variable defaults substituted.
58
+ - **Parity surface:** auth, retries with `Retry-After` + jittered backoff, per-attempt
59
+ `context.WithTimeout`, idempotency keys, middleware, pagination (`<Op>Pages`/`<Op>Items`
60
+ as `func(yield func(T, error) bool)` — `range`-over-func needs Go ≥ 1.23; 1.21 calls
61
+ them with a callback), SSE, multipart.
62
+ - **The EMITTED FILE is gofmt-clean, not just the runtime.** `gofmt -l` on generated
63
+ output must print nothing, so the download is idiomatic as-is. The emitter earns that
64
+ deterministically, without shelling out to `gofmt`:
65
+ - `alignGoColumns` pads columns the way gofmt's tabwriter does — struct field types and
66
+ tags, `const`/`var` types and `=`, and map-literal values — within each contiguous run.
67
+ A line starting with a Go KEYWORD is a statement, never a declaration, and must never
68
+ be padded (`case "x":` is not a field).
69
+ - `case` sits at its `switch`'s own indent, so the switch body is not emitted as an
70
+ indented block.
71
+ - At most one blank line between declarations, none at end of file, and a blank line
72
+ inside a doc comment is `//` — never `// ` with a trailing space.
73
+ A change here is verified by the `gofmt -l` bar in the unit suite, at cafe AND
74
+ large-description scale.
75
+ - The runtime is hand-written in `runtime/runtime.go` in this folder (gofmt-clean, `go vet`-clean)
76
+ and embedded at prepare time.
77
+ Under `--runtime module` it is written as a same-package `runtime.go` beside the client,
78
+ whose import block then lists only the packages its own body uses.
79
+ - Authored ONLY with the neutral toolkit — the dogfooding guard fails otherwise.
80
+
81
+ - **It documents itself.** With `client.docs` (or `--docs`), the `docs` hook writes
82
+ `<stem>.go.md`: the security schemes, then one section per operation with its parameters,
83
+ body, response type, and behavior notes. The call snippets come from this generator's own
84
+ `sample` hook, so the page can only show the syntax of the SDK beside it, and the layout
85
+ comes from `renderReferencePage` in the authoring toolkit — reachable from an ejected copy
86
+ through `@redocly/client-generator`. Pagination on the page is decided by
87
+ `paginationRuleFor`, the same helper this generator resolves pagination with.
88
+
89
+ ## The modify loop
90
+
91
+ 1. Edit this skill: state the new behavior or decision.
92
+ 2. Make `generators/go/` match it.
93
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
94
+ generated files are never hand-edited.
95
+
96
+ Newer built-in versions merge in with `redocly eject-generator go --update`.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: mock-generator
3
+ description: Design of the ejected Redocly `mock` client generator. Read it, and update it, before changing generators/mock/.
4
+ ---
5
+
6
+ # The `mock` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `mock` generator (`generators/mock/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/mock/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ A standalone MSW module: `create<Name>()` data factories, `<op>Handler()` /
15
+ `<op>ErrorHandler(status, body?)` request handlers, and a `handlers` array.
16
+
17
+ ## Design decisions that must hold
18
+
19
+ - **Two data modes:** `mockData: static` bakes deterministic samples from the schema
20
+ (examples/defaults first); `faker` emits `faker.*` calls with a seed (`mockSeed`) so
21
+ runs are reproducible.
22
+ - **Interpolated identifiers are gated** (`codeIdent`): an operation name or method
23
+ reaching a code position is validated, never trusted, even though the pipeline
24
+ sanitizes upstream.
25
+ - Handlers are opt-in overrides: `<op>ErrorHandler` is NOT in `handlers`.
26
+ - The module references the sdk's TYPES only — never its runtime.
27
+
28
+ ## The stage files
29
+
30
+ `render.ts` assembles the module (factories, handlers, the `handlers` array);
31
+ `sample.ts` bakes deterministic sample values from the schema, `values.ts` renders the
32
+ data trees, and `faker.ts` emits the faker-mode expressions. `index.ts` is the entry.
33
+
34
+ ## Ejecting it
35
+
36
+ `redocly eject-generator mock` copies this generator's TypeScript source folder to
37
+ `generators/mock/`, exactly as we wrote it, importing `@redocly/client-generator`,
38
+ `@redocly/client-generator/printers/typescript`, and `@redocly/openapi-core`. Running a
39
+ `.ts` generator uses Node's type stripping (Node 22.18, 23.6, or newer); newer built-in
40
+ versions merge in per file with `--update`. Change the data strategy, the handler shape,
41
+ or the factory surface, and regenerate.
42
+
43
+ ## The modify loop
44
+
45
+ 1. Edit this skill: state the new behavior or decision.
46
+ 2. Make `generators/mock/` match it.
47
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
48
+ generated files are never hand-edited.
49
+
50
+ Newer built-in versions merge in with `redocly eject-generator mock --update`.
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: php-generator
3
+ description: Design of the ejected Redocly `php` client generator. Read it, and update it, before changing generators/php/.
4
+ ---
5
+
6
+ # The `php` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `php` generator (`generators/php/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/php/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ One self-contained `<stem>.php`: promoted-constructor model classes, a `Client` with one
15
+ typed method per operation, and the embedded runtime. PHP ≥ 8.1, HTTP over the curl
16
+ extension — zero Composer dependencies. The namespace derives from the API title
17
+ (`identifierFor(title, pascal)` — e.g. `CafeOrders`).
18
+
19
+ ## Design decisions that must hold
20
+
21
+ - **Models are `final class`es** with constructor property promotion, required parameters
22
+ first, optionals nullable `= null`. Hydration is compile-time generated per class:
23
+ `fromArray(array $data): self` and `toArray(): array` (wire names inline; nulls
24
+ skipped on serialize) — no reflection. `omit` schemas hydrate/serialize through their
25
+ base class. A property or response typed as a DISCRIMINATED union hydrates through the
26
+ union's `unmarshalX` dispatcher, so consumers can narrow with `instanceof`;
27
+ undiscriminated unions stay raw arrays.
28
+ - The `Client` class is NOT `final` — PHP test suites mock concrete classes
29
+ (`createMock(Client::class)`), and `final` would force a wrapper interface on every
30
+ consumer. Model classes stay `final`.
31
+ - **Every parameter is its own argument, so their names share one namespace** with the
32
+ arguments the method declares itself (`$body`, `$headers`, `$idempotencyKey`). Build them with
33
+ `uniqueIdentifiers(..., { taken: … })`: OpenAPI lets one operation use a name in two
34
+ locations (`id` in the path AND in the query), and PHP rejects a redefined parameter outright. The
35
+ wire name is untouched, so the request is unchanged.
36
+ - **Naming:** classes PascalCase, properties/methods camelCase via
37
+ `identifierFor(..., RESERVED_WORDS.php)`; reserved words get a trailing underscore.
38
+ - **Enums** are native backed enums (string/int); other scalars stay aliases.
39
+ **Discriminated unions** are `match`-based `unmarshalX(array $data)` dispatchers;
40
+ **allOf** is flattened.
41
+ - **Unions keep their types where PHP 8.1 can express them.** A union of scalars, enums,
42
+ classes, or arrays becomes a native union type (`int|string`, `PromotionType|array`)
43
+ rather than collapsing to `mixed` — rich list filters are the common case and losing
44
+ their types loses the point of a typed SDK. It falls back to `mixed` only when a member
45
+ has no PHP type of its own (an inline object, an intersection, `unknown`), because
46
+ `mixed` cannot appear inside a union. Nullability is expressed as `|null` in a union
47
+ (PHP forbids mixing `?` with `|`) and `?T` for a single type.
48
+ - **Errors:** exceptions ARE the error mode (`ApiError`/`TimeoutError` extend
49
+ `\RuntimeException`); `errorMode` does not change the output (the generator declares
50
+ `errorModes: ['throw']`, so `result` fails fast).
51
+ - **Dates:** `dateType: Date` types `format: date`/`date-time` as
52
+ `\DateTimeImmutable`; hydration is `new \DateTimeImmutable(...)` and serialization
53
+ formats with `\DateTimeInterface::ATOM` (date-time) or `'Y-m-d'` (date), including
54
+ for query parameters.
55
+ - **Method arguments:** required path params positional, JSON body next, optional query
56
+ params as nullable NAMED arguments, then `?array $headers`, and `?string
57
+ $idempotencyKey` on mutating methods.
58
+ - **Non-JSON success bodies** (PDFs, images, octet streams) return the raw body as
59
+ `string` — a binary download must never degrade to `void`.
60
+ - **PHPDoc carries what the signature cannot.** PHP's `array` and `\Generator` erase their
61
+ element type, so a docblock states it: `@return Customer[]` for collection returns and
62
+ `@return \Generator<int, Customer>` on `<op>Pages()`/`<op>Items()`. Static analysis and
63
+ readers go by these; a hydrated return with no annotation looks untyped.
64
+ - **Response headers:** an operation that DECLARES success-response headers gains a
65
+ `<op>WithHeaders()` variant returning an `Envelope` (`data`, `headers` — coerced to
66
+ int/bool/string with camelCase keys, absent/unparsable values omitted — and `status`).
67
+ Operations without declared headers get no variant, and the base method stays
68
+ body-only (PHP cannot vary a return type on a flag).
69
+ - **Servers:** when the description declares servers, a `Servers` class is emitted with
70
+ one static method per server; server VARIABLES become named string arguments defaulting
71
+ to the spec's defaults (`Servers::production(organizationId: 'org_x')`), so templated
72
+ base URLs need no manual string building. The client's baked default stays `servers[0]`
73
+ with variable defaults substituted.
74
+ - **Parity surface:** auth, retries with `Retry-After` + jittered backoff, per-attempt
75
+ curl timeouts, middleware callables, pagination (`<op>Pages()` / `<op>Items()` as
76
+ `\Generator`s), SSE (`iterSse` over a curl_multi pump), multipart.
77
+ - The runtime is hand-written in `runtime/runtime.php` in this folder (`php -l`-clean) and embedded
78
+ at prepare time. `curl_close` is never called (deprecated since PHP 8.5, no-op since 8.0).
79
+ Under `--runtime module` it is written as a `runtime.php` the client `require_once`s,
80
+ with its namespace rewritten to the client's so one namespace spans both files.
81
+ - Authored ONLY with the neutral toolkit — the dogfooding guard fails otherwise.
82
+
83
+ ## Migrating from a service-based SDK
84
+
85
+ - Per-resource services (`$client->customers()->get($id)`) map to flat methods named
86
+ after operationIds (`$client->getCustomer($id)`); optional query params keep their
87
+ named-argument style (`filter:`, `sort:`, `limit:`).
88
+ - Collection wrappers exposing pagination RESPONSE HEADERS (`getTotalItems()`,
89
+ `getLimit()`) map to the `<op>WithHeaders()` envelope
90
+ (`->headers['paginationTotal']`); plain iteration maps to `<op>Items()` /
91
+ `<op>Pages()` generators.
92
+ - Dedicated validation-exception classes exposing field errors map to
93
+ `catch (ApiError $e)` + `$e->status === 422` + the decoded `$e->body`.
94
+ - Session/bearer token flows map to `auth: ['bearer' => $tokenProvider]` with a
95
+ callable — resolved per request, so refresh needs no client rebuild.
96
+
97
+ - **It documents itself.** With `client.docs` (or `--docs`), the `docs` hook writes
98
+ `<stem>.php.md`: the security schemes, then one section per operation with its parameters,
99
+ body, response type, and behavior notes. The call snippets come from this generator's own
100
+ `sample` hook, so the page can only show the syntax of the SDK beside it, and the layout
101
+ comes from `renderReferencePage` in the authoring toolkit — reachable from an ejected copy
102
+ through `@redocly/client-generator`. Pagination on the page is decided by
103
+ `paginationRuleFor`, the same helper this generator resolves pagination with.
104
+
105
+ ## The modify loop
106
+
107
+ 1. Edit this skill: state the new behavior or decision.
108
+ 2. Make `generators/php/` match it.
109
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
110
+ generated files are never hand-edited.
111
+
112
+ Newer built-in versions merge in with `redocly eject-generator php --update`.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: python-generator
3
+ description: Design of the ejected Redocly `python` client generator. Read it, and update it, before changing generators/python/.
4
+ ---
5
+
6
+ # The `python` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `python` generator (`generators/python/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/python/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ One self-contained `<stem>.py`: typed dataclass models, a sync `Client` and an async
15
+ `AsyncClient`, and the embedded runtime. Python ≥ 3.9; the only dependency is
16
+ [httpx](https://www.python-httpx.org/) (`pip install httpx`).
17
+
18
+ ## Design decisions that must hold
19
+
20
+ - **The file name is an importable module name.** The `--output` stem follows the TypeScript
21
+ convention (`openapi.client.ts`), and `openapi.client.py` cannot be imported by name — nor
22
+ can hyphens or a leading digit. The stem is converted with
23
+ `identifierFor(stem, snake)`, so `rebilly-core.client.ts` emits
24
+ `rebilly_core_client.py` and `import rebilly_core_client` just works.
25
+
26
+ - **Models are dataclasses by default**, required fields first (a dataclass constraint),
27
+ optionals `Optional[T] = None`. Wire names live in a `_field_map: ClassVar[Dict[str, str]]`;
28
+ decode/encode is reflective (`_decode.py`, `get_type_hints`) — no per-model codecs.
29
+ - **`models: pydantic` emits `BaseModel` classes instead**, for the FastAPI-shaped half of
30
+ the ecosystem that expects them. A wire name becomes `Field(alias=…)` with
31
+ `populate_by_name=True`, so `_field_map` is not emitted in this mode — the alias is the
32
+ mapping. Everything else is unchanged: the same class names, the same field names, the
33
+ same `Optional[T] = None`, the same enums and union aliases, the same client and runtime.
34
+ Switching modes must not change a call site.
35
+ - **A discriminated union carries its discriminator into the pydantic annotation.** The
36
+ decoder hands a whole object tree to `model_validate`, so a union nested in a model is
37
+ resolved by pydantic and never reaches the `DISCRIMINATORS` table that dataclass mode
38
+ walks. Pydantic resolves it correctly from `Annotated[Union[...], Field(discriminator=…)]`,
39
+ which it accepts only when every member types that property as a `Literal` — and the
40
+ mapping already pins one value per member, so the members get `Literal["cat"]`. Such a
41
+ union registers no table entry: pydantic owns it at every depth, and the `Literal` makes
42
+ the decoder's member probe exact. A union whose members never declare the property keeps
43
+ the plain `Union` and the table entry, and pydantic then matches nested members its own
44
+ way — the description is what has to change there.
45
+ - **One runtime serves both model modes.** `_decode.py` dispatches on the target: a class
46
+ with `model_validate` is validated by pydantic, a dataclass is hydrated reflectively, and
47
+ `encode` mirrors that with `model_dump(by_alias=True, exclude_none=True, mode="json")`.
48
+ A second runtime variant per mode would double the surface that has to stay in step, and
49
+ pydantic's `ValidationError` already subclasses `ValueError`, so union member probing
50
+ needs no new except clause.
51
+ - **`models: pydantic` adds a dependency, and the header says so.** The default mode keeps
52
+ httpx as the only requirement; the pydantic header asks for both. A mode that quietly
53
+ needed a package the file never named would fail at import with nothing to act on.
54
+ - **Every parameter is its own argument, so their names share one namespace** with the
55
+ arguments the method declares itself (`body`, `headers`, `timeout`, `retry`, `idempotency_key`). Build them with
56
+ `uniqueIdentifiers(..., { taken: … })`: OpenAPI lets one operation use a name in two
57
+ locations (`id` in the path AND in the query), and a `def` that declared one name twice is a `SyntaxError`. The
58
+ wire name is untouched, so the request is unchanged.
59
+ - **Naming:** fields/methods snake*case via `identifierFor(..., RESERVED_WORDS.python)`;
60
+ reserved words get a trailing underscore (`class*`); `+1`/`-1`become`plus_1`/`minus_1`.
61
+ - **Enums** are `class X(str, Enum)` with SCREAMING members; **unions** are `Union[...]`
62
+ aliases. A DISCRIMINATED union registers its dispatch table in the runtime's
63
+ `DISCRIMINATORS` registry (`DISCRIMINATORS[Pet] = ("petType", {"cat": Cat, ...})`),
64
+ and `decode()` routes through it — `isinstance` narrowing works on decoded members.
65
+ Undiscriminated unions decode by trying each member in order (the first that
66
+ hydrates wins — see `_decode.py`). **allOf** is flattened via `flattenAllOf`.
67
+ - **Auth keys match the other languages.** `auth={"apiKey": {...}}` is the documented key —
68
+ the same spelling TypeScript and PHP use, and the same as the scheme kind — with
69
+ `api_key` accepted as an alias so a snake_case config keeps working.
70
+ - **Errors:** `errorMode` maps to raising `ApiError` (default) or returning a `Result`
71
+ dataclass — the only generator with both modes outside TypeScript.
72
+ - **Dates:** `dateType: Date` annotates `format: date-time` as `datetime` and `date` as
73
+ `date`; `_decode.py` parses ISO strings into them and `encode()` writes `isoformat()`
74
+ back. The default (`string`) keeps the wire shape.
75
+ - **Response headers:** an operation that DECLARES success-response headers gains a
76
+ `<op>_with_headers()` variant (sync and async) returning `Envelope[T]` — `data`,
77
+ `headers` (coerced to int/bool/str with snake_case keys; absent/unparsable values
78
+ omitted), and the raw `response`. Operations without declared headers get no
79
+ variant, and the base method stays body-only.
80
+ - **Servers:** when the description declares servers, a `Servers` class is emitted with
81
+ one static method per server; server VARIABLES become keyword arguments defaulting to
82
+ the spec's defaults (`Servers.production(organization_id="org_x")`), so templated base
83
+ URLs need no manual string building. The client's baked default stays `servers[0]`
84
+ with variable defaults substituted.
85
+ - **Parity surface:** auth (bearer/basic/apiKey), retries with `Retry-After` + jittered
86
+ backoff, timeouts, idempotency keys, middleware, pagination (`<op>_pages()` /
87
+ `<op>_items()` + `aiter` mirrors), SSE (`iter_sse`/`aiter_sse`), multipart.
88
+ - The runtime is hand-written in `runtime/*.py` in this folder and embedded as strings at prepare
89
+ time — generator code never builds runtime logic from templates.
90
+ Under `--runtime module` the same sources are written as sibling `_*.py` files instead
91
+ (package-relative imports become sibling imports; the client star-imports each module).
92
+ - Authored ONLY with the neutral toolkit (`Printer`, naming, schema, pagination helpers) —
93
+ the dogfooding guard fails otherwise.
94
+
95
+ - **It documents itself.** With `client.docs` (or `--docs`), the `docs` hook writes
96
+ `<stem>.python.md`: the security schemes, then one section per operation with its parameters,
97
+ body, response type, and behavior notes. The call snippets come from this generator's own
98
+ `sample` hook, so the page can only show the syntax of the SDK beside it, and the layout
99
+ comes from `renderReferencePage` in the authoring toolkit — reachable from an ejected copy
100
+ through `@redocly/client-generator`. Pagination on the page is decided by
101
+ `paginationRuleFor`, the same helper this generator resolves pagination with.
102
+
103
+ ## The modify loop
104
+
105
+ 1. Edit this skill: state the new behavior or decision.
106
+ 2. Make `generators/python/` match it.
107
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
108
+ generated files are never hand-edited.
109
+
110
+ Newer built-in versions merge in with `redocly eject-generator python --update`.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: swr-generator
3
+ description: Design of the ejected Redocly `swr` client generator. Read it, and update it, before changing generators/swr/.
4
+ ---
5
+
6
+ # The `swr` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `swr` generator (`generators/swr/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/swr/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ React SWR hooks over the sdk's exported operation functions: `use<Op>()` with a
15
+ `<op>Key()` key factory for queries, `useSWRMutation` for mutations.
16
+
17
+ ## Design decisions that must hold
18
+
19
+ - **Wraps the sdk's functions** — it never re-implements requests, so it requires `typescript`
20
+ and is throw-mode only.
21
+ - **Keys are exported factories** so consumers can invalidate precisely.
22
+ - **`envelope` is excluded** from hook options (`Omit<RequestOptions, "envelope">`) and
23
+ stripped from the forwarded call: cached data is always the plain body.
24
+ - **Skips what it cannot wrap** — SSE operations and `<Op>Variables` name collisions —
25
+ with a warning naming each one, never silently.
26
+
27
+ ## The stage files
28
+
29
+ `render.ts` holds the whole hook renderer; `index.ts` is the entry. The wrappable-operation
30
+ policy and the sdk calling convention come from the typescript generator's published
31
+ contract (`@redocly/client-generator/contracts/typescript`), so this generator cannot
32
+ drift from the sdk it wraps.
33
+
34
+ ## Ejecting it
35
+
36
+ `redocly eject-generator swr` copies this generator's TypeScript source folder to
37
+ `generators/swr/`, exactly as we wrote it, importing `@redocly/client-generator`,
38
+ `@redocly/client-generator/printers/typescript`, and
39
+ `@redocly/client-generator/contracts/typescript`. Running a `.ts` generator uses Node's
40
+ type stripping (Node 22.18, 23.6, or newer); newer built-in versions merge in per file
41
+ with `--update`. Change the hook shape or the key strategy, and regenerate.
42
+
43
+ ## The modify loop
44
+
45
+ 1. Edit this skill: state the new behavior or decision.
46
+ 2. Make `generators/swr/` match it.
47
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
48
+ generated files are never hand-edited.
49
+
50
+ Newer built-in versions merge in with `redocly eject-generator swr --update`.
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: tanstack-query-generator
3
+ description: Design of the ejected Redocly `tanstack-query` client generator. Read it, and update it, before changing generators/tanstack-query/.
4
+ ---
5
+
6
+ # The `tanstack-query` generator — its skill
7
+
8
+ This file is the DESIGN of your ejected `tanstack-query` generator (`generators/tanstack-query/`):
9
+ **to change the generator, edit this skill first, then make the code match it** — a diff
10
+ to `generators/tanstack-query/` that has no covering sentence here is incomplete.
11
+
12
+ ## What it emits
13
+
14
+ Query/mutation option factories for TanStack Query — `<op>Options()`,
15
+ `<op>Mutation()`, and `<op>InfiniteOptions()` for paginated operations — plus exported
16
+ query keys. One generator, four framework variants (`react` default, `-vue`,
17
+ `-svelte`, `-solid`) differing only in the imported package.
18
+
19
+ ## Design decisions that must hold
20
+
21
+ - **Options factories, not hooks:** consumers call `useQuery(<op>Options(...))`, so the
22
+ output works with any of the framework adapters and stays testable.
23
+ - **`queryKeyPrefix`** namespaces every key when several clients share a cache.
24
+ - **Infinite queries** derive `getNextPageParam` from the resolved pagination rule; a
25
+ `link`-style rule reads the `Link` header the descriptor declares.
26
+ - **`envelope` is excluded and stripped** — cached data is the plain body.
27
+ - Requires `typescript`; throw-mode only (it wraps thrown errors into query errors).
28
+
29
+ ## The stage files
30
+
31
+ `render.ts` holds the whole factory renderer; `index.ts` is the entry (the framework is
32
+ its one argument). The wrappable-operation policy and the sdk calling convention come
33
+ from the typescript generator's published contract
34
+ (`@redocly/client-generator/contracts/typescript`); the resolved pagination arrives from
35
+ the pipeline on the generator input.
36
+
37
+ ## Ejecting it
38
+
39
+ `redocly eject-generator tanstack-query` copies this generator's TypeScript source folder
40
+ to `generators/tanstack-query/`, exactly as we wrote it, importing
41
+ `@redocly/client-generator`, `@redocly/client-generator/printers/typescript`, and
42
+ `@redocly/client-generator/contracts/typescript`. Running a `.ts` generator uses Node's
43
+ type stripping (Node 22.18, 23.6, or newer); newer built-in versions merge in per file
44
+ with `--update`. The framework is a single argument in the ejected `index.ts` default
45
+ export (`tanstackQueryGenerator('react')`), so switch it to `'vue'`, `'svelte'`, or
46
+ `'solid'` there instead of ejecting four near-identical copies.
47
+
48
+ ## The modify loop
49
+
50
+ 1. Edit this skill: state the new behavior or decision.
51
+ 2. Make `generators/tanstack-query/` match it.
52
+ 3. Run `redocly generate-client` and inspect the `git diff` of the generated output —
53
+ generated files are never hand-edited.
54
+
55
+ Newer built-in versions merge in with `redocly eject-generator tanstack-query --update`.