openapi-typesafe 0.0.0 → 1.0.0-rc.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 (678) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +71 -1
  3. package/bin/cli.js +4 -0
  4. package/dist/adapters/node-file-system/node-file-system.cjs +46 -0
  5. package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -0
  6. package/dist/adapters/node-file-system/node-file-system.mjs +40 -0
  7. package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -0
  8. package/dist/adapters/redocly-loader/alias-limit.cjs +16 -0
  9. package/dist/adapters/redocly-loader/alias-limit.cjs.map +1 -0
  10. package/dist/adapters/redocly-loader/alias-limit.mjs +14 -0
  11. package/dist/adapters/redocly-loader/alias-limit.mjs.map +1 -0
  12. package/dist/adapters/redocly-loader/allowed-hosts.cjs +42 -0
  13. package/dist/adapters/redocly-loader/allowed-hosts.cjs.map +1 -0
  14. package/dist/adapters/redocly-loader/allowed-hosts.mjs +40 -0
  15. package/dist/adapters/redocly-loader/allowed-hosts.mjs.map +1 -0
  16. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +53 -0
  17. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -0
  18. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +51 -0
  19. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -0
  20. package/dist/adapters/redocly-loader/malformed-refs.cjs +41 -0
  21. package/dist/adapters/redocly-loader/malformed-refs.cjs.map +1 -0
  22. package/dist/adapters/redocly-loader/malformed-refs.mjs +38 -0
  23. package/dist/adapters/redocly-loader/malformed-refs.mjs.map +1 -0
  24. package/dist/adapters/redocly-loader/redocly-config-source.cjs +42 -0
  25. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -0
  26. package/dist/adapters/redocly-loader/redocly-config-source.mjs +35 -0
  27. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -0
  28. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +169 -0
  29. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -0
  30. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +167 -0
  31. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -0
  32. package/dist/adapters/redocly-loader/ref-access.cjs +107 -0
  33. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -0
  34. package/dist/adapters/redocly-loader/ref-access.mjs +99 -0
  35. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -0
  36. package/dist/adapters/redocly-loader/ref-holders.cjs +31 -0
  37. package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -0
  38. package/dist/adapters/redocly-loader/ref-holders.mjs +29 -0
  39. package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -0
  40. package/dist/adapters/redocly-loader/remote-fetch.cjs +60 -0
  41. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -0
  42. package/dist/adapters/redocly-loader/remote-fetch.mjs +56 -0
  43. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -0
  44. package/dist/adapters/redocly-loader/schema-load-errors.cjs +87 -0
  45. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -0
  46. package/dist/adapters/redocly-loader/schema-load-errors.mjs +77 -0
  47. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -0
  48. package/dist/adapters/redocly-loader/schema-source.cjs +104 -0
  49. package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -0
  50. package/dist/adapters/redocly-loader/schema-source.mjs +98 -0
  51. package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -0
  52. package/dist/adapters/redocly-loader/unsupported-keys.cjs +62 -0
  53. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -0
  54. package/dist/adapters/redocly-loader/unsupported-keys.mjs +58 -0
  55. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -0
  56. package/dist/adapters/terminal-logger/terminal-logger.cjs +67 -0
  57. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -0
  58. package/dist/adapters/terminal-logger/terminal-logger.mjs +59 -0
  59. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -0
  60. package/dist/adapters/type-ast-bridge/footer-nodes.cjs +21 -0
  61. package/dist/adapters/type-ast-bridge/footer-nodes.cjs.map +1 -0
  62. package/dist/adapters/type-ast-bridge/footer-nodes.mjs +17 -0
  63. package/dist/adapters/type-ast-bridge/footer-nodes.mjs.map +1 -0
  64. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.cjs +75 -0
  65. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.cjs.map +1 -0
  66. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.mjs +71 -0
  67. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.mjs.map +1 -0
  68. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +145 -0
  69. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -0
  70. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +139 -0
  71. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -0
  72. package/dist/adapters/type-ast-bridge/lazy-node.cjs +23 -0
  73. package/dist/adapters/type-ast-bridge/lazy-node.cjs.map +1 -0
  74. package/dist/adapters/type-ast-bridge/lazy-node.mjs +21 -0
  75. package/dist/adapters/type-ast-bridge/lazy-node.mjs.map +1 -0
  76. package/dist/adapters/type-ast-bridge/load-typescript.cjs +57 -0
  77. package/dist/adapters/type-ast-bridge/load-typescript.cjs.map +1 -0
  78. package/dist/adapters/type-ast-bridge/load-typescript.mjs +51 -0
  79. package/dist/adapters/type-ast-bridge/load-typescript.mjs.map +1 -0
  80. package/dist/adapters/type-ast-bridge/print-typescript.cjs +21 -0
  81. package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -0
  82. package/dist/adapters/type-ast-bridge/print-typescript.mjs +19 -0
  83. package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -0
  84. package/dist/adapters/type-ast-bridge/typescript-raw-text.cjs +33 -0
  85. package/dist/adapters/type-ast-bridge/typescript-raw-text.cjs.map +1 -0
  86. package/dist/adapters/type-ast-bridge/typescript-raw-text.mjs +29 -0
  87. package/dist/adapters/type-ast-bridge/typescript-raw-text.mjs.map +1 -0
  88. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +204 -0
  89. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -0
  90. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +201 -0
  91. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -0
  92. package/dist/api/ast-to-string.cjs +39 -0
  93. package/dist/api/ast-to-string.cjs.map +1 -0
  94. package/dist/api/ast-to-string.mjs +37 -0
  95. package/dist/api/ast-to-string.mjs.map +1 -0
  96. package/dist/api/comment-header.cjs +11 -0
  97. package/dist/api/comment-header.cjs.map +1 -0
  98. package/dist/api/comment-header.mjs +9 -0
  99. package/dist/api/comment-header.mjs.map +1 -0
  100. package/dist/api/default-ports.cjs +38 -0
  101. package/dist/api/default-ports.cjs.map +1 -0
  102. package/dist/api/default-ports.mjs +28 -0
  103. package/dist/api/default-ports.mjs.map +1 -0
  104. package/dist/api/discriminator-enum.cjs +44 -0
  105. package/dist/api/discriminator-enum.cjs.map +1 -0
  106. package/dist/api/discriminator-enum.mjs +42 -0
  107. package/dist/api/discriminator-enum.mjs.map +1 -0
  108. package/dist/api/discriminator-scan.cjs +168 -0
  109. package/dist/api/discriminator-scan.cjs.map +1 -0
  110. package/dist/api/discriminator-scan.mjs +165 -0
  111. package/dist/api/discriminator-scan.mjs.map +1 -0
  112. package/dist/api/document-declarations.cjs +28 -0
  113. package/dist/api/document-declarations.cjs.map +1 -0
  114. package/dist/api/document-declarations.mjs +26 -0
  115. package/dist/api/document-declarations.mjs.map +1 -0
  116. package/dist/api/document-refs.cjs +53 -0
  117. package/dist/api/document-refs.cjs.map +1 -0
  118. package/dist/api/document-refs.mjs +50 -0
  119. package/dist/api/document-refs.mjs.map +1 -0
  120. package/dist/api/document-run.cjs +107 -0
  121. package/dist/api/document-run.cjs.map +1 -0
  122. package/dist/api/document-run.mjs +101 -0
  123. package/dist/api/document-run.mjs.map +1 -0
  124. package/dist/api/footer-entry.cjs +18 -0
  125. package/dist/api/footer-entry.cjs.map +1 -0
  126. package/dist/api/footer-entry.mjs +15 -0
  127. package/dist/api/footer-entry.mjs.map +1 -0
  128. package/dist/api/footer-sink.cjs +53 -0
  129. package/dist/api/footer-sink.cjs.map +1 -0
  130. package/dist/api/footer-sink.mjs +51 -0
  131. package/dist/api/footer-sink.mjs.map +1 -0
  132. package/dist/api/legacy-callback-warning.cjs +25 -0
  133. package/dist/api/legacy-callback-warning.cjs.map +1 -0
  134. package/dist/api/legacy-callback-warning.mjs +22 -0
  135. package/dist/api/legacy-callback-warning.mjs.map +1 -0
  136. package/dist/api/legacy-ts-helpers.cjs +203 -0
  137. package/dist/api/legacy-ts-helpers.cjs.map +1 -0
  138. package/dist/api/legacy-ts-helpers.mjs +187 -0
  139. package/dist/api/legacy-ts-helpers.mjs.map +1 -0
  140. package/dist/api/legacy-utils.cjs +65 -0
  141. package/dist/api/legacy-utils.cjs.map +1 -0
  142. package/dist/api/legacy-utils.mjs +50 -0
  143. package/dist/api/legacy-utils.mjs.map +1 -0
  144. package/dist/api/openapi-ts.cjs +40 -0
  145. package/dist/api/openapi-ts.cjs.map +1 -0
  146. package/dist/api/openapi-ts.mjs +34 -0
  147. package/dist/api/openapi-ts.mjs.map +1 -0
  148. package/dist/api/schema-callbacks.cjs +140 -0
  149. package/dist/api/schema-callbacks.cjs.map +1 -0
  150. package/dist/api/schema-callbacks.mjs +136 -0
  151. package/dist/api/schema-callbacks.mjs.map +1 -0
  152. package/dist/api/string-to-ast.cjs +21 -0
  153. package/dist/api/string-to-ast.cjs.map +1 -0
  154. package/dist/api/string-to-ast.mjs +18 -0
  155. package/dist/api/string-to-ast.mjs.map +1 -0
  156. package/dist/api/transform-context.cjs +82 -0
  157. package/dist/api/transform-context.cjs.map +1 -0
  158. package/dist/api/transform-context.mjs +65 -0
  159. package/dist/api/transform-context.mjs.map +1 -0
  160. package/dist/api/transform-schema.cjs +31 -0
  161. package/dist/api/transform-schema.cjs.map +1 -0
  162. package/dist/api/transform-schema.mjs +26 -0
  163. package/dist/api/transform-schema.mjs.map +1 -0
  164. package/dist/api/type-helpers.cjs +85 -0
  165. package/dist/api/type-helpers.cjs.map +1 -0
  166. package/dist/api/type-helpers.mjs +66 -0
  167. package/dist/api/type-helpers.mjs.map +1 -0
  168. package/dist/api/unsupported-feature-warnings.cjs +17 -0
  169. package/dist/api/unsupported-feature-warnings.cjs.map +1 -0
  170. package/dist/api/unsupported-feature-warnings.mjs +15 -0
  171. package/dist/api/unsupported-feature-warnings.mjs.map +1 -0
  172. package/dist/application/print/comment-writer.cjs +95 -0
  173. package/dist/application/print/comment-writer.cjs.map +1 -0
  174. package/dist/application/print/comment-writer.mjs +93 -0
  175. package/dist/application/print/comment-writer.mjs.map +1 -0
  176. package/dist/application/print/declaration-printer.cjs +83 -0
  177. package/dist/application/print/declaration-printer.cjs.map +1 -0
  178. package/dist/application/print/declaration-printer.mjs +81 -0
  179. package/dist/application/print/declaration-printer.mjs.map +1 -0
  180. package/dist/application/print/literal-text.cjs +52 -0
  181. package/dist/application/print/literal-text.cjs.map +1 -0
  182. package/dist/application/print/literal-text.mjs +48 -0
  183. package/dist/application/print/literal-text.mjs.map +1 -0
  184. package/dist/application/print/print-nodes.cjs +38 -0
  185. package/dist/application/print/print-nodes.cjs.map +1 -0
  186. package/dist/application/print/print-nodes.mjs +36 -0
  187. package/dist/application/print/print-nodes.mjs.map +1 -0
  188. package/dist/application/print/print-options.cjs +6 -0
  189. package/dist/application/print/print-options.cjs.map +1 -0
  190. package/dist/application/print/print-options.mjs +4 -0
  191. package/dist/application/print/print-options.mjs.map +1 -0
  192. package/dist/application/print/text-writer.cjs +63 -0
  193. package/dist/application/print/text-writer.cjs.map +1 -0
  194. package/dist/application/print/text-writer.mjs +60 -0
  195. package/dist/application/print/text-writer.mjs.map +1 -0
  196. package/dist/application/print/type-printer.cjs +214 -0
  197. package/dist/application/print/type-printer.cjs.map +1 -0
  198. package/dist/application/print/type-printer.mjs +210 -0
  199. package/dist/application/print/type-printer.mjs.map +1 -0
  200. package/dist/application/stack-overflow.cjs +36 -0
  201. package/dist/application/stack-overflow.cjs.map +1 -0
  202. package/dist/application/stack-overflow.mjs +31 -0
  203. package/dist/application/stack-overflow.mjs.map +1 -0
  204. package/dist/application/transform/document/components.cjs +104 -0
  205. package/dist/application/transform/document/components.cjs.map +1 -0
  206. package/dist/application/transform/document/components.mjs +102 -0
  207. package/dist/application/transform/document/components.mjs.map +1 -0
  208. package/dist/application/transform/document/defs-root.cjs +18 -0
  209. package/dist/application/transform/document/defs-root.cjs.map +1 -0
  210. package/dist/application/transform/document/defs-root.mjs +16 -0
  211. package/dist/application/transform/document/defs-root.mjs.map +1 -0
  212. package/dist/application/transform/document/document-member.cjs +13 -0
  213. package/dist/application/transform/document/document-member.cjs.map +1 -0
  214. package/dist/application/transform/document/document-member.mjs +11 -0
  215. package/dist/application/transform/document/document-member.mjs.map +1 -0
  216. package/dist/application/transform/document/document.cjs +86 -0
  217. package/dist/application/transform/document/document.cjs.map +1 -0
  218. package/dist/application/transform/document/document.mjs +83 -0
  219. package/dist/application/transform/document/document.mjs.map +1 -0
  220. package/dist/application/transform/document/header.cjs +27 -0
  221. package/dist/application/transform/document/header.cjs.map +1 -0
  222. package/dist/application/transform/document/header.mjs +25 -0
  223. package/dist/application/transform/document/header.mjs.map +1 -0
  224. package/dist/application/transform/document/kept-deprecated.cjs +96 -0
  225. package/dist/application/transform/document/kept-deprecated.cjs.map +1 -0
  226. package/dist/application/transform/document/kept-deprecated.mjs +94 -0
  227. package/dist/application/transform/document/kept-deprecated.mjs.map +1 -0
  228. package/dist/application/transform/document/media-type.cjs +42 -0
  229. package/dist/application/transform/document/media-type.cjs.map +1 -0
  230. package/dist/application/transform/document/media-type.mjs +38 -0
  231. package/dist/application/transform/document/media-type.mjs.map +1 -0
  232. package/dist/application/transform/document/operation.cjs +45 -0
  233. package/dist/application/transform/document/operation.cjs.map +1 -0
  234. package/dist/application/transform/document/operation.mjs +43 -0
  235. package/dist/application/transform/document/operation.mjs.map +1 -0
  236. package/dist/application/transform/document/parameter.cjs +25 -0
  237. package/dist/application/transform/document/parameter.cjs.map +1 -0
  238. package/dist/application/transform/document/parameter.mjs +23 -0
  239. package/dist/application/transform/document/parameter.mjs.map +1 -0
  240. package/dist/application/transform/document/parameters.cjs +114 -0
  241. package/dist/application/transform/document/parameters.cjs.map +1 -0
  242. package/dist/application/transform/document/parameters.mjs +112 -0
  243. package/dist/application/transform/document/parameters.mjs.map +1 -0
  244. package/dist/application/transform/document/path-item-conflicts.cjs +51 -0
  245. package/dist/application/transform/document/path-item-conflicts.cjs.map +1 -0
  246. package/dist/application/transform/document/path-item-conflicts.mjs +49 -0
  247. package/dist/application/transform/document/path-item-conflicts.mjs.map +1 -0
  248. package/dist/application/transform/document/path-item.cjs +82 -0
  249. package/dist/application/transform/document/path-item.cjs.map +1 -0
  250. package/dist/application/transform/document/path-item.mjs +80 -0
  251. package/dist/application/transform/document/path-item.mjs.map +1 -0
  252. package/dist/application/transform/document/path-key-overlaps.cjs +57 -0
  253. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -0
  254. package/dist/application/transform/document/path-key-overlaps.mjs +55 -0
  255. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -0
  256. package/dist/application/transform/document/paths-enum.cjs +75 -0
  257. package/dist/application/transform/document/paths-enum.cjs.map +1 -0
  258. package/dist/application/transform/document/paths-enum.mjs +72 -0
  259. package/dist/application/transform/document/paths-enum.mjs.map +1 -0
  260. package/dist/application/transform/document/paths.cjs +127 -0
  261. package/dist/application/transform/document/paths.cjs.map +1 -0
  262. package/dist/application/transform/document/paths.mjs +125 -0
  263. package/dist/application/transform/document/paths.mjs.map +1 -0
  264. package/dist/application/transform/document/request-body.cjs +36 -0
  265. package/dist/application/transform/document/request-body.cjs.map +1 -0
  266. package/dist/application/transform/document/request-body.mjs +34 -0
  267. package/dist/application/transform/document/request-body.mjs.map +1 -0
  268. package/dist/application/transform/document/response.cjs +59 -0
  269. package/dist/application/transform/document/response.cjs.map +1 -0
  270. package/dist/application/transform/document/response.mjs +57 -0
  271. package/dist/application/transform/document/response.mjs.map +1 -0
  272. package/dist/application/transform/document/responses.cjs +23 -0
  273. package/dist/application/transform/document/responses.cjs.map +1 -0
  274. package/dist/application/transform/document/responses.mjs +21 -0
  275. package/dist/application/transform/document/responses.mjs.map +1 -0
  276. package/dist/application/transform/document/root-type-aliases.cjs +69 -0
  277. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -0
  278. package/dist/application/transform/document/root-type-aliases.mjs +65 -0
  279. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -0
  280. package/dist/application/transform/document/webhooks.cjs +19 -0
  281. package/dist/application/transform/document/webhooks.cjs.map +1 -0
  282. package/dist/application/transform/document/webhooks.mjs +17 -0
  283. package/dist/application/transform/document/webhooks.mjs.map +1 -0
  284. package/dist/application/transform/document-entries.cjs +17 -0
  285. package/dist/application/transform/document-entries.cjs.map +1 -0
  286. package/dist/application/transform/document-entries.mjs +14 -0
  287. package/dist/application/transform/document-entries.mjs.map +1 -0
  288. package/dist/application/transform/footer/document-footer.cjs +88 -0
  289. package/dist/application/transform/footer/document-footer.cjs.map +1 -0
  290. package/dist/application/transform/footer/document-footer.mjs +86 -0
  291. package/dist/application/transform/footer/document-footer.mjs.map +1 -0
  292. package/dist/application/transform/footer/enum-naming.cjs +121 -0
  293. package/dist/application/transform/footer/enum-naming.cjs.map +1 -0
  294. package/dist/application/transform/footer/enum-naming.mjs +115 -0
  295. package/dist/application/transform/footer/enum-naming.mjs.map +1 -0
  296. package/dist/application/transform/helper-types.cjs +68 -0
  297. package/dist/application/transform/helper-types.cjs.map +1 -0
  298. package/dist/application/transform/helper-types.mjs +65 -0
  299. package/dist/application/transform/helper-types.mjs.map +1 -0
  300. package/dist/application/transform/literal-type.cjs +36 -0
  301. package/dist/application/transform/literal-type.cjs.map +1 -0
  302. package/dist/application/transform/literal-type.mjs +34 -0
  303. package/dist/application/transform/literal-type.mjs.map +1 -0
  304. package/dist/application/transform/numbered-names.cjs +18 -0
  305. package/dist/application/transform/numbered-names.cjs.map +1 -0
  306. package/dist/application/transform/numbered-names.mjs +16 -0
  307. package/dist/application/transform/numbered-names.mjs.map +1 -0
  308. package/dist/application/transform/ref-type.cjs +57 -0
  309. package/dist/application/transform/ref-type.cjs.map +1 -0
  310. package/dist/application/transform/ref-type.mjs +54 -0
  311. package/dist/application/transform/ref-type.mjs.map +1 -0
  312. package/dist/application/transform/schema/array-type.cjs +105 -0
  313. package/dist/application/transform/schema/array-type.cjs.map +1 -0
  314. package/dist/application/transform/schema/array-type.mjs +103 -0
  315. package/dist/application/transform/schema/array-type.mjs.map +1 -0
  316. package/dist/application/transform/schema/composition-type.cjs +107 -0
  317. package/dist/application/transform/schema/composition-type.cjs.map +1 -0
  318. package/dist/application/transform/schema/composition-type.mjs +105 -0
  319. package/dist/application/transform/schema/composition-type.mjs.map +1 -0
  320. package/dist/application/transform/schema/core-type.cjs +84 -0
  321. package/dist/application/transform/schema/core-type.cjs.map +1 -0
  322. package/dist/application/transform/schema/core-type.mjs +82 -0
  323. package/dist/application/transform/schema/core-type.mjs.map +1 -0
  324. package/dist/application/transform/schema/discriminator-property.cjs +21 -0
  325. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -0
  326. package/dist/application/transform/schema/discriminator-property.mjs +19 -0
  327. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -0
  328. package/dist/application/transform/schema/enum-rule.cjs +107 -0
  329. package/dist/application/transform/schema/enum-rule.cjs.map +1 -0
  330. package/dist/application/transform/schema/enum-rule.mjs +105 -0
  331. package/dist/application/transform/schema/enum-rule.mjs.map +1 -0
  332. package/dist/application/transform/schema/object-type.cjs +173 -0
  333. package/dist/application/transform/schema/object-type.cjs.map +1 -0
  334. package/dist/application/transform/schema/object-type.mjs +170 -0
  335. package/dist/application/transform/schema/object-type.mjs.map +1 -0
  336. package/dist/application/transform/schema/presence-members.cjs +59 -0
  337. package/dist/application/transform/schema/presence-members.cjs.map +1 -0
  338. package/dist/application/transform/schema/presence-members.mjs +57 -0
  339. package/dist/application/transform/schema/presence-members.mjs.map +1 -0
  340. package/dist/application/transform/schema/schema-transform.cjs +72 -0
  341. package/dist/application/transform/schema/schema-transform.cjs.map +1 -0
  342. package/dist/application/transform/schema/schema-transform.mjs +68 -0
  343. package/dist/application/transform/schema/schema-transform.mjs.map +1 -0
  344. package/dist/application/transform/schema/unevaluated-properties.cjs +61 -0
  345. package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -0
  346. package/dist/application/transform/schema/unevaluated-properties.mjs +59 -0
  347. package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -0
  348. package/dist/application/transform/schema-comment.cjs +84 -0
  349. package/dist/application/transform/schema-comment.cjs.map +1 -0
  350. package/dist/application/transform/schema-comment.mjs +81 -0
  351. package/dist/application/transform/schema-comment.mjs.map +1 -0
  352. package/dist/application/transform/shared-types.cjs +8 -0
  353. package/dist/application/transform/shared-types.cjs.map +1 -0
  354. package/dist/application/transform/shared-types.mjs +6 -0
  355. package/dist/application/transform/shared-types.mjs.map +1 -0
  356. package/dist/application/transform/type-combinators.cjs +49 -0
  357. package/dist/application/transform/type-combinators.cjs.map +1 -0
  358. package/dist/application/transform/type-combinators.mjs +42 -0
  359. package/dist/application/transform/type-combinators.mjs.map +1 -0
  360. package/dist/cli/cli-arguments.cjs +137 -0
  361. package/dist/cli/cli-arguments.cjs.map +1 -0
  362. package/dist/cli/cli-arguments.mjs +129 -0
  363. package/dist/cli/cli-arguments.mjs.map +1 -0
  364. package/dist/cli/cli-errors.cjs +80 -0
  365. package/dist/cli/cli-errors.cjs.map +1 -0
  366. package/dist/cli/cli-errors.mjs +76 -0
  367. package/dist/cli/cli-errors.mjs.map +1 -0
  368. package/dist/cli/cli-output.cjs +37 -0
  369. package/dist/cli/cli-output.cjs.map +1 -0
  370. package/dist/cli/cli-output.mjs +30 -0
  371. package/dist/cli/cli-output.mjs.map +1 -0
  372. package/dist/cli/docs-links.cjs +6 -0
  373. package/dist/cli/docs-links.cjs.map +1 -0
  374. package/dist/cli/docs-links.mjs +4 -0
  375. package/dist/cli/docs-links.mjs.map +1 -0
  376. package/dist/cli/fix-option.cjs +19 -0
  377. package/dist/cli/fix-option.cjs.map +1 -0
  378. package/dist/cli/fix-option.mjs +16 -0
  379. package/dist/cli/fix-option.mjs.map +1 -0
  380. package/dist/cli/help-text.cjs +44 -0
  381. package/dist/cli/help-text.cjs.map +1 -0
  382. package/dist/cli/help-text.mjs +42 -0
  383. package/dist/cli/help-text.mjs.map +1 -0
  384. package/dist/cli/main.cjs +62 -0
  385. package/dist/cli/main.cjs.map +1 -0
  386. package/dist/cli/main.d.cts +2 -0
  387. package/dist/cli/main.d.mts +2 -0
  388. package/dist/cli/main.d.ts +2 -0
  389. package/dist/cli/main.mjs +54 -0
  390. package/dist/cli/main.mjs.map +1 -0
  391. package/dist/cli/redocly-apis.cjs +65 -0
  392. package/dist/cli/redocly-apis.cjs.map +1 -0
  393. package/dist/cli/redocly-apis.mjs +62 -0
  394. package/dist/cli/redocly-apis.mjs.map +1 -0
  395. package/dist/cli/ref-limits.cjs +14 -0
  396. package/dist/cli/ref-limits.cjs.map +1 -0
  397. package/dist/cli/ref-limits.mjs +12 -0
  398. package/dist/cli/ref-limits.mjs.map +1 -0
  399. package/dist/cli/run-cli.cjs +100 -0
  400. package/dist/cli/run-cli.cjs.map +1 -0
  401. package/dist/cli/run-cli.mjs +98 -0
  402. package/dist/cli/run-cli.mjs.map +1 -0
  403. package/dist/domain/assert-never.cjs +8 -0
  404. package/dist/domain/assert-never.cjs.map +1 -0
  405. package/dist/domain/assert-never.mjs +6 -0
  406. package/dist/domain/assert-never.mjs.map +1 -0
  407. package/dist/domain/errors.cjs +50 -0
  408. package/dist/domain/errors.cjs.map +1 -0
  409. package/dist/domain/errors.mjs +46 -0
  410. package/dist/domain/errors.mjs.map +1 -0
  411. package/dist/domain/ir/constructors.cjs +89 -0
  412. package/dist/domain/ir/constructors.cjs.map +1 -0
  413. package/dist/domain/ir/constructors.mjs +71 -0
  414. package/dist/domain/ir/constructors.mjs.map +1 -0
  415. package/dist/domain/ir/identifier-text.cjs +29 -0
  416. package/dist/domain/ir/identifier-text.cjs.map +1 -0
  417. package/dist/domain/ir/identifier-text.mjs +25 -0
  418. package/dist/domain/ir/identifier-text.mjs.map +1 -0
  419. package/dist/domain/ir/newer-identifier-ranges.cjs +109 -0
  420. package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -0
  421. package/dist/domain/ir/newer-identifier-ranges.mjs +106 -0
  422. package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -0
  423. package/dist/domain/ir/normalize.cjs +32 -0
  424. package/dist/domain/ir/normalize.cjs.map +1 -0
  425. package/dist/domain/ir/normalize.mjs +29 -0
  426. package/dist/domain/ir/normalize.mjs.map +1 -0
  427. package/dist/domain/ir/property-name.cjs +19 -0
  428. package/dist/domain/ir/property-name.cjs.map +1 -0
  429. package/dist/domain/ir/property-name.mjs +16 -0
  430. package/dist/domain/ir/property-name.mjs.map +1 -0
  431. package/dist/domain/ir/raw-text-escapes.cjs +25 -0
  432. package/dist/domain/ir/raw-text-escapes.cjs.map +1 -0
  433. package/dist/domain/ir/raw-text-escapes.mjs +22 -0
  434. package/dist/domain/ir/raw-text-escapes.mjs.map +1 -0
  435. package/dist/domain/openapi/alias-expansion.cjs +50 -0
  436. package/dist/domain/openapi/alias-expansion.cjs.map +1 -0
  437. package/dist/domain/openapi/alias-expansion.mjs +45 -0
  438. package/dist/domain/openapi/alias-expansion.mjs.map +1 -0
  439. package/dist/domain/openapi/binary-content.cjs +48 -0
  440. package/dist/domain/openapi/binary-content.cjs.map +1 -0
  441. package/dist/domain/openapi/binary-content.mjs +45 -0
  442. package/dist/domain/openapi/binary-content.mjs.map +1 -0
  443. package/dist/domain/openapi/components-object.cjs +29 -0
  444. package/dist/domain/openapi/components-object.cjs.map +1 -0
  445. package/dist/domain/openapi/components-object.mjs +24 -0
  446. package/dist/domain/openapi/components-object.mjs.map +1 -0
  447. package/dist/domain/openapi/json-pointer.cjs +31 -0
  448. package/dist/domain/openapi/json-pointer.cjs.map +1 -0
  449. package/dist/domain/openapi/json-pointer.mjs +27 -0
  450. package/dist/domain/openapi/json-pointer.mjs.map +1 -0
  451. package/dist/domain/openapi/media-type-object.cjs +14 -0
  452. package/dist/domain/openapi/media-type-object.cjs.map +1 -0
  453. package/dist/domain/openapi/media-type-object.mjs +11 -0
  454. package/dist/domain/openapi/media-type-object.mjs.map +1 -0
  455. package/dist/domain/openapi/parameter-object.cjs +13 -0
  456. package/dist/domain/openapi/parameter-object.cjs.map +1 -0
  457. package/dist/domain/openapi/parameter-object.mjs +10 -0
  458. package/dist/domain/openapi/parameter-object.mjs.map +1 -0
  459. package/dist/domain/openapi/path-item-object.cjs +35 -0
  460. package/dist/domain/openapi/path-item-object.cjs.map +1 -0
  461. package/dist/domain/openapi/path-item-object.mjs +30 -0
  462. package/dist/domain/openapi/path-item-object.mjs.map +1 -0
  463. package/dist/domain/openapi/unsupported-features.cjs +87 -0
  464. package/dist/domain/openapi/unsupported-features.cjs.map +1 -0
  465. package/dist/domain/openapi/unsupported-features.mjs +84 -0
  466. package/dist/domain/openapi/unsupported-features.mjs.map +1 -0
  467. package/dist/domain/output-fixes.cjs +66 -0
  468. package/dist/domain/output-fixes.cjs.map +1 -0
  469. package/dist/domain/output-fixes.mjs +59 -0
  470. package/dist/domain/output-fixes.mjs.map +1 -0
  471. package/dist/index.cjs +98 -0
  472. package/dist/index.cjs.map +1 -0
  473. package/dist/index.d.cts +812 -0
  474. package/dist/index.d.mts +812 -0
  475. package/dist/index.d.ts +812 -0
  476. package/dist/index.mjs +27 -0
  477. package/dist/index.mjs.map +1 -0
  478. package/dist/transform/components-object.cjs +14 -0
  479. package/dist/transform/components-object.cjs.map +1 -0
  480. package/dist/transform/components-object.mjs +10 -0
  481. package/dist/transform/components-object.mjs.map +1 -0
  482. package/dist/transform/header-object.cjs +12 -0
  483. package/dist/transform/header-object.cjs.map +1 -0
  484. package/dist/transform/header-object.mjs +10 -0
  485. package/dist/transform/header-object.mjs.map +1 -0
  486. package/dist/transform/media-type-object.cjs +12 -0
  487. package/dist/transform/media-type-object.cjs.map +1 -0
  488. package/dist/transform/media-type-object.mjs +10 -0
  489. package/dist/transform/media-type-object.mjs.map +1 -0
  490. package/dist/transform/operation-object.cjs +26 -0
  491. package/dist/transform/operation-object.cjs.map +1 -0
  492. package/dist/transform/operation-object.mjs +21 -0
  493. package/dist/transform/operation-object.mjs.map +1 -0
  494. package/dist/transform/parameter-object.cjs +12 -0
  495. package/dist/transform/parameter-object.cjs.map +1 -0
  496. package/dist/transform/parameter-object.mjs +10 -0
  497. package/dist/transform/parameter-object.mjs.map +1 -0
  498. package/dist/transform/path-item-object.cjs +12 -0
  499. package/dist/transform/path-item-object.cjs.map +1 -0
  500. package/dist/transform/path-item-object.mjs +10 -0
  501. package/dist/transform/path-item-object.mjs.map +1 -0
  502. package/dist/transform/paths-object.cjs +11 -0
  503. package/dist/transform/paths-object.cjs.map +1 -0
  504. package/dist/transform/paths-object.mjs +9 -0
  505. package/dist/transform/paths-object.mjs.map +1 -0
  506. package/dist/transform/request-body-object.cjs +12 -0
  507. package/dist/transform/request-body-object.cjs.map +1 -0
  508. package/dist/transform/request-body-object.mjs +10 -0
  509. package/dist/transform/request-body-object.mjs.map +1 -0
  510. package/dist/transform/response-object.cjs +12 -0
  511. package/dist/transform/response-object.cjs.map +1 -0
  512. package/dist/transform/response-object.mjs +10 -0
  513. package/dist/transform/response-object.mjs.map +1 -0
  514. package/dist/transform/responses-object.cjs +12 -0
  515. package/dist/transform/responses-object.cjs.map +1 -0
  516. package/dist/transform/responses-object.mjs +10 -0
  517. package/dist/transform/responses-object.mjs.map +1 -0
  518. package/dist/transform/schema-object.cjs +21 -0
  519. package/dist/transform/schema-object.cjs.map +1 -0
  520. package/dist/transform/schema-object.mjs +16 -0
  521. package/dist/transform/schema-object.mjs.map +1 -0
  522. package/package.json +115 -4
  523. package/src/adapters/node-file-system/node-file-system.ts +44 -0
  524. package/src/adapters/redocly-loader/alias-limit.ts +20 -0
  525. package/src/adapters/redocly-loader/allowed-hosts.ts +62 -0
  526. package/src/adapters/redocly-loader/bundled-ref-repair.ts +65 -0
  527. package/src/adapters/redocly-loader/malformed-refs.ts +61 -0
  528. package/src/adapters/redocly-loader/redocly-config-source.ts +43 -0
  529. package/src/adapters/redocly-loader/redocly-schema-loader.ts +246 -0
  530. package/src/adapters/redocly-loader/ref-access.ts +146 -0
  531. package/src/adapters/redocly-loader/ref-holders.ts +43 -0
  532. package/src/adapters/redocly-loader/remote-fetch.ts +104 -0
  533. package/src/adapters/redocly-loader/schema-load-errors.ts +124 -0
  534. package/src/adapters/redocly-loader/schema-source.ts +151 -0
  535. package/src/adapters/redocly-loader/unsupported-keys.ts +102 -0
  536. package/src/adapters/terminal-logger/terminal-logger.ts +98 -0
  537. package/src/adapters/type-ast-bridge/footer-nodes.ts +38 -0
  538. package/src/adapters/type-ast-bridge/ir-declarations-to-typescript.ts +100 -0
  539. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +220 -0
  540. package/src/adapters/type-ast-bridge/lazy-node.ts +24 -0
  541. package/src/adapters/type-ast-bridge/load-typescript.ts +84 -0
  542. package/src/adapters/type-ast-bridge/print-typescript.ts +33 -0
  543. package/src/adapters/type-ast-bridge/typescript-raw-text.ts +49 -0
  544. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +280 -0
  545. package/src/adapters/type-ast-bridge/typescript-types.ts +8 -0
  546. package/src/api/ast-to-string.ts +59 -0
  547. package/src/api/comment-header.ts +7 -0
  548. package/src/api/default-ports.ts +44 -0
  549. package/src/api/discriminator-enum.ts +76 -0
  550. package/src/api/discriminator-scan.ts +272 -0
  551. package/src/api/document-declarations.ts +41 -0
  552. package/src/api/document-refs.ts +71 -0
  553. package/src/api/document-run.ts +159 -0
  554. package/src/api/footer-entry.ts +23 -0
  555. package/src/api/footer-sink.ts +67 -0
  556. package/src/api/legacy-callback-warning.ts +29 -0
  557. package/src/api/legacy-ts-helpers.ts +311 -0
  558. package/src/api/legacy-utils.ts +118 -0
  559. package/src/api/openapi-ts.ts +62 -0
  560. package/src/api/schema-callbacks.ts +211 -0
  561. package/src/api/string-to-ast.ts +27 -0
  562. package/src/api/transform-context.ts +87 -0
  563. package/src/api/transform-schema.ts +39 -0
  564. package/src/api/type-helpers.ts +130 -0
  565. package/src/api/unsupported-feature-warnings.ts +26 -0
  566. package/src/application/ports/file-system.ts +12 -0
  567. package/src/application/ports/logger.ts +16 -0
  568. package/src/application/ports/redocly-config-source.ts +16 -0
  569. package/src/application/ports/schema-loader.ts +32 -0
  570. package/src/application/print/comment-writer.ts +91 -0
  571. package/src/application/print/declaration-printer.ts +100 -0
  572. package/src/application/print/literal-text.ts +62 -0
  573. package/src/application/print/print-nodes.ts +62 -0
  574. package/src/application/print/print-options.ts +11 -0
  575. package/src/application/print/text-writer.ts +83 -0
  576. package/src/application/print/type-printer.ts +281 -0
  577. package/src/application/stack-overflow.ts +54 -0
  578. package/src/application/transform/document/components.ts +189 -0
  579. package/src/application/transform/document/defs-root.ts +25 -0
  580. package/src/application/transform/document/document-member.ts +20 -0
  581. package/src/application/transform/document/document.ts +157 -0
  582. package/src/application/transform/document/header.ts +34 -0
  583. package/src/application/transform/document/kept-deprecated.ts +135 -0
  584. package/src/application/transform/document/media-type.ts +78 -0
  585. package/src/application/transform/document/operation.ts +64 -0
  586. package/src/application/transform/document/parameter.ts +45 -0
  587. package/src/application/transform/document/parameters.ts +200 -0
  588. package/src/application/transform/document/path-item-conflicts.ts +79 -0
  589. package/src/application/transform/document/path-item.ts +168 -0
  590. package/src/application/transform/document/path-key-overlaps.ts +112 -0
  591. package/src/application/transform/document/paths-enum.ts +127 -0
  592. package/src/application/transform/document/paths.ts +211 -0
  593. package/src/application/transform/document/request-body.ts +50 -0
  594. package/src/application/transform/document/response.ts +109 -0
  595. package/src/application/transform/document/responses.ts +29 -0
  596. package/src/application/transform/document/root-type-aliases.ts +106 -0
  597. package/src/application/transform/document/webhooks.ts +22 -0
  598. package/src/application/transform/document-entries.ts +28 -0
  599. package/src/application/transform/footer/document-footer.ts +127 -0
  600. package/src/application/transform/footer/enum-naming.ts +181 -0
  601. package/src/application/transform/helper-types.ts +92 -0
  602. package/src/application/transform/literal-type.ts +54 -0
  603. package/src/application/transform/numbered-names.ts +20 -0
  604. package/src/application/transform/ref-type.ts +97 -0
  605. package/src/application/transform/schema/array-type.ts +152 -0
  606. package/src/application/transform/schema/composition-type.ts +183 -0
  607. package/src/application/transform/schema/core-type.ts +115 -0
  608. package/src/application/transform/schema/discriminator-property.ts +28 -0
  609. package/src/application/transform/schema/enum-rule.ts +157 -0
  610. package/src/application/transform/schema/object-type.ts +271 -0
  611. package/src/application/transform/schema/presence-members.ts +96 -0
  612. package/src/application/transform/schema/schema-context.ts +110 -0
  613. package/src/application/transform/schema/schema-rule.ts +29 -0
  614. package/src/application/transform/schema/schema-transform.ts +99 -0
  615. package/src/application/transform/schema/unevaluated-properties.ts +105 -0
  616. package/src/application/transform/schema-comment.ts +116 -0
  617. package/src/application/transform/shared-types.ts +9 -0
  618. package/src/application/transform/transform-context.ts +51 -0
  619. package/src/application/transform/type-combinators.ts +57 -0
  620. package/src/cli/cli-arguments.ts +198 -0
  621. package/src/cli/cli-dependencies.ts +42 -0
  622. package/src/cli/cli-errors.ts +125 -0
  623. package/src/cli/cli-output.ts +53 -0
  624. package/src/cli/docs-links.ts +6 -0
  625. package/src/cli/fix-option.ts +29 -0
  626. package/src/cli/help-text.ts +52 -0
  627. package/src/cli/main.ts +67 -0
  628. package/src/cli/redocly-apis.ts +91 -0
  629. package/src/cli/ref-limits.ts +16 -0
  630. package/src/cli/run-cli.ts +114 -0
  631. package/src/domain/assert-never.ts +8 -0
  632. package/src/domain/errors.ts +74 -0
  633. package/src/domain/ir/constructors.ts +137 -0
  634. package/src/domain/ir/identifier-text.ts +49 -0
  635. package/src/domain/ir/newer-identifier-ranges.ts +109 -0
  636. package/src/domain/ir/nodes.ts +224 -0
  637. package/src/domain/ir/normalize.ts +51 -0
  638. package/src/domain/ir/property-name.ts +28 -0
  639. package/src/domain/ir/raw-text-escapes.ts +37 -0
  640. package/src/domain/openapi/alias-expansion.ts +72 -0
  641. package/src/domain/openapi/binary-content.ts +74 -0
  642. package/src/domain/openapi/components-object.ts +52 -0
  643. package/src/domain/openapi/document-object.ts +12 -0
  644. package/src/domain/openapi/header-object.ts +9 -0
  645. package/src/domain/openapi/json-pointer.ts +46 -0
  646. package/src/domain/openapi/media-type-object.ts +26 -0
  647. package/src/domain/openapi/operation-object.ts +13 -0
  648. package/src/domain/openapi/parameter-object.ts +30 -0
  649. package/src/domain/openapi/path-item-object.ts +70 -0
  650. package/src/domain/openapi/request-body-object.ts +7 -0
  651. package/src/domain/openapi/response-object.ts +14 -0
  652. package/src/domain/openapi/schema-object.ts +59 -0
  653. package/src/domain/openapi/unsupported-features.ts +139 -0
  654. package/src/domain/output-fixes.ts +95 -0
  655. package/src/index.ts +67 -0
  656. package/src/transform/components-object.ts +25 -0
  657. package/src/transform/header-object.ts +19 -0
  658. package/src/transform/media-type-object.ts +19 -0
  659. package/src/transform/operation-object.ts +36 -0
  660. package/src/transform/parameter-object.ts +19 -0
  661. package/src/transform/parameters-array.ts +19 -0
  662. package/src/transform/path-item-object.ts +22 -0
  663. package/src/transform/paths-enum.ts +8 -0
  664. package/src/transform/paths-object.ts +15 -0
  665. package/src/transform/request-body-object.ts +19 -0
  666. package/src/transform/response-object.ts +19 -0
  667. package/src/transform/responses-object.ts +19 -0
  668. package/src/transform/schema-object.ts +36 -0
  669. package/src/transform/webhooks-object.ts +15 -0
  670. package/src/types/generator-options.ts +267 -0
  671. package/src/types/openapi-common.ts +100 -0
  672. package/src/types/openapi-document.ts +196 -0
  673. package/src/types/openapi-path-item.ts +130 -0
  674. package/src/types/openapi-request.ts +209 -0
  675. package/src/types/openapi-response.ts +81 -0
  676. package/src/types/openapi-schema.ts +169 -0
  677. package/src/types/openapi-security.ts +116 -0
  678. package/src/types.ts +12 -0
