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
@@ -0,0 +1,192 @@
1
+ import { irIndexedAccess, irKeyword, irReference } from "../../../domain/ir/constructors.js";
2
+ import type { IrKeyword, IrType } from "../../../domain/ir/nodes.js";
3
+ import { indexBy, indexKeyword, rootType } from "../ref-type.js";
4
+ import type { RefResolver, SchemaOptions } from "../schema/schema-context.js";
5
+ import {
6
+ followRefs,
7
+ isArrayShape,
8
+ isJsonObject,
9
+ isObjectShape,
10
+ type Presence,
11
+ propertyPresence,
12
+ schemaPresence,
13
+ } from "./generated-shape.js";
14
+ import {
15
+ isOptionalHeader,
16
+ isOptionalRequestBody,
17
+ isParameterList,
18
+ isTypedAsSchema,
19
+ leadingNode,
20
+ leadingSegmentsOf,
21
+ type RefPointer,
22
+ startsInSchema,
23
+ } from "./pointer-walk.js";
24
+
25
+ /**
26
+ * The type of a `$ref` pointer as the generated types have it: the `schema` of a media type,
27
+ * header or component parameter is its type, `items` is indexed by `number`,
28
+ * `additionalProperties` by `string`, and a value that may be `undefined` or `null` is wrapped in
29
+ * `NonNullable` before it is indexed. The walk stops at a segment with no type of its own
30
+ * (`allOf/0`, `definitions/A`, operation `parameters/0`): the caller types the target itself.
31
+ */
32
+
33
+ const DEFS_KEYWORD = "$defs";
34
+
35
+ export interface TypedWalk {
36
+ readonly type: IrType;
37
+ /** The document node the type stands for (not followed through a `$ref`). */
38
+ readonly node: unknown;
39
+ readonly isSchema: boolean;
40
+ /** The segment is a property or `$defs` name, not a keyword. */
41
+ readonly isName: boolean;
42
+ readonly presence: Presence;
43
+ }
44
+
45
+ export interface TypedWalkInput {
46
+ readonly pointer: RefPointer;
47
+ readonly options: SchemaOptions;
48
+ readonly refs: RefResolver;
49
+ }
50
+
51
+ /** The walk result: a type, or the index of the first segment that has no type. */
52
+ export type TypedWalkResult =
53
+ | { readonly kind: "typed"; readonly walk: TypedWalk }
54
+ | { readonly kind: "untyped"; readonly index: number };
55
+
56
+ function present(walk: TypedWalk): IrType {
57
+ return walk.presence === "present" ? walk.type : irReference("NonNullable", [walk.type]);
58
+ }
59
+
60
+ function indexEntries(walk: TypedWalk, key: IrKeyword, keyword: string, refs: RefResolver) {
61
+ const owner = followRefs(walk.node, refs);
62
+ const child = isJsonObject(owner) ? owner[keyword] : undefined;
63
+ return {
64
+ ...walk,
65
+ type: irIndexedAccess(present(walk), irKeyword(key)),
66
+ node: child,
67
+ presence: schemaPresence(child, refs),
68
+ };
69
+ }
70
+
71
+ function nameStep(walk: TypedWalk, name: string, isLast: boolean, input: TypedWalkInput) {
72
+ const owner = followRefs(walk.node, input.refs);
73
+ const properties = isJsonObject(owner) && isJsonObject(owner.properties) ? owner.properties : {};
74
+ const type =
75
+ walk.presence === "present"
76
+ ? indexKeyword(walk.type, name, isLast)
77
+ : indexBy(present(walk), name);
78
+ return {
79
+ ...walk,
80
+ type,
81
+ node: properties[name],
82
+ isName: false,
83
+ presence: propertyPresence(walk.node, name, input.options, input.refs),
84
+ };
85
+ }
86
+
87
+ /** `$defs` is optional (`NonNullable` when more follows); its members are present. */
88
+ function defsStep(walk: TypedWalk, owner: unknown, isLast: boolean): TypedWalk {
89
+ const defs = isJsonObject(owner) && isJsonObject(owner[DEFS_KEYWORD]) ? owner[DEFS_KEYWORD] : {};
90
+ return {
91
+ ...walk,
92
+ type: indexKeyword(present(walk), DEFS_KEYWORD, isLast),
93
+ node: { properties: defs, required: Object.keys(defs) },
94
+ isName: true,
95
+ presence: "present",
96
+ };
97
+ }
98
+
99
+ const SHAPED_KEYWORDS: ReadonlySet<string> = new Set([
100
+ "properties",
101
+ "items",
102
+ "additionalProperties",
103
+ ]);
104
+
105
+ /**
106
+ * Whether the keyword gives the owner's generated type a member: `items` only an array,
107
+ * `properties` and `additionalProperties` only an object (`type: string` ignores them). A node
108
+ * that is not in the document is indexed as the keyword says.
109
+ */
110
+ function hasKeywordMember(owner: unknown, segment: string): boolean {
111
+ if (!SHAPED_KEYWORDS.has(segment) || !isJsonObject(owner)) {
112
+ return true;
113
+ }
114
+ return segment === "items" ? isArrayShape(owner) : isObjectShape(owner);
115
+ }
116
+
117
+ function keywordStep(walk: TypedWalk, segment: string, isLast: boolean, input: TypedWalkInput) {
118
+ const owner = followRefs(walk.node, input.refs);
119
+ if (!hasKeywordMember(owner, segment)) {
120
+ return null;
121
+ }
122
+ switch (segment) {
123
+ case "properties":
124
+ return { ...walk, isName: true };
125
+ case "items":
126
+ return indexEntries(walk, "number", "items", input.refs);
127
+ case "additionalProperties":
128
+ return indexEntries(walk, "string", "additionalProperties", input.refs);
129
+ case DEFS_KEYWORD:
130
+ return defsStep(walk, owner, isLast);
131
+ default:
132
+ return null;
133
+ }
134
+ }
135
+
136
+ function containerStep(walk: TypedWalk, index: number, input: TypedWalkInput): TypedWalk {
137
+ const segment = input.pointer.segments[index] as string;
138
+ const owner = followRefs(walk.node, input.refs);
139
+ const isOptional =
140
+ (segment === "requestBody" && isOptionalRequestBody(owner, input.refs)) ||
141
+ isOptionalHeader(input.pointer, index, owner);
142
+ return {
143
+ ...walk,
144
+ type: indexBy(present(walk), segment),
145
+ node: isJsonObject(owner) ? owner[segment] : undefined,
146
+ presence: isOptional ? "absent" : "present",
147
+ };
148
+ }
149
+
150
+ function step(walk: TypedWalk, index: number, input: TypedWalkInput): TypedWalk | null {
151
+ const { segments } = input.pointer;
152
+ const segment = segments[index] as string;
153
+ const isLast = index === segments.length - 1;
154
+ if (walk.isSchema) {
155
+ return walk.isName
156
+ ? nameStep(walk, segment, isLast, input)
157
+ : keywordStep(walk, segment, isLast, input);
158
+ }
159
+ if (segment === "schema" && isTypedAsSchema(input.pointer, index)) {
160
+ const owner = followRefs(walk.node, input.refs);
161
+ const schema = isJsonObject(owner) ? owner.schema : undefined;
162
+ // The container's type is its schema's type: an optional header stays optional.
163
+ const presence = walk.presence === "absent" ? "absent" : schemaPresence(schema, input.refs);
164
+ return { ...walk, node: schema, isSchema: true, presence };
165
+ }
166
+ return isParameterList(input.pointer, index) ? null : containerStep(walk, index, input);
167
+ }
168
+
169
+ /** Walk the whole pointer; see the module comment. */
170
+ export function typedWalk(input: TypedWalkInput): TypedWalkResult {
171
+ const { pointer } = input;
172
+ const node = leadingNode(pointer, input.refs);
173
+ const isSchema = startsInSchema(pointer);
174
+ let walk: TypedWalk = {
175
+ type: indexBy(
176
+ rootType(pointer.rootSegment, false),
177
+ ...pointer.segments.slice(0, leadingSegmentsOf(pointer)),
178
+ ),
179
+ node,
180
+ isSchema,
181
+ isName: false,
182
+ presence: isSchema ? schemaPresence(node, input.refs) : "present",
183
+ };
184
+ for (let index = leadingSegmentsOf(pointer); index < pointer.segments.length; index++) {
185
+ const next = step(walk, index, input);
186
+ if (next === null) {
187
+ return { kind: "untyped", index };
188
+ }
189
+ walk = next;
190
+ }
191
+ return { kind: "typed", walk };
192
+ }
@@ -8,6 +8,7 @@ import {
8
8
  irString,
9
9
  } from "../../domain/ir/constructors.js";
