openapi-typesafe 1.0.0-rc.3 → 1.0.0-rc.4

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 (448) hide show
  1. package/CHANGELOG.md +1831 -0
  2. package/dist/adapters/node-file-system/file-claims.cjs +105 -0
  3. package/dist/adapters/node-file-system/file-claims.cjs.map +1 -0
  4. package/dist/adapters/node-file-system/file-claims.mjs +95 -0
  5. package/dist/adapters/node-file-system/file-claims.mjs.map +1 -0
  6. package/dist/adapters/node-file-system/file-identity.cjs +82 -0
  7. package/dist/adapters/node-file-system/file-identity.cjs.map +1 -0
  8. package/dist/adapters/node-file-system/file-identity.mjs +74 -0
  9. package/dist/adapters/node-file-system/file-identity.mjs.map +1 -0
  10. package/dist/adapters/node-file-system/node-file-system.cjs +90 -14
  11. package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -1
  12. package/dist/adapters/node-file-system/node-file-system.mjs +90 -14
  13. package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +75 -0
  15. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -0
  16. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +72 -0
  17. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -0
  18. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +1 -1
  19. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -1
  20. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +2 -2
  21. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -1
  22. package/dist/adapters/redocly-loader/loaded-documents.cjs +28 -0
  23. package/dist/adapters/redocly-loader/loaded-documents.cjs.map +1 -0
  24. package/dist/adapters/redocly-loader/loaded-documents.mjs +21 -0
  25. package/dist/adapters/redocly-loader/loaded-documents.mjs.map +1 -0
  26. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +14 -15
  27. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  28. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +12 -13
  29. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  30. package/dist/adapters/redocly-loader/ref-access.cjs +31 -3
  31. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  32. package/dist/adapters/redocly-loader/ref-access.mjs +31 -3
  33. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  34. package/dist/adapters/redocly-loader/ref-holders.cjs +2 -2
  35. package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
  36. package/dist/adapters/redocly-loader/ref-holders.mjs +3 -3
  37. package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
  38. package/dist/adapters/redocly-loader/remote-body-limit.cjs +50 -0
  39. package/dist/adapters/redocly-loader/remote-body-limit.cjs.map +1 -0
  40. package/dist/adapters/redocly-loader/remote-body-limit.mjs +48 -0
  41. package/dist/adapters/redocly-loader/remote-body-limit.mjs.map +1 -0
  42. package/dist/adapters/redocly-loader/remote-fetch.cjs +35 -6
  43. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  44. package/dist/adapters/redocly-loader/remote-fetch.mjs +35 -6
  45. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  46. package/dist/adapters/redocly-loader/remote-node-limit.cjs +47 -0
  47. package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -0
  48. package/dist/adapters/redocly-loader/remote-node-limit.mjs +44 -0
  49. package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -0
  50. package/dist/adapters/redocly-loader/schema-load-errors.cjs +32 -8
  51. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
  52. package/dist/adapters/redocly-loader/schema-load-errors.mjs +32 -9
  53. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
  54. package/dist/adapters/redocly-loader/schema-source.cjs +11 -7
  55. package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
  56. package/dist/adapters/redocly-loader/schema-source.mjs +12 -8
  57. package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
  58. package/dist/adapters/redocly-loader/unsupported-keys.cjs +3 -5
  59. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
  60. package/dist/adapters/redocly-loader/unsupported-keys.mjs +3 -5
  61. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
  62. package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
  63. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  64. package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
  65. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  66. package/dist/api/default-ports.cjs +14 -2
  67. package/dist/api/default-ports.cjs.map +1 -1
  68. package/dist/api/default-ports.mjs +14 -2
  69. package/dist/api/default-ports.mjs.map +1 -1
  70. package/dist/api/discriminator-enum-parent.cjs +2 -2
  71. package/dist/api/discriminator-enum-parent.cjs.map +1 -1
  72. package/dist/api/discriminator-enum-parent.mjs +3 -3
  73. package/dist/api/discriminator-enum-parent.mjs.map +1 -1
  74. package/dist/api/discriminator-other-owners.cjs +5 -3
  75. package/dist/api/discriminator-other-owners.cjs.map +1 -1
  76. package/dist/api/discriminator-other-owners.mjs +5 -3
  77. package/dist/api/discriminator-other-owners.mjs.map +1 -1
  78. package/dist/api/discriminator-patch.cjs +5 -1
  79. package/dist/api/discriminator-patch.cjs.map +1 -1
  80. package/dist/api/discriminator-patch.mjs +5 -1
  81. package/dist/api/discriminator-patch.mjs.map +1 -1
  82. package/dist/api/discriminator-scan.cjs +15 -8
  83. package/dist/api/discriminator-scan.cjs.map +1 -1
  84. package/dist/api/discriminator-scan.mjs +15 -8
  85. package/dist/api/discriminator-scan.mjs.map +1 -1
  86. package/dist/api/document-run.cjs +2 -2
  87. package/dist/api/document-run.cjs.map +1 -1
  88. package/dist/api/document-run.mjs +2 -2
  89. package/dist/api/document-run.mjs.map +1 -1
  90. package/dist/api/legacy-utils.cjs.map +1 -1
  91. package/dist/api/legacy-utils.mjs.map +1 -1
  92. package/dist/api/openapi-ts.cjs +8 -4
  93. package/dist/api/openapi-ts.cjs.map +1 -1
  94. package/dist/api/openapi-ts.mjs +8 -5
  95. package/dist/api/openapi-ts.mjs.map +1 -1
  96. package/dist/api/schema-callbacks.cjs +36 -12
  97. package/dist/api/schema-callbacks.cjs.map +1 -1
  98. package/dist/api/schema-callbacks.mjs +36 -12
  99. package/dist/api/schema-callbacks.mjs.map +1 -1
  100. package/dist/api/transform-context.cjs +7 -3
  101. package/dist/api/transform-context.cjs.map +1 -1
  102. package/dist/api/transform-context.mjs +7 -3
  103. package/dist/api/transform-context.mjs.map +1 -1
  104. package/dist/api/transform-schema.cjs +40 -10
  105. package/dist/api/transform-schema.cjs.map +1 -1
  106. package/dist/api/transform-schema.mjs +41 -11
  107. package/dist/api/transform-schema.mjs.map +1 -1
  108. package/dist/application/print/text-writer.cjs +10 -3
  109. package/dist/application/print/text-writer.cjs.map +1 -1
  110. package/dist/application/print/text-writer.mjs +10 -3
  111. package/dist/application/print/text-writer.mjs.map +1 -1
  112. package/dist/application/stack-overflow.cjs +2 -1
  113. package/dist/application/stack-overflow.cjs.map +1 -1
  114. package/dist/application/stack-overflow.mjs +2 -1
  115. package/dist/application/stack-overflow.mjs.map +1 -1
  116. package/dist/application/transform/document/components.cjs +1 -1
  117. package/dist/application/transform/document/components.cjs.map +1 -1
  118. package/dist/application/transform/document/components.mjs +2 -2
  119. package/dist/application/transform/document/components.mjs.map +1 -1
  120. package/dist/application/transform/document/declared-type-names.cjs +23 -0
  121. package/dist/application/transform/document/declared-type-names.cjs.map +1 -0
  122. package/dist/application/transform/document/declared-type-names.mjs +20 -0
  123. package/dist/application/transform/document/declared-type-names.mjs.map +1 -0
  124. package/dist/application/transform/document/defs-root.cjs +1 -1
  125. package/dist/application/transform/document/defs-root.cjs.map +1 -1
  126. package/dist/application/transform/document/defs-root.mjs +2 -2
  127. package/dist/application/transform/document/defs-root.mjs.map +1 -1
  128. package/dist/application/transform/document/document.cjs +4 -1
  129. package/dist/application/transform/document/document.cjs.map +1 -1
  130. package/dist/application/transform/document/document.mjs +3 -2
  131. package/dist/application/transform/document/document.mjs.map +1 -1
  132. package/dist/application/transform/document/enum-names-given-back.cjs +62 -0
  133. package/dist/application/transform/document/enum-names-given-back.cjs.map +1 -0
  134. package/dist/application/transform/document/enum-names-given-back.mjs +58 -0
  135. package/dist/application/transform/document/enum-names-given-back.mjs.map +1 -0
  136. package/dist/application/transform/document/global-type-references.cjs +1 -0
  137. package/dist/application/transform/document/global-type-references.cjs.map +1 -1
  138. package/dist/application/transform/document/global-type-references.mjs +1 -1
  139. package/dist/application/transform/document/global-type-references.mjs.map +1 -1
  140. package/dist/application/transform/document/media-type.cjs +2 -2
  141. package/dist/application/transform/document/media-type.cjs.map +1 -1
  142. package/dist/application/transform/document/media-type.mjs +3 -3
  143. package/dist/application/transform/document/media-type.mjs.map +1 -1
  144. package/dist/application/transform/document/operation-keys-written.cjs +26 -0
  145. package/dist/application/transform/document/operation-keys-written.cjs.map +1 -0
  146. package/dist/application/transform/document/operation-keys-written.mjs +24 -0
  147. package/dist/application/transform/document/operation-keys-written.mjs.map +1 -0
  148. package/dist/application/transform/document/operation.cjs +1 -1
  149. package/dist/application/transform/document/operation.cjs.map +1 -1
  150. package/dist/application/transform/document/operation.mjs +2 -2
  151. package/dist/application/transform/document/operation.mjs.map +1 -1
  152. package/dist/application/transform/document/parameter-entries.cjs +34 -0
  153. package/dist/application/transform/document/parameter-entries.cjs.map +1 -0
  154. package/dist/application/transform/document/parameter-entries.mjs +30 -0
  155. package/dist/application/transform/document/parameter-entries.mjs.map +1 -0
  156. package/dist/application/transform/document/parameter.cjs +12 -4
  157. package/dist/application/transform/document/parameter.cjs.map +1 -1
  158. package/dist/application/transform/document/parameter.mjs +13 -5
  159. package/dist/application/transform/document/parameter.mjs.map +1 -1
  160. package/dist/application/transform/document/parameters.cjs +6 -29
  161. package/dist/application/transform/document/parameters.cjs.map +1 -1
  162. package/dist/application/transform/document/parameters.mjs +6 -29
  163. package/dist/application/transform/document/parameters.mjs.map +1 -1
  164. package/dist/application/transform/document/path-item.cjs +11 -14
  165. package/dist/application/transform/document/path-item.cjs.map +1 -1
  166. package/dist/application/transform/document/path-item.mjs +12 -16
  167. package/dist/application/transform/document/path-item.mjs.map +1 -1
  168. package/dist/application/transform/document/paths-enum.cjs +1 -0
  169. package/dist/application/transform/document/paths-enum.cjs.map +1 -1
  170. package/dist/application/transform/document/paths-enum.mjs +1 -1
  171. package/dist/application/transform/document/paths-enum.mjs.map +1 -1
  172. package/dist/application/transform/document/paths.cjs +5 -1
  173. package/dist/application/transform/document/paths.cjs.map +1 -1
  174. package/dist/application/transform/document/paths.mjs +6 -2
  175. package/dist/application/transform/document/paths.mjs.map +1 -1
  176. package/dist/application/transform/document/referenced-parameter.cjs +80 -0
  177. package/dist/application/transform/document/referenced-parameter.cjs.map +1 -0
  178. package/dist/application/transform/document/referenced-parameter.mjs +78 -0
  179. package/dist/application/transform/document/referenced-parameter.mjs.map +1 -0
  180. package/dist/application/transform/document/request-body.cjs +1 -1
  181. package/dist/application/transform/document/request-body.cjs.map +1 -1
  182. package/dist/application/transform/document/request-body.mjs +2 -2
  183. package/dist/application/transform/document/request-body.mjs.map +1 -1
  184. package/dist/application/transform/document/response.cjs +2 -2
  185. package/dist/application/transform/document/response.cjs.map +1 -1
  186. package/dist/application/transform/document/response.mjs +3 -3
  187. package/dist/application/transform/document/response.mjs.map +1 -1
  188. package/dist/application/transform/document/responses.cjs +1 -1
  189. package/dist/application/transform/document/responses.cjs.map +1 -1
  190. package/dist/application/transform/document/responses.mjs +2 -2
  191. package/dist/application/transform/document/responses.mjs.map +1 -1
  192. package/dist/application/transform/document/root-type-aliases.cjs +8 -23
  193. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  194. package/dist/application/transform/document/root-type-aliases.mjs +8 -24
  195. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  196. package/dist/application/transform/document/type-resolution.cjs +3 -1
  197. package/dist/application/transform/document/type-resolution.cjs.map +1 -1
  198. package/dist/application/transform/document/type-resolution.mjs +3 -1
  199. package/dist/application/transform/document/type-resolution.mjs.map +1 -1
  200. package/dist/application/transform/document/webhooks.cjs +1 -1
  201. package/dist/application/transform/document/webhooks.cjs.map +1 -1
  202. package/dist/application/transform/document/webhooks.mjs +2 -2
  203. package/dist/application/transform/document/webhooks.mjs.map +1 -1
  204. package/dist/application/transform/footer/document-footer.cjs +10 -2
  205. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  206. package/dist/application/transform/footer/document-footer.mjs +10 -2
  207. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  208. package/dist/application/transform/footer/enum-name-claims.cjs +48 -0
  209. package/dist/application/transform/footer/enum-name-claims.cjs.map +1 -0
  210. package/dist/application/transform/footer/enum-name-claims.mjs +46 -0
  211. package/dist/application/transform/footer/enum-name-claims.mjs.map +1 -0
  212. package/dist/application/transform/footer/operation-keys.cjs +23 -0
  213. package/dist/application/transform/footer/operation-keys.cjs.map +1 -0
  214. package/dist/application/transform/footer/operation-keys.mjs +21 -0
  215. package/dist/application/transform/footer/operation-keys.mjs.map +1 -0
  216. package/dist/application/transform/footer/type-evaluation.cjs +4 -4
  217. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
  218. package/dist/application/transform/footer/type-evaluation.mjs +4 -4
  219. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
  220. package/dist/application/transform/helper-types.cjs +1 -1
  221. package/dist/application/transform/helper-types.cjs.map +1 -1
  222. package/dist/application/transform/helper-types.mjs +1 -1
  223. package/dist/application/transform/helper-types.mjs.map +1 -1
  224. package/dist/application/transform/numbered-names.cjs +9 -0
  225. package/dist/application/transform/numbered-names.cjs.map +1 -1
  226. package/dist/application/transform/numbered-names.mjs +9 -1
  227. package/dist/application/transform/numbered-names.mjs.map +1 -1
  228. package/dist/application/transform/ref-pointer/generated-location.cjs +1 -1
  229. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
  230. package/dist/application/transform/ref-pointer/generated-location.mjs +2 -2
  231. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
  232. package/dist/application/transform/ref-type.cjs +2 -1
  233. package/dist/application/transform/ref-type.cjs.map +1 -1
  234. package/dist/application/transform/ref-type.mjs +2 -1
  235. package/dist/application/transform/ref-type.mjs.map +1 -1
  236. package/dist/application/transform/schema/composition-type.cjs +1 -1
  237. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  238. package/dist/application/transform/schema/composition-type.mjs +2 -2
  239. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  240. package/dist/application/transform/schema/enum-rule.cjs +1 -1
  241. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  242. package/dist/application/transform/schema/enum-rule.mjs +2 -2
  243. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  244. package/dist/application/transform/schema/object-type.cjs +3 -3
  245. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  246. package/dist/application/transform/schema/object-type.mjs +4 -4
  247. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  248. package/dist/application/transform/schema/ref-siblings.cjs +47 -0
  249. package/dist/application/transform/schema/ref-siblings.cjs.map +1 -0
  250. package/dist/application/transform/schema/ref-siblings.mjs +45 -0
  251. package/dist/application/transform/schema/ref-siblings.mjs.map +1 -0
  252. package/dist/application/transform/schema/schema-transform.cjs +4 -2
  253. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  254. package/dist/application/transform/schema/schema-transform.mjs +4 -2
  255. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  256. package/dist/application/transform/schema-comment.cjs +5 -1
  257. package/dist/application/transform/schema-comment.cjs.map +1 -1
  258. package/dist/application/transform/schema-comment.mjs +5 -1
  259. package/dist/application/transform/schema-comment.mjs.map +1 -1
  260. package/dist/cli/api-settings.cjs +62 -6
  261. package/dist/cli/api-settings.cjs.map +1 -1
  262. package/dist/cli/api-settings.mjs +60 -7
  263. package/dist/cli/api-settings.mjs.map +1 -1
  264. package/dist/cli/api-writes.cjs +72 -0
  265. package/dist/cli/api-writes.cjs.map +1 -0
  266. package/dist/cli/api-writes.mjs +69 -0
  267. package/dist/cli/api-writes.mjs.map +1 -0
  268. package/dist/cli/cli-errors.cjs +12 -1
  269. package/dist/cli/cli-errors.cjs.map +1 -1
  270. package/dist/cli/cli-errors.mjs +12 -1
  271. package/dist/cli/cli-errors.mjs.map +1 -1
  272. package/dist/cli/cli-output.cjs +106 -1
  273. package/dist/cli/cli-output.cjs.map +1 -1
  274. package/dist/cli/cli-output.mjs +99 -2
  275. package/dist/cli/cli-output.mjs.map +1 -1
  276. package/dist/cli/main.cjs +5 -1
  277. package/dist/cli/main.cjs.map +1 -1
  278. package/dist/cli/main.mjs +6 -2
  279. package/dist/cli/main.mjs.map +1 -1
  280. package/dist/cli/redocly-apis.cjs +82 -36
  281. package/dist/cli/redocly-apis.cjs.map +1 -1
  282. package/dist/cli/redocly-apis.mjs +85 -39
  283. package/dist/cli/redocly-apis.mjs.map +1 -1
  284. package/dist/cli/run-cli.cjs +13 -7
  285. package/dist/cli/run-cli.cjs.map +1 -1
  286. package/dist/cli/run-cli.mjs +14 -8
  287. package/dist/cli/run-cli.mjs.map +1 -1
  288. package/dist/domain/append-all.cjs +10 -0
  289. package/dist/domain/append-all.cjs.map +1 -0
  290. package/dist/domain/append-all.mjs +8 -0
  291. package/dist/domain/append-all.mjs.map +1 -0
  292. package/dist/domain/cause-secrets.cjs +37 -0
  293. package/dist/domain/cause-secrets.cjs.map +1 -0
  294. package/dist/domain/cause-secrets.mjs +35 -0
  295. package/dist/domain/cause-secrets.mjs.map +1 -0
  296. package/dist/domain/errors.cjs +9 -3
  297. package/dist/domain/errors.cjs.map +1 -1
  298. package/dist/domain/errors.mjs +9 -3
  299. package/dist/domain/errors.mjs.map +1 -1
  300. package/dist/domain/ir/identifier-text.cjs.map +1 -1
  301. package/dist/domain/ir/identifier-text.mjs +1 -1
  302. package/dist/domain/ir/identifier-text.mjs.map +1 -1
  303. package/dist/domain/ir/ir-shape.cjs +187 -0
  304. package/dist/domain/ir/ir-shape.cjs.map +1 -0
  305. package/dist/domain/ir/ir-shape.mjs +184 -0
  306. package/dist/domain/ir/ir-shape.mjs.map +1 -0
  307. package/dist/domain/ir/newer-identifier-ranges.cjs +182 -29
  308. package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -1
  309. package/dist/domain/ir/newer-identifier-ranges.mjs +182 -29
  310. package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -1
  311. package/dist/domain/openapi/alias-expansion.cjs +3 -1
  312. package/dist/domain/openapi/alias-expansion.cjs.map +1 -1
  313. package/dist/domain/openapi/alias-expansion.mjs +3 -1
  314. package/dist/domain/openapi/alias-expansion.mjs.map +1 -1
  315. package/dist/domain/openapi/discriminated-union.cjs +3 -3
  316. package/dist/domain/openapi/discriminated-union.cjs.map +1 -1
  317. package/dist/domain/openapi/discriminated-union.mjs +4 -4
  318. package/dist/domain/openapi/discriminated-union.mjs.map +1 -1
  319. package/dist/domain/openapi/discriminator-conflicts.cjs +10 -6
  320. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -1
  321. package/dist/domain/openapi/discriminator-conflicts.mjs +11 -7
  322. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -1
  323. package/dist/domain/openapi/json-pointer.cjs +43 -1
  324. package/dist/domain/openapi/json-pointer.cjs.map +1 -1
  325. package/dist/domain/openapi/json-pointer.mjs +40 -2
  326. package/dist/domain/openapi/json-pointer.mjs.map +1 -1
  327. package/dist/domain/openapi/schema-dialect.cjs +15 -0
  328. package/dist/domain/openapi/schema-dialect.cjs.map +1 -0
  329. package/dist/domain/openapi/schema-dialect.mjs +12 -0
  330. package/dist/domain/openapi/schema-dialect.mjs.map +1 -0
  331. package/dist/domain/openapi/unsupported-features.cjs +1 -1
  332. package/dist/domain/openapi/unsupported-features.cjs.map +1 -1
  333. package/dist/domain/openapi/unsupported-features.mjs +2 -2
  334. package/dist/domain/openapi/unsupported-features.mjs.map +1 -1
  335. package/dist/domain/output-fixes.cjs +14 -0
  336. package/dist/domain/output-fixes.cjs.map +1 -1
  337. package/dist/domain/output-fixes.mjs +14 -0
  338. package/dist/domain/output-fixes.mjs.map +1 -1
  339. package/dist/domain/url-secrets.cjs +48 -0
  340. package/dist/domain/url-secrets.cjs.map +1 -0
  341. package/dist/domain/url-secrets.mjs +45 -0
  342. package/dist/domain/url-secrets.mjs.map +1 -0
  343. package/dist/index.d.cts +22 -4
  344. package/dist/index.d.mts +22 -4
  345. package/dist/index.d.ts +22 -4
  346. package/package.json +4 -5
  347. package/src/adapters/node-file-system/file-claims.ts +138 -0
  348. package/src/adapters/node-file-system/file-identity.ts +137 -0
  349. package/src/adapters/node-file-system/node-file-system.ts +145 -18
  350. package/src/adapters/redocly-loader/bundled-mapping-copies.ts +95 -0
  351. package/src/adapters/redocly-loader/bundled-ref-repair.ts +2 -2
  352. package/src/adapters/redocly-loader/loaded-documents.ts +46 -0
  353. package/src/adapters/redocly-loader/redocly-schema-loader.ts +18 -24
  354. package/src/adapters/redocly-loader/ref-access.ts +37 -3
  355. package/src/adapters/redocly-loader/ref-holders.ts +3 -3
  356. package/src/adapters/redocly-loader/remote-body-limit.ts +66 -0
  357. package/src/adapters/redocly-loader/remote-fetch.ts +74 -11
  358. package/src/adapters/redocly-loader/remote-node-limit.ts +62 -0
  359. package/src/adapters/redocly-loader/schema-load-errors.ts +52 -13
  360. package/src/adapters/redocly-loader/schema-source.ts +20 -8
  361. package/src/adapters/redocly-loader/unsupported-keys.ts +3 -7
  362. package/src/adapters/terminal-logger/terminal-logger.ts +10 -5
  363. package/src/api/default-ports.ts +33 -4
  364. package/src/api/discriminator-enum-parent.ts +3 -3
  365. package/src/api/discriminator-other-owners.ts +5 -3
  366. package/src/api/discriminator-patch.ts +5 -1
  367. package/src/api/discriminator-scan.ts +16 -8
  368. package/src/api/document-run.ts +4 -3
  369. package/src/api/legacy-utils.ts +5 -1
  370. package/src/api/openapi-ts.ts +20 -5
  371. package/src/api/run-context.ts +3 -0
  372. package/src/api/schema-callbacks.ts +60 -17
  373. package/src/api/transform-context.ts +7 -3
  374. package/src/api/transform-schema.ts +64 -12
  375. package/src/application/ports/file-system.ts +39 -0
  376. package/src/application/ports/schema-loader.ts +11 -1
  377. package/src/application/print/text-writer.ts +10 -3
  378. package/src/application/stack-overflow.ts +9 -5
  379. package/src/application/transform/document/components.ts +2 -2
  380. package/src/application/transform/document/declared-type-names.ts +36 -0
  381. package/src/application/transform/document/defs-root.ts +2 -2
  382. package/src/application/transform/document/document.ts +4 -3
  383. package/src/application/transform/document/enum-names-given-back.ts +91 -0
  384. package/src/application/transform/document/global-type-references.ts +1 -1
  385. package/src/application/transform/document/media-type.ts +4 -3
  386. package/src/application/transform/document/operation-keys-written.ts +27 -0
  387. package/src/application/transform/document/operation.ts +2 -2
  388. package/src/application/transform/document/parameter-entries.ts +70 -0
  389. package/src/application/transform/document/parameter.ts +21 -9
  390. package/src/application/transform/document/parameters.ts +11 -56
  391. package/src/application/transform/document/path-item.ts +13 -31
  392. package/src/application/transform/document/paths-enum.ts +1 -1
  393. package/src/application/transform/document/paths.ts +6 -2
  394. package/src/application/transform/document/referenced-parameter.ts +146 -0
  395. package/src/application/transform/document/request-body.ts +2 -2
  396. package/src/application/transform/document/response.ts +3 -3
  397. package/src/application/transform/document/responses.ts +2 -2
  398. package/src/application/transform/document/root-type-aliases.ts +17 -38
  399. package/src/application/transform/document/type-resolution.ts +2 -1
  400. package/src/application/transform/document/webhooks.ts +2 -2
  401. package/src/application/transform/footer/document-footer.ts +18 -1
  402. package/src/application/transform/footer/enum-name-claims.ts +62 -0
  403. package/src/application/transform/footer/operation-keys.ts +28 -0
  404. package/src/application/transform/footer/type-evaluation.ts +4 -4
  405. package/src/application/transform/helper-types.ts +6 -5
  406. package/src/application/transform/numbered-names.ts +15 -0
  407. package/src/application/transform/ref-pointer/generated-location.ts +2 -2
  408. package/src/application/transform/ref-type.ts +2 -1
  409. package/src/application/transform/schema/composition-type.ts +2 -2
  410. package/src/application/transform/schema/enum-rule.ts +6 -2
  411. package/src/application/transform/schema/object-type.ts +4 -4
  412. package/src/application/transform/schema/ref-siblings.ts +76 -0
  413. package/src/application/transform/schema/schema-context.ts +3 -0
  414. package/src/application/transform/schema/schema-transform.ts +4 -2
  415. package/src/application/transform/schema-comment.ts +5 -1
  416. package/src/application/transform/transform-context.ts +5 -0
  417. package/src/cli/api-settings.ts +82 -7
  418. package/src/cli/api-writes.ts +117 -0
  419. package/src/cli/cli-dependencies.ts +21 -4
  420. package/src/cli/cli-errors.ts +20 -1
  421. package/src/cli/cli-output.ts +186 -7
  422. package/src/cli/main.ts +6 -3
  423. package/src/cli/redocly-apis.ts +153 -48
  424. package/src/cli/run-cli.ts +37 -8
  425. package/src/domain/append-all.ts +10 -0
  426. package/src/domain/cause-secrets.ts +52 -0
  427. package/src/domain/errors.ts +14 -5
  428. package/src/domain/ir/identifier-text.ts +6 -5
  429. package/src/domain/ir/ir-shape.ts +299 -0
  430. package/src/domain/ir/newer-identifier-ranges.ts +183 -30
  431. package/src/domain/openapi/alias-expansion.ts +4 -1
  432. package/src/domain/openapi/discriminated-union.ts +6 -4
  433. package/src/domain/openapi/discriminator-conflicts.ts +21 -7
  434. package/src/domain/openapi/document-object.ts +2 -0
  435. package/src/domain/openapi/json-pointer.ts +96 -7
  436. package/src/domain/openapi/schema-dialect.ts +22 -0
  437. package/src/domain/openapi/unsupported-features.ts +2 -2
  438. package/src/domain/output-fixes.ts +21 -2
  439. package/src/domain/url-secrets.ts +72 -0
  440. package/src/types/generator-options.ts +1 -1
  441. package/dist/cli/main.d.cts +0 -2
  442. package/dist/cli/main.d.mts +0 -2
  443. package/dist/cli/main.d.ts +0 -2
  444. package/dist/domain/url-credentials.cjs +0 -10
  445. package/dist/domain/url-credentials.cjs.map +0 -1
  446. package/dist/domain/url-credentials.mjs +0 -8
  447. package/dist/domain/url-credentials.mjs.map +0 -1
  448. package/src/domain/url-credentials.ts +0 -18
