openapi-typesafe 1.0.0-rc.0 → 1.0.0-rc.2

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 (513) hide show
  1. package/README.md +12 -5
  2. package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
  3. package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
  4. package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
  5. package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
  6. package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
  7. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
  8. package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
  9. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
  10. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +34 -11
  11. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  12. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +33 -10
  13. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
  15. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  16. package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
  17. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  18. package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
  19. package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
  20. package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
  21. package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
  22. package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
  23. package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
  24. package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
  25. package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
  26. package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
  27. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  28. package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
  29. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  30. package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
  31. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
  32. package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
  33. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
  34. package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
  35. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
  36. package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
  37. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
  38. package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
  39. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  40. package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
  41. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  42. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +5 -1
  43. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
  44. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +5 -1
  45. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
  46. package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
  47. package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
  48. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
  49. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
  50. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
  51. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
  52. package/dist/api/default-ports.cjs +9 -0
  53. package/dist/api/default-ports.cjs.map +1 -1
  54. package/dist/api/default-ports.mjs +8 -1
  55. package/dist/api/default-ports.mjs.map +1 -1
  56. package/dist/api/discriminator-conflict-warnings.cjs +25 -0
  57. package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
  58. package/dist/api/discriminator-conflict-warnings.mjs +23 -0
  59. package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
  60. package/dist/api/discriminator-enum-names.cjs +19 -0
  61. package/dist/api/discriminator-enum-names.cjs.map +1 -0
  62. package/dist/api/discriminator-enum-names.mjs +17 -0
  63. package/dist/api/discriminator-enum-names.mjs.map +1 -0
  64. package/dist/api/discriminator-enum-parent.cjs +59 -0
  65. package/dist/api/discriminator-enum-parent.cjs.map +1 -0
  66. package/dist/api/discriminator-enum-parent.mjs +57 -0
  67. package/dist/api/discriminator-enum-parent.mjs.map +1 -0
  68. package/dist/api/discriminator-enum.cjs +25 -0
  69. package/dist/api/discriminator-enum.cjs.map +1 -1
  70. package/dist/api/discriminator-enum.mjs +25 -1
  71. package/dist/api/discriminator-enum.mjs.map +1 -1
  72. package/dist/api/discriminator-other-owners.cjs +67 -0
  73. package/dist/api/discriminator-other-owners.cjs.map +1 -0
  74. package/dist/api/discriminator-other-owners.mjs +64 -0
  75. package/dist/api/discriminator-other-owners.mjs.map +1 -0
  76. package/dist/api/discriminator-patch.cjs +92 -0
  77. package/dist/api/discriminator-patch.cjs.map +1 -0
  78. package/dist/api/discriminator-patch.mjs +86 -0
  79. package/dist/api/discriminator-patch.mjs.map +1 -0
  80. package/dist/api/discriminator-scan.cjs +50 -65
  81. package/dist/api/discriminator-scan.cjs.map +1 -1
  82. package/dist/api/discriminator-scan.mjs +44 -59
  83. package/dist/api/discriminator-scan.mjs.map +1 -1
  84. package/dist/api/document-refs.cjs +15 -12
  85. package/dist/api/document-refs.cjs.map +1 -1
  86. package/dist/api/document-refs.mjs +15 -12
  87. package/dist/api/document-refs.mjs.map +1 -1
  88. package/dist/api/document-run.cjs +21 -4
  89. package/dist/api/document-run.cjs.map +1 -1
  90. package/dist/api/document-run.mjs +22 -5
  91. package/dist/api/document-run.mjs.map +1 -1
  92. package/dist/api/enum-values-warnings.cjs +16 -0
  93. package/dist/api/enum-values-warnings.cjs.map +1 -0
  94. package/dist/api/enum-values-warnings.mjs +14 -0
  95. package/dist/api/enum-values-warnings.mjs.map +1 -0
  96. package/dist/api/footer-sink.cjs +25 -2
  97. package/dist/api/footer-sink.cjs.map +1 -1
  98. package/dist/api/footer-sink.mjs +25 -2
  99. package/dist/api/footer-sink.mjs.map +1 -1
  100. package/dist/api/legacy-callback-warning.cjs +4 -1
  101. package/dist/api/legacy-callback-warning.cjs.map +1 -1
  102. package/dist/api/legacy-callback-warning.mjs +4 -1
  103. package/dist/api/legacy-callback-warning.mjs.map +1 -1
  104. package/dist/api/legacy-ts-helpers.cjs.map +1 -1
  105. package/dist/api/legacy-ts-helpers.mjs.map +1 -1
  106. package/dist/api/legacy-utils.cjs.map +1 -1
  107. package/dist/api/legacy-utils.mjs.map +1 -1
  108. package/dist/api/openapi-ts.cjs +2 -1
  109. package/dist/api/openapi-ts.cjs.map +1 -1
  110. package/dist/api/openapi-ts.mjs +3 -2
  111. package/dist/api/openapi-ts.mjs.map +1 -1
  112. package/dist/api/path-template-warnings.cjs +21 -0
  113. package/dist/api/path-template-warnings.cjs.map +1 -0
  114. package/dist/api/path-template-warnings.mjs +19 -0
  115. package/dist/api/path-template-warnings.mjs.map +1 -0
  116. package/dist/api/transform-context.cjs +4 -2
  117. package/dist/api/transform-context.cjs.map +1 -1
  118. package/dist/api/transform-context.mjs +4 -2
  119. package/dist/api/transform-context.mjs.map +1 -1
  120. package/dist/api/transform-schema.cjs +52 -3
  121. package/dist/api/transform-schema.cjs.map +1 -1
  122. package/dist/api/transform-schema.mjs +53 -4
  123. package/dist/api/transform-schema.mjs.map +1 -1
  124. package/dist/api/unsupported-feature-warnings.cjs +6 -1
  125. package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
  126. package/dist/api/unsupported-feature-warnings.mjs +6 -1
  127. package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
  128. package/dist/application/print/type-printer.cjs +7 -1
  129. package/dist/application/print/type-printer.cjs.map +1 -1
  130. package/dist/application/print/type-printer.mjs +7 -1
  131. package/dist/application/print/type-printer.mjs.map +1 -1
  132. package/dist/application/transform/document/assignability.cjs +144 -0
  133. package/dist/application/transform/document/assignability.cjs.map +1 -0
  134. package/dist/application/transform/document/assignability.mjs +138 -0
  135. package/dist/application/transform/document/assignability.mjs.map +1 -0
  136. package/dist/application/transform/document/components.cjs +2 -2
  137. package/dist/application/transform/document/components.cjs.map +1 -1
  138. package/dist/application/transform/document/components.mjs +4 -4
  139. package/dist/application/transform/document/components.mjs.map +1 -1
  140. package/dist/application/transform/document/declared-types.cjs +66 -0
  141. package/dist/application/transform/document/declared-types.cjs.map +1 -0
  142. package/dist/application/transform/document/declared-types.mjs +63 -0
  143. package/dist/application/transform/document/declared-types.mjs.map +1 -0
  144. package/dist/application/transform/document/document.cjs +32 -9
  145. package/dist/application/transform/document/document.cjs.map +1 -1
  146. package/dist/application/transform/document/document.mjs +34 -11
  147. package/dist/application/transform/document/document.mjs.map +1 -1
  148. package/dist/application/transform/document/exploded-query.cjs +46 -0
  149. package/dist/application/transform/document/exploded-query.cjs.map +1 -0
  150. package/dist/application/transform/document/exploded-query.mjs +43 -0
  151. package/dist/application/transform/document/exploded-query.mjs.map +1 -0
  152. package/dist/application/transform/document/global-type-references.cjs +63 -0
  153. package/dist/application/transform/document/global-type-references.cjs.map +1 -0
  154. package/dist/application/transform/document/global-type-references.mjs +61 -0
  155. package/dist/application/transform/document/global-type-references.mjs.map +1 -0
  156. package/dist/application/transform/document/list-assignability.cjs +54 -0
  157. package/dist/application/transform/document/list-assignability.cjs.map +1 -0
  158. package/dist/application/transform/document/list-assignability.mjs +52 -0
  159. package/dist/application/transform/document/list-assignability.mjs.map +1 -0
  160. package/dist/application/transform/document/parameters.cjs +41 -9
  161. package/dist/application/transform/document/parameters.cjs.map +1 -1
  162. package/dist/application/transform/document/parameters.mjs +42 -10
  163. package/dist/application/transform/document/parameters.mjs.map +1 -1
  164. package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
  165. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
  166. package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
  167. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
  168. package/dist/application/transform/document/path-template-replace.cjs +48 -0
  169. package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
  170. package/dist/application/transform/document/path-template-replace.mjs +45 -0
  171. package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
  172. package/dist/application/transform/document/paths.cjs +55 -29
  173. package/dist/application/transform/document/paths.cjs.map +1 -1
  174. package/dist/application/transform/document/paths.mjs +54 -30
  175. package/dist/application/transform/document/paths.mjs.map +1 -1
  176. package/dist/application/transform/document/root-type-aliases.cjs +15 -14
  177. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  178. package/dist/application/transform/document/root-type-aliases.mjs +15 -13
  179. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  180. package/dist/application/transform/document/template-key-match.cjs +128 -0
  181. package/dist/application/transform/document/template-key-match.cjs.map +1 -0
  182. package/dist/application/transform/document/template-key-match.mjs +125 -0
  183. package/dist/application/transform/document/template-key-match.mjs.map +1 -0
  184. package/dist/application/transform/document/type-assignability.cjs +192 -0
  185. package/dist/application/transform/document/type-assignability.cjs.map +1 -0
  186. package/dist/application/transform/document/type-assignability.mjs +190 -0
  187. package/dist/application/transform/document/type-assignability.mjs.map +1 -0
  188. package/dist/application/transform/document/type-key.cjs +70 -0
  189. package/dist/application/transform/document/type-key.cjs.map +1 -0
  190. package/dist/application/transform/document/type-key.mjs +68 -0
  191. package/dist/application/transform/document/type-key.mjs.map +1 -0
  192. package/dist/application/transform/document/type-resolution.cjs +131 -0
  193. package/dist/application/transform/document/type-resolution.cjs.map +1 -0
  194. package/dist/application/transform/document/type-resolution.mjs +125 -0
  195. package/dist/application/transform/document/type-resolution.mjs.map +1 -0
  196. package/dist/application/transform/footer/document-footer.cjs +66 -4
  197. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  198. package/dist/application/transform/footer/document-footer.mjs +67 -5
  199. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  200. package/dist/application/transform/footer/enum-naming.cjs +17 -0
  201. package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
  202. package/dist/application/transform/footer/enum-naming.mjs +17 -1
  203. package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
  204. package/dist/application/transform/footer/enum-values-check.cjs +129 -0
  205. package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
  206. package/dist/application/transform/footer/enum-values-check.mjs +127 -0
  207. package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
  208. package/dist/application/transform/footer/evaluation.cjs +42 -0
  209. package/dist/application/transform/footer/evaluation.cjs.map +1 -0
  210. package/dist/application/transform/footer/evaluation.mjs +33 -0
  211. package/dist/application/transform/footer/evaluation.mjs.map +1 -0
  212. package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
  213. package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
  214. package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
  215. package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
  216. package/dist/application/transform/footer/type-evaluation.cjs +138 -0
  217. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
  218. package/dist/application/transform/footer/type-evaluation.mjs +136 -0
  219. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
  220. package/dist/application/transform/footer/type-indexing.cjs +107 -0
  221. package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
  222. package/dist/application/transform/footer/type-indexing.mjs +105 -0
  223. package/dist/application/transform/footer/type-indexing.mjs.map +1 -0
  224. package/dist/application/transform/footer/type-rules.cjs +172 -0
  225. package/dist/application/transform/footer/type-rules.cjs.map +1 -0
  226. package/dist/application/transform/footer/type-rules.mjs +166 -0
  227. package/dist/application/transform/footer/type-rules.mjs.map +1 -0
  228. package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
  229. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
  230. package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
  231. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
  232. package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
  233. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
  234. package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
  235. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
  236. package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
  237. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
  238. package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
  239. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
  240. package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
  241. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
  242. package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
  243. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
  244. package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
  245. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
  246. package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
  247. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
  248. package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
  249. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
  250. package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
  251. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
  252. package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
  253. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
  254. package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
  255. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
  256. package/dist/application/transform/ref-type.cjs +7 -2
  257. package/dist/application/transform/ref-type.cjs.map +1 -1
  258. package/dist/application/transform/ref-type.mjs +3 -2
  259. package/dist/application/transform/ref-type.mjs.map +1 -1
  260. package/dist/application/transform/schema/access-flags.cjs +38 -0
  261. package/dist/application/transform/schema/access-flags.cjs.map +1 -0
  262. package/dist/application/transform/schema/access-flags.mjs +36 -0
  263. package/dist/application/transform/schema/access-flags.mjs.map +1 -0
  264. package/dist/application/transform/schema/array-type.cjs +32 -1
  265. package/dist/application/transform/schema/array-type.cjs.map +1 -1
  266. package/dist/application/transform/schema/array-type.mjs +33 -2
  267. package/dist/application/transform/schema/array-type.mjs.map +1 -1
  268. package/dist/application/transform/schema/composition-type.cjs +50 -15
  269. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  270. package/dist/application/transform/schema/composition-type.mjs +50 -15
  271. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  272. package/dist/application/transform/schema/core-type.cjs +3 -1
  273. package/dist/application/transform/schema/core-type.cjs.map +1 -1
  274. package/dist/application/transform/schema/core-type.mjs +3 -1
  275. package/dist/application/transform/schema/core-type.mjs.map +1 -1
  276. package/dist/application/transform/schema/discriminated-union.cjs +30 -0
  277. package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
  278. package/dist/application/transform/schema/discriminated-union.mjs +27 -0
  279. package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
  280. package/dist/application/transform/schema/discriminator-property.cjs +3 -2
  281. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
  282. package/dist/application/transform/schema/discriminator-property.mjs +3 -2
  283. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
  284. package/dist/application/transform/schema/enum-rule.cjs +66 -10
  285. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  286. package/dist/application/transform/schema/enum-rule.mjs +67 -12
  287. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  288. package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
  289. package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
  290. package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
  291. package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
  292. package/dist/application/transform/schema/object-type.cjs +38 -25
  293. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  294. package/dist/application/transform/schema/object-type.mjs +39 -27
  295. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  296. package/dist/application/transform/schema/required-variants.cjs +45 -0
  297. package/dist/application/transform/schema/required-variants.cjs.map +1 -0
  298. package/dist/application/transform/schema/required-variants.mjs +42 -0
  299. package/dist/application/transform/schema/required-variants.mjs.map +1 -0
  300. package/dist/application/transform/schema/schema-transform.cjs +2 -2
  301. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  302. package/dist/application/transform/schema/schema-transform.mjs +2 -2
  303. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  304. package/dist/application/transform/schema-comment.cjs +51 -5
  305. package/dist/application/transform/schema-comment.cjs.map +1 -1
  306. package/dist/application/transform/schema-comment.mjs +50 -6
  307. package/dist/application/transform/schema-comment.mjs.map +1 -1
  308. package/dist/application/transform/type-combinators.mjs +1 -1
  309. package/dist/cli/api-settings.cjs +78 -0
  310. package/dist/cli/api-settings.cjs.map +1 -0
  311. package/dist/cli/api-settings.mjs +73 -0
  312. package/dist/cli/api-settings.mjs.map +1 -0
  313. package/dist/cli/cli-arguments.cjs +12 -3
  314. package/dist/cli/cli-arguments.cjs.map +1 -1
  315. package/dist/cli/cli-arguments.mjs +12 -4
  316. package/dist/cli/cli-arguments.mjs.map +1 -1
  317. package/dist/cli/cli-errors.cjs +3 -2
  318. package/dist/cli/cli-errors.cjs.map +1 -1
  319. package/dist/cli/cli-errors.mjs +3 -2
  320. package/dist/cli/cli-errors.mjs.map +1 -1
  321. package/dist/cli/cli-output.cjs +8 -3
  322. package/dist/cli/cli-output.cjs.map +1 -1
  323. package/dist/cli/cli-output.mjs +9 -4
  324. package/dist/cli/cli-output.mjs.map +1 -1
  325. package/dist/cli/help-text.cjs +3 -3
  326. package/dist/cli/help-text.cjs.map +1 -1
  327. package/dist/cli/help-text.mjs +3 -3
  328. package/dist/cli/help-text.mjs.map +1 -1
  329. package/dist/cli/main.cjs +5 -0
  330. package/dist/cli/main.cjs.map +1 -1
  331. package/dist/cli/main.mjs +5 -0
  332. package/dist/cli/main.mjs.map +1 -1
  333. package/dist/cli/redocly-apis.cjs +15 -7
  334. package/dist/cli/redocly-apis.cjs.map +1 -1
  335. package/dist/cli/redocly-apis.mjs +15 -7
  336. package/dist/cli/redocly-apis.mjs.map +1 -1
  337. package/dist/cli/ref-limits.cjs +1 -1
  338. package/dist/cli/ref-limits.cjs.map +1 -1
  339. package/dist/cli/ref-limits.mjs +2 -2
  340. package/dist/cli/ref-limits.mjs.map +1 -1
  341. package/dist/cli/run-cli.cjs +20 -3
  342. package/dist/cli/run-cli.cjs.map +1 -1
  343. package/dist/cli/run-cli.mjs +21 -4
  344. package/dist/cli/run-cli.mjs.map +1 -1
  345. package/dist/domain/errors.cjs +6 -1
  346. package/dist/domain/errors.cjs.map +1 -1
  347. package/dist/domain/errors.mjs +6 -1
  348. package/dist/domain/errors.mjs.map +1 -1
  349. package/dist/domain/ir/constructors.cjs +7 -1
  350. package/dist/domain/ir/constructors.cjs.map +1 -1
  351. package/dist/domain/ir/constructors.mjs +6 -2
  352. package/dist/domain/ir/constructors.mjs.map +1 -1
  353. package/dist/domain/openapi/admitted-values.cjs +75 -0
  354. package/dist/domain/openapi/admitted-values.cjs.map +1 -0
  355. package/dist/domain/openapi/admitted-values.mjs +72 -0
  356. package/dist/domain/openapi/admitted-values.mjs.map +1 -0
  357. package/dist/domain/openapi/discriminated-union.cjs +68 -0
  358. package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
  359. package/dist/domain/openapi/discriminated-union.mjs +62 -0
  360. package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
  361. package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
  362. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
  363. package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
  364. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
  365. package/dist/domain/openapi/parameter-object.cjs.map +1 -1
  366. package/dist/domain/openapi/parameter-object.mjs.map +1 -1
  367. package/dist/domain/openapi/path-templates.cjs +23 -0
  368. package/dist/domain/openapi/path-templates.cjs.map +1 -0
  369. package/dist/domain/openapi/path-templates.mjs +21 -0
  370. package/dist/domain/openapi/path-templates.mjs.map +1 -0
  371. package/dist/domain/output-fixes.cjs +36 -1
  372. package/dist/domain/output-fixes.cjs.map +1 -1
  373. package/dist/domain/output-fixes.mjs +36 -1
  374. package/dist/domain/output-fixes.mjs.map +1 -1
  375. package/dist/domain/url-credentials.cjs +10 -0
  376. package/dist/domain/url-credentials.cjs.map +1 -0
  377. package/dist/domain/url-credentials.mjs +8 -0
  378. package/dist/domain/url-credentials.mjs.map +1 -0
  379. package/dist/domain/warnings.cjs +23 -0
  380. package/dist/domain/warnings.cjs.map +1 -0
  381. package/dist/domain/warnings.mjs +20 -0
  382. package/dist/domain/warnings.mjs.map +1 -0
  383. package/dist/index.cjs +2 -0
  384. package/dist/index.cjs.map +1 -1
  385. package/dist/index.d.cts +1182 -46
  386. package/dist/index.d.mts +1182 -46
  387. package/dist/index.d.ts +1182 -46
  388. package/dist/index.mjs +1 -0
  389. package/dist/index.mjs.map +1 -1
  390. package/dist/transform/components-object.cjs +2 -1
  391. package/dist/transform/components-object.cjs.map +1 -1
  392. package/dist/transform/components-object.mjs +2 -1
  393. package/dist/transform/components-object.mjs.map +1 -1
  394. package/dist/transform/path-item-object.cjs.map +1 -1
  395. package/dist/transform/path-item-object.mjs.map +1 -1
  396. package/package.json +6 -5
  397. package/src/adapters/redocly-loader/configured-headers.ts +65 -0
  398. package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
  399. package/src/adapters/redocly-loader/redocly-schema-loader.ts +44 -13
  400. package/src/adapters/redocly-loader/ref-access.ts +60 -5
  401. package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
  402. package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
  403. package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
  404. package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
  405. package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
  406. package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
  407. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +5 -1
  408. package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
  409. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
  410. package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
  411. package/src/api/default-ports.ts +16 -0
  412. package/src/api/discriminator-conflict-warnings.ts +43 -0
  413. package/src/api/discriminator-enum-names.ts +26 -0
  414. package/src/api/discriminator-enum-parent.ts +129 -0
  415. package/src/api/discriminator-enum.ts +39 -0
  416. package/src/api/discriminator-other-owners.ts +97 -0
  417. package/src/api/discriminator-patch.ts +152 -0
  418. package/src/api/discriminator-scan.ts +78 -90
  419. package/src/api/document-refs.ts +19 -15
  420. package/src/api/document-run.ts +32 -11
  421. package/src/api/enum-values-warnings.ts +21 -0
  422. package/src/api/footer-sink.ts +34 -2
  423. package/src/api/legacy-callback-warning.ts +7 -3
  424. package/src/api/legacy-ts-helpers.ts +7 -5
  425. package/src/api/legacy-utils.ts +1 -1
  426. package/src/api/openapi-ts.ts +2 -0
  427. package/src/api/path-template-warnings.ts +27 -0
  428. package/src/api/run-context.ts +34 -0
  429. package/src/api/transform-context.ts +17 -9
  430. package/src/api/transform-schema.ts +90 -5
  431. package/src/api/unsupported-feature-warnings.ts +8 -1
  432. package/src/application/ports/redocly-config-source.ts +5 -1
  433. package/src/application/print/type-printer.ts +8 -1
  434. package/src/application/transform/document/assignability.ts +203 -0
  435. package/src/application/transform/document/components.ts +6 -6
  436. package/src/application/transform/document/declared-types.ts +93 -0
  437. package/src/application/transform/document/document.ts +71 -13
  438. package/src/application/transform/document/exploded-query.ts +91 -0
  439. package/src/application/transform/document/global-type-references.ts +78 -0
  440. package/src/application/transform/document/list-assignability.ts +87 -0
  441. package/src/application/transform/document/parameters.ts +78 -12
  442. package/src/application/transform/document/path-key-overlaps.ts +148 -59
  443. package/src/application/transform/document/path-template-replace.ts +90 -0
  444. package/src/application/transform/document/paths.ts +101 -38
  445. package/src/application/transform/document/root-type-aliases.ts +29 -28
  446. package/src/application/transform/document/template-key-match.ts +183 -0
  447. package/src/application/transform/document/type-assignability.ts +268 -0
  448. package/src/application/transform/document/type-key.ts +80 -0
  449. package/src/application/transform/document/type-resolution.ts +163 -0
  450. package/src/application/transform/footer/document-footer.ts +91 -6
  451. package/src/application/transform/footer/enum-naming.ts +29 -0
  452. package/src/application/transform/footer/enum-values-check.ts +171 -0
  453. package/src/application/transform/footer/evaluation.ts +57 -0
  454. package/src/application/transform/footer/shared-enum-names.ts +86 -0
  455. package/src/application/transform/footer/type-evaluation.ts +167 -0
  456. package/src/application/transform/footer/type-indexing.ts +152 -0
  457. package/src/application/transform/footer/type-rules.ts +269 -0
  458. package/src/application/transform/ref-pointer/generated-location.ts +211 -0
  459. package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
  460. package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
  461. package/src/application/transform/ref-pointer/original-index.ts +95 -0
  462. package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
  463. package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
  464. package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
  465. package/src/application/transform/ref-type.ts +11 -6
  466. package/src/application/transform/schema/access-flags.ts +63 -0
  467. package/src/application/transform/schema/array-type.ts +66 -5
  468. package/src/application/transform/schema/composition-type.ts +96 -24
  469. package/src/application/transform/schema/core-type.ts +8 -4
  470. package/src/application/transform/schema/discriminated-union.ts +58 -0
  471. package/src/application/transform/schema/discriminator-property.ts +8 -3
  472. package/src/application/transform/schema/enum-rule.ts +136 -13
  473. package/src/application/transform/schema/inherited-discriminator.ts +54 -0
  474. package/src/application/transform/schema/object-type.ts +51 -33
  475. package/src/application/transform/schema/required-variants.ts +88 -0
  476. package/src/application/transform/schema/schema-context.ts +26 -0
  477. package/src/application/transform/schema/schema-transform.ts +2 -2
  478. package/src/application/transform/schema-comment.ts +84 -4
  479. package/src/cli/api-settings.ts +109 -0
  480. package/src/cli/cli-arguments.ts +18 -5
  481. package/src/cli/cli-dependencies.ts +5 -0
  482. package/src/cli/cli-errors.ts +4 -2
  483. package/src/cli/cli-output.ts +18 -4
  484. package/src/cli/help-text.ts +4 -4
  485. package/src/cli/main.ts +6 -0
  486. package/src/cli/redocly-apis.ts +21 -11
  487. package/src/cli/ref-limits.ts +2 -2
  488. package/src/cli/run-cli.ts +25 -4
  489. package/src/domain/errors.ts +10 -2
  490. package/src/domain/ir/constructors.ts +9 -1
  491. package/src/domain/ir/nodes.ts +11 -7
  492. package/src/domain/openapi/admitted-values.ts +113 -0
  493. package/src/domain/openapi/discriminated-union.ts +109 -0
  494. package/src/domain/openapi/discriminator-conflicts.ts +251 -0
  495. package/src/domain/openapi/parameter-object.ts +4 -0
  496. package/src/domain/openapi/path-templates.ts +32 -0
  497. package/src/domain/openapi/schema-object.ts +2 -0
  498. package/src/domain/output-fixes.ts +43 -2
  499. package/src/domain/url-credentials.ts +18 -0
  500. package/src/domain/warnings.ts +28 -0
  501. package/src/index.ts +1 -0
  502. package/src/transform/components-object.ts +3 -1
  503. package/src/transform/path-item-object.ts +6 -2
  504. package/src/types/generator-options.ts +12 -21
  505. package/src/types/openapi-common.ts +1 -0
  506. package/src/types/openapi-request.ts +3 -0
  507. package/src/types/openapi-schema.ts +2 -0
  508. package/src/types/openapi-security.ts +1 -0
  509. package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
  510. package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
  511. package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
  512. package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
  513. package/src/application/transform/document/path-item-conflicts.ts +0 -79