10
10
  import type { IrType } from "../../domain/ir/nodes.js";
11
+ import { toPropertyName } from "../../domain/ir/property-name.js";
11
12
  import { parseRefPointer } from "../../domain/openapi/json-pointer.js";
12
13
 
13
14
  /** Where a referenced parameter lives in the generated `parameters` type. */
@@ -37,16 +38,20 @@ export class InvalidRefError extends OpenAPITypesafeError {
37
38
  }
38
39
 
39
40
  /** Segments that index into the root type, always as escaped string literal types. */
40
- function indexBy(type: IrType, ...segments: readonly string[]): IrType {
41
+ export function indexBy(type: IrType, ...segments: readonly string[]): IrType {
41
42
  return segments.reduce<IrType>(
42
43
  (object, segment) => irIndexedAccess(object, irString(segment, "escaped")),
43
44
  type,
44
45
  );
45
46
  }
46
47
 
47
- /** `Extract<T, { name: unknown }>`; the name is written as an identifier, as in the original. */
48
- function extractVariantsWith(type: IrType, propertyName: string): IrType {
49
- const probe = irProperty({ kind: "identifier", text: propertyName }, irKeyword("unknown"));
48
+ /**
49
+ * `Extract<T, { name: unknown }>`. The original wrote the name as an identifier even when it is
50
+ * not one (`{ content-type: unknown }`), which is a syntax error; it is now quoted like any other
51
+ * property name, and an identifier stays as it was.
52
+ */
53
+ export function extractVariantsWith(type: IrType, propertyName: string): IrType {
54
+ const probe = irProperty(toPropertyName(propertyName), irKeyword("unknown"));
50
55
  return irReference("Extract", [type, irObject([probe])]);
51
56
  }
52
57
 
@@ -57,12 +62,12 @@ const DEFS_KEYWORD = "$defs";
57
62
  * segments follow it is wrapped in `NonNullable<…>` first; otherwise the next index fails on
58
63
  * `undefined` (upstream #2664).
59
64
  */
60
- function indexKeyword(type: IrType, segment: string, isLast: boolean): IrType {
65
+ export function indexKeyword(type: IrType, segment: string, isLast: boolean): IrType {
61
66
  const indexed = indexBy(type, segment);
62
67
  return segment === DEFS_KEYWORD && !isLast ? irReference("NonNullable", [indexed]) : indexed;
63
68
  }
64
69
 
65
- function rootType(rootSegment: string, isDeep: boolean): IrType {
70
+ export function rootType(rootSegment: string, isDeep: boolean): IrType {
66
71
  return irReference(isDeep ? `FlattenedDeepRequired<${rootSegment}>` : rootSegment);
67
72
  }
68
73
 
@@ -0,0 +1,63 @@
1
+ import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
2
+ import { OutputFix } from "../../../domain/output-fixes.js";
3
+ import type { SchemaContext } from "./schema-context.js";
4
+
5
+ /** Whether a property is `readOnly` or `writeOnly` (JSON Schema 2020-12 Validation §9.4). */
6
+ export interface AccessFlags {
7
+ readonly isReadOnly: boolean;
8
+ readonly isWriteOnly: boolean;
9
+ }
10
+
11
+ const NO_FLAGS: AccessFlags = { isReadOnly: false, isWriteOnly: false };
12
+
13
+ function ownFlags(schema: SchemaObject): AccessFlags {
14
+ return { isReadOnly: Boolean(schema.readOnly), isWriteOnly: Boolean(schema.writeOnly) };
15
+ }
16
+
17
+ function merged(left: AccessFlags, right: AccessFlags): AccessFlags {
18
+ return {
19
+ isReadOnly: left.isReadOnly || right.isReadOnly,
20
+ isWriteOnly: left.isWriteOnly || right.isWriteOnly,
21
+ };
22
+ }
23
+
24
+ /**
25
+ * The flags of a schema and of the schemas that always apply to the same value: the one its
26
+ * `$ref` names and its `allOf` members, followed until a schema repeats. `readOnly` is an
27
+ * annotation, and the annotations of those schemas are the value's (2020-12 Core §7.7.1); in
28
+ * OpenAPI 3.0 a referenced schema is the property's definition. `anyOf` and `oneOf` members apply
29
+ * only when they match, which the type cannot tell, so they are not read.
30
+ */
31
+ function appliedFlags(
32
+ schema: Schema | undefined,
33
+ context: SchemaContext,
34
+ seen: ReadonlySet<Schema>,
35
+ ): AccessFlags {
36
+ if (typeof schema !== "object" || schema === null || seen.has(schema)) {
37
+ return NO_FLAGS;
38
+ }
39
+ const inner = new Set([...seen, schema]);
40
+ // `readOnly` next to a `$ref` is read too, as the generator always has.
41
+ const object = schema as SchemaObject & { readonly $ref?: unknown };
42
+ const target =
43
+ typeof object.$ref === "string" ? (context.refs.resolve(object.$ref) as Schema) : undefined;
44
+ return (object.allOf ?? []).reduce<AccessFlags>(
45
+ (flags, member) => merged(flags, appliedFlags(member, context, inner)),
46
+ merged(ownFlags(object), appliedFlags(target, context, inner)),
47
+ );
48
+ }
49
+
50
+ /**
51
+ * The flags of a property schema. Without the `read-write-refs` fix only the keywords written on
52
+ * it count, as in openapi-typescript; with it, also those of the schemas its `$ref` and `allOf`
53
+ * apply (upstream #1938).
54
+ */
55
+ export function propertyAccessFlags(value: Schema, context: SchemaContext): AccessFlags {
56
+ if (typeof value !== "object") {
57
+ return NO_FLAGS;
58
+ }
59
+ if (!context.options.fixes.has(OutputFix.READ_WRITE_REFS)) {
60
+ return ownFlags(value as SchemaObject);
61
+ }
62
+ return appliedFlags(value, context, new Set());
63
+ }
@@ -1,6 +1,12 @@
1
- import { irArray, irReadonly, irTuple, irTupleElement } from "../../../domain/ir/constructors.js";
2
- import type { IrType } from "../../../domain/ir/nodes.js";
3
- import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
1
+ import {
2
+ irArray,
3
+ irOptionalTupleElement,
4
+ irReadonly,
5
+ irTuple,
6
+ irTupleElement,
7
+ } from "../../../domain/ir/constructors.js";
8
+ import type { IrTupleElement, IrType } from "../../../domain/ir/nodes.js";
9
+ import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
4
10
  import { OutputFix } from "../../../domain/output-fixes.js";
5
11
  import { UNKNOWN_TYPE } from "../shared-types.js";
6
12
  import { unionOf } from "../type-combinators.js";
@@ -12,9 +18,15 @@ import type { SchemaRequest } from "./schema-rule.js";
12
18
  */
13
19
  const MAX_LENGTH_TUPLE_ELEMENTS = 30;
14
20
 
15
- /** The tuple of `prefixItems` (or of an `items` list); null without either. */
21
+ /**
22
+ * The tuple of `prefixItems` (or of an `items` list); null without either. The original closes a
23
+ * `prefixItems` tuple and requires every element; the `prefix-items` fix does not.
24
+ */
16
25
  function prefixTupleType(schema: SchemaObject, request: SchemaRequest): IrType | null {
17
26
  const { items } = schema;
27
+ if (schema.prefixItems && isPrefixItemsFixed(schema, request)) {
28
+ return prefixItemsTupleType(schema.prefixItems, schema, request);
29
+ }
18
30
  if (!schema.prefixItems && !Array.isArray(items)) {
19
31
  return null;
20
32
  }
@@ -24,6 +36,54 @@ function prefixTupleType(schema: SchemaObject, request: SchemaRequest): IrType |
24
36
  );
25
37
  }
26
38
 
39
+ /** The type of the items after the prefix, or null when there may be none (`false`). */
40
+ function restItemType(schema: Schema, request: SchemaRequest): IrType | null {
41
+ return schema === false ? null : request.transformNested(schema, request.location);
42
+ }
43
+
44
+ /**
45
+ * The type of the items after a `prefixItems` tuple (JSON Schema 2020-12 §10.3.1): `items`, else
46
+ * `unevaluatedItems`, which does not apply to the items `contains` matches, else any item. Null
47
+ * when no item may follow. An `items` list is not a schema in 2020-12, so it allows any item.
48
+ */
49
+ function prefixRestType(schema: SchemaObject, request: SchemaRequest): IrType | null {
50
+ const { items, unevaluatedItems, contains } = schema;
51
+ if (items !== undefined && !Array.isArray(items)) {
52
+ return restItemType(items as Schema, request);
53
+ }
54
+ if (unevaluatedItems === undefined || items !== undefined) {
55
+ return UNKNOWN_TYPE;
56
+ }
57
+ const unevaluated = restItemType(unevaluatedItems, request);
58
+ const matched = contains === undefined ? null : restItemType(contains, request);
59
+ const types = [unevaluated, matched].filter((type): type is IrType => type !== null);
60
+ return types.length === 0 ? null : unionOf(types);
61
+ }
62
+
63
+ /**
64
+ * The `prefix-items` tuple of `prefixItems`: an array may end before the prefix does, so the
65
+ * elements from `minItems` on are optional (`T?`), and a rest element types the items after it.
66
+ */
67
+ function prefixItemsTupleType(
68
+ prefixItems: readonly Schema[],
69
+ schema: SchemaObject,
70
+ request: SchemaRequest,
71
+ ): IrType {
72
+ const { min } = lengthBounds(schema);
73
+ const elements = prefixItems.map((item, index): IrTupleElement => {
74
+ const type = request.transformNested(item, request.location);
75
+ return index < min ? irTupleElement(type) : irOptionalTupleElement(type);
76
+ });
77
+ const rest = prefixRestType(schema, request);
78
+ return irTuple(rest === null ? elements : [...elements, irTupleElement(irArray(rest), true)]);
79
+ }
80
+
81
+ function isPrefixItemsFixed(schema: SchemaObject, request: SchemaRequest): boolean {
82
+ return (
83
+ schema.prefixItems !== undefined && request.context.options.fixes.has(OutputFix.PREFIX_ITEMS)
84
+ );
85
+ }
86
+
27
87
  /** The type of one item; `unknown` without `items`. */
28
88
  function singleItemType(schema: SchemaObject, request: SchemaRequest): IrType {
29
89
  const { items } = schema;
@@ -143,7 +203,8 @@ export function arrayType(schema: SchemaObject, request: SchemaRequest): IrType
143
203
  }
144
204
  const item = itemType(schema, request);
145
205
  const bounds = lengthBounds(schema);
146
- if (isLengthTupleWanted(bounds, request)) {
206
+ // A `prefix-items` tuple has its own lengths, so `--array-length` adds no tuples around it.
207
+ if (!isPrefixItemsFixed(schema, request) && isLengthTupleWanted(bounds, request)) {
147
208
  return lengthTupleType(schema, item, bounds);
148
209
  }
149
210
  // A tuple or an array item is used as the array type itself.
@@ -3,6 +3,7 @@ import type { IrType } from "../../../domain/ir/nodes.js";
3
3
  import { createRef } from "../../../domain/openapi/json-pointer.js";
4
4
  import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
5
5
  import { OutputFix } from "../../../domain/output-fixes.js";
6
+ import { requirableRefType } from "../ref-pointer/pointer-type.js";
6
7
  import { UNKNOWN_TYPE } from "../shared-types.js";
7
8
  import {
8
9
  intersectionOf,
@@ -13,7 +14,9 @@ import {
13
14
  withRequiredKeys,
14
15
  } from "../type-combinators.js";
15
16
  import { coreType } from "./core-type.js";
17
+ import { unionItemOf, unionOwnKeywords } from "./discriminated-union.js";
16
18
  import { allOfMembers } from "./presence-members.js";
19
+ import { requiredVariantsType } from "./required-variants.js";
17
20
  import type { SchemaRequest } from "./schema-rule.js";
18
21
  import { unevaluatedPropertiesType } from "./unevaluated-properties.js";
19
22
 
@@ -39,6 +42,28 @@ function isRefItem(item: Schema): item is { readonly $ref: string } {
39
42
  return "$ref" in (item as object);
40
43
  }
41
44
 
45
+ /**
46
+ * The parent's `required` keys that the target at `ref` defines. A target that the discriminator
47
+ * scan gave its property got none: the scan made that property required, but the other keys were
48
+ * lost too. With `discriminator-member-required` only keys the target requires already are left
49
+ * out (#2162).
50
+ */
51
+ function keysToRequire(
52
+ ref: string,
53
+ target: SchemaObject,
54
+ required: readonly string[],
55
+ request: SchemaRequest,
56
+ ): readonly string[] {
57
+ const defined = required.filter((key) => Boolean(target.properties?.[key]));
58
+ if (!request.context.discriminators.isHandled(ref)) {
59
+ return defined;
60
+ }
61
+ if (!request.context.options.fixes.has(OutputFix.DISCRIMINATOR_MEMBER_REQUIRED)) {
62
+ return [];
63
+ }
64
+ return defined.filter((key) => !target.required?.includes(key));
65
+ }
66
+
42
67
  /** A `$ref` item gets the parent's `required` keys that its target defines (`WithRequired`). */
43
68
  function refItemType(
44
69
  item: { readonly $ref: string },
@@ -46,21 +71,16 @@ function refItemType(
46
71
  request: SchemaRequest,
47
72
  ): IrType {
48
73
  const type = request.transformNested(item, request.location);
49
- const { refs, discriminators, footer } = request.context;
50
- const resolved = refs.resolve(item.$ref) as SchemaObject | undefined;
51
- const isEligible =
52
- resolved &&
53
- typeof resolved === "object" &&
54
- "properties" in resolved &&
55
- !discriminators.isHandled(item.$ref);
56
- if (!isEligible) {
74
+ const resolved = request.context.refs.resolve(item.$ref) as SchemaObject | undefined;
75
+ if (!resolved || typeof resolved !== "object" || !("properties" in resolved)) {
57
76
  return type;
58
77
  }
59
- const keys = required.filter((key) => Boolean(resolved.properties?.[key]));
60
- if (keys.length > 0) {
61
- footer.requireWithRequired();
78
+ const keys = keysToRequire(item.$ref, resolved, required, request);
79
+ if (keys.length === 0) {
80
+ return type;
62
81
  }
63
- return withRequiredKeys(type, keys);
82
+ request.context.footer.requireWithRequired();
83
+ return withRequiredKeys(requirableRefType(item.$ref, type, request), keys);
64
84
  }
65
85
 
66
86
  /** An inline item merges the parent's `required` keys with its own. */
@@ -75,22 +95,59 @@ function inlineItemType(item: Schema, required: readonly string[], request: Sche
75
95
  );
76
96
  }
77
97
 
78
- /** `allOf` items; an item with a discriminator omits that property (the parent redefines it). */
98
+ /**
99
+ * The union's own keywords at the union's location, so nested names (enums) stay the union's.
100
+ * Null when the union has none.
101
+ */
102
+ function ownKeywordsType(own: SchemaObject, ref: string, request: SchemaRequest): IrType | null {
103
+ return combinedType(own, { ...request, location: { ...request.location, path: ref } });
104
+ }
105
+
106
+ /**
107
+ * An `allOf` item; one with a discriminator omits that property (the parent redefines it). A
108
+ * `$ref` to a discriminated union is not such a parent: for a member of the union it is the
109
+ * union's own keywords, since the union contains the member (#1665); with
110
+ * `allof-discriminated-union` it is the union, since `Omit` on a union drops keys (#1464), unless
111
+ * the union's mapping names the schema: then it is a member, as the discriminator scan has it.
112
+ */
113
+ function allOfItemType(
114
+ item: Schema,
115
+ required: readonly string[],
116
+ request: SchemaRequest,
117
+ ): IrType | null {
118
+ const isRef = isRefItem(item);
119
+ const discriminator =
120
+ (isRef && request.context.discriminators.objectAt(item.$ref)) ||
121
+ (item as SchemaObject).discriminator;
122
+ const propertyName = discriminator?.propertyName;
123
+ const unionItem = isRef && propertyName ? unionItemOf(item.$ref, request) : undefined;
124
+ if (isRef && propertyName && unionItem?.isMember) {
125
+ const own = unionOwnKeywords(unionItem.union, propertyName, required);
126
+ return ownKeywordsType(own, item.$ref, request);
127
+ }
128
+ const type = isRef
129
+ ? refItemType(item, required, request)
130
+ : inlineItemType(item, required, request);
131
+ const isUnion =
132
+ unionItem !== undefined &&
133
+ !unionItem.isMapped &&
134
+ request.context.options.fixes.has(OutputFix.ALLOF_DISCRIMINATED_UNION);
135
+ if (!propertyName || isUnion) {
136
+ return type;
137
+ }
138
+ // With `discriminator-values` the schema also redefines the properties of other owners above
139
+ // it, so no item may keep a value of its own for them (a parent mapped as `content`).
140
+ const { path } = request.location;
141
+ const others = path === undefined ? [] : request.context.discriminators.otherPropertiesAt(path);
142
+ return omitKeys(type, [propertyName, ...others]);
143
+ }
144
+
79
145
  function allOfTypes(
80
146
  items: readonly Schema[],
81
147
  required: readonly string[],
82
148
  request: SchemaRequest,
83
149
  ): IrType[] {
84
- return items.map((item) => {
85
- const isRef = isRefItem(item);
86
- const type = isRef
87
- ? refItemType(item, required, request)
88
- : inlineItemType(item, required, request);
89
- const discriminator =
90
- (isRef && request.context.discriminators.objectAt(item.$ref)) ||
91
- (item as SchemaObject).discriminator;
92
- return discriminator?.propertyName ? omitKeys(type, [discriminator.propertyName]) : type;
93
- });
150
+ return items.flatMap((item) => allOfItemType(item, required, request) ?? []);
94
151
  }
95
152
 
96
153
  function oneOfType(previous: IrType | null, variants: readonly IrType[]): IrType {
@@ -147,7 +204,22 @@ function composedType(schema: SchemaObject, request: SchemaRequest): IrType | nu
147
204
  const allOfType = allOf.length > 0 ? [intersectionOf(allOf)] : [];
148
205
  type = intersectionOf([...(core === null ? [] : [core]), ...allOfType]);
149
206
  }
150
- type = anyOfType(type, schema, request);
207
+ return variantsType(type, schema, request);
208
+ }
209
+
210
+ /** `anyOf`, then `oneOf`, applied to the core and `allOf` type (`anyof-oneof-required` first). */
211
+ function variantsType(
212
+ previous: IrType | null,
213
+ schema: SchemaObject,
214
+ request: SchemaRequest,
215
+ ): IrType | null {
216
+ const type =
217
+ requiredVariantsType(previous, schema, schema.anyOf ?? [], request) ??
218
+ anyOfType(previous, schema, request);
219
+ const oneOfRequired = requiredVariantsType(type, schema, schema.oneOf ?? [], request);
220
+ if (oneOfRequired !== null) {
221
+ return oneOfRequired;
222
+ }
151
223
  const oneOf = variantTypes(oneOfVariants(schema), "oneOf", request);
152
224
  return oneOf.length > 0 ? oneOfType(type, oneOf) : type;
153
225
  }
@@ -9,6 +9,7 @@ import type {
9
9
  import { unionOf } from "../type-combinators.js";
10
10
  import { arrayType } from "./array-type.js";
11
11
  import { objectType } from "./object-type.js";
12
+ import { hasRequiredVariants } from "./required-variants.js";
12
13
  import type { SchemaRequest, SchemaRule } from "./schema-rule.js";
13
14
 
14
15
  const PRIMITIVE_TYPE_NAMES: ReadonlySet<SchemaTypeName | null> = new Set([
@@ -34,10 +35,13 @@ function multipleTypes(schema: SchemaObject, request: SchemaRequest): IrType {
34
35
  if (isInOneOf) {
35
36
  continue;
36
37
  }
37
- // With oneOf, the member drops it, so oneOf is not applied once per member.
38
- const variant = Array.isArray(oneOf)
39
- ? { ...schema, type: typeName, oneOf: undefined }
40
- : { ...schema, type: typeName };
38
+ // With oneOf, the member drops it, so oneOf is not applied once per member. Variants that
39
+ // only require properties (`anyof-oneof-required`) belong to the object member.
40
+ const isKept = typeName === "object" && hasRequiredVariants(schema, oneOf ?? [], request);
41
+ const variant =
42
+ Array.isArray(oneOf) && !isKept
43
+ ? { ...schema, type: typeName, oneOf: undefined }
44
+ : { ...schema, type: typeName };
41
45
  members.push(
42
46
  typeName === "null" || typeName === null
43
47
  ? irKeyword("null")
@@ -0,0 +1,58 @@
1
+ import { unionAt, unionMaps, unionReaches } from "../../../domain/openapi/discriminated-union.js";
2
+ import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
3
+ import type { SchemaRequest } from "./schema-rule.js";
4
+
5
+ /**
6
+ * `allOf` items that are a `$ref` to a discriminated union (`oneOf` / `anyOf` and a
7
+ * discriminator). Such an item cannot be typed as the parent of the inheritance pattern,
8
+ * `Omit<Union, "kind">`.
9
+ */
10
+
11
+ /** The union an `allOf` item refers to, and whether the union's type contains this schema. */
12
+ export interface UnionItem {
13
+ readonly union: SchemaObject;
14
+ /**
15
+ * The schema is one of the union's members: intersecting the union would make it refer to
16
+ * itself, which does not compile (TS2502, upstream #1665).
17
+ */
18
+ readonly isMember: boolean;
19
+ /** The union's mapping names the schema, so it is a member even where the type is not. */
20
+ readonly isMapped: boolean;
21
+ }
22
+
23
+ /** The union at `ref`, if the schema there is one. */
24
+ export function unionItemOf(ref: string, request: SchemaRequest): UnionItem | undefined {
25
+ const path = request.location.path;
26
+ const resolve = (target: string) => request.context.refs.resolve(target);
27
+ const union = unionAt(ref, resolve);
28
+ if (union === undefined) {
29
+ return undefined;
30
+ }
31
+ const isMember = path !== undefined && unionReaches(union, path, resolve);
32
+ return { union, isMember, isMapped: path !== undefined && unionMaps(union, path) };
33
+ }
34
+
35
+ function withoutKey<T>(record: Readonly<Record<string, T>>, key: string): Record<string, T> {
36
+ return Object.fromEntries(Object.entries(record).filter(([name]) => name !== key));
37
+ }
38
+
39
+ /**
40
+ * The keywords of a union that its members inherit: everything but the members and the
41
+ * discriminator property, which each member redefines (as `Omit` does for a parent). The item's
42
+ * `required` keys are added, as for an inline `allOf` item.
43
+ */
44
+ export function unionOwnKeywords(
45
+ union: SchemaObject,
46
+ propertyName: string,
47
+ required: readonly string[],
48
+ ): SchemaObject {
49
+ const { oneOf: _oneOf, anyOf: _anyOf, ...own } = union;
50
+ const ownRequired = (union.required ?? []).filter((key) => key !== propertyName);
51
+ return {
52
+ ...own,
53
+ ...(union.properties === undefined
54
+ ? {}
55
+ : { properties: withoutKey(union.properties, propertyName) }),
56
+ required: [...required, ...ownRequired],
57
+ };
58
+ }