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,98 @@
1
+ import colors from "ansi-colors";
2
+ import type { DebugGroup, Logger } from "../../application/ports/logger.js";
3
+
4
+ /**
5
+ * The Logger port on a terminal, with the original output format: ` ⚠ ` warnings, ` ✘ `
6
+ * errors, and `openapi-ts:<group>` debug lines filtered by `DEBUG` (ENGINEERING_PLAN 4.5).
7
+ */
8
+
9
+ /** Where the lines go: `console` in production, a recording sink in tests. */
10
+ export interface TerminalSink {
11
+ debug(line: string): void;
12
+ warn(line: string): void;
13
+ error(line: string): void;
14
+ }
15
+
16
+ export interface TerminalLoggerOptions {
17
+ /** Drop warnings (errors and debug lines are still written). */
18
+ readonly silent: boolean;
19
+ /** The value of `DEBUG`: `*`, `openapi-ts:*` or `openapi-ts:<group>` turn debug lines on. */
20
+ readonly debugFilter: string | undefined;
21
+ readonly useColors: boolean;
22
+ readonly sink: TerminalSink;
23
+ }
24
+
25
+ type Colors = ReturnType<typeof colors.create>;
26
+
27
+ const MILLISECONDS_PER_SECOND = 1000;
28
+ const MILLISECONDS_PER_MINUTE = 60_000;
29
+
30
+ /** A duration as the original prints it: one decimal, in ms, s or m. */
31
+ export function formatDuration(milliseconds: number): string {
32
+ if (milliseconds < MILLISECONDS_PER_SECOND) {
33
+ return `${Math.round(10 * milliseconds) / 10}ms`;
34
+ }
35
+ if (milliseconds < MILLISECONDS_PER_MINUTE) {
36
+ return `${Math.round(milliseconds / 100) / 10}s`;
37
+ }
38
+ return `${Math.round(milliseconds / 6000) / 10}m`;
39
+ }
40
+
41
+ function groupColor(palette: Colors, group: DebugGroup | undefined): (text: string) => string {
42
+ const byGroup: Readonly<Partial<Record<DebugGroup, (text: string) => string>>> = {
43
+ redoc: palette.cyanBright,
44
+ lint: palette.yellowBright,
45
+ bundle: palette.magentaBright,
46
+ ts: palette.blueBright,
47
+ };
48
+ return (group && byGroup[group]) || palette.whiteBright;
49
+ }
50
+
51
+ /** Whether `DEBUG` asks for this group (the original check, case-insensitive for the group). */
52
+ export function isDebugEnabled(filter: string | undefined, group: DebugGroup | undefined): boolean {
53
+ if (!filter) {
54
+ return false;
55
+ }
56
+ return (
57
+ !group ||
58
+ filter === "*" ||
59
+ filter === "openapi-ts:*" ||
60
+ filter.toLocaleLowerCase() === `openapi-ts:${group.toLocaleLowerCase()}`
61
+ );
62
+ }
63
+
64
+ class TerminalLogger implements Logger {
65
+ readonly #options: TerminalLoggerOptions;
66
+ readonly #palette: Colors;
67
+
68
+ constructor(options: TerminalLoggerOptions) {
69
+ this.#options = options;
70
+ this.#palette = colors.create();
71
+ this.#palette.enabled = options.useColors;
72
+ }
73
+
74
+ debug(message: string, group?: DebugGroup, durationMs?: number): void {
75
+ if (!isDebugEnabled(this.#options.debugFilter, group)) {
76
+ return;
77
+ }
78
+ const name = groupColor(this.#palette, group)(`openapi-ts:${group ?? "info"}`);
79
+ const time =
80
+ durationMs === undefined ? "" : this.#palette.green(` ${formatDuration(durationMs)} `);
81
+ this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${message}`);
82
+ }
83
+
84
+ warn(message: string): void {
85
+ if (!this.#options.silent) {
86
+ this.#options.sink.warn(this.#palette.yellow(` ⚠ ${message}`));
87
+ }
88
+ }
89
+
90
+ error(message: string): void {
91
+ this.#options.sink.error(this.#palette.red(` ✘ ${message}`));
92
+ }
93
+ }
94
+
95
+ /** A Logger that writes to a terminal sink. */
96
+ export function createTerminalLogger(options: TerminalLoggerOptions): Logger {
97
+ return new TerminalLogger(options);
98
+ }
@@ -0,0 +1,38 @@
1
+ import type ts from "typescript";
2
+ import type { IrPropertySignature } from "../../domain/ir/nodes.js";
3
+ import { toPropertySignature } from "./ir-to-typescript.js";
4
+ import type { TypeScriptModule } from "./load-typescript.js";
5
+
6
+ /**
7
+ * TypeScript nodes that user code adds to the footer (`ctx.injectFooter`). The generator's own
8
+ * footer entries are IR; these functions are the only places that read or change a user's node.
9
+ */
10
+
11
+ /** Whether the node is a type alias with this name (the original's helper check). */
12
+ export function isTypeAliasNamed(ts: TypeScriptModule, node: ts.Node, name: string): boolean {
13
+ return ts.isTypeAliasDeclaration(node) && node.name.text === name;
14
+ }
15
+
16
+ /** The node as an interface with this name, or null. */
17
+ export function asInterfaceNamed(
18
+ ts: TypeScriptModule,
19
+ node: ts.Node,
20
+ name: string,
21
+ ): ts.InterfaceDeclaration | null {
22
+ return ts.isInterfaceDeclaration(node) && node.name.text === name ? node : null;
23
+ }
24
+
25
+ /**
26
+ * Add a member to a user's interface in place, as the original `injectOperationObject` did:
27
+ * other references to the node see the member.
28
+ */
29
+ export function appendMember(
30
+ ts: TypeScriptModule,
31
+ node: ts.InterfaceDeclaration,
32
+ member: IrPropertySignature,
33
+ ): void {
34
+ (node as { members: ts.NodeArray<ts.TypeElement> }).members = ts.factory.createNodeArray([
35
+ ...node.members,
36
+ toPropertySignature(ts, member),
37
+ ]);
38
+ }
@@ -0,0 +1,100 @@
1
+ import type ts from "typescript";
2
+ import { assertNever } from "../../domain/assert-never.js";
3
+ import type { IrDeclaration } from "../../domain/ir/nodes.js";
4
+ import { toTypeElement, toTypeNode, toValueExpression, withComments } from "./ir-to-typescript.js";
5
+ import type { TypeScriptModule } from "./load-typescript.js";
6
+
7
+ /**
8
+ * Convert IR declarations to TypeScript statements, with the factory calls the original makes
9
+ * (see `ir-to-typescript.ts` for types and members).
10
+ */
11
+
12
+ function exportModifiers(ts: TypeScriptModule, isExported: boolean): ts.Modifier[] | undefined {
13
+ return isExported ? [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)] : undefined;
14
+ }
15
+
16
+ function toConstArrayStatement(
17
+ ts: TypeScriptModule,
18
+ declaration: Extract<IrDeclaration, { kind: "constArray" }>,
19
+ ): ts.Statement {
20
+ const initializer = ts.factory.createArrayLiteralExpression(
21
+ declaration.values.map((value) => toValueExpression(ts, value)),
22
+ );
23
+ const variable = ts.factory.createVariableDeclaration(
24
+ declaration.name,
25
+ undefined,
26
+ toTypeNode(ts, declaration.type),
27
+ initializer,
28
+ );
29
+ const list = ts.factory.createVariableDeclarationList([variable], ts.NodeFlags.Const);
30
+ return ts.factory.createVariableStatement(exportModifiers(ts, declaration.isExported), list);
31
+ }
32
+
33
+ /** Parse source text into statements, like the original's `stringToAST`. */
34
+ export function parseStatements(ts: TypeScriptModule, text: string): readonly ts.Statement[] {
35
+ return ts.createSourceFile("raw.ts", text, ts.ScriptTarget.ESNext).statements;
36
+ }
37
+
38
+ /** Convert one IR declaration; a raw declaration gives every statement its text holds. */
39
+ export function toStatements(ts: TypeScriptModule, declaration: IrDeclaration): ts.Statement[] {
40
+ return declaration.kind === "rawDeclaration"
41
+ ? [...parseStatements(ts, declaration.text)]
42
+ : [toStatement(ts, declaration)];
43
+ }
44
+
45
+ function toEnumStatement(
46
+ ts: TypeScriptModule,
47
+ declaration: Extract<IrDeclaration, { kind: "enum" }>,
48
+ ): ts.Statement {
49
+ const members = declaration.members.map((member) =>
50
+ withComments(
51
+ ts,
52
+ ts.factory.createEnumMember(member.name, toValueExpression(ts, member.value)),
53
+ member.comments,
54
+ ),
55
+ );
56
+ const modifiers = exportModifiers(ts, declaration.isExported);
57
+ return ts.factory.createEnumDeclaration(modifiers, declaration.name, members);
58
+ }
59
+
60
+ function toInterfaceStatement(
61
+ ts: TypeScriptModule,
62
+ declaration: Extract<IrDeclaration, { kind: "interface" }>,
63
+ ): ts.Statement {
64
+ const members = declaration.members.map((member) => toTypeElement(ts, member));
65
+ const modifiers = exportModifiers(ts, declaration.isExported);
66
+ return ts.factory.createInterfaceDeclaration(
67
+ modifiers,
68
+ declaration.name,
69
+ undefined,
70
+ undefined,
71
+ members,
72
+ );
73
+ }
74
+
75
+ function toTypeAliasStatement(
76
+ ts: TypeScriptModule,
77
+ declaration: Extract<IrDeclaration, { kind: "typeAlias" }>,
78
+ ): ts.Statement {
79
+ const type = toTypeNode(ts, declaration.type);
80
+ const modifiers = exportModifiers(ts, declaration.isExported);
81
+ return ts.factory.createTypeAliasDeclaration(modifiers, declaration.name, undefined, type);
82
+ }
83
+
84
+ /** Convert one IR declaration. A raw declaration is parsed, like the original's `stringToAST`. */
85
+ export function toStatement(ts: TypeScriptModule, declaration: IrDeclaration): ts.Statement {
86
+ switch (declaration.kind) {
87
+ case "interface":
88
+ return withComments(ts, toInterfaceStatement(ts, declaration), declaration.comments);
89
+ case "typeAlias":
90
+ return withComments(ts, toTypeAliasStatement(ts, declaration), declaration.comments);
91
+ case "enum":
92
+ return withComments(ts, toEnumStatement(ts, declaration), declaration.comments);
93
+ case "constArray":
94
+ return withComments(ts, toConstArrayStatement(ts, declaration), declaration.comments);
95
+ case "rawDeclaration":
96
+ return parseStatements(ts, declaration.text)[0] as ts.Statement;
97
+ default:
98
+ return assertNever(declaration);
99
+ }
100
+ }
@@ -0,0 +1,220 @@
1
+ import type ts from "typescript";
2
+ import { assertNever } from "../../domain/assert-never.js";
3
+ import type {
4
+ IrComment,
5
+ IrKeyword,
6
+ IrMember,
7
+ IrPropertyName,
8
+ IrPropertySignature,
9
+ IrTupleElement,
10
+ IrType,
11
+ } from "../../domain/ir/nodes.js";
12
+ import type { TypeScriptModule } from "./load-typescript.js";
13
+
14
+ /**
15
+ * Convert IR to TypeScript AST nodes with the same factory calls the original generator makes.
16
+ * Printing the result with the TypeScript printer gives the original output, which is how the
17
+ * printer parity tests (ENGINEERING_PLAN 4.3) define "byte-identical". Every function takes the
18
+ * TypeScript module to build with (ADR-004, decision 4): the nodes must come from the same module
19
+ * that later reads or prints them.
20
+ */
21
+
22
+ type KeywordName = Exclude<IrKeyword, "null">;
23
+
24
+ function keywordKind(ts: TypeScriptModule, keyword: KeywordName): ts.KeywordTypeSyntaxKind {
25
+ const kinds: Readonly<Record<KeywordName, ts.KeywordTypeSyntaxKind>> = {
26
+ string: ts.SyntaxKind.StringKeyword,
27
+ number: ts.SyntaxKind.NumberKeyword,
28
+ boolean: ts.SyntaxKind.BooleanKeyword,
29
+ undefined: ts.SyntaxKind.UndefinedKeyword,
30
+ unknown: ts.SyntaxKind.UnknownKeyword,
31
+ never: ts.SyntaxKind.NeverKeyword,
32
+ };
33
+ return kinds[keyword];
34
+ }
35
+
36
+ function toKeywordType(ts: TypeScriptModule, keyword: IrKeyword): ts.TypeNode {
37
+ return keyword === "null"
38
+ ? ts.factory.createLiteralTypeNode(ts.factory.createNull())
39
+ : ts.factory.createKeywordTypeNode(keywordKind(ts, keyword));
40
+ }
41
+
42
+ /**
43
+ * Numbers as the original writes them: a negative value is a prefix minus on its absolute value.
44
+ */
45
+ function toNumberExpression(
46
+ ts: TypeScriptModule,
47
+ value: number,
48
+ ): ts.PrefixUnaryExpression | ts.NumericLiteral {
49
+ return value < 0
50
+ ? ts.factory.createPrefixUnaryExpression(
51
+ ts.SyntaxKind.MinusToken,
52
+ ts.factory.createNumericLiteral(Math.abs(value)),
53
+ )
54
+ : ts.factory.createNumericLiteral(value);
55
+ }
56
+
57
+ /** An enum member or array element value, written as the original writes it. */
58
+ export function toValueExpression(ts: TypeScriptModule, value: string | number): ts.Expression {
59
+ return typeof value === "number"
60
+ ? toNumberExpression(ts, value)
61
+ : ts.factory.createStringLiteral(value);
62
+ }
63
+
64
+ /** The original writes JSON-encoded literal types as identifiers to keep UTF-8 readable. */
65
+ function toStringLiteralType(
66
+ ts: TypeScriptModule,
67
+ value: string,
68
+ encoding: "json" | "escaped",
69
+ ): ts.TypeNode {
70
+ return encoding === "json"
71
+ ? (ts.factory.createIdentifier(JSON.stringify(value)) as unknown as ts.TypeNode)
72
+ : ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(value));
73
+ }
74
+
75
+ function toTupleElement(ts: TypeScriptModule, element: IrTupleElement): ts.TypeNode {
76
+ const type = toTypeNode(ts, element.type);
77
+ return element.isRest ? ts.factory.createRestTypeNode(type) : type;
78
+ }
79
+
80
+ type LeafType = Extract<
81
+ IrType,
82
+ { kind: "keyword" | "stringLiteral" | "numberLiteral" | "booleanLiteral" | "raw" }
83
+ >;
84
+
85
+ function toLeafTypeNode(ts: TypeScriptModule, type: LeafType): ts.TypeNode {
86
+ switch (type.kind) {
87
+ case "keyword":
88
+ return toKeywordType(ts, type.keyword);
89
+ case "stringLiteral":
90
+ return toStringLiteralType(ts, type.value, type.encoding);
91
+ case "numberLiteral":
92
+ return ts.factory.createLiteralTypeNode(toNumberExpression(ts, type.value));
93
+ case "booleanLiteral":
94
+ return ts.factory.createLiteralTypeNode(
95
+ type.value ? ts.factory.createTrue() : ts.factory.createFalse(),
96
+ );
97
+ case "raw":
98
+ // A node read from TypeScript goes back as it was, so the TypeScript printer indents it.
99
+ return (
100
+ (type.origin as ts.TypeNode | undefined) ??
101
+ (ts.factory.createIdentifier(type.text) as unknown as ts.TypeNode)
102
+ );
103
+ default:
104
+ return assertNever(type);
105
+ }
106
+ }
107
+
108
+ function toReferenceNode(
109
+ ts: TypeScriptModule,
110
+ type: Extract<IrType, { kind: "reference" }>,
111
+ ): ts.TypeNode {
112
+ const typeArguments =
113
+ type.typeArguments.length > 0
114
+ ? type.typeArguments.map((argument) => toTypeNode(ts, argument))
115
+ : undefined;
116
+ return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(type.name), typeArguments);
117
+ }
118
+
119
+ /** Convert one IR type. */
120
+ export function toTypeNode(ts: TypeScriptModule, type: IrType): ts.TypeNode {
121
+ const convert = (inner: IrType) => toTypeNode(ts, inner);
122
+ const { factory } = ts;
123
+ switch (type.kind) {
124
+ case "keyword":
125
+ case "stringLiteral":
126
+ case "numberLiteral":
127
+ case "booleanLiteral":
128
+ case "raw":
129
+ return toLeafTypeNode(ts, type);
130
+ case "reference":
131
+ return toReferenceNode(ts, type);
132
+ case "array":
133
+ return factory.createArrayTypeNode(convert(type.element));
134
+ case "tuple":
135
+ return factory.createTupleTypeNode(
136
+ type.elements.map((element) => toTupleElement(ts, element)),
137
+ );
138
+ case "union":
139
+ return factory.createUnionTypeNode(type.types.map(convert));
140
+ case "intersection":
141
+ return factory.createIntersectionTypeNode(type.types.map(convert));
142
+ case "object":
143
+ return factory.createTypeLiteralNode(type.members.map((member) => toTypeElement(ts, member)));
144
+ case "indexedAccess":
145
+ return factory.createIndexedAccessTypeNode(convert(type.object), convert(type.index));
146
+ case "readonly":
147
+ return factory.createTypeOperatorNode(ts.SyntaxKind.ReadonlyKeyword, convert(type.type));
148
+ default:
149
+ return assertNever(type);
150
+ }
151
+ }
152
+
153
+ /** Attach IR comments to a node as synthetic leading comments, as the original does. */
154
+ export function withComments<T extends ts.Node>(
155
+ ts: TypeScriptModule,
156
+ node: T,
157
+ comments: readonly IrComment[],
158
+ ): T {
159
+ for (const comment of comments) {
160
+ const kind =
161
+ comment.kind === "block"
162
+ ? ts.SyntaxKind.MultiLineCommentTrivia
163
+ : ts.SyntaxKind.SingleLineCommentTrivia;
164
+ ts.addSyntheticLeadingComment(node, kind, comment.text, true);
165
+ }
166
+ return node;
167
+ }
168
+
169
+ function toPropertyName(ts: TypeScriptModule, name: IrPropertyName): ts.PropertyName {
170
+ switch (name.kind) {
171
+ case "identifier":
172
+ return ts.factory.createIdentifier(name.text);
173
+ case "string":
174
+ return ts.factory.createStringLiteral(name.value);
175
+ case "number":
176
+ return ts.factory.createNumericLiteral(name.text);
177
+ default:
178
+ return assertNever(name);
179
+ }
180
+ }
181
+
182
+ function readonlyModifiers(ts: TypeScriptModule, isReadonly: boolean): ts.Modifier[] | undefined {
183
+ return isReadonly ? [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined;
184
+ }
185
+
186
+ /** Convert one property signature (for callbacks that receive a `ts.PropertySignature`). */
187
+ export function toPropertySignature(
188
+ ts: TypeScriptModule,
189
+ property: IrPropertySignature,
190
+ ): ts.PropertySignature {
191
+ const questionToken = property.isOptional
192
+ ? ts.factory.createToken(ts.SyntaxKind.QuestionToken)
193
+ : undefined;
194
+ const signature = ts.factory.createPropertySignature(
195
+ readonlyModifiers(ts, property.isReadonly),
196
+ toPropertyName(ts, property.name),
197
+ questionToken,
198
+ toTypeNode(ts, property.type),
199
+ );
200
+ return withComments(ts, signature, property.comments);
201
+ }
202
+
203
+ export function toTypeElement(ts: TypeScriptModule, member: IrMember): ts.TypeElement {
204
+ if (member.kind === "property") {
205
+ return toPropertySignature(ts, member);
206
+ }
207
+ const parameter = ts.factory.createParameterDeclaration(
208
+ undefined,
209
+ undefined,
210
+ member.parameterName,
211
+ undefined,
212
+ toTypeNode(ts, member.parameterType),
213
+ );
214
+ const signature = ts.factory.createIndexSignature(
215
+ readonlyModifiers(ts, member.isReadonly),
216
+ [parameter],
217
+ toTypeNode(ts, member.type),
218
+ );
219
+ return withComments(ts, signature, member.comments);
220
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A TypeScript node that is created on first use (for the deprecated `QUESTION_TOKEN` export):
3
+ * the package must import without TypeScript installed (ADR-004, decision 4). Every property read,
4
+ * write and check goes to the node, so the TypeScript factory and printer see a normal node.
5
+ */
6
+ export function lazyNode<T extends object>(create: () => T): T {
7
+ let node: T | undefined;
8
+ const target = (): T => {
9
+ node ??= create();
10
+ return node;
11
+ };
12
+ return new Proxy({} as T, {
13
+ get: (_, key) => Reflect.get(target(), key),
14
+ set: (_, key, value) => Reflect.set(target(), key, value),
15
+ has: (_, key) => Reflect.has(target(), key),
16
+ ownKeys: () => Reflect.ownKeys(target()),
17
+ getOwnPropertyDescriptor: (_, key) => {
18
+ const descriptor = Reflect.getOwnPropertyDescriptor(target(), key);
19
+ // A proxy may report a property only as configurable when its own (empty) target lacks it.
20
+ return descriptor === undefined ? undefined : { ...descriptor, configurable: true };
21
+ },
22
+ getPrototypeOf: () => Reflect.getPrototypeOf(target()),
23
+ });
24
+ }
@@ -0,0 +1,84 @@
1
+ import { createRequire } from "node:module";
2
+ import { join } from "node:path";
3
+ import { ERROR_CODES, OpenAPITypesafeError } from "../../domain/errors.js";
4
+
5
+ /**
6
+ * Load a TypeScript compiler module with the JavaScript API (ADR-004, decision 4). The bridge
7
+ * needs it only for legacy `ts.Node` callbacks and the deprecated `ts.Node` helpers, so it is
8
+ * loaded on first use, never at import time. TypeScript 7 has no JavaScript API: on such a project
9
+ * the user installs `@typescript/typescript6`.
10
+ */
11
+
12
+ /** The `typescript` module of TypeScript 6 or earlier (or `@typescript/typescript6`). */
13
+ export type TypeScriptModule = typeof import("typescript");
14
+
15
+ /** Loads one package by name, like `require`. */
16
+ export type ModuleRequire = (id: string) => unknown;
17
+
18
+ /** The packages to try, in order: the project's own TypeScript first. */
19
+ export const TYPESCRIPT_PACKAGES = ["typescript", "@typescript/typescript6"] as const;
20
+
21
+ /** Error codes of a package that is missing or cannot be loaded with `require`. */
22
+ const UNAVAILABLE_CODES = new Set([
23
+ "MODULE_NOT_FOUND",
24
+ "ERR_REQUIRE_ESM",
25
+ "ERR_PACKAGE_PATH_NOT_EXPORTED",
26
+ ]);
27
+
28
+ export class TypeScriptNotFoundError extends OpenAPITypesafeError {
29
+ constructor() {
30
+ super({
31
+ code: ERROR_CODES.TYPESCRIPT_NOT_FOUND,
32
+ message:
33
+ "A callback or helper uses TypeScript compiler nodes, " +
34
+ "which needs the TypeScript JavaScript API. " +
35
+ 'Install "typescript" version 6 or earlier, ' +
36
+ 'or "@typescript/typescript6" on TypeScript 7, ' +
37
+ "or use IR callbacks (irCallbacks: true).",
38
+ details: { packages: [...TYPESCRIPT_PACKAGES] },
39
+ });
40
+ this.name = "TypeScriptNotFoundError";
41
+ }
42
+ }
43
+
44
+ /** Where to look: the current project, then this package's own location. */
45
+ export function defaultModuleRequires(): readonly ModuleRequire[] {
46
+ return [createRequire(join(process.cwd(), "package.json")), createRequire(import.meta.url)];
47
+ }
48
+
49
+ function hasCompilerApi(value: unknown): value is TypeScriptModule {
50
+ const module = value as Partial<TypeScriptModule> | undefined;
51
+ return (
52
+ typeof module?.factory?.createTypeReferenceNode === "function" &&
53
+ typeof module.createPrinter === "function"
54
+ );
55
+ }
56
+
57
+ function tryRequire(load: ModuleRequire, id: string): unknown {
58
+ try {
59
+ return load(id);
60
+ } catch (error) {
61
+ if (UNAVAILABLE_CODES.has((error as { code?: string }).code ?? "")) {
62
+ return undefined;
63
+ }
64
+ throw error;
65
+ }
66
+ }
67
+
68
+ /**
69
+ * The first package with the compiler API, trying each package name with each location. Node
70
+ * caches resolved modules, so repeated calls are cheap and return the same module.
71
+ */
72
+ export function loadTypeScript(
73
+ requires: readonly ModuleRequire[] = defaultModuleRequires(),
74
+ ): TypeScriptModule {
75
+ for (const id of TYPESCRIPT_PACKAGES) {
76
+ for (const load of requires) {
77
+ const module = tryRequire(load, id);
78
+ if (hasCompilerApi(module)) {
79
+ return module;
80
+ }
81
+ }
82
+ }
83
+ throw new TypeScriptNotFoundError();
84
+ }
@@ -0,0 +1,33 @@
1
+ import type ts from "typescript";
2
+ import type { TypeScriptModule } from "./load-typescript.js";
3
+
4
+ /** Options of `astToString` for the TypeScript printer, as in the original. */
5
+ export interface AstToStringOptions {
6
+ fileName?: string;
7
+ sourceText?: string;
8
+ formatOptions?: ts.PrinterOptions;
9
+ }
10
+
11
+ /** Print TypeScript nodes as the original `astToString` did. */
12
+ export function printWithTypeScript(
13
+ ts: TypeScriptModule,
14
+ nodes: readonly ts.Node[],
15
+ options?: AstToStringOptions,
16
+ ): string {
17
+ const sourceFile = ts.createSourceFile(
18
+ options?.fileName ?? "openapi-ts.ts",
19
+ options?.sourceText ?? "",
20
+ ts.ScriptTarget.ESNext,
21
+ false,
22
+ ts.ScriptKind.TS,
23
+ );
24
+ // The source file is new and not shared, so its statements can be set once.
25
+ (sourceFile as { statements: ts.NodeArray<ts.Statement> }).statements =
26
+ ts.factory.createNodeArray(nodes as readonly ts.Statement[]);
27
+ const printer = ts.createPrinter({
28
+ newLine: ts.NewLineKind.LineFeed,
29
+ removeComments: false,
30
+ ...options?.formatOptions,
31
+ });
32
+ return printer.printFile(sourceFile);
33
+ }
@@ -0,0 +1,49 @@
1
+ import type ts from "typescript";
2
+ import { irRaw } from "../../domain/ir/constructors.js";
3
+ import type { IrType } from "../../domain/ir/nodes.js";
4
+ import { toTypeNode } from "./ir-to-typescript.js";
5
+ import type { TypeScriptModule } from "./load-typescript.js";
6
+
7
+ /**
8
+ * Callback nodes that the IR cannot model exactly are kept as text, printed the way the original
9
+ * printed them (ADR-004, decision 3).
10
+ */
11
+
12
+ /** IR nodes have a string `kind`; TypeScript nodes have a numeric one. */
13
+ export function isIrNode(value: unknown): value is IrType {
14
+ return typeof (value as { kind?: unknown }).kind === "string";
15
+ }
16
+
17
+ /** Replace IR nodes nested in a TypeScript tree, so the TypeScript printer can print it. */
18
+ function withoutIrNodes<T extends ts.Node>(ts: TypeScriptModule, node: T): T {
19
+ const visit = (child: ts.Node): ts.Node =>
20
+ isIrNode(child) ? toTypeNode(ts, child) : ts.visitEachChild(child, visit, undefined);
21
+ return visit(node) as T;
22
+ }
23
+
24
+ function printPlainNode(ts: TypeScriptModule, node: ts.Node): string {
25
+ const source = ts.createSourceFile("openapi-ts.ts", "", ts.ScriptTarget.ESNext, false);
26
+ const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
27
+ return printer.printNode(ts.EmitHint.Unspecified, node, source);
28
+ }
29
+
30
+ /** Print as the original did: the TypeScript printer with an empty source file and LF. */
31
+ export function printTypeScriptNode(ts: TypeScriptModule, node: ts.Node): string {
32
+ return printPlainNode(ts, withoutIrNodes(ts, node));
33
+ }
34
+
35
+ /** The node as text, keeping the node itself for the way back to TypeScript (`toTypeNode`). */
36
+ export function asRaw(ts: TypeScriptModule, node: ts.TypeNode): IrType {
37
+ const printable = withoutIrNodes(ts, node);
38
+ return irRaw(printPlainNode(ts, printable), printable);
39
+ }
40
+
41
+ function hasSyntheticComments(ts: TypeScriptModule, node: ts.Node): boolean {
42
+ const leading = ts.getSyntheticLeadingComments(node)?.length ?? 0;
43
+ return leading + (ts.getSyntheticTrailingComments(node)?.length ?? 0) > 0;
44
+ }
45
+
46
+ /** Parsed nodes print from their source text, and comments attach to text: keep both printed. */
47
+ export function needsPrintedText(ts: TypeScriptModule, node: ts.Node): boolean {
48
+ return node.pos >= 0 || hasSyntheticComments(ts, node);
49
+ }