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

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 (404) hide show
  1. package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
  2. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
  3. package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
  4. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
  5. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +15 -5
  6. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  7. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +15 -5
  8. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  9. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +3 -0
  10. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
  11. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +3 -0
  12. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
  13. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
  14. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
  15. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
  16. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
  17. package/dist/api/discriminator-conflict-warnings.cjs +25 -0
  18. package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
  19. package/dist/api/discriminator-conflict-warnings.mjs +23 -0
  20. package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
  21. package/dist/api/discriminator-enum-names.cjs +19 -0
  22. package/dist/api/discriminator-enum-names.cjs.map +1 -0
  23. package/dist/api/discriminator-enum-names.mjs +17 -0
  24. package/dist/api/discriminator-enum-names.mjs.map +1 -0
  25. package/dist/api/discriminator-enum-parent.cjs +59 -0
  26. package/dist/api/discriminator-enum-parent.cjs.map +1 -0
  27. package/dist/api/discriminator-enum-parent.mjs +57 -0
  28. package/dist/api/discriminator-enum-parent.mjs.map +1 -0
  29. package/dist/api/discriminator-enum.cjs +25 -0
  30. package/dist/api/discriminator-enum.cjs.map +1 -1
  31. package/dist/api/discriminator-enum.mjs +25 -1
  32. package/dist/api/discriminator-enum.mjs.map +1 -1
  33. package/dist/api/discriminator-other-owners.cjs +67 -0
  34. package/dist/api/discriminator-other-owners.cjs.map +1 -0
  35. package/dist/api/discriminator-other-owners.mjs +64 -0
  36. package/dist/api/discriminator-other-owners.mjs.map +1 -0
  37. package/dist/api/discriminator-patch.cjs +88 -0
  38. package/dist/api/discriminator-patch.cjs.map +1 -0
  39. package/dist/api/discriminator-patch.mjs +82 -0
  40. package/dist/api/discriminator-patch.mjs.map +1 -0
  41. package/dist/api/discriminator-scan.cjs +50 -65
  42. package/dist/api/discriminator-scan.cjs.map +1 -1
  43. package/dist/api/discriminator-scan.mjs +44 -59
  44. package/dist/api/discriminator-scan.mjs.map +1 -1
  45. package/dist/api/document-run.cjs +18 -3
  46. package/dist/api/document-run.cjs.map +1 -1
  47. package/dist/api/document-run.mjs +19 -4
  48. package/dist/api/document-run.mjs.map +1 -1
  49. package/dist/api/enum-values-warnings.cjs +16 -0
  50. package/dist/api/enum-values-warnings.cjs.map +1 -0
  51. package/dist/api/enum-values-warnings.mjs +14 -0
  52. package/dist/api/enum-values-warnings.mjs.map +1 -0
  53. package/dist/api/path-template-warnings.cjs +21 -0
  54. package/dist/api/path-template-warnings.cjs.map +1 -0
  55. package/dist/api/path-template-warnings.mjs +19 -0
  56. package/dist/api/path-template-warnings.mjs.map +1 -0
  57. package/dist/api/transform-context.cjs +3 -1
  58. package/dist/api/transform-context.cjs.map +1 -1
  59. package/dist/api/transform-context.mjs +3 -1
  60. package/dist/api/transform-context.mjs.map +1 -1
  61. package/dist/api/transform-schema.cjs +52 -3
  62. package/dist/api/transform-schema.cjs.map +1 -1
  63. package/dist/api/transform-schema.mjs +53 -4
  64. package/dist/api/transform-schema.mjs.map +1 -1
  65. package/dist/api/unsupported-feature-warnings.cjs +6 -1
  66. package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
  67. package/dist/api/unsupported-feature-warnings.mjs +6 -1
  68. package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
  69. package/dist/application/print/type-printer.cjs +5 -0
  70. package/dist/application/print/type-printer.cjs.map +1 -1
  71. package/dist/application/print/type-printer.mjs +5 -0
  72. package/dist/application/print/type-printer.mjs.map +1 -1
  73. package/dist/application/transform/document/assignability.cjs +144 -0
  74. package/dist/application/transform/document/assignability.cjs.map +1 -0
  75. package/dist/application/transform/document/assignability.mjs +138 -0
  76. package/dist/application/transform/document/assignability.mjs.map +1 -0
  77. package/dist/application/transform/document/components.cjs +2 -2
  78. package/dist/application/transform/document/components.cjs.map +1 -1
  79. package/dist/application/transform/document/components.mjs +4 -4
  80. package/dist/application/transform/document/components.mjs.map +1 -1
  81. package/dist/application/transform/document/declared-types.cjs +66 -0
  82. package/dist/application/transform/document/declared-types.cjs.map +1 -0
  83. package/dist/application/transform/document/declared-types.mjs +63 -0
  84. package/dist/application/transform/document/declared-types.mjs.map +1 -0
  85. package/dist/application/transform/document/document.cjs +32 -9
  86. package/dist/application/transform/document/document.cjs.map +1 -1
  87. package/dist/application/transform/document/document.mjs +34 -11
  88. package/dist/application/transform/document/document.mjs.map +1 -1
  89. package/dist/application/transform/document/exploded-query.cjs +46 -0
  90. package/dist/application/transform/document/exploded-query.cjs.map +1 -0
  91. package/dist/application/transform/document/exploded-query.mjs +43 -0
  92. package/dist/application/transform/document/exploded-query.mjs.map +1 -0
  93. package/dist/application/transform/document/global-type-references.cjs +63 -0
  94. package/dist/application/transform/document/global-type-references.cjs.map +1 -0
  95. package/dist/application/transform/document/global-type-references.mjs +61 -0
  96. package/dist/application/transform/document/global-type-references.mjs.map +1 -0
  97. package/dist/application/transform/document/list-assignability.cjs +54 -0
  98. package/dist/application/transform/document/list-assignability.cjs.map +1 -0
  99. package/dist/application/transform/document/list-assignability.mjs +52 -0
  100. package/dist/application/transform/document/list-assignability.mjs.map +1 -0
  101. package/dist/application/transform/document/parameters.cjs +40 -8
  102. package/dist/application/transform/document/parameters.cjs.map +1 -1
  103. package/dist/application/transform/document/parameters.mjs +41 -9
  104. package/dist/application/transform/document/parameters.mjs.map +1 -1
  105. package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
  106. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
  107. package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
  108. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
  109. package/dist/application/transform/document/path-template-replace.cjs +48 -0
  110. package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
  111. package/dist/application/transform/document/path-template-replace.mjs +45 -0
  112. package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
  113. package/dist/application/transform/document/paths.cjs +54 -28
  114. package/dist/application/transform/document/paths.cjs.map +1 -1
  115. package/dist/application/transform/document/paths.mjs +53 -29
  116. package/dist/application/transform/document/paths.mjs.map +1 -1
  117. package/dist/application/transform/document/root-type-aliases.cjs +15 -14
  118. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  119. package/dist/application/transform/document/root-type-aliases.mjs +15 -13
  120. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  121. package/dist/application/transform/document/template-key-match.cjs +128 -0
  122. package/dist/application/transform/document/template-key-match.cjs.map +1 -0
  123. package/dist/application/transform/document/template-key-match.mjs +125 -0
  124. package/dist/application/transform/document/template-key-match.mjs.map +1 -0
  125. package/dist/application/transform/document/type-assignability.cjs +192 -0
  126. package/dist/application/transform/document/type-assignability.cjs.map +1 -0
  127. package/dist/application/transform/document/type-assignability.mjs +190 -0
  128. package/dist/application/transform/document/type-assignability.mjs.map +1 -0
  129. package/dist/application/transform/document/type-key.cjs +70 -0
  130. package/dist/application/transform/document/type-key.cjs.map +1 -0
  131. package/dist/application/transform/document/type-key.mjs +68 -0
  132. package/dist/application/transform/document/type-key.mjs.map +1 -0
  133. package/dist/application/transform/document/type-resolution.cjs +131 -0
  134. package/dist/application/transform/document/type-resolution.cjs.map +1 -0
  135. package/dist/application/transform/document/type-resolution.mjs +125 -0
  136. package/dist/application/transform/document/type-resolution.mjs.map +1 -0
  137. package/dist/application/transform/footer/document-footer.cjs +66 -4
  138. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  139. package/dist/application/transform/footer/document-footer.mjs +67 -5
  140. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  141. package/dist/application/transform/footer/enum-naming.cjs +17 -0
  142. package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
  143. package/dist/application/transform/footer/enum-naming.mjs +17 -1
  144. package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
  145. package/dist/application/transform/footer/enum-values-check.cjs +129 -0
  146. package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
  147. package/dist/application/transform/footer/enum-values-check.mjs +127 -0
  148. package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
  149. package/dist/application/transform/footer/evaluation.cjs +33 -0
  150. package/dist/application/transform/footer/evaluation.cjs.map +1 -0
  151. package/dist/application/transform/footer/evaluation.mjs +26 -0
  152. package/dist/application/transform/footer/evaluation.mjs.map +1 -0
  153. package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
  154. package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
  155. package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
  156. package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
  157. package/dist/application/transform/footer/type-evaluation.cjs +246 -0
  158. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
  159. package/dist/application/transform/footer/type-evaluation.mjs +244 -0
  160. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
  161. package/dist/application/transform/footer/type-rules.cjs +172 -0
  162. package/dist/application/transform/footer/type-rules.cjs.map +1 -0
  163. package/dist/application/transform/footer/type-rules.mjs +166 -0
  164. package/dist/application/transform/footer/type-rules.mjs.map +1 -0
  165. package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
  166. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
  167. package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
  168. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
  169. package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
  170. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
  171. package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
  172. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
  173. package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
  174. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
  175. package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
  176. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
  177. package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
  178. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
  179. package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
  180. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
  181. package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
  182. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
  183. package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
  184. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
  185. package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
  186. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
  187. package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
  188. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
  189. package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
  190. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
  191. package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
  192. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
  193. package/dist/application/transform/ref-type.cjs +7 -2
  194. package/dist/application/transform/ref-type.cjs.map +1 -1
  195. package/dist/application/transform/ref-type.mjs +3 -2
  196. package/dist/application/transform/ref-type.mjs.map +1 -1
  197. package/dist/application/transform/schema/access-flags.cjs +38 -0
  198. package/dist/application/transform/schema/access-flags.cjs.map +1 -0
  199. package/dist/application/transform/schema/access-flags.mjs +36 -0
  200. package/dist/application/transform/schema/access-flags.mjs.map +1 -0
  201. package/dist/application/transform/schema/array-type.cjs +32 -1
  202. package/dist/application/transform/schema/array-type.cjs.map +1 -1
  203. package/dist/application/transform/schema/array-type.mjs +33 -2
  204. package/dist/application/transform/schema/array-type.mjs.map +1 -1
  205. package/dist/application/transform/schema/composition-type.cjs +50 -15
  206. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  207. package/dist/application/transform/schema/composition-type.mjs +50 -15
  208. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  209. package/dist/application/transform/schema/core-type.cjs +3 -1
  210. package/dist/application/transform/schema/core-type.cjs.map +1 -1
  211. package/dist/application/transform/schema/core-type.mjs +3 -1
  212. package/dist/application/transform/schema/core-type.mjs.map +1 -1
  213. package/dist/application/transform/schema/discriminated-union.cjs +30 -0
  214. package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
  215. package/dist/application/transform/schema/discriminated-union.mjs +27 -0
  216. package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
  217. package/dist/application/transform/schema/discriminator-property.cjs +3 -2
  218. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
  219. package/dist/application/transform/schema/discriminator-property.mjs +3 -2
  220. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
  221. package/dist/application/transform/schema/enum-rule.cjs +66 -10
  222. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  223. package/dist/application/transform/schema/enum-rule.mjs +67 -12
  224. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  225. package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
  226. package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
  227. package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
  228. package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
  229. package/dist/application/transform/schema/object-type.cjs +38 -25
  230. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  231. package/dist/application/transform/schema/object-type.mjs +39 -27
  232. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  233. package/dist/application/transform/schema/required-variants.cjs +45 -0
  234. package/dist/application/transform/schema/required-variants.cjs.map +1 -0
  235. package/dist/application/transform/schema/required-variants.mjs +42 -0
  236. package/dist/application/transform/schema/required-variants.mjs.map +1 -0
  237. package/dist/application/transform/schema/schema-transform.cjs +2 -2
  238. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  239. package/dist/application/transform/schema/schema-transform.mjs +2 -2
  240. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  241. package/dist/application/transform/schema-comment.cjs +51 -5
  242. package/dist/application/transform/schema-comment.cjs.map +1 -1
  243. package/dist/application/transform/schema-comment.mjs +50 -6
  244. package/dist/application/transform/schema-comment.mjs.map +1 -1
  245. package/dist/application/transform/type-combinators.mjs +1 -1
  246. package/dist/cli/cli-arguments.cjs +11 -3
  247. package/dist/cli/cli-arguments.cjs.map +1 -1
  248. package/dist/cli/cli-arguments.mjs +11 -3
  249. package/dist/cli/cli-arguments.mjs.map +1 -1
  250. package/dist/cli/cli-errors.cjs +3 -2
  251. package/dist/cli/cli-errors.cjs.map +1 -1
  252. package/dist/cli/cli-errors.mjs +3 -2
  253. package/dist/cli/cli-errors.mjs.map +1 -1
  254. package/dist/cli/cli-output.cjs +8 -3
  255. package/dist/cli/cli-output.cjs.map +1 -1
  256. package/dist/cli/cli-output.mjs +9 -4
  257. package/dist/cli/cli-output.mjs.map +1 -1
  258. package/dist/cli/main.cjs +5 -0
  259. package/dist/cli/main.cjs.map +1 -1
  260. package/dist/cli/main.mjs +5 -0
  261. package/dist/cli/main.mjs.map +1 -1
  262. package/dist/cli/redocly-apis.cjs +7 -3
  263. package/dist/cli/redocly-apis.cjs.map +1 -1
  264. package/dist/cli/redocly-apis.mjs +8 -4
  265. package/dist/cli/redocly-apis.mjs.map +1 -1
  266. package/dist/cli/ref-limits.cjs +1 -1
  267. package/dist/cli/ref-limits.cjs.map +1 -1
  268. package/dist/cli/ref-limits.mjs +2 -2
  269. package/dist/cli/ref-limits.mjs.map +1 -1
  270. package/dist/cli/run-cli.cjs +15 -2
  271. package/dist/cli/run-cli.cjs.map +1 -1
  272. package/dist/cli/run-cli.mjs +16 -3
  273. package/dist/cli/run-cli.mjs.map +1 -1
  274. package/dist/domain/errors.cjs +2 -0
  275. package/dist/domain/errors.cjs.map +1 -1
  276. package/dist/domain/errors.mjs +2 -0
  277. package/dist/domain/errors.mjs.map +1 -1
  278. package/dist/domain/ir/constructors.cjs +5 -1
  279. package/dist/domain/ir/constructors.cjs.map +1 -1
  280. package/dist/domain/ir/constructors.mjs +5 -2
  281. package/dist/domain/ir/constructors.mjs.map +1 -1
  282. package/dist/domain/openapi/admitted-values.cjs +75 -0
  283. package/dist/domain/openapi/admitted-values.cjs.map +1 -0
  284. package/dist/domain/openapi/admitted-values.mjs +72 -0
  285. package/dist/domain/openapi/admitted-values.mjs.map +1 -0
  286. package/dist/domain/openapi/discriminated-union.cjs +68 -0
  287. package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
  288. package/dist/domain/openapi/discriminated-union.mjs +62 -0
  289. package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
  290. package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
  291. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
  292. package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
  293. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
  294. package/dist/domain/openapi/parameter-object.cjs.map +1 -1
  295. package/dist/domain/openapi/parameter-object.mjs.map +1 -1
  296. package/dist/domain/openapi/path-templates.cjs +23 -0
  297. package/dist/domain/openapi/path-templates.cjs.map +1 -0
  298. package/dist/domain/openapi/path-templates.mjs +21 -0
  299. package/dist/domain/openapi/path-templates.mjs.map +1 -0
  300. package/dist/domain/output-fixes.cjs +36 -1
  301. package/dist/domain/output-fixes.cjs.map +1 -1
  302. package/dist/domain/output-fixes.mjs +36 -1
  303. package/dist/domain/output-fixes.mjs.map +1 -1
  304. package/dist/domain/warnings.cjs +15 -0
  305. package/dist/domain/warnings.cjs.map +1 -0
  306. package/dist/domain/warnings.mjs +12 -0
  307. package/dist/domain/warnings.mjs.map +1 -0
  308. package/dist/index.d.cts +29 -0
  309. package/dist/index.d.mts +29 -0
  310. package/dist/index.d.ts +29 -0
  311. package/dist/transform/components-object.cjs +2 -1
  312. package/dist/transform/components-object.cjs.map +1 -1
  313. package/dist/transform/components-object.mjs +2 -1
  314. package/dist/transform/components-object.mjs.map +1 -1
  315. package/package.json +1 -1
  316. package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
  317. package/src/adapters/redocly-loader/redocly-schema-loader.ts +22 -6
  318. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +3 -0
  319. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
  320. package/src/api/discriminator-conflict-warnings.ts +43 -0
  321. package/src/api/discriminator-enum-names.ts +26 -0
  322. package/src/api/discriminator-enum-parent.ts +129 -0
  323. package/src/api/discriminator-enum.ts +39 -0
  324. package/src/api/discriminator-other-owners.ts +97 -0
  325. package/src/api/discriminator-patch.ts +147 -0
  326. package/src/api/discriminator-scan.ts +78 -90
  327. package/src/api/document-run.ts +24 -6
  328. package/src/api/enum-values-warnings.ts +21 -0
  329. package/src/api/path-template-warnings.ts +27 -0
  330. package/src/api/transform-context.ts +7 -1
  331. package/src/api/transform-schema.ts +88 -4
  332. package/src/api/unsupported-feature-warnings.ts +8 -1
  333. package/src/application/ports/redocly-config-source.ts +5 -1
  334. package/src/application/print/type-printer.ts +6 -0
  335. package/src/application/transform/document/assignability.ts +203 -0
  336. package/src/application/transform/document/components.ts +6 -6
  337. package/src/application/transform/document/declared-types.ts +93 -0
  338. package/src/application/transform/document/document.ts +71 -13
  339. package/src/application/transform/document/exploded-query.ts +91 -0
  340. package/src/application/transform/document/global-type-references.ts +78 -0
  341. package/src/application/transform/document/list-assignability.ts +87 -0
  342. package/src/application/transform/document/parameters.ts +76 -11
  343. package/src/application/transform/document/path-key-overlaps.ts +148 -59
  344. package/src/application/transform/document/path-template-replace.ts +90 -0
  345. package/src/application/transform/document/paths.ts +99 -37
  346. package/src/application/transform/document/root-type-aliases.ts +29 -28
  347. package/src/application/transform/document/template-key-match.ts +183 -0
  348. package/src/application/transform/document/type-assignability.ts +268 -0
  349. package/src/application/transform/document/type-key.ts +80 -0
  350. package/src/application/transform/document/type-resolution.ts +163 -0
  351. package/src/application/transform/footer/document-footer.ts +91 -6
  352. package/src/application/transform/footer/enum-naming.ts +29 -0
  353. package/src/application/transform/footer/enum-values-check.ts +171 -0
  354. package/src/application/transform/footer/evaluation.ts +47 -0
  355. package/src/application/transform/footer/shared-enum-names.ts +86 -0
  356. package/src/application/transform/footer/type-evaluation.ts +294 -0
  357. package/src/application/transform/footer/type-rules.ts +269 -0
  358. package/src/application/transform/ref-pointer/generated-location.ts +211 -0
  359. package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
  360. package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
  361. package/src/application/transform/ref-pointer/original-index.ts +95 -0
  362. package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
  363. package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
  364. package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
  365. package/src/application/transform/ref-type.ts +11 -6
  366. package/src/application/transform/schema/access-flags.ts +63 -0
  367. package/src/application/transform/schema/array-type.ts +66 -5
  368. package/src/application/transform/schema/composition-type.ts +96 -24
  369. package/src/application/transform/schema/core-type.ts +8 -4
  370. package/src/application/transform/schema/discriminated-union.ts +58 -0
  371. package/src/application/transform/schema/discriminator-property.ts +8 -3
  372. package/src/application/transform/schema/enum-rule.ts +136 -13
  373. package/src/application/transform/schema/inherited-discriminator.ts +54 -0
  374. package/src/application/transform/schema/object-type.ts +51 -33
  375. package/src/application/transform/schema/required-variants.ts +88 -0
  376. package/src/application/transform/schema/schema-context.ts +26 -0
  377. package/src/application/transform/schema/schema-transform.ts +2 -2
  378. package/src/application/transform/schema-comment.ts +84 -4
  379. package/src/cli/cli-arguments.ts +13 -3
  380. package/src/cli/cli-dependencies.ts +5 -0
  381. package/src/cli/cli-errors.ts +4 -2
  382. package/src/cli/cli-output.ts +18 -4
  383. package/src/cli/main.ts +6 -0
  384. package/src/cli/redocly-apis.ts +8 -4
  385. package/src/cli/ref-limits.ts +2 -2
  386. package/src/cli/run-cli.ts +20 -3
  387. package/src/domain/errors.ts +2 -0
  388. package/src/domain/ir/constructors.ts +6 -1
  389. package/src/domain/ir/nodes.ts +2 -1
  390. package/src/domain/openapi/admitted-values.ts +113 -0
  391. package/src/domain/openapi/discriminated-union.ts +109 -0
  392. package/src/domain/openapi/discriminator-conflicts.ts +251 -0
  393. package/src/domain/openapi/parameter-object.ts +4 -0
  394. package/src/domain/openapi/path-templates.ts +31 -0
  395. package/src/domain/openapi/schema-object.ts +2 -0
  396. package/src/domain/output-fixes.ts +43 -2
  397. package/src/domain/warnings.ts +20 -0
  398. package/src/transform/components-object.ts +3 -1
  399. package/src/types/generator-options.ts +11 -0
  400. package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
  401. package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
  402. package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
  403. package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
  404. package/src/application/transform/document/path-item-conflicts.ts +0 -79