@@ -1,7 +1,7 @@
1
1
  import { irObject, irProperty } from "../../../domain/ir/constructors.js";
2
2
  import type { IrType } from "../../../domain/ir/nodes.js";
3
3
  import { toPropertyName } from "../../../domain/ir/property-name.js";
4
- import { createRef } from "../../../domain/openapi/json-pointer.js";
4
+ import { appendPointer, ROOT_POINTER } from "../../../domain/openapi/json-pointer.js";
5
5
  import type { PathItemObject, PathsObject } from "../../../domain/openapi/path-item-object.js";
6
6
  import { documentEntries } from "../document-entries.js";
7
7
  import type { TransformContext } from "../transform-context.js";
@@ -14,7 +14,7 @@ import { pathItemType } from "./path-item.js";
14
14
  */
15
15
  export function webhooksType(webhooks: PathsObject, context: TransformContext): IrType {
16
16
  const members = documentEntries(webhooks, context.options).map(([name, pathItem]) => {
17
- const location = { path: createRef(["webhooks", name]) };
17
+ const location = { path: appendPointer(ROOT_POINTER, ["webhooks", name]) };
18
18
  const type = pathItemType(pathItem as PathItemObject, location, context);
19
19
  return irProperty(toPropertyName(name), type, { isReadonly: context.options.immutable });
20
20
  });
@@ -12,12 +12,14 @@ import type {
12
12
  EnumValuesRequest,
13
13
  } from "../schema/schema-context.js";
14
14
  import type { DocumentFooter } from "../transform-context.js";
15
+ import { EnumNameClaims } from "./enum-name-claims.js";
15
16
  import {
16
17
  type DeclaredMembers,
17
18
  EnumNaming,
18
19
  enumDeclaration,
19
20
  withoutDeclaredMembers,
20
21
  } from "./enum-naming.js";
22
+ import { OperationKeys } from "./operation-keys.js";
21
23
  import { FIRST_SCHEMA_NAMES, type SharedEnumNames } from "./shared-enum-names.js";
22
24
 
23
25
  /** Where footer declarations go, in order: the run's `ctx.injectFooter`, open to user code. */
@@ -62,6 +64,12 @@ function declarationKey(name: string, request: EnumDeclarationRequest): string {
62
64
  return JSON.stringify([name, request.values, request.metadata]);
63
65
  }
64
66
 
67
+ /** The naming state a run's footer shares with the rest of the run. */
68
+ export interface RunFooterNames {
69
+ readonly enums: EnumNameClaims;
70
+ readonly operations: OperationKeys;
71
+ }
72
+
65
73
  /**
66
74
  * The footer of one run: enums (deduplicated with `--dedupe-enums`), `--enum-values` arrays, the
67
75
  * helper types they need, and the `operations` interface. Replaces the original's module-level
@@ -83,15 +91,18 @@ export class RunFooter implements DocumentFooter {
83
91
  private readonly sink: FooterSink;
84
92
  private readonly isDedupingEnums: boolean;
85
93
  private readonly sharedNames: SharedEnumNames;
94
+ private readonly names: RunFooterNames;
86
95
 
87
96
  constructor(
88
97
  sink: FooterSink,
89
98
  isDedupingEnums: boolean,
90
99
  sharedNames: SharedEnumNames = FIRST_SCHEMA_NAMES,
100
+ names: RunFooterNames = { enums: new EnumNameClaims(), operations: new OperationKeys() },
91
101
  ) {
92
102
  this.sink = sink;
93
103
  this.isDedupingEnums = isDedupingEnums;
94
104
  this.sharedNames = sharedNames;
105
+ this.names = names;
95
106
  }
96
107
 
97
108
  addEnum(request: EnumDeclarationRequest): string {
@@ -99,11 +110,13 @@ export class RunFooter implements DocumentFooter {
99
110
  const ownName = this.naming.enumName(request.name);
100
111
  const key = this.isDedupingEnums ? dedupeKey(request) : null;
101
112
  // Every schema of a shared enum goes to `sharedNames`, the later ones too.
102
- const name = key === null ? ownName : this.sharedNames.nameOf(key, ownName, request);
113
+ const sharedName = key === null ? ownName : this.sharedNames.nameOf(key, ownName, request);
103
114
  const known = key === null ? undefined : this.enumNamesByKey.get(key);
104
115
  if (known !== undefined) {
105
116
  return known;
106
117
  }
118
+ // The owner is the schema location: its requests share one enum, with `--dedupe-enums` too.
119
+ const name = this.names.enums.nameFor(sharedName, request.name);
107
120
  // Only a repeated member fails to compile; two empty declarations merge, so they stay.
108
121
  const declared = request.values.length > 0 ? declarationKey(name, request) : null;
109
122
  if (declared !== null && this.declaredEnums.has(declared)) {
@@ -200,6 +213,10 @@ export class RunFooter implements DocumentFooter {
200
213
  this.sink.addOperation(build);
201
214
  }
202
215
 
216
+ operationKey(operationId: string): string {
217
+ return this.names.operations.keyFor(operationId);
218
+ }
219
+
203
220
  private require(helper: HelperType): void {
204
221
  if (!this.sink.hasTypeAlias(helper.name)) {
205
222
  this.sink.add({ kind: "rawDeclaration", name: helper.name, text: helper.text });
@@ -0,0 +1,62 @@
1
+ import { freeNumberedName } from "../numbered-names.js";
2
+
3
+ /**
4
+ * The names of the `--enum` declarations of one run, unique across the enums and apart from the
5
+ * names the rest of the output may need.
6
+ *
7
+ * Every enum has an owner: the schema location it is named after, or with `--dedupe-enums` its
8
+ * members. Two owners whose names come out the same (`status` and `Status`) merged into one enum
9
+ * before, so each accepted the values of the other (upstream behavior). Now the first owner keeps
10
+ * the name and each later one gets the next free `Name_2`, `Name_3`, …; requests of one owner (a
11
+ * property and an inline `allOf` item of one schema) still share one enum.
12
+ *
13
+ * An enum also gives way to a name the output may need, which is only known at the end: a global
14
+ * type the output refers to (the `Blob` of `--binary-as-blob`, the `Record` of
15
+ * `Record<string, never>`), a helper type, or `ApiPaths`. Until then it takes the numbered name;
16
+ * `givenBack` lists the ones whose own name the output turned out not to need, so output that
17
+ * compiled before keeps its names (ADR-021).
18
+ */
19
+ export class EnumNameClaims {
20
+ private readonly mayBeNeeded: ReadonlySet<string>;
21
+ /** The first owner of each name an enum asked for. */
22
+ private readonly owners = new Map<string, string>();
23
+ /** The name given to each owner, by name asked for and owner. */
24
+ private readonly given = new Map<string, string>();
25
+ /** Every name given, and every name the output may need. */
26
+ private readonly taken: Set<string>;
27
+ /** A numbered name given only because the output may need the name asked for: that name. */
28
+ private readonly standIns = new Map<string, string>();
29
+
30
+ /** `mayBeNeeded`: the names an enum avoids until the end of the run; empty outside a run. */
31
+ constructor(mayBeNeeded: ReadonlySet<string> = new Set()) {
32
+ this.mayBeNeeded = mayBeNeeded;
33
+ this.taken = new Set(mayBeNeeded);
34
+ }
35
+
36
+ /** The declaration name of the enum `owner` asks to name `name`; the same for every request. */
37
+ nameFor(name: string, owner: string): string {
38
+ const key = JSON.stringify([name, owner]);
39
+ const known = this.given.get(key);
40
+ if (known !== undefined) {
41
+ return known;
42
+ }
43
+ const isFirstOwner = (this.owners.get(name) ?? owner) === owner;
44
+ this.owners.set(name, this.owners.get(name) ?? owner);
45
+ const isFree = isFirstOwner && !this.taken.has(name);
46
+ const declared = isFree ? name : freeNumberedName(name, this.taken);
47
+ if (isFirstOwner && this.mayBeNeeded.has(name)) {
48
+ this.standIns.set(declared, name);
49
+ }
50
+ this.taken.add(declared);
51
+ this.given.set(key, declared);
52
+ return declared;
53
+ }
54
+
55
+ /**
56
+ * The numbered names to rename back to the name asked for, because `needed` (the names the
57
+ * finished output declares or refers to) does not hold that name.
58
+ */
59
+ givenBack(needed: ReadonlySet<string>): ReadonlyMap<string, string> {
60
+ return new Map([...this.standIns].filter(([, name]) => !needed.has(name)));
61
+ }
62
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The keys of the `operations` interface in one run. A repeated `operationId` (Redocly warns
3
+ * about it) gave the interface two members of one name, which did not compile (TS2300). Now the
4
+ * first operation with an ID keeps it, and each later one gets the lowest number from 2 whose key
5
+ * no operation of the document has: the second `listItems` is `listItems2`, the name
6
+ * `--make-paths-enum` gives it in `ApiPaths` too. Keys follow the order the operations are
7
+ * transformed in, which is the document order (or the `--alphabetize` order).
8
+ */
9
+ export class OperationKeys {
10
+ private readonly written: ReadonlySet<string>;
11
+ private readonly taken = new Set<string>();
12
+
13
+ /** `written`: every operation key of the document; empty outside a document run. */
14
+ constructor(written: ReadonlySet<string> = new Set()) {
15
+ this.written = written;
16
+ }
17
+
18
+ /** The key of the next operation with this key, written or numbered. */
19
+ keyFor(key: string): string {
20
+ let unique = key;
21
+ for (let count = 2; this.taken.has(unique); count += 1) {
22
+ const candidate = `${key}${count}`;
23
+ unique = this.written.has(candidate) ? unique : candidate;
24
+ }
25
+ this.taken.add(unique);
26
+ return unique;
27
+ }
28
+ }
@@ -22,7 +22,7 @@ import { extracted, markerObject, omitted } from "./type-rules.js";
22
22
 
23
23
  /** How many references one evaluation expands; a deeper one is opaque. */
24
24
  const MAX_EXPANSIONS = 200;
25
- const DEEP_PREFIX = "FlattenedDeepRequired<";
25
+ const DEEP_HELPER = "FlattenedDeepRequired";
26
26
  /** How many members distributing an intersection may give; more is opaque. */
27
27
  const MAX_DISTRIBUTED = 64;
28
28
 
@@ -75,15 +75,15 @@ export class TypeEvaluator {
75
75
  if (this.expansions++ > MAX_EXPANSIONS) {
76
76
  return OPAQUE;
77
77
  }
78
- if (name.startsWith(DEEP_PREFIX) && name.endsWith(">")) {
79
- const root = this.declared.get(name.slice(DEEP_PREFIX.length, -1));
78
+ const [first, second] = args;
79
+ if (name === DEEP_HELPER && first?.kind === "reference" && first.typeArguments.length === 0) {
80
+ const root = this.declared.get(first.name);
80
81
  return root === undefined ? OPAQUE : this.expand({ kind: "type", type: root, deep: true });
81
82
  }
82
83
  const declared = args.length === 0 ? this.declared.get(name) : undefined;
83
84
  if (declared !== undefined) {
84
85
  return this.expand({ ...value, type: declared });
85
86
  }
86
- const [first, second] = args;
87
87
  if (first === undefined) {
88
88
  return OPAQUE;
89
89
  }
@@ -51,9 +51,10 @@ export const HELPER_TYPES = {
51
51
  /**
52
52
  * The `--read-write-markers` helper types, written before the root types. Task 7.6 replaces the
53
53
  * original text on purpose (ADR-014): primitives (also branded), readonly arrays, tuples,
54
- * intersected arrays and null-only properties keep their types (upstream #2615, #2620, #2632,
55
- * #2717, #2765). The declarations equal `Readable` / `Writable` of openapi-typesafe-helpers
56
- * (`test/api/read-write-marker-types.test.ts`); the text is what the TypeScript printer prints.
54
+ * intersected arrays, null-only and `any` properties keep their types (upstream #2615, #2620,
55
+ * #2632, #2717, #2765). The declarations equal the `Readable` / `Writable` that
56
+ * openapi-typesafe-fetch declares (`test/api/read-write-marker-types.test.ts`); the text is what
57
+ * the TypeScript printer prints.
57
58
  */
58
59
  export const READ_WRITE_MARKER_TYPES = lines(
59
60
  "export type $Read<T> = {",
@@ -65,8 +66,8 @@ export const READ_WRITE_MARKER_TYPES = lines(
65
66
  "type ReadWritePrimitive = string | number | boolean | bigint | symbol | null | undefined;",
66
67
  "type ReadWriteLeaf = ReadWritePrimitive | ((...args: never) => unknown);",
67
68
  "type ReadWriteMarkedKeys<T, Marker> = {",
68
- " [K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> " +
69
- "extends Marker ? K : never;",
69
+ " [K in keyof T]-?: 0 extends 1 & T[K] ? never : NonNullable<T[K]> extends never ? never : " +
70
+ "NonNullable<T[K]> extends Marker ? K : never;",
70
71
  "}[keyof T];",
71
72
  'type ReadWriteResolveArray<T extends readonly unknown[], Resolved extends "read" | ' +
72
73
  '"write"> = T[number][] extends T ? T extends unknown[] ? ReadWriteResolve<T[number], ' +
@@ -18,3 +18,18 @@ export function withNumberedRepeats(names: readonly string[], numbered: Numbered
18
18
  return unique;
19
19
  });
20
20
  }
21
+
22
+ /** Separates a repeated declaration name from its number: `Status` → `Status_2`. */
23
+ const DECLARATION_NUMBER_SEPARATOR = "_";
24
+
25
+ /**
26
+ * The first of `Name_2`, `Name_3`, … that `taken` does not hold: the suffix `--root-types` uses for
27
+ * its own conflicts, and every other declaration that must give way to another name.
28
+ */
29
+ export function freeNumberedName(name: string, taken: ReadonlySet<string>): string {
30
+ let count = 2;
31
+ while (taken.has(`${name}${DECLARATION_NUMBER_SEPARATOR}${count}`)) {
32
+ count += 1;
33
+ }
34
+ return `${name}${DECLARATION_NUMBER_SEPARATOR}${count}`;
35
+ }
@@ -1,4 +1,4 @@
1
- import { createRef } from "../../../domain/openapi/json-pointer.js";
1
+ import { appendPointer, ROOT_POINTER } from "../../../domain/openapi/json-pointer.js";
2
2
  import type { RefResolver } from "../schema/schema-context.js";
3
3
  import { isJsonObject } from "./generated-shape.js";
4
4
  import {
@@ -205,7 +205,7 @@ function walkTo(ref: string, refs: RefResolver, seen: readonly string[]): Locati
205
205
  export function generatedLocationOf(ref: string, refs: RefResolver): GeneratedLocation {
206
206
  const walk = walkTo(ref, refs, []);
207
207
  return {
208
- path: walk === null ? ref : createRef(walk.path),
208
+ path: walk === null ? ref : appendPointer(ROOT_POINTER, walk.path),
209
209
  isFromAdditionalProperties: walk?.isFromAdditionalProperties ?? false,
210
210
  };
211
211
  }
@@ -68,7 +68,8 @@ export function indexKeyword(type: IrType, segment: string, isLast: boolean): Ir
68
68
  }
69
69
 
70
70
  export function rootType(rootSegment: string, isDeep: boolean): IrType {
71
- return irReference(isDeep ? `FlattenedDeepRequired<${rootSegment}>` : rootSegment);
71
+ const root = irReference(rootSegment);
72
+ return isDeep ? irReference("FlattenedDeepRequired", [root]) : root;
72
73
  }
73
74
 
74
75
  /**
@@ -1,6 +1,6 @@
1
1
  import { irKeyword, irRecord } from "../../../domain/ir/constructors.js";
2
2
  import type { IrType } from "../../../domain/ir/nodes.js";
3
- import { createRef } from "../../../domain/openapi/json-pointer.js";
3
+ import { appendPointer } from "../../../domain/openapi/json-pointer.js";
4
4
  import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
5
5
  import { FIX } from "../../../domain/output-fixes.js";
6
6
  import { requirableRefType } from "../ref-pointer/pointer-type.js";
@@ -29,7 +29,7 @@ function variantTypes(
29
29
  return variants.map((variant, index) =>
30
30
  request.transformNested(variant, {
31
31
  ...request.location,
32
- path: createRef([request.location.path, keyword, String(index)]),
32
+ path: appendPointer(request.location.path, [keyword, index]),
33
33
  }),
34
34
  );
35
35
  }
@@ -6,7 +6,11 @@ import {
6
6
  irString,
7
7
  } from "../../../domain/ir/constructors.js";
8
8
  import type { IrType } from "../../../domain/ir/nodes.js";
9
- import { createRef, parseRefPointer } from "../../../domain/openapi/json-pointer.js";
9
+ import {
10
+ appendPointer,
11
+ parseRefPointer,
12
+ ROOT_POINTER,
13
+ } from "../../../domain/openapi/json-pointer.js";
10
14
  import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
11
15
  import { FIX } from "../../../domain/output-fixes.js";
12
16
  import { literalType } from "../literal-type.js";
@@ -228,7 +232,7 @@ function enumValuesPointer(path: string | undefined): { ref: string; extract: st
228
232
  : pointer
229
233
  .slice(firstVariantStart)
230
234
  .filter((segment) => !UNION_KEYWORDS.has(segment) && !INDEX_RE.test(segment));
231
- return { ref: createRef(kept), extract };
235
+ return { ref: appendPointer(ROOT_POINTER, kept), extract };
232
236
  }
233
237
 
234
238
  function addEnumValues(schema: SchemaObject, request: SchemaRequest): void {
@@ -7,7 +7,7 @@ import {
7
7
  } from "../../../domain/ir/constructors.js";
8
8
  import type { IrMember, IrPropertySignature, IrType } from "../../../domain/ir/nodes.js";
9
9
  import { toPropertyName } from "../../../domain/ir/property-name.js";
10
- import { createRef } from "../../../domain/openapi/json-pointer.js";
10
+ import { appendPointer } from "../../../domain/openapi/json-pointer.js";
11
11
  import type { Schema, SchemaObject } from "../../../domain/openapi/schema-object.js";
12
12
  import { documentEntries } from "../document-entries.js";
13
13
  import { schemaRefType } from "../ref-pointer/pointer-type.js";
@@ -117,7 +117,7 @@ function propertyType(
117
117
  facts: PropertyFacts,
118
118
  request: SchemaRequest,
119
119
  ): CustomResult {
120
- const path = createRef([request.location.path, key]);
120
+ const path = appendPointer(request.location.path, [key]);
121
121
  const type = facts.ref
122
122
  ? schemaRefType(facts.ref, request)
123
123
  : request.transformNested(value, { ...request.location, path });
@@ -151,7 +151,7 @@ function propertyMember(
151
151
  isReadonly: options.immutable || (!options.readWriteMarkers && facts.flags.isReadOnly),
152
152
  },
153
153
  );
154
- return finishProperty(property, value, createRef([request.location.path, key]), request);
154
+ return finishProperty(property, value, appendPointer(request.location.path, [key]), request);
155
155
  }
156
156
 
157
157
  function propertyMembers(schema: SchemaObject, request: SchemaRequest): IrMember[] {
@@ -176,7 +176,7 @@ function defsMember(
176
176
  ): IrMember {
177
177
  const { options } = request.context;
178
178
  const members = Object.entries(defs).map(([key, value]) => {
179
- const path = createRef([request.location.path, "$defs", key]);
179
+ const path = appendPointer(request.location.path, ["$defs", key]);
180
180
  const flags = propertyAccessFlags(value, request.context);
181
181
  const type = withReadWriteMarker(
182
182
  request.transformNested(value, { ...request.location, path }),
@@ -0,0 +1,76 @@
1
+ import { SCHEMA_DIALECTS } from "../../../domain/openapi/schema-dialect.js";
2
+ import type {
3
+ ReferenceSchema,
4
+ Schema,
5
+ SchemaObject,
6
+ } from "../../../domain/openapi/schema-object.js";
7
+ import { FIX } from "../../../domain/output-fixes.js";
8
+ import type { SchemaOptions } from "./schema-context.js";
9
+
10
+ /**
11
+ * The `ref-siblings` fix (ADR-021 amendment 2, RC4 G16): in JSON Schema 2020-12 (OpenAPI 3.1 and
12
+ * 3.2) the keywords next to a `$ref` apply too, so `{ $ref: Base, required: [extra], properties:
13
+ * { extra } }` is a `Base` that also has a required `extra`. That is what `allOf: [{ $ref: Base }]`
14
+ * next to the same keywords means, so the schema is typed as that `allOf`, with every rule the
15
+ * generator has for `allOf` and its siblings (`WithRequired`, intersections).
16
+ */
17
+
18
+ /**
19
+ * Keywords that only annotate (JSON Schema 2020-12 meta-data, format-annotation and content
20
+ * vocabularies, OpenAPI fixed fields), or that change no type on their own (`discriminator`
21
+ * without `oneOf`). Next to a `$ref` they stay where they were, so the output keeps the plain
22
+ * reference with its comment. Extension keywords (`x-…`) count as annotations too.
23
+ */
24
+ const ANNOTATION_KEYWORDS: ReadonlySet<string> = new Set([
25
+ "$anchor",
26
+ "$comment",
27
+ "$defs",
28
+ "$dynamicAnchor",
29
+ "$id",
30
+ "$ref",
31
+ "$schema",
32
+ "contentEncoding",
33
+ "contentMediaType",
34
+ "default",
35
+ "deprecated",
36
+ "description",
37
+ "discriminator",
38
+ "example",
39
+ "examples",
40
+ "externalDocs",
41
+ "format",
42
+ "readOnly",
43
+ "title",
44
+ "writeOnly",
45
+ "xml",
46
+ ]);
47
+
48
+ const EXTENSION_PREFIX = "x-";
49
+
50
+ function hasRef(schema: SchemaObject): schema is SchemaObject & ReferenceSchema {
51
+ return typeof (schema as Partial<ReferenceSchema>).$ref === "string";
52
+ }
53
+
54
+ function isTypeKeyword(keyword: string): boolean {
55
+ return !ANNOTATION_KEYWORDS.has(keyword) && !keyword.startsWith(EXTENSION_PREFIX);
56
+ }
57
+
58
+ /**
59
+ * A `$ref` schema as the `allOf` it means, or null where nothing changes: a schema without `$ref`,
60
+ * no fix, an OpenAPI 3.0 document, or no sibling that changes the type. The result has no
61
+ * `$ref`, so the shape rules type it as `enum`, `const` or a composition.
62
+ */
63
+ export function refWithSiblingsAsAllOf(
64
+ schema: SchemaObject,
65
+ options: SchemaOptions,
66
+ ): SchemaObject | null {
67
+ const isApplied =
68
+ options.fixes.has(FIX.REF_SIBLINGS) &&
69
+ options.schemaDialect === SCHEMA_DIALECTS.JSON_SCHEMA_2020_12;
70
+ if (!isApplied || !hasRef(schema) || !Object.keys(schema).some(isTypeKeyword)) {
71
+ return null;
72
+ }
73
+ const { $ref, allOf = [], ...siblings } = schema;
74
+ const members: readonly Schema[] = [{ $ref }, ...allOf];
75
+ return { ...siblings, allOf: members };
76
+ }
@@ -1,4 +1,5 @@
1
1
  import type { IrPropertySignature, IrType } from "../../../domain/ir/nodes.js";
2
+ import type { SchemaDialect } from "../../../domain/openapi/schema-dialect.js";
2
3
  import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
3
4
  import type { OutputFix } from "../../../domain/output-fixes.js";
4
5
 
@@ -27,6 +28,8 @@ export interface SchemaOptions {
27
28
  readonly immutable: boolean;
28
29
  readonly propertiesRequiredByDefault: boolean;
29
30
  readonly readWriteMarkers: boolean;
31
+ /** Whether keywords next to a `$ref` apply (OpenAPI 3.1 and 3.2) or not (3.0). */
32
+ readonly schemaDialect: SchemaDialect;
30
33
  }
31
34
 
32
35
  /**
@@ -7,6 +7,7 @@ import { schemaRefType } from "../ref-pointer/pointer-type.js";
7
7
  import { UNKNOWN_TYPE } from "../shared-types.js";
8
8
  import { compositionType } from "./composition-type.js";
9
9
  import { enumRule } from "./enum-rule.js";
10
+ import { refWithSiblingsAsAllOf } from "./ref-siblings.js";
10
11
  import type { SchemaContext, SchemaLocation } from "./schema-context.js";
11
12
  import type { SchemaRequest, SchemaRule } from "./schema-rule.js";
12
13
 
@@ -83,8 +84,9 @@ export function transformSchemaShape(
83
84
  return checked.type;
84
85
  }
85
86
  const current = request(location, context, isFromAdditionalProperties);
86
- const rule = SHAPE_RULES.find((candidate) => candidate.matches(checked.schema));
87
- return rule ? rule.transform(checked.schema, current) : compositionType(checked.schema, current);
87
+ const shaped = refWithSiblingsAsAllOf(checked.schema, context.options) ?? checked.schema;
88
+ const rule = SHAPE_RULES.find((candidate) => candidate.matches(shaped));
89
+ return rule ? rule.transform(shaped, current) : compositionType(shaped, current);
88
90
  }
89
91
 
90
92
  /** Transform a schema to IR, then apply `postTransform` (the original `transformSchemaObject`). */
@@ -1,3 +1,4 @@
1
+ import { appendAll } from "../../domain/append-all.js";
1
2
  import type { IrComment, IrPropertySignature } from "../../domain/ir/nodes.js";
2
3
  import { FIX, type OutputFix } from "../../domain/output-fixes.js";
3
4
 
@@ -80,7 +81,10 @@ function valueTagLines(schema: AnnotatedSchema): string[] {
80
81
  lines.push(`@${tag} ${formatValue(value)}`);
81
82
  }
82
83
  if (Array.isArray(schema.examples)) {
83
- lines.push(...schema.examples.map((example: unknown) => `@example ${formatValue(example)}`));
84
+ appendAll(
85
+ lines,
86
+ schema.examples.map((example: unknown) => `@example ${formatValue(example)}`),
87
+ );
84
88
  }
85
89
  return lines;
86
90
  }
@@ -33,6 +33,11 @@ export interface DocumentFooter extends FooterDeclarations {
33
33
  * it comes before any declaration the operation adds, as in the original.
34
34
  */
35
35
  addOperation(build: () => IrPropertySignature): void;
36
+ /**
37
+ * The key in `operations` of the next operation with this (normalized) `operationId`: the ID,
38
+ * or for a repeated ID a numbered one (`OperationKeys`).
39
+ */
40
+ operationKey(operationId: string): string;
36
41
  }
37
42
 
38
43
  /** Debug output for slow parts of a run (`DEBUG=openapi-ts:*`). */
@@ -1,8 +1,11 @@
1
1
  import { kebabCase } from "scule";
2
+ import { isOpenAPITypesafeError, OpenAPITypesafeError } from "../domain/errors.js";
3
+ import type { OutputFixName } from "../domain/output-fixes.js";
2
4
  import { WARNING_CODES, warningText } from "../domain/warnings.js";
3
- import { GENERATOR_FLAGS, hostList } from "./cli-arguments.js";
5
+ import { GENERATOR_FLAGS, type GeneratorFlags, hostList } from "./cli-arguments.js";
4
6
  import { cliError } from "./cli-errors.js";
5
7
  import { resolveLocationUrl } from "./cli-output.js";
8
+ import { fixNamesOf } from "./fix-option.js";
6
9
  import type { RefLimitOptions } from "./ref-limits.js";
7
10
 
8
11
  /**
@@ -51,22 +54,94 @@ export function unknownSettingWarnings(apiName: string, settings: ApiSettings):
51
54
  );
52
55
  }
53
56
 
57
+ /** The key a setting is written with: camelCase, else kebab-case; undefined when it is absent. */
58
+ function settingKey(settings: ApiSettings, name: string): string | undefined {
59
+ if (name in settings) {
60
+ return name;
61
+ }
62
+ const kebabName = kebabCase(name);
63
+ return kebabName in settings ? kebabName : undefined;
64
+ }
65
+
54
66
  /** The value of a setting in camelCase, else in kebab-case; `undefined` when it is absent. */
55
67
  function settingValue(settings: ApiSettings, name: string): unknown {
56
- return name in settings ? settings[name] : settings[kebabCase(name)];
68
+ const key = settingKey(settings, name);
69
+ return key === undefined ? undefined : settings[key];
57
70
  }
58
71
 
59
72
  function hasSetting(settings: ApiSettings, name: string): boolean {
60
- return name in settings || kebabCase(name) in settings;
73
+ return settingKey(settings, name) !== undefined;
61
74
  }
62
75
 
63
- function invalidSetting(apiName: string, name: string, expected: string): Error {
76
+ /** `CLI_CONFIG_INVALID` for the setting `name` of an API, named as the user wrote it. */
77
+ function invalidSetting(apiName: string, settings: ApiSettings, name: string, expected: string) {
78
+ const key = settingKey(settings, name) ?? kebabCase(name);
64
79
  return cliError(
65
80
  "CLI_CONFIG_INVALID",
66
- `API ${apiName}: \`${kebabCase(name)}\` in x-openapi-ts must be ${expected}`,
81
+ `API ${apiName}: \`${key}\` in x-openapi-ts must be ${expected}`,
67
82
  );
68
83
  }
69
84
 
85
+ /**
86
+ * The boolean flags an API sets, in camelCase or kebab-case; they win over the CLI's flags. A
87
+ * value of another type (`root-types: "true"`) fails with `CLI_CONFIG_INVALID`: ignoring it
88
+ * would generate other types than the config asks for, without a word.
89
+ */
90
+ export function apiFlags(apiName: string, settings: ApiSettings): GeneratorFlags {
91
+ const flags: Partial<Record<(typeof GENERATOR_FLAGS)[number], boolean>> = {};
92
+ for (const name of GENERATOR_FLAGS) {
93
+ const value = settingValue(settings, name);
94
+ if (typeof value === "boolean") {
95
+ flags[name] = value;
96
+ } else if (hasSetting(settings, name)) {
97
+ throw invalidSetting(apiName, settings, name, "true or false");
98
+ }
99
+ }
100
+ return flags;
101
+ }
102
+
103
+ /** The API's `output` file as written; fails with `CLI_CONFIG_INVALID` when it is not text. */
104
+ export function apiOutputOf(apiName: string, settings: ApiSettings): string {
105
+ const output = settings[OUTPUT_SETTING];
106
+ if (typeof output !== "string") {
107
+ throw invalidSetting(apiName, settings, OUTPUT_SETTING, "a file path");
108
+ }
109
+ return output;
110
+ }
111
+
112
+ /**
113
+ * The API's `fix` names, which replace the CLI's `--fix` (ADR-021). An entry that is not text
114
+ * fails with `CLI_CONFIG_INVALID`; an unknown name with `OPTION_FIX_UNKNOWN`, naming the API.
115
+ */
116
+ export function apiFixNames(
117
+ apiName: string,
118
+ settings: ApiSettings,
119
+ ): readonly OutputFixName[] | undefined {
120
+ if (!hasSetting(settings, FIX_SETTING)) {
121
+ return undefined;
122
+ }
123
+ const entries = [settingValue(settings, FIX_SETTING)].flat();
124
+ if (entries.some((entry) => typeof entry !== "string")) {
125
+ throw invalidSetting(apiName, settings, FIX_SETTING, "a list of fix names or a comma list");
126
+ }
127
+ try {
128
+ return fixNamesOf(entries);
129
+ } catch (error) {
130
+ throw isOpenAPITypesafeError(error) ? withApiName(apiName, error) : error;
131
+ }
132
+ }
133
+
134
+ /** The same error, with the API named first in its message. */
135
+ function withApiName(apiName: string, error: OpenAPITypesafeError): OpenAPITypesafeError {
136
+ const { code, details, cause } = error;
137
+ return new OpenAPITypesafeError({
138
+ code,
139
+ message: `API ${apiName}: ${error.message}`,
140
+ details,
141
+ cause,
142
+ });
143
+ }
144
+
70
145
  /** `local-ref-root: dir`, relative to the config file; empty means the config file's directory. */
71
146
  function localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL): RefLimitOptions {
72
147
  if (!hasSetting(settings, LOCAL_REF_ROOT_SETTING)) {
@@ -74,7 +149,7 @@ function localRefRootOf(apiName: string, settings: ApiSettings, configRoot: URL)
74
149
  }
75
150
  const value = settingValue(settings, LOCAL_REF_ROOT_SETTING) ?? "";
76
151
  if (typeof value !== "string") {
77
- throw invalidSetting(apiName, LOCAL_REF_ROOT_SETTING, "a directory path");
152
+ throw invalidSetting(apiName, settings, LOCAL_REF_ROOT_SETTING, "a directory path");
78
153
  }
79
154
  return { localRefRoot: resolveLocationUrl(value === "" ? "." : value, configRoot) };
80
155
  }
@@ -87,7 +162,7 @@ function remoteRefHostsOf(apiName: string, settings: ApiSettings): RefLimitOptio
87
162
  const value = settingValue(settings, REMOTE_REF_HOSTS_SETTING) ?? [];
88
163
  const entries = [value].flat();
89
164
  if (entries.some((entry) => typeof entry !== "string")) {
90
- throw invalidSetting(apiName, REMOTE_REF_HOSTS_SETTING, "a host list");
165
+ throw invalidSetting(apiName, settings, REMOTE_REF_HOSTS_SETTING, "a host list");
91
166
  }
92
167
  return { remoteRefHosts: hostList(entries) ?? [] };
93
168
  }