@@ -0,0 +1,272 @@
1
+ import type { Logger } from "../application/ports/logger.js";
2
+ import type {
3
+ DiscriminatorObject,
4
+ GeneratorOptions,
5
+ OpenAPI3,
6
+ ReferenceObject,
7
+ SchemaObject,
8
+ } from "../types.js";
9
+ import { defaultLogger } from "./default-ports.js";
10
+ import { addEnumProperty, type EnumPatch } from "./discriminator-enum.js";
11
+ import { resolveDocumentRef, walkDocument } from "./document-refs.js";
12
+ import { createRef } from "./legacy-utils.js";
13
+
14
+ /**
15
+ * The inherited discriminator pre-pass. It finds every discriminator in the bundled document and
16
+ * patches the mapped schemas in place with a required enum property, so that TypeScript can narrow
17
+ * the generated union. The behavior and the warning text match the original `scanDiscriminators`.
18
+ */
19
+
20
+ type DiscriminatorMapping = Record<string, { inferred?: string; defined?: string[] }>;
21
+
22
+ /** How to scan; `fixesValueConflicts` is the `discriminator-values` fix (ADR-021, roadmap R12). */
23
+ export interface DiscriminatorScanOptions {
24
+ readonly silent: boolean;
25
+ readonly logger: Logger;
26
+ readonly fixesValueConflicts: boolean;
27
+ }
28
+
29
+ /** What the two passes share: the document they patch and what they found so far. */
30
+ interface ScanState extends DiscriminatorScanOptions {
31
+ readonly schema: OpenAPI3;
32
+ readonly objects: Record<string, DiscriminatorObject>;
33
+ readonly refsHandled: string[];
34
+ /** With the fix: the enum added to each schema, by schema and property, so values merge. */
35
+ readonly patchedEnums: Map<string, SchemaObject>;
36
+ /** With the fix: schema-name values, applied after both passes where no mapping names one. */
37
+ readonly inferredPatches: EnumPatch[];
38
+ }
39
+
40
+ /** The enum the schema at `patch.ref` gets, or null (with a warning) for another kind of schema. */
41
+ function addDiscriminatorEnum(state: ScanState, patch: EnumPatch): SchemaObject | null {
42
+ const { silent, logger } = state;
43
+ const resolved = resolveDocumentRef<SchemaObject>(state.schema, patch.ref, { silent, logger });
44
+ const added = addEnumProperty(resolved, patch);
45
+ if (added === null) {
46
+ warnInvalidMapping(patch, state.logger);
47
+ }
48
+ return added;
49
+ }
50
+
51
+ /** One schema and discriminator property; two discriminators of one property share an enum. */
52
+ function enumKey(patch: EnumPatch): string {
53
+ return `${patch.ref}\n${patch.discriminator.propertyName}`;
54
+ }
55
+
56
+ /** With the fix, a second discriminator of the same property adds its values to the first enum. */
57
+ function mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly string[]): boolean {
58
+ const patched = state.patchedEnums.get(key);
59
+ if (patched === undefined) {
60
+ return false;
61
+ }
62
+ const merged = patched.enum as unknown[];
63
+ merged.push(...values.filter((value) => !merged.includes(value)));
64
+ return true;
65
+ }
66
+
67
+ /**
68
+ * Add or replace the discriminator enum in the schema at `patch.ref`. Returns false, with a
69
+ * warning, when that schema is neither an `allOf` nor an object schema. Without the fix every
70
+ * patch adds a property, so two discriminators with different values intersect to `never`.
71
+ */
72
+ function patchDiscriminatorEnum(state: ScanState, patch: EnumPatch): boolean {
73
+ if (!state.fixesValueConflicts) {
74
+ return addDiscriminatorEnum(state, patch) !== null;
75
+ }
76
+ const key = enumKey(patch);
77
+ if (mergeIntoPatchedEnum(state, key, patch.values)) {
78
+ return true;
79
+ }
80
+ const added = addDiscriminatorEnum(state, patch);
81
+ if (added !== null) {
82
+ state.patchedEnums.set(key, added);
83
+ }
84
+ return added !== null;
85
+ }
86
+
87
+ function markHandled(state: ScanState, ref: string): void {
88
+ if (!state.refsHandled.includes(ref)) {
89
+ state.refsHandled.push(ref);
90
+ }
91
+ }
92
+
93
+ function warnInvalidMapping(patch: EnumPatch, logger: Logger): void {
94
+ const mapped = `${patch.ref} => ${patch.values.join(", ")}`;
95
+ logger.warn(
96
+ "Discriminator mapping has an invalid schema (neither an object schema nor an allOf array): " +
97
+ `${mapped} (Discriminator: ${patch.discriminatorRef})`,
98
+ );
99
+ }
100
+
101
+ /** The schema name at the end of each `oneOf` `$ref` is the inferred discriminator value. */
102
+ function inferredMapping(oneOf: (SchemaObject | ReferenceObject)[]): DiscriminatorMapping {
103
+ const mapping: DiscriminatorMapping = {};
104
+ for (const item of oneOf) {
105
+ if (!("$ref" in item)) {
106
+ continue;
107
+ }
108
+ const value = item.$ref.split("/").pop();
109
+ if (value) {
110
+ mapping[item.$ref] = { ...mapping[item.$ref], inferred: value };
111
+ }
112
+ }
113
+ return mapping;
114
+ }
115
+
116
+ /** Values defined in `discriminator.mapping` replace inferred ones for the same schema. */
117
+ function addDefinedMapping(
118
+ mapping: DiscriminatorMapping,
119
+ discriminator: DiscriminatorObject,
120
+ ): void {
121
+ for (const [mappedValue, mappedRef] of Object.entries(discriminator.mapping ?? {})) {
122
+ if (!mappedRef) {
123
+ continue;
124
+ }
125
+ if (!mapping[mappedRef]?.defined) {
126
+ mapping[mappedRef] = { defined: [] };
127
+ }
128
+ mapping[mappedRef].defined?.push(mappedValue);
129
+ }
130
+ }
131
+
132
+ function patchMappedSchemas(
133
+ state: ScanState,
134
+ mapping: DiscriminatorMapping,
135
+ discriminator: Omit<EnumPatch, "ref" | "values">,
136
+ ): void {
137
+ for (const [ref, { inferred, defined }] of Object.entries(mapping)) {
138
+ const isSkipped = !state.fixesValueConflicts && state.refsHandled.includes(ref);
139
+ if (isSkipped || (!inferred && !defined)) {
140
+ continue;
141
+ }
142
+ // A defined value wins: the schema name may not be the value the API sends.
143
+ const values = defined ?? [inferred as string];
144
+ if (state.fixesValueConflicts && defined === undefined) {
145
+ // A mapping found later, in this pass or the next, may name the schema.
146
+ state.inferredPatches.push({ ...discriminator, ref, values });
147
+ } else if (patchDiscriminatorEnum(state, { ...discriminator, ref, values })) {
148
+ markHandled(state, ref);
149
+ }
150
+ }
151
+ }
152
+
153
+ /** Pass 1: collect every discriminator; patch the schemas of a discriminator + `oneOf`. */
154
+ function collectDiscriminator(
155
+ state: ScanState,
156
+ value: Record<string, unknown>,
157
+ path: (string | number)[],
158
+ ): void {
159
+ const discriminator = value.discriminator as DiscriminatorObject | undefined;
160
+ if (!discriminator?.propertyName) {
161
+ return;
162
+ }
163
+ const discriminatorRef = createRef(path);
164
+ state.objects[discriminatorRef] = discriminator;
165
+ if (!Array.isArray(value.oneOf)) {
166
+ return;
167
+ }
168
+ const mapping = inferredMapping(value.oneOf);
169
+ if (discriminator.mapping) {
170
+ addDefinedMapping(mapping, discriminator);
171
+ }
172
+ patchMappedSchemas(state, mapping, { discriminator, discriminatorRef });
173
+ }
174
+
175
+ /** The mapping keys of `discriminator` that point at `ref`. */
176
+ function valuesMappedTo(discriminator: DiscriminatorObject, ref: string): string[] {
177
+ return Object.entries(discriminator.mapping ?? {})
178
+ .filter(([, mappedRef]) => mappedRef === ref)
179
+ .map(([mappedValue]) => mappedValue);
180
+ }
181
+
182
+ /**
183
+ * An `allOf` item that is a `$ref` to a discriminator owner: the schema at `ref` inherits the
184
+ * discriminator, and gets its enum when the parent's mapping names it. Returns false when the
185
+ * `$ref` owns no discriminator, which ends the scan of this `allOf` (as in the original).
186
+ */
187
+ function inheritFromRef(state: ScanState, parentRef: string, ref: string): boolean {
188
+ const discriminator = state.objects[parentRef];
189
+ if (!discriminator) {
190
+ return false;
191
+ }
192
+ const values = valuesMappedTo(discriminator, ref);
193
+ const patch = { ref, values, discriminator, discriminatorRef: parentRef };
194
+ if (values.length > 0 && patchDiscriminatorEnum(state, patch)) {
195
+ markHandled(state, ref);
196
+ }
197
+ state.objects[ref] = { ...discriminator };
198
+ return true;
199
+ }
200
+
201
+ /** Pass 2: a schema whose `allOf` holds a discriminator, or a `$ref` to one, inherits it. */
202
+ function inheritDiscriminators(
203
+ state: ScanState,
204
+ value: Record<string, unknown>,
205
+ path: (string | number)[],
206
+ ): void {
207
+ if (!Array.isArray(value.allOf)) {
208
+ return;
209
+ }
210
+ for (const item of value.allOf as (SchemaObject | ReferenceObject)[]) {
211
+ if ("$ref" in item) {
212
+ if (!inheritFromRef(state, item.$ref, createRef(path))) {
213
+ return;
214
+ }
215
+ } else if (item.discriminator?.propertyName) {
216
+ state.objects[createRef(path)] = { ...item.discriminator };
217
+ }
218
+ }
219
+ }
220
+
221
+ /** The discriminators of a bundled document, after patching the mapped schemas in place. */
222
+ export interface DiscriminatorScan {
223
+ objects: Record<string, DiscriminatorObject>;
224
+ refsHandled: string[];
225
+ }
226
+
227
+ /**
228
+ * With the fix: a schema-name value, only for a schema and property that no mapping gave a value.
229
+ * Every enum patched so far came from a mapping, since schema-name values wait for this step.
230
+ */
231
+ function applyInferredPatches(state: ScanState): void {
232
+ const mapped = new Set(state.patchedEnums.keys());
233
+ for (const patch of state.inferredPatches) {
234
+ if (!mapped.has(enumKey(patch)) && patchDiscriminatorEnum(state, patch)) {
235
+ markHandled(state, patch.ref);
236
+ }
237
+ }
238
+ }
239
+
240
+ /** Find every discriminator in `schema`; warnings go to `logger` unless `silent`. */
241
+ export function findDiscriminators(
242
+ schema: OpenAPI3,
243
+ options: DiscriminatorScanOptions,
244
+ ): DiscriminatorScan {
245
+ const state: ScanState = {
246
+ ...options,
247
+ schema,
248
+ objects: {},
249
+ refsHandled: [],
250
+ patchedEnums: new Map(),
251
+ inferredPatches: [],
252
+ };
253
+ walkDocument(schema, (value, path) => collectDiscriminator(state, value, path));
254
+ // A second pass, because an `allOf` may name a discriminator that is defined later.
255
+ walkDocument(schema, (value, path) => inheritDiscriminators(state, value, path));
256
+ applyInferredPatches(state);
257
+ return { objects: state.objects, refsHandled: state.refsHandled };
258
+ }
259
+
260
+ /**
261
+ * Return a key–value map of discriminator objects found in a schema. Warnings go to `logger`;
262
+ * without one, to the default terminal logger, as the original did.
263
+ * @deprecated Kept for 1.x; removed in 2.0 (ADR-004, decision 9).
264
+ */
265
+ export function scanDiscriminators(
266
+ schema: OpenAPI3,
267
+ options: GeneratorOptions,
268
+ logger: Logger = defaultLogger(options.silent ?? false),
269
+ ): DiscriminatorScan {
270
+ const silent = options.silent ?? false;
271
+ return findDiscriminators(schema, { silent, logger, fixesValueConflicts: false });
272
+ }
@@ -0,0 +1,41 @@
1
+ import { loadTypeScript } from "../adapters/type-ast-bridge/load-typescript.js";
2
+ import { printWithTypeScript } from "../adapters/type-ast-bridge/print-typescript.js";
3
+ import type { ts } from "../adapters/type-ast-bridge/typescript-types.js";
4
+ import type { IrDeclaration } from "../domain/ir/nodes.js";
5
+ import { type FooterEntry, isIrDeclaration } from "./footer-entry.js";
6
+
7
+ /** The document in three parts; the footer may hold TypeScript nodes from user code. */
8
+ export interface TransformedDocument {
9
+ readonly body: readonly IrDeclaration[];
10
+ readonly footer: readonly FooterEntry[];
11
+ readonly closing: readonly IrDeclaration[];
12
+ }
13
+
14
+ /** The TypeScript printer ends the file with a line break; a raw declaration's text has none. */
15
+ function withoutFinalLineBreak(text: string): string {
16
+ return text.endsWith("\n") ? text.slice(0, -1) : text;
17
+ }
18
+
19
+ /** A TypeScript node from user code, as the TypeScript printer prints it. */
20
+ function printedNode(node: ts.Node): IrDeclaration {
21
+ return {
22
+ kind: "rawDeclaration",
23
+ text: withoutFinalLineBreak(printWithTypeScript(loadTypeScript(), [node])),
24
+ };
25
+ }
26
+
27
+ function entryDeclaration(entry: FooterEntry): IrDeclaration {
28
+ return isIrDeclaration(entry) ? entry : printedNode(entry);
29
+ }
30
+
31
+ /**
32
+ * The document as IR declarations in output order. Footer TypeScript nodes from user code become
33
+ * raw text through the bridge; raw text is printed as written (ADR-010, decision 4).
34
+ */
35
+ export function documentDeclarations({
36
+ body,
37
+ footer,
38
+ closing,
39
+ }: TransformedDocument): IrDeclaration[] {
40
+ return [...body, ...footer.map(entryDeclaration), ...closing];
41
+ }
@@ -0,0 +1,71 @@
1
+ import { parseRef } from "@redocly/openapi-core/lib/ref-utils.js";
2
+ import type { Logger } from "../application/ports/logger.js";
3
+ import { defaultLogger } from "./default-ports.js";
4
+
5
+ /** `$ref` resolution and the document walk that the generator's pre-pass uses. */
6
+
7
+ export interface ResolveRefOptions {
8
+ silent: boolean;
9
+ visited?: string[];
10
+ /** @internal Where warnings go; the default terminal logger (respecting `silent`) if absent. */
11
+ logger?: Logger;
12
+ }
13
+
14
+ /** Resolve a `$ref` in a document; warns and returns undefined when it cannot. */
15
+ export function resolveDocumentRef<T>(
16
+ schema: any,
17
+ $ref: string,
18
+ options: ResolveRefOptions,
19
+ ): T | undefined {
20
+ const { visited = [] } = options;
21
+ const logger = options.logger ?? defaultLogger(options.silent ?? false);
22
+ const { pointer } = parseRef($ref);
23
+ if (!pointer.length) {
24
+ return undefined;
25
+ }
26
+ let node = schema;
27
+ for (const key of pointer) {
28
+ if (node && typeof node === "object" && node[key]) {
29
+ node = node[key];
30
+ } else {
31
+ logger.warn(`Could not resolve $ref "${$ref}"`);
32
+ return undefined;
33
+ }
34
+ }
35
+
36
+ // if this is also a $ref, keep tracing
37
+ if (node && typeof node === "object" && node.$ref) {
38
+ if (visited.includes(node.$ref)) {
39
+ logger.warn(`Could not resolve circular $ref "${$ref}"`);
40
+ return undefined;
41
+ }
42
+ return resolveDocumentRef(schema, node.$ref, {
43
+ ...options,
44
+ logger,
45
+ visited: [...visited, node.$ref],
46
+ });
47
+ }
48
+
49
+ return node;
50
+ }
51
+
52
+ /** Call `cb` for every object in a JSON-serializable (non-circular) value, depth first. */
53
+ export function walkDocument(
54
+ obj: unknown,
55
+ cb: (value: Record<string, unknown>, path: (string | number)[]) => void,
56
+ path: (string | number)[] = [],
57
+ ): void {
58
+ if (!obj || typeof obj !== "object") {
59
+ return;
60
+ }
61
+ if (Array.isArray(obj)) {
62
+ for (let i = 0; i < obj.length; i++) {
63
+ walkDocument(obj[i], cb, path.concat(i));
64
+ }
65
+ return;
66
+ }
67
+ cb(obj as Record<string, unknown>, path);
68
+ for (const k of Object.keys(obj)) {
69
+ walkDocument((obj as Record<string, unknown>)[k], cb, path.concat(k));
70
+ }
71
+ }
@@ -0,0 +1,159 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath, pathToFileURL } from "node:url";
3
+ import type { Config as RedoclyConfig } from "@redocly/openapi-core";
4
+ import { sourceEmptyError } from "../adapters/redocly-loader/schema-load-errors.js";
5
+ import type { Logger } from "../application/ports/logger.js";
6
+ import type { RefAccess, SchemaLoader } from "../application/ports/schema-loader.js";
7
+ import { withStackOverflowReported } from "../application/stack-overflow.js";
8
+ import {
9
+ ineffectiveFixNotices,
10
+ OutputFix,
11
+ outputFixNamesOf,
12
+ resolveOutputFixes,
13
+ } from "../domain/output-fixes.js";
14
+ import type { GeneratorOptions, GlobalContext, OpenAPI3, SchemaSource } from "../types.js";
15
+ import { findDiscriminators } from "./discriminator-scan.js";
16
+ import { resolveDocumentRef } from "./document-refs.js";
17
+ import { warnUnsupportedFeatures } from "./unsupported-feature-warnings.js";
18
+
19
+ /** The ports of one generator run, wired by the Node API or the CLI (ENGINEERING_PLAN 4.5). */
20
+ export interface GeneratorPorts {
21
+ readonly loader: SchemaLoader;
22
+ readonly logger: Logger;
23
+ /** The Redocly config the loader uses; the run's context exposes it as `ctx.redoc`. */
24
+ readonly redoc: RedoclyConfig;
25
+ /** A monotonic time in milliseconds, for debug durations. */
26
+ readonly now: () => number;
27
+ }
28
+
29
+ /** A validated, bundled document and the context of one generator run. */
30
+ export interface DocumentRun {
31
+ readonly schema: OpenAPI3;
32
+ readonly ctx: GlobalContext;
33
+ }
34
+
35
+ /** The context fields that are user flags, with the original defaults. */
36
+ type ContextFlags = Omit<
37
+ GlobalContext,
38
+ | "discriminators"
39
+ | "injectFooter"
40
+ | "redoc"
41
+ | "resolve"
42
+ | "runFooter"
43
+ | "legacyCallbackWarnings"
44
+ | "logger"
45
+ | "fix"
46
+ >;
47
+
48
+ function sourceCwd(options: GeneratorOptions): URL {
49
+ return options.cwd instanceof URL
50
+ ? options.cwd
51
+ : new URL(`file://${options.cwd ?? process.cwd()}/`);
52
+ }
53
+
54
+ /** The `$ref` limits of the options; a relative local root resolves against the cwd. */
55
+ function refAccessOf(options: GeneratorOptions, cwd: URL): RefAccess {
56
+ const { localRefRoot, remoteRefHosts } = options;
57
+ const localRoot =
58
+ typeof localRefRoot === "string"
59
+ ? pathToFileURL(path.resolve(fileURLToPath(cwd), localRefRoot))
60
+ : localRefRoot;
61
+ return {
62
+ ...(localRoot === undefined ? {} : { localRoot }),
63
+ ...(remoteRefHosts === undefined ? {} : { remoteHosts: remoteRefHosts }),
64
+ };
65
+ }
66
+
67
+ function callbackOptions(options: GeneratorOptions) {
68
+ return {
69
+ irCallbacks: options.irCallbacks === true,
70
+ postTransform: typeof options.postTransform === "function" ? options.postTransform : undefined,
71
+ transform: typeof options.transform === "function" ? options.transform : undefined,
72
+ transformProperty:
73
+ typeof options.transformProperty === "function" ? options.transformProperty : undefined,
74
+ };
75
+ }
76
+
77
+ function contextFlags(options: GeneratorOptions): ContextFlags {
78
+ return {
79
+ additionalProperties: options.additionalProperties ?? false,
80
+ alphabetize: options.alphabetize ?? false,
81
+ arrayLength: options.arrayLength ?? false,
82
+ binaryAsBlob: options.binaryAsBlob ?? false,
83
+ defaultNonNullable: options.defaultNonNullable ?? true,
84
+ emptyObjectsUnknown: options.emptyObjectsUnknown ?? false,
85
+ enum: options.enum ?? false,
86
+ enumValues: options.enumValues ?? false,
87
+ conditionalEnums: options.conditionalEnums ?? false,
88
+ dedupeEnums: options.dedupeEnums ?? false,
89
+ excludeDeprecated: options.excludeDeprecated ?? false,
90
+ exportType: options.exportType ?? false,
91
+ immutable: options.immutable ?? false,
92
+ rootTypes: options.rootTypes ?? false,
93
+ rootTypesNoSchemaPrefix: options.rootTypesNoSchemaPrefix ?? false,
94
+ rootTypesKeepCasing: options.rootTypesKeepCasing ?? false,
95
+ pathParamsAsTypes: options.pathParamsAsTypes ?? false,
96
+ propertiesRequiredByDefault: options.propertiesRequiredByDefault ?? false,
97
+ silent: options.silent ?? false,
98
+ ...(options.inject === undefined ? {} : { inject: options.inject }),
99
+ makePathsEnum: options.makePathsEnum ?? false,
100
+ generatePathParams: options.generatePathParams ?? false,
101
+ readWriteMarkers: options.readWriteMarkers ?? false,
102
+ ...callbackOptions(options),
103
+ };
104
+ }
105
+
106
+ /**
107
+ * The fixes of the options, `all` expanded; fails with `OPTION_FIX_UNKNOWN` for another name.
108
+ * A fix named without the option it needs is reported, since it changes nothing.
109
+ */
110
+ function outputFixesOf(options: GeneratorOptions, logger: Logger): readonly OutputFix[] {
111
+ const names = outputFixNamesOf(options.fix ?? []);
112
+ for (const notice of ineffectiveFixNotices(names, (option) => options[option] === true)) {
113
+ logger.warn(notice);
114
+ }
115
+ return [...resolveOutputFixes(names)];
116
+ }
117
+
118
+ /**
119
+ * Load the source through the ports, then build the run's context from the options. The fix names
120
+ * are checked first, so a typo fails before the document is read.
121
+ */
122
+ export async function createDocumentRun(
123
+ source: SchemaSource,
124
+ options: GeneratorOptions,
125
+ ports: GeneratorPorts,
126
+ ): Promise<DocumentRun> {
127
+ if (!source) {
128
+ throw sourceEmptyError("Empty schema. Please specify a URL, file path, or Redocly Config");
129
+ }
130
+ const { logger } = ports;
131
+ const fix = outputFixesOf(options, logger);
132
+ const silent = options.silent ?? false;
133
+ const cwd = sourceCwd(options);
134
+ const schema = await ports.loader.load({
135
+ source,
136
+ cwd,
137
+ shouldLint: options.lint ?? true,
138
+ refAccess: refAccessOf(options, cwd),
139
+ });
140
+ withStackOverflowReported("transform", () => warnUnsupportedFeatures(schema, logger));
141
+ const ctx: GlobalContext = {
142
+ ...contextFlags(options),
143
+ fix,
144
+ // The scan walks every schema before the transform does, so on a larger stack, where loading
145
+ // passed, it is the first step to run out.
146
+ discriminators: withStackOverflowReported("transform", () =>
147
+ findDiscriminators(schema, {
148
+ silent,
149
+ logger,
150
+ fixesValueConflicts: fix.includes(OutputFix.DISCRIMINATOR_VALUES),
151
+ }),
152
+ ),
153
+ injectFooter: [],
154
+ redoc: ports.redoc,
155
+ resolve: ($ref) => resolveDocumentRef(schema, $ref, { silent, logger }),
156
+ logger,
157
+ };
158
+ return { schema, ctx };
159
+ }
@@ -0,0 +1,23 @@
1
+ import { isTypeAliasNamed } from "../adapters/type-ast-bridge/footer-nodes.js";
2
+ import { loadTypeScript } from "../adapters/type-ast-bridge/load-typescript.js";
3
+ import type { ts } from "../adapters/type-ast-bridge/typescript-types.js";
4
+ import type { IrDeclaration } from "../domain/ir/nodes.js";
5
+
6
+ /** A footer entry: a declaration in IR, or a TypeScript node added by user code. */
7
+ export type FooterEntry = IrDeclaration | ts.Node;
8
+
9
+ /** IR nodes have a string `kind`; TypeScript nodes have a numeric `SyntaxKind`. */
10
+ export function isIrDeclaration(entry: FooterEntry): entry is IrDeclaration {
11
+ return typeof entry.kind === "string";
12
+ }
13
+
14
+ /**
15
+ * Whether the entry declares a type alias with this name: an IR type alias, a named raw
16
+ * declaration (the helper types), or a user's TypeScript type alias. Helpers are added once.
17
+ */
18
+ export function declaresTypeAlias(entry: FooterEntry, name: string): boolean {
19
+ if (!isIrDeclaration(entry)) {
20
+ return isTypeAliasNamed(loadTypeScript(), entry, name);
21
+ }
22
+ return (entry.kind === "typeAlias" || entry.kind === "rawDeclaration") && entry.name === name;
23
+ }
@@ -0,0 +1,67 @@
1
+ import { appendMember, asInterfaceNamed } from "../adapters/type-ast-bridge/footer-nodes.js";
2
+ import { loadTypeScript } from "../adapters/type-ast-bridge/load-typescript.js";
3
+ import type { FooterSink } from "../application/transform/footer/document-footer.js";
4
+ import type {
5
+ IrDeclaration,
6
+ IrInterfaceDeclaration,
7
+ IrPropertySignature,
8
+ } from "../domain/ir/nodes.js";
9
+ import { declaresTypeAlias, type FooterEntry, isIrDeclaration } from "./footer-entry.js";
10
+
11
+ const OPERATIONS_NAME = "operations";
12
+
13
+ /**
14
+ * The footer of a run is its `ctx.injectFooter` list. The generator adds IR declarations; user
15
+ * code may add IR declarations or TypeScript nodes (ENGINEERING_PLAN 6.2).
16
+ */
17
+ export class ContextFooterSink implements FooterSink {
18
+ private readonly footer: FooterEntry[];
19
+
20
+ constructor(footer: FooterEntry[]) {
21
+ this.footer = footer;
22
+ }
23
+
24
+ hasTypeAlias(name: string): boolean {
25
+ return this.footer.some((entry) => declaresTypeAlias(entry, name));
26
+ }
27
+
28
+ add(declaration: IrDeclaration): void {
29
+ this.footer.push(declaration);
30
+ }
31
+
32
+ /**
33
+ * Add a member to the `operations` interface, declared first (exported) when missing, so it
34
+ * comes before any declaration `build` adds. A user's TypeScript `operations` interface gets
35
+ * the member in place, as in the original.
36
+ */
37
+ addOperation(build: () => IrPropertySignature): void {
38
+ const existing = this.findOperations();
39
+ if (existing !== null && !isIrDeclaration(existing.entry)) {
40
+ const ts = loadTypeScript();
41
+ const node = asInterfaceNamed(ts, existing.entry, OPERATIONS_NAME);
42
+ if (node) {
43
+ appendMember(ts, node, build());
44
+ }
45
+ return;
46
+ }
47
+ const index = existing?.index ?? this.footer.push(emptyOperations()) - 1;
48
+ const member = build();
49
+ const operations = this.footer[index] as IrInterfaceDeclaration;
50
+ this.footer[index] = { ...operations, members: [...operations.members, member] };
51
+ }
52
+
53
+ /** The first `operations` interface: the generator's (IR) or a user's (TypeScript). */
54
+ private findOperations(): { entry: FooterEntry; index: number } | null {
55
+ const index = this.footer.findIndex((entry) =>
56
+ isIrDeclaration(entry)
57
+ ? entry.kind === "interface" && entry.name === OPERATIONS_NAME
58
+ : asInterfaceNamed(loadTypeScript(), entry, OPERATIONS_NAME) !== null,
59
+ );
60
+ const entry = this.footer[index];
61
+ return entry === undefined ? null : { entry, index };
62
+ }
63
+ }
64
+
65
+ function emptyOperations(): IrInterfaceDeclaration {
66
+ return { kind: "interface", name: OPERATIONS_NAME, isExported: true, members: [], comments: [] };
67
+ }
@@ -0,0 +1,29 @@
1
+ import type { GlobalContext, LegacyCallbackName } from "../types.js";
2
+ import { defaultLogger } from "./default-ports.js";
3
+
4
+ /** Where the IR callbacks are documented; the warning points users there. */
5
+ export const IR_CALLBACKS_GUIDE_URL =
6
+ "https://github.com/openapi-typesafe/openapi-typesafe/blob/main/docs/node.md#ir-callbacks";
7
+
8
+ const USES: Readonly<Record<LegacyCallbackName, string>> = {
9
+ transform: "`transform` returned a TypeScript node",
10
+ postTransform: "`postTransform` receives TypeScript nodes",
11
+ transformProperty: "`transformProperty` receives TypeScript nodes",
12
+ };
13
+
14
+ function message(name: LegacyCallbackName): string {
15
+ return (
16
+ `${USES[name]}. This form works in 1.x through the TypeScript bridge and is removed in 2.0. ` +
17
+ `Use irCallbacks: true and return IR or type text instead: ${IR_CALLBACKS_GUIDE_URL}`
18
+ );
19
+ }
20
+
21
+ /** Warn once per run and callback; `silent` runs record the use but print nothing. */
22
+ export function warnLegacyCallback(ctx: GlobalContext, name: LegacyCallbackName): void {
23
+ ctx.legacyCallbackWarnings ??= new Set();
24
+ if (ctx.legacyCallbackWarnings.has(name)) {
25
+ return;
26
+ }
27
+ ctx.legacyCallbackWarnings.add(name);
28
+ (ctx.logger ?? defaultLogger(ctx.silent)).warn(message(name));
29
+ }