@@ -0,0 +1,251 @@
1
+ import { admittedPropertyValues, resolveLocalRef } from "./admitted-values.js";
2
+ import { isUnionMember, unionAt } from "./discriminated-union.js";
3
+ import { createRef, escapePointerSegment, parseRefPointer } from "./json-pointer.js";
4
+
5
+ /**
6
+ * Discriminator members whose discriminator value their own property does not allow. By the
7
+ * Discriminator Object rule, a member that no `mapping` entry names has its schema name as the
8
+ * value, so with a property `enum` (or `const`) that does not list it no value of the member
9
+ * matches, and where the generator adds the value to the member the property type is `never`.
10
+ * Each one gets a warning (CODING_PRINCIPLES §8.7).
11
+ */
12
+
13
+ export interface DiscriminatorValueConflict {
14
+ /** The member schema, such as `#/components/schemas/EpisodeObject`. */
15
+ readonly member: string;
16
+ /** The schema that has the Discriminator Object. */
17
+ readonly owner: string;
18
+ readonly propertyName: string;
19
+ /** The values the discriminator gives the member: its mapping keys, or its name. */
20
+ readonly values: readonly string[];
21
+ /** The values the member's property allows. */
22
+ readonly allowed: readonly (string | number | boolean | null)[];
23
+ /** Whether no mapping entry names the member, so its value is its schema name. */
24
+ readonly isImplicit: boolean;
25
+ }
26
+
27
+ type JsonObject = Readonly<Record<string, unknown>>;
28
+
29
+ const COMPONENT_SCHEMAS = "#/components/schemas/";
30
+
31
+ function isObject(value: unknown): value is JsonObject {
32
+ return typeof value === "object" && value !== null && !Array.isArray(value);
33
+ }
34
+
35
+ interface Owner {
36
+ readonly pointer: string;
37
+ readonly propertyName: string;
38
+ readonly mapping: Readonly<Record<string, string>>;
39
+ readonly memberRefs: readonly string[];
40
+ }
41
+
42
+ function refsOf(list: unknown): string[] {
43
+ return (Array.isArray(list) ? list : []).flatMap((item) =>
44
+ isObject(item) && typeof item.$ref === "string" ? [item.$ref] : [],
45
+ );
46
+ }
47
+
48
+ function mappingTarget(target: string): string {
49
+ return target.startsWith("#") ? target : `${COMPONENT_SCHEMAS}${escapePointerSegment(target)}`;
50
+ }
51
+
52
+ function ownerAt(node: JsonObject, pointer: () => string): Owner | null {
53
+ const discriminator = node.discriminator;
54
+ if (!isObject(discriminator) || typeof discriminator.propertyName !== "string") {
55
+ return null;
56
+ }
57
+ const mapping = isObject(discriminator.mapping)
58
+ ? (discriminator.mapping as Readonly<Record<string, string>>)
59
+ : {};
60
+ const mapped = Object.values(mapping)
61
+ .filter((t) => typeof t === "string")
62
+ .map(mappingTarget);
63
+ const memberRefs = [...refsOf(node.oneOf), ...refsOf(node.anyOf), ...mapped];
64
+ return { pointer: pointer(), propertyName: discriminator.propertyName, mapping, memberRefs };
65
+ }
66
+
67
+ /** A node of the document walk; the pointer is built only for the nodes that need it. */
68
+ interface Visit {
69
+ readonly node: unknown;
70
+ readonly key: string | null;
71
+ readonly parent: Visit | null;
72
+ }
73
+
74
+ function pointerOf(visit: Visit): string {
75
+ const segments: string[] = [];
76
+ for (let current: Visit | null = visit; current?.key != null; current = current.parent) {
77
+ segments.unshift(current.key);
78
+ }
79
+ return createRef(segments);
80
+ }
81
+
82
+ function childrenOf(visit: Visit): Visit[] {
83
+ const { node } = visit;
84
+ const entries: [string, unknown][] = Array.isArray(node)
85
+ ? node.map((item, index) => [String(index), item])
86
+ : isObject(node)
87
+ ? Object.entries(node)
88
+ : [];
89
+ return entries.map(([key, child]) => ({ node: child, key, parent: visit }));
90
+ }
91
+
92
+ /**
93
+ * Every Discriminator Object of the document, depth first, with its pointer. The walk keeps its
94
+ * own stack, so a document nested past the call stack fails in the transform, as it did before.
95
+ */
96
+ function ownersIn(document: unknown): Owner[] {
97
+ const found: Owner[] = [];
98
+ const stack: Visit[] = [{ node: document, key: null, parent: null }];
99
+ for (let visit = stack.pop(); visit !== undefined; visit = stack.pop()) {
100
+ const owner = isObject(visit.node) ? ownerAt(visit.node, () => pointerOf(visit)) : null;
101
+ if (owner !== null) {
102
+ found.push(owner);
103
+ }
104
+ stack.push(...childrenOf(visit).reverse());
105
+ }
106
+ return found;
107
+ }
108
+
109
+ /** A member and the `$ref`s whose properties its type leaves out (`Omit` of its parents). */
110
+ interface Member {
111
+ readonly ref: string;
112
+ readonly skipped: ReadonlySet<string>;
113
+ }
114
+
115
+ interface Child {
116
+ readonly ref: string;
117
+ readonly schema: JsonObject;
118
+ }
119
+
120
+ /** How the run types an `allOf` of a discriminated union. */
121
+ export interface ConflictOptions {
122
+ /**
123
+ * `allof-discriminated-union`: a schema that `allOf`s a union which does not contain it reuses
124
+ * the union and gets no value, so neither it nor the schemas below it are members.
125
+ */
126
+ readonly isUnionReused: boolean;
127
+ }
128
+
129
+ /** What the search for conflicts reads: the document and its `allOf` children by parent. */
130
+ interface ConflictSearch extends ConflictOptions {
131
+ readonly document: unknown;
132
+ readonly children: ReadonlyMap<string, readonly Child[]>;
133
+ }
134
+
135
+ /** The `allOf` children of the owner that inherit its discriminator. */
136
+ function inheritingChildren(owner: Owner, search: ConflictSearch): readonly Child[] {
137
+ const children = search.children.get(owner.pointer) ?? [];
138
+ const resolve = (ref: string) => resolveLocalRef(search.document, ref);
139
+ const union = search.isUnionReused ? unionAt(owner.pointer, resolve) : undefined;
140
+ return union === undefined
141
+ ? children
142
+ : children.filter((child) => isUnionMember(union, child.ref, resolve));
143
+ }
144
+
145
+ /** The component schemas whose `allOf` holds a `$ref`, by that `$ref`, in document order. */
146
+ function allOfChildren(document: unknown): Map<string, Child[]> {
147
+ const schemas = resolveLocalRef(document, "#/components/schemas");
148
+ const children = new Map<string, Child[]>();
149
+ for (const [name, schema] of Object.entries(isObject(schemas) ? schemas : {})) {
150
+ if (!isObject(schema)) {
151
+ continue;
152
+ }
153
+ const child = { ref: `${COMPONENT_SCHEMAS}${escapePointerSegment(name)}`, schema };
154
+ for (const parent of new Set(refsOf(schema.allOf))) {
155
+ const siblings = children.get(parent) ?? [];
156
+ siblings.push(child);
157
+ children.set(parent, siblings);
158
+ }
159
+ }
160
+ return children;
161
+ }
162
+
163
+ /** Whether a schema defines a discriminator of the property itself: it is the owner below. */
164
+ function ownsProperty(schema: JsonObject, propertyName: string): boolean {
165
+ const discriminator = schema.discriminator;
166
+ return isObject(discriminator) && discriminator.propertyName === propertyName;
167
+ }
168
+
169
+ /**
170
+ * Component schemas that inherit the owner through `allOf`, also through a chain
171
+ * (`Lion: { allOf: [Cat] }`, `Cat: { allOf: [Pet] }`). Each parent on the way is left out of the
172
+ * member's values, as its type omits the property. A schema with its own discriminator of the
173
+ * property is a member, but the schemas below it are its own members.
174
+ */
175
+ function inheritingMembers(owner: Owner, search: ConflictSearch): Member[] {
176
+ const found: Member[] = [];
177
+ const visited = new Set([owner.pointer]);
178
+ const parents: Member[] = [{ ref: owner.pointer, skipped: new Set([owner.pointer]) }];
179
+ for (let parent = parents.shift(); parent !== undefined; parent = parents.shift()) {
180
+ const children =
181
+ parent.ref === owner.pointer
182
+ ? inheritingChildren(owner, search)
183
+ : (search.children.get(parent.ref) ?? []);
184
+ for (const child of children) {
185
+ if (visited.has(child.ref)) {
186
+ continue;
187
+ }
188
+ visited.add(child.ref);
189
+ found.push({ ref: child.ref, skipped: parent.skipped });
190
+ if (!ownsProperty(child.schema, owner.propertyName)) {
191
+ parents.push({ ref: child.ref, skipped: new Set([...parent.skipped, child.ref]) });
192
+ }
193
+ }
194
+ }
195
+ return found;
196
+ }
197
+
198
+ /** The members of an owner, each once: the listed and mapped ones, then the inheriting ones. */
199
+ function membersOf(owner: Owner, search: ConflictSearch): Member[] {
200
+ const listed = owner.memberRefs.map((ref) => ({ ref, skipped: new Set([owner.pointer]) }));
201
+ const members = new Map<string, Member>();
202
+ for (const member of [...listed, ...inheritingMembers(owner, search)]) {
203
+ if (!members.has(member.ref)) {
204
+ members.set(member.ref, member);
205
+ }
206
+ }
207
+ return [...members.values()];
208
+ }
209
+
210
+ function memberValues(owner: Owner, member: string): { values: string[]; isImplicit: boolean } {
211
+ const values = Object.entries(owner.mapping)
212
+ .filter(([, target]) => typeof target === "string" && mappingTarget(target) === member)
213
+ .map(([key]) => key);
214
+ const name = parseRefPointer(member).pop() ?? "";
215
+ return values.length > 0 ? { values, isImplicit: false } : { values: [name], isImplicit: true };
216
+ }
217
+
218
+ function conflictOf(owner: Owner, { ref: member, skipped }: Member, document: unknown) {
219
+ // The owner's own property is left out of an inheriting member's type (`Omit`).
220
+ const allowed = admittedPropertyValues(
221
+ resolveLocalRef(document, member),
222
+ owner.propertyName,
223
+ document,
224
+ skipped,
225
+ );
226
+ const { values, isImplicit } = memberValues(owner, member);
227
+ if (allowed === null || values.some((value) => allowed.has(value))) {
228
+ return null;
229
+ }
230
+ const { pointer, propertyName } = owner;
231
+ return { member, owner: pointer, propertyName, values, allowed: [...allowed], isImplicit };
232
+ }
233
+
234
+ /** The conflicts of the document, one per member and value list, in document order. */
235
+ export function findDiscriminatorValueConflicts(
236
+ document: unknown,
237
+ options: ConflictOptions = { isUnionReused: false },
238
+ ): readonly DiscriminatorValueConflict[] {
239
+ const conflicts = new Map<string, DiscriminatorValueConflict>();
240
+ const search = { ...options, document, children: allOfChildren(document) };
241
+ for (const owner of ownersIn(document)) {
242
+ for (const member of membersOf(owner, search)) {
243
+ const conflict = conflictOf(owner, member, document);
244
+ const key = JSON.stringify([member.ref, conflict?.propertyName, conflict?.values]);
245
+ if (conflict !== null && !conflicts.has(key)) {
246
+ conflicts.set(key, conflict);
247
+ }
248
+ }
249
+ }
250
+ return [...conflicts.values()];
251
+ }
@@ -23,6 +23,10 @@ export interface ParameterObject {
23
23
  readonly in: ParameterLocation | typeof QUERYSTRING_LOCATION;
24
24
  readonly required?: boolean;
25
25
  readonly deprecated?: boolean;
26
+ /** How the value is serialized; `form` for `in: query` when absent (§4.8.12.4). */
27
+ readonly style?: string;
28
+ /** Whether an array or object value is sent as several values; true for `form` when absent. */
29
+ readonly explode?: boolean;
26
30
  readonly schema?: Schema;
27
31
  readonly content?: ContentMap;
28
32
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The Paths Object rule (OpenAPI 3.1 §4.8.8): "Templated paths with the same hierarchy but
3
+ * different templated names MUST NOT exist as they are identical." Such paths, `/a/{id}` and
4
+ * `/a/{name}`, match the same URLs, so a client cannot tell which one a request is for.
5
+ */
6
+
7
+ const PATH_PARAMETER_RE = /\{[^}]+\}/g;
8
+ const PATH_PREFIX = "/";
9
+ const UNNAMED_PARAMETER = "{}";
10
+
11
+ function isObject(value: unknown): value is Readonly<Record<string, unknown>> {
12
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13
+ }
14
+
15
+ /**
16
+ * The groups of paths that differ only in the names of their template parameters, each group in
17
+ * document order, the groups in the order of their first path. Keys that are no path, such as an
18
+ * `x-` extension, are left out.
19
+ */
20
+ export function findIdenticalPathTemplates(document: unknown): string[][] {
21
+ const paths = isObject(document) && isObject(document.paths) ? document.paths : {};
22
+ const byHierarchy = new Map<string, string[]>();
23
+ for (const url of Object.keys(paths)) {
24
+ if (!url.startsWith(PATH_PREFIX) || !url.includes("{")) {
25
+ continue;
26
+ }
27
+ const hierarchy = url.replace(PATH_PARAMETER_RE, UNNAMED_PARAMETER);
28
+ byHierarchy.set(hierarchy, [...(byHierarchy.get(hierarchy) ?? []), url]);
29
+ }
30
+ return [...byHierarchy.values()].filter((urls) => urls.length > 1);
31
+ }
@@ -42,6 +42,8 @@ export interface SchemaObject {
42
42
  readonly $defs?: Readonly<Record<string, SchemaObject>>;
43
43
  readonly items?: Schema | readonly Schema[];
44
44
  readonly prefixItems?: readonly Schema[];
45
+ readonly unevaluatedItems?: Schema;
46
+ readonly contains?: Schema;
45
47
  readonly minItems?: number;
46
48
  readonly maxItems?: number;
47
49
  readonly allOf?: readonly Schema[];
@@ -6,14 +6,43 @@ import { ERROR_CODES, OpenAPITypesafeError } from "./errors.js";
6
6
  * default.
7
7
  */
8
8
  export const OutputFix = {
9
+ /** An `allOf` `$ref` to a discriminated union is the union, without `Omit` or a schema name. */
10
+ ALLOF_DISCRIMINATED_UNION: "allof-discriminated-union",
9
11
  /** An `allOf` member with only `required` makes those properties of the others required. */
10
12
  ALLOF_REQUIRED: "allof-required",
13
+ /** The JSDoc of a schema lists the descriptions of its `anyOf` and `oneOf` members. */
14
+ ANYOF_ONEOF_DESCRIPTIONS: "anyof-oneof-descriptions",
15
+ /** `anyOf` / `oneOf` variants with only `required` make those keys of the parent required. */
16
+ ANYOF_ONEOF_REQUIRED: "anyof-oneof-required",
11
17
  /** `anyOf` next to object keywords or `allOf` is intersected with them, not added to a union. */
12
18
  ANYOF_PROPERTIES: "anyof-properties",
13
19
  /** `--array-length` tuples have `min` to `max` items, nest right and follow `--immutable`. */
14
20
  ARRAY_LENGTH_TUPLES: "array-length-tuples",
15
- /** A schema two discriminators name gets one enum of their values, a mapping before its name. */
21
+ /** `--dedupe-enums` names a shared enum by all of its schemas, not by the first one. */
22
+ DEDUPE_ENUM_NAMES: "dedupe-enum-names",
23
+ /** `required` next to an `allOf` `$ref` to a discriminator member still gives `WithRequired`. */
24
+ DISCRIMINATOR_MEMBER_REQUIRED: "discriminator-member-required",
25
+ /**
26
+ * The value a discriminator member gets: one enum of every discriminator's values, a mapping
27
+ * before the schema name, a schema's own mapping before an inherited one, none where the member
28
+ * declares it, and with `--enum` a member of the owner's enum.
29
+ */
16
30
  DISCRIMINATOR_VALUES: "discriminator-values",
31
+ /** An exploded object query parameter's properties are keys of `query`, as they are sent. */
32
+ EXPLODED_QUERY_OBJECTS: "exploded-query-objects",
33
+ /** `--enum` declares an enum that lists `null` without it, and the type adds `| null`. */
34
+ NULLABLE_ENUMS: "nullable-enums",
35
+ /** `--path-params-as-types` gives each `{name}` its placeholder, `{number}` included. */
36
+ PATH_PARAM_TYPE_NAMES: "path-param-type-names",
37
+ /** A `prefixItems` tuple is open unless `items` or `unevaluatedItems` closes it (2020-12). */
38
+ PREFIX_ITEMS: "prefix-items",
39
+ /** `readOnly` and `writeOnly` of the schema a `$ref` names, or of `allOf` members, count. */
40
+ READ_WRITE_REFS: "read-write-refs",
41
+ /**
42
+ * A `$ref` into schema keywords (`content/<type>/schema`, `items`, `allOf/0`) gets the type it
43
+ * points at, also where the original type compiles through an index signature.
44
+ */
45
+ REF_POINTERS: "ref-pointers",
17
46
  /** Schemas of one root type name without the prefix each get an alias, the earlier numbered. */
18
47
  ROOT_TYPE_NUMBERING: "root-type-numbering",
19
48
  /** `unevaluatedProperties` types the keys no other keyword declares (an index signature). */
@@ -58,11 +87,18 @@ export function resolveOutputFixes(names: readonly OutputFixName[]): ReadonlySet
58
87
 
59
88
  /** A generator option that a fix works with; without it, the fix changes nothing (ADR-021). */
60
89
  export interface OutputFixRequirement {
61
- readonly option: "arrayLength" | "rootTypes" | "rootTypesNoSchemaPrefix";
90
+ readonly option:
91
+ | "arrayLength"
92
+ | "dedupeEnums"
93
+ | "enum"
94
+ | "pathParamsAsTypes"
95
+ | "rootTypes"
96
+ | "rootTypesNoSchemaPrefix";
62
97
  readonly flag: string;
63
98
  }
64
99
 
65
100
  const ROOT_TYPES = { option: "rootTypes", flag: "--root-types" } as const;
101
+ const ENUM = { option: "enum", flag: "--enum" } as const;
66
102
  const NO_SCHEMA_PREFIX = {
67
103
  option: "rootTypesNoSchemaPrefix",
68
104
  flag: "--root-types-no-schema-prefix",
@@ -71,6 +107,11 @@ const NO_SCHEMA_PREFIX = {
71
107
  /** The options each fix needs, by fix name; `all` has none. */
72
108
  const REQUIREMENTS: Readonly<Partial<Record<OutputFixName, readonly OutputFixRequirement[]>>> = {
73
109
  [OutputFix.ARRAY_LENGTH_TUPLES]: [{ option: "arrayLength", flag: "--array-length" }],
110
+ [OutputFix.DEDUPE_ENUM_NAMES]: [ENUM, { option: "dedupeEnums", flag: "--dedupe-enums" }],
111
+ [OutputFix.NULLABLE_ENUMS]: [ENUM],
112
+ [OutputFix.PATH_PARAM_TYPE_NAMES]: [
113
+ { option: "pathParamsAsTypes", flag: "--path-params-as-types" },
114
+ ],
74
115
  [OutputFix.ROOT_TYPE_NUMBERING]: [ROOT_TYPES, NO_SCHEMA_PREFIX],
75
116
  };
76
117
 
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Typed warnings. A warning does not stop the run: the output is written and the CLI exits with 0.
3
+ * Each one ends with a stable machine-readable code in parentheses, as the CLI prints errors
4
+ * (`message (CODE)`), so a script or a person can search for it.
5
+ */
6
+
7
+ /** Every warning code. */
8
+ export const WARNING_CODES = {
9
+ DISCRIMINATOR_VALUE_NOT_ALLOWED: "DISCRIMINATOR_VALUE_NOT_ALLOWED",
10
+ ENUM_VALUES_EXCLUDED: "ENUM_VALUES_EXCLUDED",
11
+ PATH_TEMPLATES_IDENTICAL: "PATH_TEMPLATES_IDENTICAL",
12
+ QUERYSTRING_NEXT_TO_QUERY: "QUERYSTRING_NEXT_TO_QUERY",
13
+ } as const;
14
+
15
+ export type WarningCode = (typeof WARNING_CODES)[keyof typeof WARNING_CODES];
16
+
17
+ /** The warning line for people, with its code at the end. */
18
+ export function warningText(message: string, code: WarningCode): string {
19
+ return `${message} (${code})`;
20
+ }
@@ -1,5 +1,6 @@
1
1
  import { createTransformContext } from "../api/transform-context.js";
2
2
  import { componentsType } from "../application/transform/document/components.js";
3
+ import { renameTakenAliases } from "../application/transform/document/root-type-aliases.js";
3
4
  import type { IrType, IrTypeAliasDeclaration } from "../domain/ir/nodes.js";
4
5
  import { isEnumSchema, singularizeComponentKind } from "../domain/openapi/components-object.js";
5
6
  import type { ComponentsObject, GlobalContext } from "../types.js";
@@ -21,5 +22,6 @@ export default function transformComponentsObject(
21
22
  ctx: GlobalContext,
22
23
  ): (IrType | IrTypeAliasDeclaration)[] {
23
24
  const { type, rootTypes } = componentsType(componentsObject, createTransformContext(ctx));
24
- return [type, ...rootTypes];
25
+ // No footer here: only the aliases the `root-type-numbering` fix keeps get numbers.
26
+ return [type, ...renameTakenAliases(rootTypes, [])];
25
27
  }
@@ -208,6 +208,17 @@ export interface GlobalContext {
208
208
  discriminators: {
209
209
  objects: Record<string, DiscriminatorObject>;
210
210
  refsHandled: string[];
211
+ /**
212
+ * @internal With the `discriminator-values` fix: for each enum the scan added to a
213
+ * member and each inherited discriminator object, the enum of the owner's property and the
214
+ * location it is typed at.
215
+ */
216
+ enumParents?: ReadonlyMap<object, { readonly schema: SchemaObject; readonly path: string }>;
217
+ /**
218
+ * @internal With the `discriminator-values` fix: for each schema, the properties of the
219
+ * discriminators it inherits besides `objects[ref]`, which it redefines too.
220
+ */
221
+ otherProperties?: Readonly<Record<string, readonly string[]>>;
211
222
  };
212
223
  emptyObjectsUnknown: boolean;
213
224
  enum: boolean;
@@ -1,51 +0,0 @@
1
- 'use strict';
2
-
3
- function nameOf(member) {
4
- return member.name.kind === "string" ? member.name.value : member.name.text;
5
- }
6
- function presenceOf(member) {
7
- if (member === void 0) {
8
- return "absent";
9
- }
10
- if (member.type.kind === "keyword" && member.type.keyword === "never") {
11
- return member.isOptional ? "never" : "unknown";
12
- }
13
- return member.isOptional ? "optional" : "required";
14
- }
15
- function propertiesOf(type) {
16
- if (type.kind !== "object") {
17
- return null;
18
- }
19
- const properties = type.members.filter((member) => {
20
- return member.kind === "property";
21
- });
22
- return new Map(properties.map((property) => [nameOf(property), property]));
23
- }
24
- function isPresenceRejected(covering, covered) {
25
- if (covered === "unknown") {
26
- return false;
27
- }
28
- if (covering === "required") {
29
- return covered !== "required";
30
- }
31
- return covering === "never" && (covered === "optional" || covered === "required");
32
- }
33
- function isPropertyRejected(covering, covered) {
34
- if (isPresenceRejected(presenceOf(covering), presenceOf(covered))) {
35
- return true;
36
- }
37
- return covered !== void 0 && isCoveredPathItemRejected(covered.type, covering.type);
38
- }
39
- function isCoveredPathItemRejected(covered, covering) {
40
- const coveredProperties = propertiesOf(covered);
41
- const coveringProperties = propertiesOf(covering);
42
- if (coveredProperties === null || coveringProperties === null) {
43
- return false;
44
- }
45
- return [...coveringProperties].some(
46
- ([name, property]) => isPropertyRejected(property, coveredProperties.get(name))
47
- );
48
- }
49
-
50
- exports.isCoveredPathItemRejected = isCoveredPathItemRejected;
51
- //# sourceMappingURL=path-item-conflicts.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"path-item-conflicts.cjs","sources":["../../../../src/application/transform/document/path-item-conflicts.ts"],"sourcesContent":["import type { IrMember, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\n\n/**\n * Whether TypeScript surely rejects a covered path item for the index signature that covers it\n * (roadmap R10.2). The original output compiles when every covered type is assignable to the\n * signature's type, and that output must stay the same, so a signature is only moved when this\n * check proves the error. It compares object types property by property, as the checker does: a\n * property the signature needs and the covered type may lack, or a value where the signature has\n * the `?: never` of an empty slot (a missing method, an empty parameter location), proves it. Two\n * object properties are compared the same way, inside. Any other pair of types (references,\n * unions, keywords) decides nothing, and that output is left as it was.\n */\n\n/**\n * How a property is written. `never` is the `?: never` of an empty slot; a required `never`\n * (assignable to every type) is `unknown` and decides nothing.\n */\ntype Presence = \"absent\" | \"never\" | \"optional\" | \"required\" | \"unknown\";\n\nfunction nameOf(member: IrPropertySignature): string {\n return member.name.kind === \"string\" ? member.name.value : member.name.text;\n}\n\nfunction presenceOf(member: IrPropertySignature | undefined): Presence {\n if (member === undefined) {\n return \"absent\";\n }\n if (member.type.kind === \"keyword\" && member.type.keyword === \"never\") {\n return member.isOptional ? \"never\" : \"unknown\";\n }\n return member.isOptional ? \"optional\" : \"required\";\n}\n\nfunction propertiesOf(type: IrType): ReadonlyMap<string, IrPropertySignature> | null {\n if (type.kind !== \"object\") {\n return null;\n }\n const properties = type.members.filter((member: IrMember): member is IrPropertySignature => {\n return member.kind === \"property\";\n });\n return new Map(properties.map((property) => [nameOf(property), property]));\n}\n\n/**\n * Whether the covered property's presence fails the signature's: a required value it may lack, or\n * a value where the signature has `never` (an object is not `undefined`).\n */\nfunction isPresenceRejected(covering: Presence, covered: Presence): boolean {\n if (covered === \"unknown\") {\n return false;\n }\n if (covering === \"required\") {\n return covered !== \"required\";\n }\n return covering === \"never\" && (covered === \"optional\" || covered === \"required\");\n}\n\nfunction isPropertyRejected(\n covering: IrPropertySignature,\n covered: IrPropertySignature | undefined,\n): boolean {\n if (isPresenceRejected(presenceOf(covering), presenceOf(covered))) {\n return true;\n }\n // A `never` is not an object type, so a slot that is empty on either side decides nothing here.\n return covered !== undefined && isCoveredPathItemRejected(covered.type, covering.type);\n}\n\n/** Whether the covered type is surely not assignable to the covering signature's type. */\nexport function isCoveredPathItemRejected(covered: IrType, covering: IrType): boolean {\n const coveredProperties = propertiesOf(covered);\n const coveringProperties = propertiesOf(covering);\n if (coveredProperties === null || coveringProperties === null) {\n return false;\n }\n return [...coveringProperties].some(([name, property]) =>\n isPropertyRejected(property, coveredProperties.get(name)),\n );\n}\n"],"names":[],"mappings":";;AAmBA,SAAS,OAAO,MAAA,EAAqC;AACnD,EAAA,OAAO,MAAA,CAAO,KAAK,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,CAAK,KAAA,GAAQ,OAAO,IAAA,CAAK,IAAA;AACzE;AAEA,SAAS,WAAW,MAAA,EAAmD;AACrE,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,aAAa,MAAA,CAAO,IAAA,CAAK,YAAY,OAAA,EAAS;AACrE,IAAA,OAAO,MAAA,CAAO,aAAa,OAAA,GAAU,SAAA;AAAA,EACvC;AACA,EAAA,OAAO,MAAA,CAAO,aAAa,UAAA,GAAa,UAAA;AAC1C;AAEA,SAAS,aAAa,IAAA,EAA+D;AACnF,EAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAoD;AAC1F,IAAA,OAAO,OAAO,IAAA,KAAS,UAAA;AAAA,EACzB,CAAC,CAAA;AACD,EAAA,OAAO,IAAI,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAC,QAAA,KAAa,CAAC,MAAA,CAAO,QAAQ,CAAA,EAAG,QAAQ,CAAC,CAAC,CAAA;AAC3E;AAMA,SAAS,kBAAA,CAAmB,UAAoB,OAAA,EAA4B;AAC1E,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,IAAA,OAAO,OAAA,KAAY,UAAA;AAAA,EACrB;AACA,EAAA,OAAO,QAAA,KAAa,OAAA,KAAY,OAAA,KAAY,UAAA,IAAc,OAAA,KAAY,UAAA,CAAA;AACxE;AAEA,SAAS,kBAAA,CACP,UACA,OAAA,EACS;AACT,EAAA,IAAI,mBAAmB,UAAA,CAAW,QAAQ,GAAG,UAAA,CAAW,OAAO,CAAC,CAAA,EAAG;AACjE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,YAAY,MAAA,IAAa,yBAAA,CAA0B,OAAA,CAAQ,IAAA,EAAM,SAAS,IAAI,CAAA;AACvF;AAGO,SAAS,yBAAA,CAA0B,SAAiB,QAAA,EAA2B;AACpF,EAAA,MAAM,iBAAA,GAAoB,aAAa,OAAO,CAAA;AAC9C,EAAA,MAAM,kBAAA,GAAqB,aAAa,QAAQ,CAAA;AAChD,EAAA,IAAI,iBAAA,KAAsB,IAAA,IAAQ,kBAAA,KAAuB,IAAA,EAAM;AAC7D,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAC,GAAG,kBAAkB,CAAA,CAAE,IAAA;AAAA,IAAK,CAAC,CAAC,IAAA,EAAM,QAAQ,CAAA,KAClD,mBAAmB,QAAA,EAAU,iBAAA,CAAkB,GAAA,CAAI,IAAI,CAAC;AAAA,GAC1D;AACF;;"}
@@ -1,49 +0,0 @@
1
- function nameOf(member) {
2
- return member.name.kind === "string" ? member.name.value : member.name.text;
3
- }
4
- function presenceOf(member) {
5
- if (member === void 0) {
6
- return "absent";
7
- }
8
- if (member.type.kind === "keyword" && member.type.keyword === "never") {
9
- return member.isOptional ? "never" : "unknown";
10
- }
11
- return member.isOptional ? "optional" : "required";
12
- }
13
- function propertiesOf(type) {
14
- if (type.kind !== "object") {
15
- return null;
16
- }
17
- const properties = type.members.filter((member) => {
18
- return member.kind === "property";
19
- });
20
- return new Map(properties.map((property) => [nameOf(property), property]));
21
- }
22
- function isPresenceRejected(covering, covered) {
23
- if (covered === "unknown") {
24
- return false;
25
- }
26
- if (covering === "required") {
27
- return covered !== "required";
28
- }
29
- return covering === "never" && (covered === "optional" || covered === "required");
30
- }
31
- function isPropertyRejected(covering, covered) {
32
- if (isPresenceRejected(presenceOf(covering), presenceOf(covered))) {
33
- return true;
34
- }
35
- return covered !== void 0 && isCoveredPathItemRejected(covered.type, covering.type);
36
- }
37
- function isCoveredPathItemRejected(covered, covering) {
38
- const coveredProperties = propertiesOf(covered);
39
- const coveringProperties = propertiesOf(covering);
40
- if (coveredProperties === null || coveringProperties === null) {
41
- return false;
42
- }
43
- return [...coveringProperties].some(
44
- ([name, property]) => isPropertyRejected(property, coveredProperties.get(name))
45
- );
46
- }
47
-
48
- export { isCoveredPathItemRejected };
49
- //# sourceMappingURL=path-item-conflicts.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"path-item-conflicts.mjs","sources":["../../../../src/application/transform/document/path-item-conflicts.ts"],"sourcesContent":["import type { IrMember, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\n\n/**\n * Whether TypeScript surely rejects a covered path item for the index signature that covers it\n * (roadmap R10.2). The original output compiles when every covered type is assignable to the\n * signature's type, and that output must stay the same, so a signature is only moved when this\n * check proves the error. It compares object types property by property, as the checker does: a\n * property the signature needs and the covered type may lack, or a value where the signature has\n * the `?: never` of an empty slot (a missing method, an empty parameter location), proves it. Two\n * object properties are compared the same way, inside. Any other pair of types (references,\n * unions, keywords) decides nothing, and that output is left as it was.\n */\n\n/**\n * How a property is written. `never` is the `?: never` of an empty slot; a required `never`\n * (assignable to every type) is `unknown` and decides nothing.\n */\ntype Presence = \"absent\" | \"never\" | \"optional\" | \"required\" | \"unknown\";\n\nfunction nameOf(member: IrPropertySignature): string {\n return member.name.kind === \"string\" ? member.name.value : member.name.text;\n}\n\nfunction presenceOf(member: IrPropertySignature | undefined): Presence {\n if (member === undefined) {\n return \"absent\";\n }\n if (member.type.kind === \"keyword\" && member.type.keyword === \"never\") {\n return member.isOptional ? \"never\" : \"unknown\";\n }\n return member.isOptional ? \"optional\" : \"required\";\n}\n\nfunction propertiesOf(type: IrType): ReadonlyMap<string, IrPropertySignature> | null {\n if (type.kind !== \"object\") {\n return null;\n }\n const properties = type.members.filter((member: IrMember): member is IrPropertySignature => {\n return member.kind === \"property\";\n });\n return new Map(properties.map((property) => [nameOf(property), property]));\n}\n\n/**\n * Whether the covered property's presence fails the signature's: a required value it may lack, or\n * a value where the signature has `never` (an object is not `undefined`).\n */\nfunction isPresenceRejected(covering: Presence, covered: Presence): boolean {\n if (covered === \"unknown\") {\n return false;\n }\n if (covering === \"required\") {\n return covered !== \"required\";\n }\n return covering === \"never\" && (covered === \"optional\" || covered === \"required\");\n}\n\nfunction isPropertyRejected(\n covering: IrPropertySignature,\n covered: IrPropertySignature | undefined,\n): boolean {\n if (isPresenceRejected(presenceOf(covering), presenceOf(covered))) {\n return true;\n }\n // A `never` is not an object type, so a slot that is empty on either side decides nothing here.\n return covered !== undefined && isCoveredPathItemRejected(covered.type, covering.type);\n}\n\n/** Whether the covered type is surely not assignable to the covering signature's type. */\nexport function isCoveredPathItemRejected(covered: IrType, covering: IrType): boolean {\n const coveredProperties = propertiesOf(covered);\n const coveringProperties = propertiesOf(covering);\n if (coveredProperties === null || coveringProperties === null) {\n return false;\n }\n return [...coveringProperties].some(([name, property]) =>\n isPropertyRejected(property, coveredProperties.get(name)),\n );\n}\n"],"names":[],"mappings":"AAmBA,SAAS,OAAO,MAAA,EAAqC;AACnD,EAAA,OAAO,MAAA,CAAO,KAAK,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,CAAK,KAAA,GAAQ,OAAO,IAAA,CAAK,IAAA;AACzE;AAEA,SAAS,WAAW,MAAA,EAAmD;AACrE,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,aAAa,MAAA,CAAO,IAAA,CAAK,YAAY,OAAA,EAAS;AACrE,IAAA,OAAO,MAAA,CAAO,aAAa,OAAA,GAAU,SAAA;AAAA,EACvC;AACA,EAAA,OAAO,MAAA,CAAO,aAAa,UAAA,GAAa,UAAA;AAC1C;AAEA,SAAS,aAAa,IAAA,EAA+D;AACnF,EAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAoD;AAC1F,IAAA,OAAO,OAAO,IAAA,KAAS,UAAA;AAAA,EACzB,CAAC,CAAA;AACD,EAAA,OAAO,IAAI,GAAA,CAAI,UAAA,CAAW,GAAA,CAAI,CAAC,QAAA,KAAa,CAAC,MAAA,CAAO,QAAQ,CAAA,EAAG,QAAQ,CAAC,CAAC,CAAA;AAC3E;AAMA,SAAS,kBAAA,CAAmB,UAAoB,OAAA,EAA4B;AAC1E,EAAA,IAAI,YAAY,SAAA,EAAW;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,IAAA,OAAO,OAAA,KAAY,UAAA;AAAA,EACrB;AACA,EAAA,OAAO,QAAA,KAAa,OAAA,KAAY,OAAA,KAAY,UAAA,IAAc,OAAA,KAAY,UAAA,CAAA;AACxE;AAEA,SAAS,kBAAA,CACP,UACA,OAAA,EACS;AACT,EAAA,IAAI,mBAAmB,UAAA,CAAW,QAAQ,GAAG,UAAA,CAAW,OAAO,CAAC,CAAA,EAAG;AACjE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,YAAY,MAAA,IAAa,yBAAA,CAA0B,OAAA,CAAQ,IAAA,EAAM,SAAS,IAAI,CAAA;AACvF;AAGO,SAAS,yBAAA,CAA0B,SAAiB,QAAA,EAA2B;AACpF,EAAA,MAAM,iBAAA,GAAoB,aAAa,OAAO,CAAA;AAC9C,EAAA,MAAM,kBAAA,GAAqB,aAAa,QAAQ,CAAA;AAChD,EAAA,IAAI,iBAAA,KAAsB,IAAA,IAAQ,kBAAA,KAAuB,IAAA,EAAM;AAC7D,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAC,GAAG,kBAAkB,CAAA,CAAE,IAAA;AAAA,IAAK,CAAC,CAAC,IAAA,EAAM,QAAQ,CAAA,KAClD,mBAAmB,QAAA,EAAU,iBAAA,CAAkB,GAAA,CAAI,IAAI,CAAC;AAAA,GAC1D;AACF;;"}
@@ -1,79 +0,0 @@
1
- import type { IrMember, IrPropertySignature, IrType } from "../../../domain/ir/nodes.js";
2
-
3
- /**
4
- * Whether TypeScript surely rejects a covered path item for the index signature that covers it
5
- * (roadmap R10.2). The original output compiles when every covered type is assignable to the
6
- * signature's type, and that output must stay the same, so a signature is only moved when this
7
- * check proves the error. It compares object types property by property, as the checker does: a
8
- * property the signature needs and the covered type may lack, or a value where the signature has
9
- * the `?: never` of an empty slot (a missing method, an empty parameter location), proves it. Two
10
- * object properties are compared the same way, inside. Any other pair of types (references,
11
- * unions, keywords) decides nothing, and that output is left as it was.
12
- */
13
-
14
- /**
15
- * How a property is written. `never` is the `?: never` of an empty slot; a required `never`
16
- * (assignable to every type) is `unknown` and decides nothing.
17
- */
18
- type Presence = "absent" | "never" | "optional" | "required" | "unknown";
19
-
20
- function nameOf(member: IrPropertySignature): string {
21
- return member.name.kind === "string" ? member.name.value : member.name.text;
22
- }
23
-
24
- function presenceOf(member: IrPropertySignature | undefined): Presence {
25
- if (member === undefined) {
26
- return "absent";
27
- }
28
- if (member.type.kind === "keyword" && member.type.keyword === "never") {
29
- return member.isOptional ? "never" : "unknown";
30
- }
31
- return member.isOptional ? "optional" : "required";
32
- }
33
-
34
- function propertiesOf(type: IrType): ReadonlyMap<string, IrPropertySignature> | null {
35
- if (type.kind !== "object") {
36
- return null;
37
- }
38
- const properties = type.members.filter((member: IrMember): member is IrPropertySignature => {
39
- return member.kind === "property";
40
- });
41
- return new Map(properties.map((property) => [nameOf(property), property]));
42
- }
43
-
44
- /**
45
- * Whether the covered property's presence fails the signature's: a required value it may lack, or
46
- * a value where the signature has `never` (an object is not `undefined`).
47
- */
48
- function isPresenceRejected(covering: Presence, covered: Presence): boolean {
49
- if (covered === "unknown") {
50
- return false;
51
- }
52
- if (covering === "required") {
53
- return covered !== "required";
54
- }
55
- return covering === "never" && (covered === "optional" || covered === "required");
56
- }
57
-
58
- function isPropertyRejected(
59
- covering: IrPropertySignature,
60
- covered: IrPropertySignature | undefined,
61
- ): boolean {
62
- if (isPresenceRejected(presenceOf(covering), presenceOf(covered))) {
63
- return true;
64
- }
65
- // A `never` is not an object type, so a slot that is empty on either side decides nothing here.
66
- return covered !== undefined && isCoveredPathItemRejected(covered.type, covering.type);
67
- }
68
-
69
- /** Whether the covered type is surely not assignable to the covering signature's type. */
70
- export function isCoveredPathItemRejected(covered: IrType, covering: IrType): boolean {
71
- const coveredProperties = propertiesOf(covered);
72
- const coveringProperties = propertiesOf(covering);
73
- if (coveredProperties === null || coveringProperties === null) {
74
- return false;
75
- }
76
- return [...coveringProperties].some(([name, property]) =>
77
- isPropertyRejected(property, coveredProperties.get(name)),
78
- );
79
- }