@@ -1,4 +1,5 @@
1
1
  import type { IrComment, IrPropertySignature } from "../../domain/ir/nodes.js";
2
+ import { OutputFix } from "../../domain/output-fixes.js";
2
3
 
3
4
  /** Schema fields that produce JSDoc lines (the original `AnnotatedSchemaObject`). */
4
5
  export interface AnnotatedSchema {
@@ -24,6 +25,27 @@ const COMMENT_END_RE = /\*\//g;
24
25
  const VALUE_TAGS = ["description", "default", "example"] as const;
25
26
  const TAGS_KEEPING_EMPTY_STRING: ReadonlySet<string> = new Set(["default", "example"]);
26
27
  const JSON_INDENT = 2;
28
+ /** The member lists whose descriptions `anyof-oneof-descriptions` adds, with their headings. */
29
+ const MEMBER_LISTS = [
30
+ ["anyOf", "Any of:"],
31
+ ["oneOf", "One of:"],
32
+ ] as const;
33
+ /** The later lines of a member's description are indented under its bullet. */
34
+ const BULLET_CONTINUATION = "\n ";
35
+
36
+ /** How a schema's JSDoc is written. */
37
+ export interface SchemaCommentOptions {
38
+ /** `anyof-oneof-descriptions`: the descriptions of `anyOf` and `oneOf` members are listed. */
39
+ readonly hasMemberDescriptions: boolean;
40
+ }
41
+
42
+ /** The JSDoc the original writes. */
43
+ export const ORIGINAL_SCHEMA_COMMENT: SchemaCommentOptions = { hasMemberDescriptions: false };
44
+
45
+ /** How the fixes turned on write a schema's JSDoc. */
46
+ export function schemaCommentOptionsOf(fixes: ReadonlySet<OutputFix>): SchemaCommentOptions {
47
+ return { hasMemberDescriptions: fixes.has(OutputFix.ANYOF_ONEOF_DESCRIPTIONS) };
48
+ }
27
49
 
28
50
  function formatValue(value: unknown): string {
29
51
  const text = typeof value === "object" ? JSON.stringify(value, null, JSON_INDENT) : value;
@@ -81,17 +103,74 @@ function constantAndEnumLines(schema: AnnotatedSchema): string[] {
81
103
  return lines;
82
104
  }
83
105
 
106
+ /** The own, non-blank `description` of each member; a member without one is left out. */
107
+ function memberDescriptions(members: unknown): string[] {
108
+ if (!Array.isArray(members)) {
109
+ return [];
110
+ }
111
+ return members.flatMap((member: unknown) => {
112
+ const description = isSchemaObject(member) ? member.description : undefined;
113
+ return typeof description === "string" && description.trim() !== "" ? [description.trim()] : [];
114
+ });
115
+ }
116
+
117
+ /** Each member list with a described member, as a heading and one bullet per description. */
118
+ function memberDescriptionLists(schema: SchemaRecord): string[] {
119
+ return MEMBER_LISTS.flatMap(([keyword, heading]) => {
120
+ const descriptions = memberDescriptions(schema[keyword]);
121
+ if (descriptions.length === 0) {
122
+ return [];
123
+ }
124
+ const bullets = descriptions.map(
125
+ (description) => `- ${description.replace(LINE_BREAK_RE, BULLET_CONTINUATION)}`,
126
+ );
127
+ return [[heading, ...bullets].join("\n")];
128
+ });
129
+ }
130
+
131
+ /**
132
+ * The schema with the descriptions of its `anyOf` and `oneOf` members after its own description
133
+ * (upstream #2142). A member's description holds only where that member applies, so each one is
134
+ * listed under its keyword rather than merged into one sentence. A `description` that is not a
135
+ * string is kept as it is.
136
+ */
137
+ function withMemberDescriptions(schema: SchemaRecord): AnnotatedSchema {
138
+ const lists = memberDescriptionLists(schema);
139
+ const own = schema.description;
140
+ if (lists.length === 0 || (own !== undefined && typeof own !== "string")) {
141
+ // As the original, the keywords are read as they are, without validating them.
142
+ return schema as AnnotatedSchema;
143
+ }
144
+ const ownLines = typeof own === "string" && own.trim() !== "" ? [own.trim()] : [];
145
+ return { ...(schema as AnnotatedSchema), description: [...ownLines, ...lists].join("\n") };
146
+ }
147
+
148
+ /** A schema object read without knowing its keywords. */
149
+ interface SchemaRecord {
150
+ readonly description?: unknown;
151
+ readonly [keyword: string]: unknown;
152
+ }
153
+
154
+ function isSchemaObject(value: unknown): value is SchemaRecord {
155
+ return typeof value === "object" && value !== null && !Array.isArray(value);
156
+ }
157
+
84
158
  /**
85
159
  * The JSDoc comment the original writes for a schema (`addJSDocComment`): title, summary and
86
160
  * format, then `@deprecated`, `@description`, `@default`, `@example`, `@constant` and `@enum`
87
161
  * tags. One short line stays on the `/**` line; anything else is a block. Returns null when there
88
162
  * is nothing to say, or when the value is not a schema object.
89
163
  */
90
- export function schemaComment(schema: unknown): IrComment | null {
91
- if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
164
+ export function schemaComment(
165
+ schema: unknown,
166
+ options: SchemaCommentOptions = ORIGINAL_SCHEMA_COMMENT,
167
+ ): IrComment | null {
168
+ if (!isSchemaObject(schema)) {
92
169
  return null;
93
170
  }
94
- const annotated = schema as AnnotatedSchema;
171
+ const annotated = options.hasMemberDescriptions
172
+ ? withMemberDescriptions(schema)
173
+ : (schema as AnnotatedSchema);
95
174
  const lines = [
96
175
  ...plainLines(annotated),
97
176
  ...valueTagLines(annotated),
@@ -110,7 +189,8 @@ export function schemaComment(schema: unknown): IrComment | null {
110
189
  export function withSchemaComment(
111
190
  property: IrPropertySignature,
112
191
  schema: unknown,
192
+ options: SchemaCommentOptions = ORIGINAL_SCHEMA_COMMENT,
113
193
  ): IrPropertySignature {
114
- const comment = schemaComment(schema);
194
+ const comment = schemaComment(schema, options);
115
195
  return comment === null ? property : { ...property, comments: [...property.comments, comment] };
116
196
  }
@@ -0,0 +1,109 @@
1
+ import { kebabCase } from "scule";
2
+ import { WARNING_CODES, warningText } from "../domain/warnings.js";
3
+ import { GENERATOR_FLAGS, hostList } from "./cli-arguments.js";
4
+ import { cliError } from "./cli-errors.js";
5
+ import { resolveLocationUrl } from "./cli-output.js";
6
+ import type { RefLimitOptions } from "./ref-limits.js";
7
+
8
+ /**
9
+ * The settings of one API in `redocly.yaml` (`apis.<name>.x-openapi-ts`). A setting has the name
10
+ * of its CLI flag, in kebab-case or camelCase (ADR-021, decision 1); a setting the CLI does not
11
+ * read gets a warning, as an unknown flag gets a notice.
12
+ */
13
+
14
+ export type ApiSettings = Readonly<Record<string, unknown>>;
15
+
16
+ /** The setting that names the output file. */
17
+ export const OUTPUT_SETTING = "output";
18
+
19
+ /** The setting that lists the API's output fixes. */
20
+ export const FIX_SETTING = "fix";
21
+
22
+ const LOCAL_REF_ROOT_SETTING = "localRefRoot";
23
+ const REMOTE_REF_HOSTS_SETTING = "remoteRefHosts";
24
+
25
+ /** `--content-never` is accepted and has no effect, as on the command line. */
26
+ const IGNORED_SETTINGS = ["contentNever"] as const;
27
+
28
+ const CAMEL_CASE_SETTINGS = [
29
+ OUTPUT_SETTING,
30
+ FIX_SETTING,
31
+ LOCAL_REF_ROOT_SETTING,
32
+ REMOTE_REF_HOSTS_SETTING,
33
+ ...GENERATOR_FLAGS,
34
+ ...IGNORED_SETTINGS,
35
+ ];
36
+
37
+ const KNOWN_SETTINGS = new Set<string>([
38
+ ...CAMEL_CASE_SETTINGS,
39
+ ...CAMEL_CASE_SETTINGS.map((name) => kebabCase(name)),
40
+ ]);
41
+
42
+ /** The warning for each setting of an API that no code reads. */
43
+ export function unknownSettingWarnings(apiName: string, settings: ApiSettings): string[] {
44
+ return Object.keys(settings)
45
+ .filter((key) => !KNOWN_SETTINGS.has(key))
46
+ .map((key) =>
47
+ warningText(
48
+ `API ${apiName}: the setting \`${key}\` is not an openapi-typesafe option and is ignored`,
49
+ WARNING_CODES.CONFIG_SETTING_UNKNOWN,
50
+ ),
51
+ );
52
+ }
53
+
54
+ /** The value of a setting in camelCase, else in kebab-case; `undefined` when it is absent. */
55
+ function settingValue(settings: ApiSettings, name: string): unknown {
56
+ return name in settings ? settings[name] : settings[kebabCase(name)];
57
+ }
58
+
59
+ function hasSetting(settings: ApiSettings, name: string): boolean {
60
+ return name in settings || kebabCase(name) in settings;
61
+ }
62
+
63
+ function invalidSetting(apiName: string, name: string, expected: string): Error {
64
+ return cliError(
65
+ "CLI_CONFIG_INVALID",
66
+ `API ${apiName}: \`${kebabCase(name)}\` in x-openapi-ts must be ${expected}`,
67
+ );
68
+ }
69
+
70
+ /** `local-ref-root: dir`, relative to the config file; empty means the config file's directory. */
71
+ function localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL): RefLimitOptions {
72
+ if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {
73
+ return {};
74
+ }
75
+ const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? "";
76
+ if (typeof value !== "string") {
77
+ throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, "a directory path");
78
+ }
79
+ return { localRefRoot: resolveLocationUrl(value === "" ? "." : value, configRoot) };
80
+ }
81
+
82
+ /** `remote-ref-hosts: [a, b]` or `a,b`; an empty list or value allows no host. */
83
+ function remoteRefHostsOf(apiName: string, settings: ApiSettings): RefLimitOptions {
84
+ if (!hasSetting(settings, REMOTE_REF_HOSTS_SETTING)) {
85
+ return {};
86
+ }
87
+ const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];
88
+ const entries = [value].flat();
89
+ if (entries.some((entry) => typeof entry !== "string")) {
90
+ throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, "a host list");
91
+ }
92
+ return { remoteRefHosts: hostList(entries) ?? [] };
93
+ }
94
+
95
+ /**
96
+ * The `$ref` limits an API sets (threat model R1, R2). Each one replaces the CLI flag of the same
97
+ * name for this API, as its boolean settings and `fix` do; fails with `CLI_CONFIG_INVALID` for a
98
+ * value of another type.
99
+ */
100
+ export function apiRefLimitOptions(
101
+ apiName: string,
102
+ settings: ApiSettings,
103
+ configRoot: URL,
104
+ ): RefLimitOptions {
105
+ return {
106
+ ...localRefRootOf(apiName, settings, configRoot),
107
+ ...remoteRefHostsOf(apiName, settings),
108
+ };
109
+ }
@@ -122,8 +122,11 @@ function lastString(value: unknown): string | undefined {
122
122
  return optionalString(Array.isArray(value) ? value.at(-1) : value);
123
123
  }
124
124
 
125
- /** `--remote-ref-hosts a.example,b.example`, repeatable; an empty value allows no host. */
126
- function hostList(value: unknown): string[] | undefined {
125
+ /**
126
+ * `--remote-ref-hosts a.example,b.example`, repeatable; an empty value allows no host. The
127
+ * `remote-ref-hosts` setting of a `redocly.yaml` API is read the same way.
128
+ */
129
+ export function hostList(value: unknown): string[] | undefined {
127
130
  if (value === undefined) {
128
131
  return undefined;
129
132
  }
@@ -165,13 +168,23 @@ const KNOWN_FLAGS = new Set<string>([
165
168
  * Flags that no code reads. The original CLI ignored them silently, so a typo such as
166
169
  * `--alphabetise` gave other output with no hint; they still do not fail the run.
167
170
  */
168
- function unknownFlagsOf(parsed: parser.Arguments): string[] {
171
+ function unknownFlagsOf(parsed: parser.Arguments, argv: readonly string[]): string[] {
169
172
  const names = Object.keys(parsed)
170
173
  .filter((key) => key !== "_" && key !== "--" && !KNOWN_FLAGS.has(key))
171
- .map((key) => (key.length === 1 ? `-${key}` : `--${kebabCase(key)}`));
174
+ .map((key) => writtenFlagName(key, argv));
172
175
  return [...new Set(names)];
173
176
  }
174
177
 
178
+ /** The flag as the user wrote it: yargs-parser reads `--no-x` as `x: false`. */
179
+ function writtenFlagName(key: string, argv: readonly string[]): string {
180
+ if (key.length === 1) {
181
+ return `-${key}`;
182
+ }
183
+ const negated = `--no-${kebabCase(key)}`;
184
+ const isNegated = argv.some((arg) => arg === negated || arg.startsWith(`${negated}=`));
185
+ return isNegated ? negated : `--${kebabCase(key)}`;
186
+ }
187
+
175
188
  /**
176
189
  * Parse the arguments after `node cli.js`. Fails with `CLI_FLAG_REMOVED` for an old flag and with
177
190
  * `OPTION_FIX_UNKNOWN` for an unknown `--fix` name.
@@ -193,6 +206,6 @@ export function parseCliArguments(argv: readonly string[]): CliArguments {
193
206
  generatorFlags: generatorFlagsOf(parsed),
194
207
  refLimits: refLimitsOf(parsed),
195
208
  fix: fixNamesOf(parsed.fix),
196
- unknownFlags: unknownFlagsOf(parsed),
209
+ unknownFlags: unknownFlagsOf(parsed, argv),
197
210
  };
198
211
  }
@@ -33,6 +33,11 @@ export interface CliDependencies {
33
33
  readonly writeStdout: (text: string) => void;
34
34
  /** Read only when the schema comes from stdin: opening it early can keep the process alive. */
35
35
  readonly stdin: () => Readable;
36
+ /**
37
+ * Whether stdin is a terminal. Then nothing is piped in, and reading it would wait for typed
38
+ * input with no prompt, which looks like a hang (upstream #1905).
39
+ */
40
+ readonly isStdinTerminal: () => boolean;
36
41
  readonly files: FileReader & FileWriter;
37
42
  readonly redoclyConfigs: RedoclyConfigSource;
38
43
  readonly generate: GenerateTypes;
@@ -49,8 +49,8 @@ function loadFailedMessage(error: OpenAPITypesafeError): string {
49
49
  if (!(reason instanceof Error)) {
50
50
  return error.message;
51
51
  }
52
- const source = typeof error.details.source === "string" ? ` (${error.details.source})` : "";
53
- return `${error.message}: ${reason.message}${source}`;
52
+ // `loadFailedError`, the only source of this code, always sets the source.
53
+ return `${error.message}: ${reason.message} (${String(error.details.source)})`;
54
54
  }
55
55
 
56
56
  /** The message js-yaml throws at its nesting limit (docs/security/threat-model.md T2). */
@@ -88,8 +88,10 @@ const CLI_ERROR_REPORTS: Readonly<Record<ErrorCode, CliErrorReport>> = {
88
88
  CLI_FLAG_REMOVED: { exitCode: EXIT_CODES.USAGE },
89
89
  CLI_GLOB_UNSUPPORTED: { exitCode: EXIT_CODES.USAGE },
90
90
  CLI_CONFIG_NOT_FOUND: { exitCode: EXIT_CODES.USAGE },
91
+ CLI_CONFIG_INVALID: { exitCode: EXIT_CODES.USAGE },
91
92
  CLI_CONFIG_OUTPUT_MISSING: { exitCode: EXIT_CODES.USAGE },
92
93
  CLI_CHECK_OUTPUT_MISSING: { exitCode: EXIT_CODES.USAGE },
94
+ CLI_INPUT_MISSING: { exitCode: EXIT_CODES.USAGE },
93
95
  OUTPUT_STALE: { exitCode: EXIT_CODES.OUTPUT_STALE },
94
96
  OUTPUT_READ_FAILED: { exitCode: EXIT_CODES.OUTPUT },
95
97
  OUTPUT_WRITE_FAILED: { exitCode: EXIT_CODES.OUTPUT },
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { pathToFileURL } from "node:url";
2
+ import { fileURLToPath, pathToFileURL } from "node:url";
3
3
  import { formatDuration } from "../adapters/terminal-logger/terminal-logger.js";
4
4
  import type { CliArguments } from "./cli-arguments.js";
5
5
  import type { CliDependencies } from "./cli-dependencies.js";
@@ -21,9 +21,23 @@ export interface OutputFile {
21
21
  readonly file: URL;
22
22
  }
23
23
 
24
- /** A file URL for a path that is absolute, or relative to `base` (a directory or file URL). */
25
- export function resolveFileUrl(filePath: string, base: URL): URL {
26
- return path.isAbsolute(filePath) ? pathToFileURL(filePath) : new URL(filePath, base);
24
+ /**
25
+ * A scheme of two or more characters (`https:`, `file:`). One letter is a Windows drive (`C:`), so
26
+ * `C:\\specs\\api.yaml` stays a path.
27
+ */
28
+ const URL_SCHEME = /^[a-z][a-z\d+.-]+:/i;
29
+
30
+ /**
31
+ * The URL of a location the user wrote: a URL as it is, else a file path, absolute or relative to
32
+ * the directory of `base` (a directory or file URL). A path is not parsed as a URL, so `#`, `?` and
33
+ * `%` are part of the file name.
34
+ */
35
+ export function resolveLocationUrl(location: string, base: URL): URL {
36
+ if (URL_SCHEME.test(location)) {
37
+ return new URL(location);
38
+ }
39
+ const baseDirectory = fileURLToPath(new URL(".", base));
40
+ return pathToFileURL(path.resolve(baseDirectory, location));
27
41
  }
28
42
 
29
43
  function printDone(run: CliRun, output: OutputFile): void {
@@ -4,7 +4,7 @@ export const HELP_TEXT = [
4
4
  " $ openapi-typesafe [input] [options]",
5
5
  "",
6
6
  "Options",
7
- " --help Display this",
7
+ " --help Show this help",
8
8
  " --version Display the version",
9
9
  " --redocly [path], -c Specify path to Redocly config (default: redocly.yaml)",
10
10
  " --output, -o Specify output file (if not specified in redocly.yaml)",
@@ -20,8 +20,8 @@ export const HELP_TEXT = [
20
20
  " --additional-properties Treat schema objects as if `additionalProperties: true` is set",
21
21
  " --empty-objects-unknown Generate `unknown` instead of" +
22
22
  " `Record<string, never>` for empty objects",
23
- " --default-non-nullable Set to `false` to ignore default values" +
24
- " when generating non-nullable types",
23
+ " --default-non-nullable A property with a `default` is required" +
24
+ " (default: true; =false makes it optional)",
25
25
  " --properties-required-by-default",
26
26
  " Treat schema objects as if `required` is" +
27
27
  " set to all properties by default",
@@ -35,7 +35,7 @@ export const HELP_TEXT = [
35
35
  " undefined by schema",
36
36
  " --alphabetize Sort object keys alphabetically",
37
37
  " --exclude-deprecated Exclude deprecated types",
38
- " --root-types Export schemas types at root level",
38
+ " --root-types Export `components` types as root-level aliases",
39
39
  " --root-types-no-schema-prefix",
40
40
  ' Do not add "Schema" prefix to types at' +
41
41
  " the root level (should only be used with --root-types)",
package/src/cli/main.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import fs from "node:fs";
2
+ import { isatty } from "node:tty";
2
3
  import { pathToFileURL } from "node:url";
3
4
  import colors from "ansi-colors";
4
5
  import { createNodeFileSystem } from "../adapters/node-file-system/node-file-system.js";
@@ -33,6 +34,8 @@ function terminalStyle(): TextStyle {
33
34
  };
34
35
  }
35
36
 
37
+ const STDIN_DESCRIPTOR = 0;
38
+
36
39
  const generateTypes: GenerateTypes = async (source, options) =>
37
40
  `${COMMENT_HEADER}${astToString(await openapiTS(source, options))}`;
38
41
 
@@ -54,6 +57,9 @@ function processDependencies(): CliDependencies {
54
57
  console: terminalConsole(),
55
58
  writeStdout: (text) => process.stdout.write(text),
56
59
  stdin: () => process.stdin,
60
+ // `isatty` reads the descriptor without opening `process.stdin`, which would keep the
61
+ // process alive.
62
+ isStdinTerminal: () => isatty(STDIN_DESCRIPTOR),
57
63
  files: createNodeFileSystem(),
58
64
  redoclyConfigs: createRedoclyConfigSource(cwd),
59
65
  generate: generateTypes,
@@ -2,9 +2,16 @@ import { kebabCase } from "scule";
2
2
  import type { RedoclyConfig } from "../application/ports/redocly-config-source.js";
3
3
  import type { OutputFixName } from "../domain/output-fixes.js";
4
4
  import type { GeneratorOptions } from "../types.js";
5
+ import {
6
+ type ApiSettings,
7
+ apiRefLimitOptions,
8
+ FIX_SETTING,
9
+ OUTPUT_SETTING,
10
+ unknownSettingWarnings,
11
+ } from "./api-settings.js";
5
12
  import { GENERATOR_FLAGS, type GeneratorFlags } from "./cli-arguments.js";
6
13
  import { cliError } from "./cli-errors.js";
7
- import { type CliRun, emitOutput, resolveFileUrl } from "./cli-output.js";
14
+ import { type CliRun, emitOutput, resolveLocationUrl } from "./cli-output.js";
8
15
  import { MULTIPLE_SCHEMAS_DOCS_URL } from "./docs-links.js";
9
16
  import { fixNamesOf, fixOption } from "./fix-option.js";
10
17
  import { refLimitOptions } from "./ref-limits.js";
@@ -14,11 +21,6 @@ import { refLimitOptions } from "./ref-limits.js";
14
21
  /** The key of an API's openapi-typesafe settings in `redocly.yaml`. */
15
22
  const REDOCLY_CONFIG_KEY = "x-openapi-ts";
16
23
 
17
- /** The setting of an API that lists its output fixes. */
18
- const FIX_SETTING = "fix";
19
-
20
- type ApiSettings = Readonly<Record<string, unknown>>;
21
-
22
24
  interface RedoclyApi {
23
25
  readonly name: string;
24
26
  readonly root: string;
@@ -55,28 +57,36 @@ function apiFixNames(settings: ApiSettings): readonly OutputFixName[] | undefine
55
57
 
56
58
  /** Paths in the config are relative to the config file; without a file, to the working dir. */
57
59
  function configRootOf(redocly: RedoclyConfig, cwd: URL): URL {
58
- return redocly.configFile ? resolveFileUrl(redocly.configFile, cwd) : cwd;
60
+ return redocly.configFile ? resolveLocationUrl(redocly.configFile, cwd) : cwd;
59
61
  }
60
62
 
61
63
  async function generateApi(run: CliRun, redocly: RedoclyConfig, api: RedoclyApi): Promise<void> {
62
- if (!api.settings?.output) {
64
+ if (!api.settings?.[OUTPUT_SETTING]) {
63
65
  throw cliError(
64
66
  "CLI_CONFIG_OUTPUT_MISSING",
65
67
  `API ${api.name} is missing an \`${REDOCLY_CONFIG_KEY}.output\` key. ` +
66
68
  `See ${MULTIPLE_SCHEMAS_DOCS_URL}`,
67
69
  );
68
70
  }
69
- const output = String(api.settings.output);
71
+ for (const warning of unknownSettingWarnings(api.name, api.settings)) {
72
+ run.deps.logger.warn(warning);
73
+ }
74
+ const output = String(api.settings[OUTPUT_SETTING]);
70
75
  const configRoot = configRootOf(redocly, run.deps.cwd);
71
76
  const options: GeneratorOptions = {
72
77
  ...run.args.generatorFlags,
73
78
  ...apiFlags(api.settings),
74
79
  ...refLimitOptions(run.args, run.deps.cwd),
80
+ ...apiRefLimitOptions(api.name, api.settings, configRoot),
75
81
  ...fixOption(apiFixNames(api.settings) ?? run.args.fix),
76
82
  redocly,
77
83
  };
78
- const contents = await run.deps.generate(new URL(api.root, configRoot), options);
79
- emitOutput(run, { source: api.name, output, file: new URL(output, configRoot) }, contents);
84
+ const contents = await run.deps.generate(resolveLocationUrl(api.root, configRoot), options);
85
+ emitOutput(
86
+ run,
87
+ { source: api.name, output, file: resolveLocationUrl(output, configRoot) },
88
+ contents,
89
+ );
80
90
  }
81
91
 
82
92
  /**
@@ -1,6 +1,6 @@
1
1
  import type { GeneratorOptions } from "../types.js";
2
2
  import type { CliArguments } from "./cli-arguments.js";
3
- import { resolveFileUrl } from "./cli-output.js";
3
+ import { resolveLocationUrl } from "./cli-output.js";
4
4
 
5
5
  /** The `$ref` limits of the CLI flags as generator options (threat model R1, R2, ADR-017). */
6
6
 
@@ -10,7 +10,7 @@ export type RefLimitOptions = Pick<GeneratorOptions, "localRefRoot" | "remoteRef
10
10
  export function refLimitOptions(args: CliArguments, cwd: URL): RefLimitOptions {
11
11
  const { localRefRoot, remoteRefHosts } = args.refLimits;
12
12
  return {
13
- ...(localRefRoot === undefined ? {} : { localRefRoot: resolveFileUrl(localRefRoot, cwd) }),
13
+ ...(localRefRoot === undefined ? {} : { localRefRoot: resolveLocationUrl(localRefRoot, cwd) }),
14
14
  ...(remoteRefHosts === undefined ? {} : { remoteRefHosts }),
15
15
  };
16
16
  }
@@ -1,9 +1,11 @@
1
1
  import type { Logger } from "../application/ports/logger.js";
2
2
  import type { RedoclyConfig } from "../application/ports/redocly-config-source.js";
3
+ import { WARNING_CODES, warningText } from "../domain/warnings.js";
4
+ import type { SchemaSource } from "../types.js";
3
5
  import { ineffectiveFlagNotices, parseCliArguments } from "./cli-arguments.js";
4
6
  import type { CliDependencies } from "./cli-dependencies.js";
5
7
  import { cliError, describeCliFailure, EXIT_CODES, type ExitCode } from "./cli-errors.js";
6
- import { type CliRun, emitOutput, resolveFileUrl } from "./cli-output.js";
8
+ import { type CliRun, emitOutput, resolveLocationUrl } from "./cli-output.js";
7
9
  import { MULTIPLE_SCHEMAS_DOCS_URL } from "./docs-links.js";
8
10
  import { fixOption } from "./fix-option.js";
9
11
  import { HELP_TEXT } from "./help-text.js";
@@ -25,6 +27,22 @@ async function loadRedoclyConfig(run: CliRun): Promise<RedoclyConfig> {
25
27
  return configPath ? redoclyConfigs.load(configPath) : redoclyConfigs.createDefault();
26
28
  }
27
29
 
30
+ /** The schema's URL, or stdin when no path or URL is given and something is piped in. */
31
+ function schemaSource(run: CliRun): SchemaSource {
32
+ const { input } = run.args;
33
+ if (input) {
34
+ return resolveLocationUrl(input, run.deps.cwd);
35
+ }
36
+ if (run.deps.isStdinTerminal()) {
37
+ throw cliError(
38
+ "CLI_INPUT_MISSING",
39
+ "No schema given: pass a schema path or URL, pipe a schema into stdin, or define `apis` " +
40
+ "in redocly.yaml. See --help.",
41
+ );
42
+ }
43
+ return run.deps.stdin();
44
+ }
45
+
28
46
  /** One schema from a path, a URL or stdin; without `--output`, the types go to stdout only. */
29
47
  async function generateSingleSchema(run: CliRun, redocly: RedoclyConfig): Promise<void> {
30
48
  const { input, output } = run.args;
@@ -42,7 +60,7 @@ async function generateSingleSchema(run: CliRun, redocly: RedoclyConfig): Promis
42
60
  "--check needs the generated file to compare with: add --output <file>.",
43
61
  );
44
62
  }
45
- const source = input ? new URL(input, run.deps.cwd) : run.deps.stdin();
63
+ const source = schemaSource(run);
46
64
  const options = {
47
65
  ...run.args.generatorFlags,
48
66
  ...refLimitOptions(run.args, run.deps.cwd),
@@ -55,7 +73,7 @@ async function generateSingleSchema(run: CliRun, redocly: RedoclyConfig): Promis
55
73
  run.deps.writeStdout(contents);
56
74
  return;
57
75
  }
58
- const file = resolveFileUrl(output, run.deps.cwd);
76
+ const file = resolveLocationUrl(output, run.deps.cwd);
59
77
  emitOutput(run, { source: input ?? "stdin", output, file }, contents);
60
78
  }
61
79
 
@@ -67,7 +85,10 @@ async function generate(run: CliRun): Promise<unknown[]> {
67
85
  }
68
86
  if (run.args.input) {
69
87
  run.deps.logger.warn(
70
- "APIs are specified both in Redocly Config and CLI argument. Only using Redocly config.",
88
+ warningText(
89
+ "APIs are specified both in Redocly Config and CLI argument. Only using Redocly config.",
90
+ WARNING_CODES.CLI_INPUT_IGNORED,
91
+ ),
71
92
  );
72
93
  }
73
94
  return generateRedoclyApis(run, redocly);
@@ -1,3 +1,5 @@
1
+ import { redactUrlCredentials } from "./url-credentials.js";
2
+
1
3
  /**
2
4
  * Typed errors (ENGINEERING_PLAN 4.6, ADR-011). Every expected failure of the generator and the CLI
3
5
  * is an `OpenAPITypesafeError` with a stable machine-readable `code` and structured `details`. The
@@ -26,8 +28,10 @@ export const ERROR_CODES = {
26
28
  CLI_FLAG_REMOVED: "CLI_FLAG_REMOVED",
27
29
  CLI_GLOB_UNSUPPORTED: "CLI_GLOB_UNSUPPORTED",
28
30
  CLI_CONFIG_NOT_FOUND: "CLI_CONFIG_NOT_FOUND",
31
+ CLI_CONFIG_INVALID: "CLI_CONFIG_INVALID",
29
32
  CLI_CONFIG_OUTPUT_MISSING: "CLI_CONFIG_OUTPUT_MISSING",
30
33
  CLI_CHECK_OUTPUT_MISSING: "CLI_CHECK_OUTPUT_MISSING",
34
+ CLI_INPUT_MISSING: "CLI_INPUT_MISSING",
31
35
  OUTPUT_STALE: "OUTPUT_STALE",
32
36
  OUTPUT_READ_FAILED: "OUTPUT_READ_FAILED",
33
37
  OUTPUT_WRITE_FAILED: "OUTPUT_WRITE_FAILED",
@@ -46,13 +50,17 @@ export interface OpenAPITypesafeErrorInit {
46
50
  readonly cause?: unknown;
47
51
  }
48
52
 
49
- /** The base of every expected failure; check `code`, not the class or the message. */
53
+ /**
54
+ * The base of every expected failure; check `code`, not the class or the message. The message
55
+ * never shows the user info of a URL (`url-credentials.ts`).
56
+ */
50
57
  export class OpenAPITypesafeError extends Error {
51
58
  readonly code: ErrorCode;
52
59
  readonly details: ErrorDetails;
53
60
 
54
61
  constructor(init: OpenAPITypesafeErrorInit) {
55
- super(init.message, init.cause === undefined ? undefined : { cause: init.cause });
62
+ const message = redactUrlCredentials(init.message);
63
+ super(message, init.cause === undefined ? undefined : { cause: init.cause });
56
64
  this.name = "OpenAPITypesafeError";
57
65
  this.code = init.code;
58
66
  this.details = init.details ?? {};
@@ -33,6 +33,9 @@ export function irKeyword(keyword: IrKeyword): IrKeywordType {
33
33
  return { kind: "keyword", keyword };
34
34
  }
35
35
 
36
+ /** The encoding of a string literal that does not name one. */
37
+ export const DEFAULT_STRING_ENCODING: IrStringEncoding = "json";
38
+
36
39
  export function irString(value: string, encoding: IrStringEncoding): IrStringLiteralType {
37
40
  return { kind: "stringLiteral", value, encoding };
38
41
  }
@@ -62,7 +65,12 @@ export function irTuple(elements: readonly IrTupleElement[]): IrTupleType {
62
65
  }
63
66
 
64
67
  export function irTupleElement(type: IrType, isRest = false): IrTupleElement {
65
- return { type, isRest };
68
+ return { type, isRest, isOptional: false };
69
+ }
70
+
71
+ /** `T?`: an element the tuple may end before. */
72
+ export function irOptionalTupleElement(type: IrType): IrTupleElement {
73
+ return { type, isRest: false, isOptional: true };
66
74
  }
67
75
 
68
76
  export function irUnion(types: readonly IrType[]): IrUnionType {