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

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 (596) hide show
  1. package/CHANGELOG.md +1972 -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 +97 -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 +97 -14
  13. package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
  14. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs +19 -0
  15. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs.map +1 -0
  16. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs +17 -0
  17. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs.map +1 -0
  18. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +48 -0
  19. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -0
  20. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +45 -0
  21. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -0
  22. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +1 -1
  23. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -1
  24. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +2 -2
  25. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -1
  26. package/dist/adapters/redocly-loader/component-schemas.cjs +17 -0
  27. package/dist/adapters/redocly-loader/component-schemas.cjs.map +1 -0
  28. package/dist/adapters/redocly-loader/component-schemas.mjs +14 -0
  29. package/dist/adapters/redocly-loader/component-schemas.mjs.map +1 -0
  30. package/dist/adapters/redocly-loader/loaded-documents.cjs +28 -0
  31. package/dist/adapters/redocly-loader/loaded-documents.cjs.map +1 -0
  32. package/dist/adapters/redocly-loader/loaded-documents.mjs +21 -0
  33. package/dist/adapters/redocly-loader/loaded-documents.mjs.map +1 -0
  34. package/dist/adapters/redocly-loader/mapping-schema-names.cjs +22 -0
  35. package/dist/adapters/redocly-loader/mapping-schema-names.cjs.map +1 -0
  36. package/dist/adapters/redocly-loader/mapping-schema-names.mjs +20 -0
  37. package/dist/adapters/redocly-loader/mapping-schema-names.mjs.map +1 -0
  38. package/dist/adapters/redocly-loader/query-named-components.cjs +137 -0
  39. package/dist/adapters/redocly-loader/query-named-components.cjs.map +1 -0
  40. package/dist/adapters/redocly-loader/query-named-components.mjs +134 -0
  41. package/dist/adapters/redocly-loader/query-named-components.mjs.map +1 -0
  42. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +40 -29
  43. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  44. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +38 -27
  45. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  46. package/dist/adapters/redocly-loader/ref-access.cjs +45 -4
  47. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  48. package/dist/adapters/redocly-loader/ref-access.mjs +45 -4
  49. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  50. package/dist/adapters/redocly-loader/ref-holders.cjs +52 -10
  51. package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
  52. package/dist/adapters/redocly-loader/ref-holders.mjs +53 -12
  53. package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
  54. package/dist/adapters/redocly-loader/remote-body-limit.cjs +50 -0
  55. package/dist/adapters/redocly-loader/remote-body-limit.cjs.map +1 -0
  56. package/dist/adapters/redocly-loader/remote-body-limit.mjs +48 -0
  57. package/dist/adapters/redocly-loader/remote-body-limit.mjs.map +1 -0
  58. package/dist/adapters/redocly-loader/remote-fetch.cjs +40 -9
  59. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  60. package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -9
  61. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  62. package/dist/adapters/redocly-loader/remote-node-limit.cjs +61 -0
  63. package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -0
  64. package/dist/adapters/redocly-loader/remote-node-limit.mjs +58 -0
  65. package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -0
  66. package/dist/adapters/redocly-loader/schema-load-errors.cjs +32 -8
  67. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
  68. package/dist/adapters/redocly-loader/schema-load-errors.mjs +32 -9
  69. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
  70. package/dist/adapters/redocly-loader/schema-source.cjs +18 -9
  71. package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
  72. package/dist/adapters/redocly-loader/schema-source.mjs +20 -11
  73. package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
  74. package/dist/adapters/redocly-loader/unsupported-keys.cjs +3 -5
  75. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
  76. package/dist/adapters/redocly-loader/unsupported-keys.mjs +3 -5
  77. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
  78. package/dist/adapters/terminal-logger/terminal-logger.cjs +10 -4
  79. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  80. package/dist/adapters/terminal-logger/terminal-logger.mjs +10 -4
  81. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  82. package/dist/api/default-ports.cjs +14 -2
  83. package/dist/api/default-ports.cjs.map +1 -1
  84. package/dist/api/default-ports.mjs +14 -2
  85. package/dist/api/default-ports.mjs.map +1 -1
  86. package/dist/api/discriminator-enum-parent.cjs +2 -2
  87. package/dist/api/discriminator-enum-parent.cjs.map +1 -1
  88. package/dist/api/discriminator-enum-parent.mjs +3 -3
  89. package/dist/api/discriminator-enum-parent.mjs.map +1 -1
  90. package/dist/api/discriminator-other-owners.cjs +5 -3
  91. package/dist/api/discriminator-other-owners.cjs.map +1 -1
  92. package/dist/api/discriminator-other-owners.mjs +5 -3
  93. package/dist/api/discriminator-other-owners.mjs.map +1 -1
  94. package/dist/api/discriminator-patch.cjs +5 -1
  95. package/dist/api/discriminator-patch.cjs.map +1 -1
  96. package/dist/api/discriminator-patch.mjs +5 -1
  97. package/dist/api/discriminator-patch.mjs.map +1 -1
  98. package/dist/api/discriminator-scan.cjs +15 -8
  99. package/dist/api/discriminator-scan.cjs.map +1 -1
  100. package/dist/api/discriminator-scan.mjs +15 -8
  101. package/dist/api/discriminator-scan.mjs.map +1 -1
  102. package/dist/api/document-refs.cjs +16 -1
  103. package/dist/api/document-refs.cjs.map +1 -1
  104. package/dist/api/document-refs.mjs +16 -1
  105. package/dist/api/document-refs.mjs.map +1 -1
  106. package/dist/api/document-run.cjs +6 -12
  107. package/dist/api/document-run.cjs.map +1 -1
  108. package/dist/api/document-run.mjs +6 -12
  109. package/dist/api/document-run.mjs.map +1 -1
  110. package/dist/api/legacy-utils.cjs.map +1 -1
  111. package/dist/api/legacy-utils.mjs.map +1 -1
  112. package/dist/api/openapi-ts.cjs +9 -6
  113. package/dist/api/openapi-ts.cjs.map +1 -1
  114. package/dist/api/openapi-ts.mjs +10 -8
  115. package/dist/api/openapi-ts.mjs.map +1 -1
  116. package/dist/api/ref-limit-options.cjs +63 -0
  117. package/dist/api/ref-limit-options.cjs.map +1 -0
  118. package/dist/api/ref-limit-options.mjs +57 -0
  119. package/dist/api/ref-limit-options.mjs.map +1 -0
  120. package/dist/api/schema-callbacks.cjs +36 -12
  121. package/dist/api/schema-callbacks.cjs.map +1 -1
  122. package/dist/api/schema-callbacks.mjs +36 -12
  123. package/dist/api/schema-callbacks.mjs.map +1 -1
  124. package/dist/api/transform-context.cjs +7 -3
  125. package/dist/api/transform-context.cjs.map +1 -1
  126. package/dist/api/transform-context.mjs +7 -3
  127. package/dist/api/transform-context.mjs.map +1 -1
  128. package/dist/api/transform-schema.cjs +47 -10
  129. package/dist/api/transform-schema.cjs.map +1 -1
  130. package/dist/api/transform-schema.mjs +48 -11
  131. package/dist/api/transform-schema.mjs.map +1 -1
  132. package/dist/application/print/text-writer.cjs +10 -3
  133. package/dist/application/print/text-writer.cjs.map +1 -1
  134. package/dist/application/print/text-writer.mjs +10 -3
  135. package/dist/application/print/text-writer.mjs.map +1 -1
  136. package/dist/application/stack-overflow.cjs +2 -1
  137. package/dist/application/stack-overflow.cjs.map +1 -1
  138. package/dist/application/stack-overflow.mjs +2 -1
  139. package/dist/application/stack-overflow.mjs.map +1 -1
  140. package/dist/application/transform/declared-value-types.cjs +36 -0
  141. package/dist/application/transform/declared-value-types.cjs.map +1 -0
  142. package/dist/application/transform/declared-value-types.mjs +34 -0
  143. package/dist/application/transform/declared-value-types.mjs.map +1 -0
  144. package/dist/application/transform/document/components.cjs +1 -1
  145. package/dist/application/transform/document/components.cjs.map +1 -1
  146. package/dist/application/transform/document/components.mjs +2 -2
  147. package/dist/application/transform/document/components.mjs.map +1 -1
  148. package/dist/application/transform/document/declared-type-names.cjs +23 -0
  149. package/dist/application/transform/document/declared-type-names.cjs.map +1 -0
  150. package/dist/application/transform/document/declared-type-names.mjs +20 -0
  151. package/dist/application/transform/document/declared-type-names.mjs.map +1 -0
  152. package/dist/application/transform/document/defs-root.cjs +1 -1
  153. package/dist/application/transform/document/defs-root.cjs.map +1 -1
  154. package/dist/application/transform/document/defs-root.mjs +2 -2
  155. package/dist/application/transform/document/defs-root.mjs.map +1 -1
  156. package/dist/application/transform/document/document.cjs +7 -2
  157. package/dist/application/transform/document/document.cjs.map +1 -1
  158. package/dist/application/transform/document/document.mjs +6 -3
  159. package/dist/application/transform/document/document.mjs.map +1 -1
  160. package/dist/application/transform/document/enum-names-given-back.cjs +62 -0
  161. package/dist/application/transform/document/enum-names-given-back.cjs.map +1 -0
  162. package/dist/application/transform/document/enum-names-given-back.mjs +58 -0
  163. package/dist/application/transform/document/enum-names-given-back.mjs.map +1 -0
  164. package/dist/application/transform/document/exploded-query-values.cjs +63 -0
  165. package/dist/application/transform/document/exploded-query-values.cjs.map +1 -0
  166. package/dist/application/transform/document/exploded-query-values.mjs +59 -0
  167. package/dist/application/transform/document/exploded-query-values.mjs.map +1 -0
  168. package/dist/application/transform/document/global-type-references.cjs +1 -0
  169. package/dist/application/transform/document/global-type-references.cjs.map +1 -1
  170. package/dist/application/transform/document/global-type-references.mjs +1 -1
  171. package/dist/application/transform/document/global-type-references.mjs.map +1 -1
  172. package/dist/application/transform/document/header.cjs +11 -3
  173. package/dist/application/transform/document/header.cjs.map +1 -1
  174. package/dist/application/transform/document/header.mjs +10 -2
  175. package/dist/application/transform/document/header.mjs.map +1 -1
  176. package/dist/application/transform/document/media-type.cjs +2 -2
  177. package/dist/application/transform/document/media-type.cjs.map +1 -1
  178. package/dist/application/transform/document/media-type.mjs +3 -3
  179. package/dist/application/transform/document/media-type.mjs.map +1 -1
  180. package/dist/application/transform/document/operation-keys-written.cjs +26 -0
  181. package/dist/application/transform/document/operation-keys-written.cjs.map +1 -0
  182. package/dist/application/transform/document/operation-keys-written.mjs +24 -0
  183. package/dist/application/transform/document/operation-keys-written.mjs.map +1 -0
  184. package/dist/application/transform/document/operation.cjs +1 -1
  185. package/dist/application/transform/document/operation.cjs.map +1 -1
  186. package/dist/application/transform/document/operation.mjs +2 -2
  187. package/dist/application/transform/document/operation.mjs.map +1 -1
  188. package/dist/application/transform/document/parameter-entries.cjs +34 -0
  189. package/dist/application/transform/document/parameter-entries.cjs.map +1 -0
  190. package/dist/application/transform/document/parameter-entries.mjs +30 -0
  191. package/dist/application/transform/document/parameter-entries.mjs.map +1 -0
  192. package/dist/application/transform/document/parameter.cjs +12 -4
  193. package/dist/application/transform/document/parameter.cjs.map +1 -1
  194. package/dist/application/transform/document/parameter.mjs +13 -5
  195. package/dist/application/transform/document/parameter.mjs.map +1 -1
  196. package/dist/application/transform/document/parameters.cjs +29 -34
  197. package/dist/application/transform/document/parameters.cjs.map +1 -1
  198. package/dist/application/transform/document/parameters.mjs +29 -34
  199. package/dist/application/transform/document/parameters.mjs.map +1 -1
  200. package/dist/application/transform/document/path-item.cjs +15 -17
  201. package/dist/application/transform/document/path-item.cjs.map +1 -1
  202. package/dist/application/transform/document/path-item.mjs +15 -19
  203. package/dist/application/transform/document/path-item.mjs.map +1 -1
  204. package/dist/application/transform/document/path-template-key.cjs +84 -0
  205. package/dist/application/transform/document/path-template-key.cjs.map +1 -0
  206. package/dist/application/transform/document/path-template-key.mjs +79 -0
  207. package/dist/application/transform/document/path-template-key.mjs.map +1 -0
  208. package/dist/application/transform/document/path-template-refs.cjs +70 -0
  209. package/dist/application/transform/document/path-template-refs.cjs.map +1 -0
  210. package/dist/application/transform/document/path-template-refs.mjs +67 -0
  211. package/dist/application/transform/document/path-template-refs.mjs.map +1 -0
  212. package/dist/application/transform/document/paths-enum.cjs +8 -6
  213. package/dist/application/transform/document/paths-enum.cjs.map +1 -1
  214. package/dist/application/transform/document/paths-enum.mjs +8 -7
  215. package/dist/application/transform/document/paths-enum.mjs.map +1 -1
  216. package/dist/application/transform/document/paths.cjs +43 -67
  217. package/dist/application/transform/document/paths.cjs.map +1 -1
  218. package/dist/application/transform/document/paths.mjs +42 -68
  219. package/dist/application/transform/document/paths.mjs.map +1 -1
  220. package/dist/application/transform/document/referenced-parameter.cjs +80 -0
  221. package/dist/application/transform/document/referenced-parameter.cjs.map +1 -0
  222. package/dist/application/transform/document/referenced-parameter.mjs +78 -0
  223. package/dist/application/transform/document/referenced-parameter.mjs.map +1 -0
  224. package/dist/application/transform/document/request-body.cjs +1 -1
  225. package/dist/application/transform/document/request-body.cjs.map +1 -1
  226. package/dist/application/transform/document/request-body.mjs +2 -2
  227. package/dist/application/transform/document/request-body.mjs.map +1 -1
  228. package/dist/application/transform/document/response.cjs +2 -2
  229. package/dist/application/transform/document/response.cjs.map +1 -1
  230. package/dist/application/transform/document/response.mjs +3 -3
  231. package/dist/application/transform/document/response.mjs.map +1 -1
  232. package/dist/application/transform/document/responses.cjs +1 -1
  233. package/dist/application/transform/document/responses.cjs.map +1 -1
  234. package/dist/application/transform/document/responses.mjs +2 -2
  235. package/dist/application/transform/document/responses.mjs.map +1 -1
  236. package/dist/application/transform/document/root-type-aliases.cjs +8 -23
  237. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  238. package/dist/application/transform/document/root-type-aliases.mjs +8 -24
  239. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  240. package/dist/application/transform/document/type-resolution.cjs +3 -1
  241. package/dist/application/transform/document/type-resolution.cjs.map +1 -1
  242. package/dist/application/transform/document/type-resolution.mjs +3 -1
  243. package/dist/application/transform/document/type-resolution.mjs.map +1 -1
  244. package/dist/application/transform/document/webhooks.cjs +10 -3
  245. package/dist/application/transform/document/webhooks.cjs.map +1 -1
  246. package/dist/application/transform/document/webhooks.mjs +10 -3
  247. package/dist/application/transform/document/webhooks.mjs.map +1 -1
  248. package/dist/application/transform/footer/document-footer.cjs +16 -5
  249. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  250. package/dist/application/transform/footer/document-footer.mjs +16 -5
  251. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  252. package/dist/application/transform/footer/enum-name-claims.cjs +48 -0
  253. package/dist/application/transform/footer/enum-name-claims.cjs.map +1 -0
  254. package/dist/application/transform/footer/enum-name-claims.mjs +46 -0
  255. package/dist/application/transform/footer/enum-name-claims.mjs.map +1 -0
  256. package/dist/application/transform/footer/operation-keys.cjs +23 -0
  257. package/dist/application/transform/footer/operation-keys.cjs.map +1 -0
  258. package/dist/application/transform/footer/operation-keys.mjs +21 -0
  259. package/dist/application/transform/footer/operation-keys.mjs.map +1 -0
  260. package/dist/application/transform/footer/type-evaluation.cjs +4 -4
  261. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
  262. package/dist/application/transform/footer/type-evaluation.mjs +4 -4
  263. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
  264. package/dist/application/transform/helper-types.cjs +3 -3
  265. package/dist/application/transform/helper-types.cjs.map +1 -1
  266. package/dist/application/transform/helper-types.mjs +3 -3
  267. package/dist/application/transform/helper-types.mjs.map +1 -1
  268. package/dist/application/transform/numbered-names.cjs +9 -0
  269. package/dist/application/transform/numbered-names.cjs.map +1 -1
  270. package/dist/application/transform/numbered-names.mjs +9 -1
  271. package/dist/application/transform/numbered-names.mjs.map +1 -1
  272. package/dist/application/transform/ref-pointer/generated-location.cjs +5 -5
  273. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
  274. package/dist/application/transform/ref-pointer/generated-location.mjs +3 -3
  275. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
  276. package/dist/application/transform/ref-pointer/generated-shape.cjs +47 -66
  277. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -1
  278. package/dist/application/transform/ref-pointer/generated-shape.mjs +36 -50
  279. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -1
  280. package/dist/application/transform/ref-pointer/inline-cycles.cjs +2 -2
  281. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -1
  282. package/dist/application/transform/ref-pointer/inline-cycles.mjs +1 -1
  283. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -1
  284. package/dist/application/transform/ref-pointer/located-node.cjs +23 -0
  285. package/dist/application/transform/ref-pointer/located-node.cjs.map +1 -0
  286. package/dist/application/transform/ref-pointer/located-node.mjs +18 -0
  287. package/dist/application/transform/ref-pointer/located-node.mjs.map +1 -0
  288. package/dist/application/transform/ref-pointer/original-index.cjs +68 -13
  289. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -1
  290. package/dist/application/transform/ref-pointer/original-index.mjs +70 -15
  291. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -1
  292. package/dist/application/transform/ref-pointer/pointer-type.cjs +2 -2
  293. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
  294. package/dist/application/transform/ref-pointer/pointer-type.mjs +1 -1
  295. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
  296. package/dist/application/transform/ref-pointer/pointer-walk.cjs +54 -13
  297. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -1
  298. package/dist/application/transform/ref-pointer/pointer-walk.mjs +46 -7
  299. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -1
  300. package/dist/application/transform/ref-pointer/property-shape.cjs +52 -0
  301. package/dist/application/transform/ref-pointer/property-shape.cjs.map +1 -0
  302. package/dist/application/transform/ref-pointer/property-shape.mjs +45 -0
  303. package/dist/application/transform/ref-pointer/property-shape.mjs.map +1 -0
  304. package/dist/application/transform/ref-pointer/typed-walk.cjs +79 -21
  305. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -1
  306. package/dist/application/transform/ref-pointer/typed-walk.mjs +76 -18
  307. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -1
  308. package/dist/application/transform/ref-type.cjs +2 -1
  309. package/dist/application/transform/ref-type.cjs.map +1 -1
  310. package/dist/application/transform/ref-type.mjs +2 -1
  311. package/dist/application/transform/ref-type.mjs.map +1 -1
  312. package/dist/application/transform/schema/access-flags.cjs.map +1 -1
  313. package/dist/application/transform/schema/access-flags.mjs.map +1 -1
  314. package/dist/application/transform/schema/composition-type.cjs +1 -1
  315. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  316. package/dist/application/transform/schema/composition-type.mjs +2 -2
  317. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  318. package/dist/application/transform/schema/enum-rule.cjs +1 -1
  319. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  320. package/dist/application/transform/schema/enum-rule.mjs +2 -2
  321. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  322. package/dist/application/transform/schema/index-signature-type.cjs +21 -0
  323. package/dist/application/transform/schema/index-signature-type.cjs.map +1 -0
  324. package/dist/application/transform/schema/index-signature-type.mjs +19 -0
  325. package/dist/application/transform/schema/index-signature-type.mjs.map +1 -0
  326. package/dist/application/transform/schema/input-location.cjs +23 -0
  327. package/dist/application/transform/schema/input-location.cjs.map +1 -0
  328. package/dist/application/transform/schema/input-location.mjs +21 -0
  329. package/dist/application/transform/schema/input-location.mjs.map +1 -0
  330. package/dist/application/transform/schema/object-type.cjs +18 -8
  331. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  332. package/dist/application/transform/schema/object-type.mjs +19 -9
  333. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  334. package/dist/application/transform/schema/ref-siblings.cjs +47 -0
  335. package/dist/application/transform/schema/ref-siblings.cjs.map +1 -0
  336. package/dist/application/transform/schema/ref-siblings.mjs +45 -0
  337. package/dist/application/transform/schema/ref-siblings.mjs.map +1 -0
  338. package/dist/application/transform/schema/schema-transform.cjs +6 -3
  339. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  340. package/dist/application/transform/schema/schema-transform.mjs +6 -3
  341. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  342. package/dist/application/transform/schema/unevaluated-properties.cjs +2 -30
  343. package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
  344. package/dist/application/transform/schema/unevaluated-properties.mjs +3 -31
  345. package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
  346. package/dist/application/transform/schema-comment.cjs +5 -1
  347. package/dist/application/transform/schema-comment.cjs.map +1 -1
  348. package/dist/application/transform/schema-comment.mjs +5 -1
  349. package/dist/application/transform/schema-comment.mjs.map +1 -1
  350. package/dist/cli/api-logger.cjs +13 -0
  351. package/dist/cli/api-logger.cjs.map +1 -0
  352. package/dist/cli/api-logger.mjs +11 -0
  353. package/dist/cli/api-logger.mjs.map +1 -0
  354. package/dist/cli/api-settings.cjs +57 -9
  355. package/dist/cli/api-settings.cjs.map +1 -1
  356. package/dist/cli/api-settings.mjs +56 -11
  357. package/dist/cli/api-settings.mjs.map +1 -1
  358. package/dist/cli/api-writes.cjs +72 -0
  359. package/dist/cli/api-writes.cjs.map +1 -0
  360. package/dist/cli/api-writes.mjs +69 -0
  361. package/dist/cli/api-writes.mjs.map +1 -0
  362. package/dist/cli/cli-arguments.cjs +51 -11
  363. package/dist/cli/cli-arguments.cjs.map +1 -1
  364. package/dist/cli/cli-arguments.mjs +51 -11
  365. package/dist/cli/cli-arguments.mjs.map +1 -1
  366. package/dist/cli/cli-errors.cjs +29 -1
  367. package/dist/cli/cli-errors.cjs.map +1 -1
  368. package/dist/cli/cli-errors.mjs +29 -2
  369. package/dist/cli/cli-errors.mjs.map +1 -1
  370. package/dist/cli/cli-output.cjs +111 -4
  371. package/dist/cli/cli-output.cjs.map +1 -1
  372. package/dist/cli/cli-output.mjs +104 -5
  373. package/dist/cli/cli-output.mjs.map +1 -1
  374. package/dist/cli/main.cjs +13 -3
  375. package/dist/cli/main.cjs.map +1 -1
  376. package/dist/cli/main.mjs +14 -4
  377. package/dist/cli/main.mjs.map +1 -1
  378. package/dist/cli/redocly-apis.cjs +94 -37
  379. package/dist/cli/redocly-apis.cjs.map +1 -1
  380. package/dist/cli/redocly-apis.mjs +99 -42
  381. package/dist/cli/redocly-apis.mjs.map +1 -1
  382. package/dist/cli/ref-limits.cjs +15 -1
  383. package/dist/cli/ref-limits.cjs.map +1 -1
  384. package/dist/cli/ref-limits.mjs +15 -2
  385. package/dist/cli/ref-limits.mjs.map +1 -1
  386. package/dist/cli/run-cli.cjs +37 -14
  387. package/dist/cli/run-cli.cjs.map +1 -1
  388. package/dist/cli/run-cli.mjs +39 -16
  389. package/dist/cli/run-cli.mjs.map +1 -1
  390. package/dist/domain/append-all.cjs +10 -0
  391. package/dist/domain/append-all.cjs.map +1 -0
  392. package/dist/domain/append-all.mjs +8 -0
  393. package/dist/domain/append-all.mjs.map +1 -0
  394. package/dist/domain/cause-secrets.cjs +52 -0
  395. package/dist/domain/cause-secrets.cjs.map +1 -0
  396. package/dist/domain/cause-secrets.mjs +50 -0
  397. package/dist/domain/cause-secrets.mjs.map +1 -0
  398. package/dist/domain/errors.cjs +11 -3
  399. package/dist/domain/errors.cjs.map +1 -1
  400. package/dist/domain/errors.mjs +11 -3
  401. package/dist/domain/errors.mjs.map +1 -1
  402. package/dist/domain/ir/identifier-text.cjs.map +1 -1
  403. package/dist/domain/ir/identifier-text.mjs +1 -1
  404. package/dist/domain/ir/identifier-text.mjs.map +1 -1
  405. package/dist/domain/ir/ir-shape.cjs +187 -0
  406. package/dist/domain/ir/ir-shape.cjs.map +1 -0
  407. package/dist/domain/ir/ir-shape.mjs +184 -0
  408. package/dist/domain/ir/ir-shape.mjs.map +1 -0
  409. package/dist/domain/ir/newer-identifier-ranges.cjs +182 -29
  410. package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -1
  411. package/dist/domain/ir/newer-identifier-ranges.mjs +182 -29
  412. package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -1
  413. package/dist/domain/location-text.cjs +9 -0
  414. package/dist/domain/location-text.cjs.map +1 -0
  415. package/dist/domain/location-text.mjs +7 -0
  416. package/dist/domain/location-text.mjs.map +1 -0
  417. package/dist/domain/openapi/alias-expansion.cjs +3 -1
  418. package/dist/domain/openapi/alias-expansion.cjs.map +1 -1
  419. package/dist/domain/openapi/alias-expansion.mjs +3 -1
  420. package/dist/domain/openapi/alias-expansion.mjs.map +1 -1
  421. package/dist/domain/openapi/discriminated-union.cjs +3 -3
  422. package/dist/domain/openapi/discriminated-union.cjs.map +1 -1
  423. package/dist/domain/openapi/discriminated-union.mjs +4 -4
  424. package/dist/domain/openapi/discriminated-union.mjs.map +1 -1
  425. package/dist/domain/openapi/discriminator-conflicts.cjs +10 -6
  426. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -1
  427. package/dist/domain/openapi/discriminator-conflicts.mjs +11 -7
  428. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -1
  429. package/dist/domain/openapi/document-places.cjs +55 -0
  430. package/dist/domain/openapi/document-places.cjs.map +1 -0
  431. package/dist/domain/openapi/document-places.mjs +53 -0
  432. package/dist/domain/openapi/document-places.mjs.map +1 -0
  433. package/dist/domain/openapi/json-pointer.cjs +43 -1
  434. package/dist/domain/openapi/json-pointer.cjs.map +1 -1
  435. package/dist/domain/openapi/json-pointer.mjs +40 -2
  436. package/dist/domain/openapi/json-pointer.mjs.map +1 -1
  437. package/dist/domain/openapi/schema-dialect.cjs +15 -0
  438. package/dist/domain/openapi/schema-dialect.cjs.map +1 -0
  439. package/dist/domain/openapi/schema-dialect.mjs +12 -0
  440. package/dist/domain/openapi/schema-dialect.mjs.map +1 -0
  441. package/dist/domain/openapi/unsupported-features.cjs +1 -1
  442. package/dist/domain/openapi/unsupported-features.cjs.map +1 -1
  443. package/dist/domain/openapi/unsupported-features.mjs +2 -2
  444. package/dist/domain/openapi/unsupported-features.mjs.map +1 -1
  445. package/dist/domain/output-fixes.cjs +20 -0
  446. package/dist/domain/output-fixes.cjs.map +1 -1
  447. package/dist/domain/output-fixes.mjs +20 -0
  448. package/dist/domain/output-fixes.mjs.map +1 -1
  449. package/dist/domain/terminal-text.cjs +31 -0
  450. package/dist/domain/terminal-text.cjs.map +1 -0
  451. package/dist/domain/terminal-text.mjs +29 -0
  452. package/dist/domain/terminal-text.mjs.map +1 -0
  453. package/dist/domain/url-secrets.cjs +48 -0
  454. package/dist/domain/url-secrets.cjs.map +1 -0
  455. package/dist/domain/url-secrets.mjs +45 -0
  456. package/dist/domain/url-secrets.mjs.map +1 -0
  457. package/dist/domain/warnings.cjs +1 -0
  458. package/dist/domain/warnings.cjs.map +1 -1
  459. package/dist/domain/warnings.mjs +1 -0
  460. package/dist/domain/warnings.mjs.map +1 -1
  461. package/dist/index.d.cts +46 -20
  462. package/dist/index.d.mts +46 -20
  463. package/dist/index.d.ts +46 -20
  464. package/package.json +4 -5
  465. package/src/adapters/node-file-system/file-claims.ts +138 -0
  466. package/src/adapters/node-file-system/file-identity.ts +137 -0
  467. package/src/adapters/node-file-system/node-file-system.ts +158 -18
  468. package/src/adapters/pipe-safe-writer/pipe-safe-writer.ts +29 -0
  469. package/src/adapters/redocly-loader/bundled-mapping-copies.ts +60 -0
  470. package/src/adapters/redocly-loader/bundled-ref-repair.ts +2 -2
  471. package/src/adapters/redocly-loader/component-schemas.ts +19 -0
  472. package/src/adapters/redocly-loader/loaded-documents.ts +46 -0
  473. package/src/adapters/redocly-loader/mapping-schema-names.ts +25 -0
  474. package/src/adapters/redocly-loader/query-named-components.ts +201 -0
  475. package/src/adapters/redocly-loader/redocly-schema-loader.ts +64 -38
  476. package/src/adapters/redocly-loader/ref-access.ts +51 -4
  477. package/src/adapters/redocly-loader/ref-holders.ts +76 -15
  478. package/src/adapters/redocly-loader/remote-body-limit.ts +66 -0
  479. package/src/adapters/redocly-loader/remote-fetch.ts +85 -13
  480. package/src/adapters/redocly-loader/remote-node-limit.ts +102 -0
  481. package/src/adapters/redocly-loader/schema-load-errors.ts +52 -13
  482. package/src/adapters/redocly-loader/schema-source.ts +35 -11
  483. package/src/adapters/redocly-loader/unsupported-keys.ts +3 -7
  484. package/src/adapters/terminal-logger/terminal-logger.ts +17 -6
  485. package/src/api/default-ports.ts +33 -4
  486. package/src/api/discriminator-enum-parent.ts +3 -3
  487. package/src/api/discriminator-other-owners.ts +5 -3
  488. package/src/api/discriminator-patch.ts +5 -1
  489. package/src/api/discriminator-scan.ts +16 -8
  490. package/src/api/document-refs.ts +29 -1
  491. package/src/api/document-run.ts +10 -19
  492. package/src/api/legacy-utils.ts +5 -1
  493. package/src/api/openapi-ts.ts +26 -8
  494. package/src/api/ref-limit-options.ts +76 -0
  495. package/src/api/run-context.ts +3 -0
  496. package/src/api/schema-callbacks.ts +60 -17
  497. package/src/api/transform-context.ts +7 -3
  498. package/src/api/transform-schema.ts +79 -12
  499. package/src/application/ports/file-system.ts +47 -0
  500. package/src/application/ports/schema-loader.ts +11 -1
  501. package/src/application/print/text-writer.ts +10 -3
  502. package/src/application/stack-overflow.ts +9 -5
  503. package/src/application/transform/declared-value-types.ts +42 -0
  504. package/src/application/transform/document/components.ts +2 -2
  505. package/src/application/transform/document/declared-type-names.ts +36 -0
  506. package/src/application/transform/document/defs-root.ts +2 -2
  507. package/src/application/transform/document/document.ts +8 -5
  508. package/src/application/transform/document/enum-names-given-back.ts +91 -0
  509. package/src/application/transform/document/exploded-query-values.ts +88 -0
  510. package/src/application/transform/document/global-type-references.ts +1 -1
  511. package/src/application/transform/document/header.ts +25 -5
  512. package/src/application/transform/document/media-type.ts +4 -3
  513. package/src/application/transform/document/operation-keys-written.ts +27 -0
  514. package/src/application/transform/document/operation.ts +2 -2
  515. package/src/application/transform/document/parameter-entries.ts +70 -0
  516. package/src/application/transform/document/parameter.ts +21 -9
  517. package/src/application/transform/document/parameters.ts +56 -66
  518. package/src/application/transform/document/path-item.ts +16 -34
  519. package/src/application/transform/document/path-template-key.ts +152 -0
  520. package/src/application/transform/document/path-template-refs.ts +106 -0
  521. package/src/application/transform/document/paths-enum.ts +24 -10
  522. package/src/application/transform/document/paths.ts +59 -125
  523. package/src/application/transform/document/referenced-parameter.ts +146 -0
  524. package/src/application/transform/document/request-body.ts +2 -2
  525. package/src/application/transform/document/response.ts +3 -3
  526. package/src/application/transform/document/responses.ts +2 -2
  527. package/src/application/transform/document/root-type-aliases.ts +17 -38
  528. package/src/application/transform/document/type-resolution.ts +2 -1
  529. package/src/application/transform/document/webhooks.ts +19 -6
  530. package/src/application/transform/footer/document-footer.ts +36 -9
  531. package/src/application/transform/footer/enum-name-claims.ts +62 -0
  532. package/src/application/transform/footer/operation-keys.ts +28 -0
  533. package/src/application/transform/footer/type-evaluation.ts +4 -4
  534. package/src/application/transform/helper-types.ts +8 -7
  535. package/src/application/transform/numbered-names.ts +15 -0
  536. package/src/application/transform/ref-pointer/generated-location.ts +3 -3
  537. package/src/application/transform/ref-pointer/generated-shape.ts +67 -78
  538. package/src/application/transform/ref-pointer/inline-cycles.ts +1 -1
  539. package/src/application/transform/ref-pointer/located-node.ts +38 -0
  540. package/src/application/transform/ref-pointer/original-index.ts +100 -17
  541. package/src/application/transform/ref-pointer/pointer-type.ts +1 -1
  542. package/src/application/transform/ref-pointer/pointer-walk.ts +82 -8
  543. package/src/application/transform/ref-pointer/property-shape.ts +97 -0
  544. package/src/application/transform/ref-pointer/typed-walk.ts +117 -25
  545. package/src/application/transform/ref-type.ts +2 -1
  546. package/src/application/transform/schema/access-flags.ts +5 -2
  547. package/src/application/transform/schema/composition-type.ts +2 -2
  548. package/src/application/transform/schema/enum-rule.ts +6 -2
  549. package/src/application/transform/schema/index-signature-type.ts +31 -0
  550. package/src/application/transform/schema/input-location.ts +35 -0
  551. package/src/application/transform/schema/object-type.ts +22 -12
  552. package/src/application/transform/schema/ref-siblings.ts +76 -0
  553. package/src/application/transform/schema/schema-context.ts +3 -0
  554. package/src/application/transform/schema/schema-transform.ts +6 -3
  555. package/src/application/transform/schema/unevaluated-properties.ts +4 -44
  556. package/src/application/transform/schema-comment.ts +5 -1
  557. package/src/application/transform/transform-context.ts +5 -0
  558. package/src/cli/api-logger.ts +17 -0
  559. package/src/cli/api-settings.ts +80 -13
  560. package/src/cli/api-writes.ts +117 -0
  561. package/src/cli/cli-arguments.ts +90 -14
  562. package/src/cli/cli-dependencies.ts +26 -4
  563. package/src/cli/cli-errors.ts +42 -1
  564. package/src/cli/cli-output.ts +195 -15
  565. package/src/cli/main.ts +14 -5
  566. package/src/cli/redocly-apis.ts +177 -52
  567. package/src/cli/ref-limits.ts +21 -2
  568. package/src/cli/run-cli.ts +76 -15
  569. package/src/domain/append-all.ts +10 -0
  570. package/src/domain/cause-secrets.ts +86 -0
  571. package/src/domain/errors.ts +16 -5
  572. package/src/domain/ir/identifier-text.ts +6 -5
  573. package/src/domain/ir/ir-shape.ts +299 -0
  574. package/src/domain/ir/newer-identifier-ranges.ts +183 -30
  575. package/src/domain/location-text.ts +12 -0
  576. package/src/domain/openapi/alias-expansion.ts +4 -1
  577. package/src/domain/openapi/discriminated-union.ts +6 -4
  578. package/src/domain/openapi/discriminator-conflicts.ts +21 -7
  579. package/src/domain/openapi/document-object.ts +2 -0
  580. package/src/domain/openapi/document-places.ts +78 -0
  581. package/src/domain/openapi/json-pointer.ts +96 -7
  582. package/src/domain/openapi/schema-dialect.ts +22 -0
  583. package/src/domain/openapi/unsupported-features.ts +2 -2
  584. package/src/domain/output-fixes.ts +28 -2
  585. package/src/domain/terminal-text.ts +44 -0
  586. package/src/domain/url-secrets.ts +72 -0
  587. package/src/domain/warnings.ts +1 -0
  588. package/src/types/generator-options.ts +1 -1
  589. package/dist/cli/main.d.cts +0 -2
  590. package/dist/cli/main.d.mts +0 -2
  591. package/dist/cli/main.d.ts +0 -2
  592. package/dist/domain/url-credentials.cjs +0 -10
  593. package/dist/domain/url-credentials.cjs.map +0 -1
  594. package/dist/domain/url-credentials.mjs +0 -8
  595. package/dist/domain/url-credentials.mjs.map +0 -1
  596. package/src/domain/url-credentials.ts +0 -18
@@ -0,0 +1,201 @@
1
+ import {
2
+ appendPointer,
3
+ canonicalRef,
4
+ parseRefPointer,
5
+ ROOT_POINTER,
6
+ } from "../../domain/openapi/json-pointer.js";
7
+ import { findMappings, findRefHolders } from "./ref-holders.js";
8
+
9
+ /**
10
+ * Redocly 1.x bundles an external `$ref` into a component named after the last segment of the
11
+ * document's URL, without its extension, when the pointer gives no free name (a `$ref` to a whole
12
+ * document, or two targets with the same pointer). The query stays in that name, and a query holds
13
+ * API keys and signatures, so `https://host/schemas/pet?token=…` became the component
14
+ * `pet?token=…` in the generated file and in messages (threat model T4b). This renames such a
15
+ * component after the URL without its query: `pet`, with a `-2` suffix when that name is taken.
16
+ */
17
+
18
+ type Components = Record<string, Record<string, unknown>>;
19
+
20
+ /** The keys of each `components` group before bundling: the bundle edits the document in place. */
21
+ export type ComponentKeys = ReadonlyMap<string, ReadonlySet<string>>;
22
+
23
+ /** Old and new name of each renamed component, per `components` group. */
24
+ type Renames = Map<string, Map<string, string>>;
25
+
26
+ const COMPONENTS_KEY = "components";
27
+ const REMOTE_URL_RE = /^https?:\/\//;
28
+ const PATH_SEPARATOR_RE = /[/\\]/;
29
+ const EXTENSION_RE = /\.[^.]+$/;
30
+ /** What Redocly puts between the base name and the rest of a component name. */
31
+ const NAME_SUFFIX_STARTS = ["_", "-"];
32
+ const FIRST_SERIAL = 2;
33
+
34
+ function isContainer(value: unknown): value is Record<string, unknown> {
35
+ return typeof value === "object" && value !== null && !Array.isArray(value);
36
+ }
37
+
38
+ function componentsOf(document: unknown): Components {
39
+ const components = isContainer(document) ? document[COMPONENTS_KEY] : undefined;
40
+ if (!isContainer(components)) {
41
+ return {};
42
+ }
43
+ const groups: Components = {};
44
+ for (const [group, entries] of Object.entries(components)) {
45
+ if (isContainer(entries)) {
46
+ groups[group] = entries;
47
+ }
48
+ }
49
+ return groups;
50
+ }
51
+
52
+ /** The keys of every `components` group of a document. */
53
+ export function componentKeysOf(document: unknown): ComponentKeys {
54
+ const keys = new Map<string, ReadonlySet<string>>();
55
+ for (const [group, entries] of Object.entries(componentsOf(document))) {
56
+ keys.set(group, new Set(Object.keys(entries)));
57
+ }
58
+ return keys;
59
+ }
60
+
61
+ /** The base name Redocly 1.34 gives a document (`refBaseName`): the last segment, no extension. */
62
+ function redoclyBaseName(ref: string): string {
63
+ return (ref.split(PATH_SEPARATOR_RE).at(-1) ?? "").replace(EXTENSION_RE, "");
64
+ }
65
+
66
+ /**
67
+ * The base name of the URL without its query and fragment. A URL with no last segment
68
+ * (`https://host/?key=…`) is named after its host, so the name is never empty.
69
+ */
70
+ function queryFreeBaseName(url: URL): string {
71
+ const withoutQuery = new URL(url.pathname, url.origin).href;
72
+ return redoclyBaseName(withoutQuery) || url.hostname;
73
+ }
74
+
75
+ /** Each base name Redocly takes from a remote URL with a query, with the name to use instead. */
76
+ function queryBaseNames(documentRefs: Iterable<string>): Map<string, string> {
77
+ const names = new Map<string, string>();
78
+ for (const ref of documentRefs) {
79
+ const url = REMOTE_URL_RE.test(ref) && URL.canParse(ref) ? new URL(ref) : undefined;
80
+ if (url === undefined || url.search === "") {
81
+ continue;
82
+ }
83
+ const named = redoclyBaseName(ref);
84
+ const clean = queryFreeBaseName(url);
85
+ if (named !== clean) {
86
+ names.set(named, clean);
87
+ }
88
+ }
89
+ return names;
90
+ }
91
+
92
+ /** The name `key` gets, or undefined when no query base name starts it. */
93
+ function queryFreeName(key: string, baseNames: ReadonlyMap<string, string>): string | undefined {
94
+ // The longest base name first: `pet?a=1` must not match as `pet?a` when both were loaded.
95
+ const matches = [...baseNames.keys()].filter(
96
+ (named) =>
97
+ key === named || NAME_SUFFIX_STARTS.some((start) => key.startsWith(`${named}${start}`)),
98
+ );
99
+ const named = matches.sort((a, b) => b.length - a.length)[0];
100
+ return named === undefined ? undefined : `${baseNames.get(named)}${key.slice(named.length)}`;
101
+ }
102
+
103
+ function freeName(name: string, taken: ReadonlySet<string>): string {
104
+ let free = name;
105
+ for (let serial = FIRST_SERIAL; taken.has(free); serial += 1) {
106
+ free = `${name}-${serial}`;
107
+ }
108
+ return free;
109
+ }
110
+
111
+ /** Rename the bundled components of one group in place, keeping their order. */
112
+ function renameGroup(
113
+ entries: Record<string, unknown>,
114
+ keysBefore: ReadonlySet<string>,
115
+ baseNames: ReadonlyMap<string, string>,
116
+ ): Map<string, string> {
117
+ const renames = new Map<string, string>();
118
+ const taken = new Set(Object.keys(entries));
119
+ for (const key of Object.keys(entries)) {
120
+ const name = keysBefore.has(key) ? undefined : queryFreeName(key, baseNames);
121
+ if (name !== undefined) {
122
+ taken.delete(key);
123
+ const free = freeName(name, taken);
124
+ taken.add(free);
125
+ renames.set(key, free);
126
+ }
127
+ }
128
+ for (const [key, value] of Object.entries(entries)) {
129
+ delete entries[key];
130
+ entries[renames.get(key) ?? key] = value;
131
+ }
132
+ return renames;
133
+ }
134
+
135
+ /** Rewrites pointers and messages that name a renamed component. */
136
+ export interface ComponentRenaming {
137
+ /** The pointer with a renamed component's new name; any other text as it is. */
138
+ readonly pointer: (pointer: string) => string;
139
+ /** The text with each renamed component's old name replaced by its new name. */
140
+ readonly text: (text: string) => string;
141
+ }
142
+
143
+ function renamedPointer(pointer: string, renames: Renames): string {
144
+ if (!pointer.startsWith(`${ROOT_POINTER}/`)) {
145
+ return pointer;
146
+ }
147
+ const [components, group = "", name = "", ...rest] = parseRefPointer(canonicalRef(pointer));
148
+ const renamed = components === COMPONENTS_KEY ? renames.get(group)?.get(name) : undefined;
149
+ return renamed === undefined
150
+ ? pointer
151
+ : appendPointer(ROOT_POINTER, [COMPONENTS_KEY, group, renamed, ...rest]);
152
+ }
153
+
154
+ function renamedText(text: string, renames: Renames): string {
155
+ const pairs = [...renames.values()].flatMap((group) => [...group]);
156
+ // The longest old name first, so a name that starts another one does not split it.
157
+ pairs.sort(([a], [b]) => b.length - a.length);
158
+ return pairs.reduce((shown, [old, renamed]) => shown.replaceAll(old, renamed), text);
159
+ }
160
+
161
+ function rewriteRefs(document: unknown, renaming: ComponentRenaming): void {
162
+ for (const { node } of findRefHolders(document)) {
163
+ node.$ref = renaming.pointer(node.$ref);
164
+ }
165
+ for (const mapping of findMappings(document)) {
166
+ for (const [name, value] of Object.entries(mapping)) {
167
+ if (typeof value === "string") {
168
+ mapping[name] = renaming.pointer(value);
169
+ }
170
+ }
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Rename, in place, the components the bundle named after a URL with a query, and every local
176
+ * `$ref` and `mapping` value that names them. `documentRefs` are the refs of the loaded documents.
177
+ */
178
+ export function renameQueryNamedComponents(
179
+ bundled: unknown,
180
+ keysBefore: ComponentKeys,
181
+ documentRefs: Iterable<string>,
182
+ ): ComponentRenaming {
183
+ const baseNames = queryBaseNames(documentRefs);
184
+ const renames: Renames = new Map();
185
+ if (baseNames.size > 0) {
186
+ for (const [group, entries] of Object.entries(componentsOf(bundled))) {
187
+ const groupRenames = renameGroup(entries, keysBefore.get(group) ?? new Set(), baseNames);
188
+ if (groupRenames.size > 0) {
189
+ renames.set(group, groupRenames);
190
+ }
191
+ }
192
+ }
193
+ const renaming: ComponentRenaming = {
194
+ pointer: (pointer) => renamedPointer(pointer, renames),
195
+ text: (text) => renamedText(text, renames),
196
+ };
197
+ if (renames.size > 0) {
198
+ rewriteRefs(bundled, renaming);
199
+ }
200
+ return renaming;
201
+ }
@@ -3,17 +3,31 @@ import {
3
3
  type BaseResolver,
4
4
  bundle,
5
5
  type Document,
6
+ type LocationObject,
6
7
  lintDocument,
7
8
  type NormalizedProblem,
8
9
  type Config as RedoclyConfig,
9
10
  } from "@redocly/openapi-core";
10
11
  import type { Logger } from "../../application/ports/logger.js";
11
- import type { SchemaLoader, SchemaLoadRequest } from "../../application/ports/schema-loader.js";
12
+ import type {
13
+ LoadedSchema,
14
+ SchemaLoader,
15
+ SchemaLoadRequest,
16
+ } from "../../application/ports/schema-loader.js";
12
17
  import { withStackOverflowReportedAsync } from "../../application/stack-overflow.js";
18
+ import { redactUrlSecrets } from "../../domain/url-secrets.js";
13
19
  import { WARNING_CODES, warningText } from "../../domain/warnings.js";
14
20
  import type { OpenAPI3 } from "../../types.js";
21
+ import { removeBundledMappingCopies, schemaKeysOf } from "./bundled-mapping-copies.js";
15
22
  import { repairBundledRefs } from "./bundled-ref-repair.js";
23
+ import { loadedDocuments, localFilesRead } from "./loaded-documents.js";
16
24
  import { findMalformedRefs, malformedRefsError } from "./malformed-refs.js";
25
+ import { pointMappingNamesAtSchemas } from "./mapping-schema-names.js";
26
+ import {
27
+ type ComponentRenaming,
28
+ componentKeysOf,
29
+ renameQueryNamedComponents,
30
+ } from "./query-named-components.js";
17
31
  import { RefAccessResolver } from "./ref-access.js";
18
32
  import { checkRefsResolve } from "./ref-resolution-check.js";
19
33
  import { REF_CYCLE_MESSAGE } from "./ref-resolution-steps.js";
@@ -25,11 +39,7 @@ import {
25
39
  versionUnsupportedError,
26
40
  } from "./schema-load-errors.js";
27
41
  import { parseSchema } from "./schema-source.js";
28
- import {
29
- findUnsupportedKeys,
30
- type LoadedDocument,
31
- unsupportedKeysError,
32
- } from "./unsupported-keys.js";
42
+ import { findUnsupportedKeys, unsupportedKeysError } from "./unsupported-keys.js";
33
43
 
34
44
  /**
35
45
  * The SchemaLoader port on Redocly 1.34 (ADR-005): parse any inherited source type, then lint and
@@ -107,21 +117,6 @@ function sourceFilePath(source: URL): string {
107
117
  }
108
118
  }
109
119
 
110
- /**
111
- * The root document and every other document the resolver loaded, as far as they parsed. A root
112
- * read from a file or URL is in the resolver cache too, and is listed once.
113
- */
114
- async function loadedDocuments(root: Document, resolver: BaseResolver): Promise<LoadedDocument[]> {
115
- const cached = await Promise.all(resolver.cache.values());
116
- const bySource = new Map<string, unknown>([[root.source.absoluteRef, root.parsed]]);
117
- for (const document of cached) {
118
- if ("parsed" in document && !bySource.has(document.source.absoluteRef)) {
119
- bySource.set(document.source.absoluteRef, document.parsed);
120
- }
121
- }
122
- return [...bySource].map(([source, parsed]) => ({ source, parsed }));
123
- }
124
-
125
120
  /** Report the document problems Redocly throws as typed errors; anything else passes through. */
126
121
  async function rethrowDocumentError(
127
122
  error: unknown,
@@ -148,7 +143,7 @@ class RedoclySchemaLoader implements SchemaLoader {
148
143
  this.#options = options;
149
144
  }
150
145
 
151
- async load(request: SchemaLoadRequest): Promise<OpenAPI3> {
146
+ async load(request: SchemaLoadRequest): Promise<LoadedSchema> {
152
147
  const resolver = this.#resolver(request);
153
148
  // Parsing is guarded too: `JSON.stringify` of a deep object source overflows the stack on
154
149
  // Node.js 22 and 24, before linting starts.
@@ -164,7 +159,7 @@ class RedoclySchemaLoader implements SchemaLoader {
164
159
  return bundled;
165
160
  }
166
161
 
167
- async #parseAndBundle(request: SchemaLoadRequest, resolver: BaseResolver): Promise<OpenAPI3> {
162
+ async #parseAndBundle(request: SchemaLoadRequest, resolver: BaseResolver): Promise<LoadedSchema> {
168
163
  const { logger, now } = this.#options;
169
164
  const configLoadedAt = now();
170
165
  logger.debug("Loaded Redoc config", "redoc", now() - configLoadedAt);
@@ -173,7 +168,11 @@ class RedoclySchemaLoader implements SchemaLoader {
173
168
  const document = await parseSchema(request.source, { absoluteRef, resolver });
174
169
  logger.debug("Parsed schema", "redoc", now() - parseStartedAt);
175
170
  assertOpenAPI3(document.parsed);
176
- return this.#lintAndBundle(document, resolver, request.shouldLint);
171
+ pointMappingNamesAtSchemas(document.parsed);
172
+ const bundled = await this.#lintAndBundle(document, resolver, request.shouldLint);
173
+ const isRootAFile = request.source instanceof URL && request.source.protocol === "file:";
174
+ const localFiles = await localFilesRead(document, resolver, isRootAFile);
175
+ return { document: bundled, localFiles };
177
176
  }
178
177
 
179
178
  #resolver(request: SchemaLoadRequest): RefAccessResolver {
@@ -181,11 +180,14 @@ class RedoclySchemaLoader implements SchemaLoader {
181
180
  const config = resolveConfigWithAccess(redoc.resolve, {
182
181
  timeoutMs: remoteRefTimeoutMs,
183
182
  access: request.refAccess,
183
+ rootUrl: request.source instanceof URL ? request.source.href : undefined,
184
184
  maxParallelFetches: remoteDocumentLimits.maxParallelFetches,
185
+ bodyLimits: remoteDocumentLimits,
185
186
  });
186
187
  return new RefAccessResolver(config, {
187
188
  access: request.refAccess,
188
189
  maxRemoteDocuments: remoteDocumentLimits.maxDocuments,
190
+ maxRemoteNodes: remoteDocumentLimits.maxNodes,
189
191
  });
190
192
  }
191
193
 
@@ -210,12 +212,14 @@ class RedoclySchemaLoader implements SchemaLoader {
210
212
  config: this.#options.redoc.styleguide,
211
213
  externalRefResolver: resolver,
212
214
  });
213
- this.#report(problems);
215
+ this.#report(problems, document.source.absoluteRef);
214
216
  this.#options.logger.debug("Linted schema", "lint", this.#options.now() - startedAt);
215
217
  }
216
218
 
217
219
  async #bundle(document: Document, resolver: BaseResolver): Promise<OpenAPI3> {
218
220
  const startedAt = this.#options.now();
221
+ const schemaKeys = schemaKeysOf(document.parsed);
222
+ const componentKeys = componentKeysOf(document.parsed);
219
223
  // The lint resolver: documents it already loaded are not fetched again.
220
224
  const bundled = await bundle({
221
225
  config: this.#options.redoc,
@@ -223,8 +227,12 @@ class RedoclySchemaLoader implements SchemaLoader {
223
227
  doc: document,
224
228
  externalRefResolver: resolver,
225
229
  });
226
- this.#report(bundled.problems);
230
+ removeBundledMappingCopies(bundled.bundle.parsed, schemaKeys);
227
231
  repairBundledRefs(bundled.bundle.parsed);
232
+ const documentRefs = resolver.getFiles();
233
+ const renaming = renameQueryNamedComponents(bundled.bundle.parsed, componentKeys, documentRefs);
234
+ // The problems name the components the bundle made, so they are shown by their new names.
235
+ this.#report(bundled.problems, document.source.absoluteRef, renaming);
228
236
  this.#options.logger.debug("Bundled schema", "bundle", this.#options.now() - startedAt);
229
237
  return bundled.bundle.parsed;
230
238
  }
@@ -234,22 +242,22 @@ class RedoclySchemaLoader implements SchemaLoader {
234
242
  * config's `.redocly.lint-ignore.yaml` lists is left out, as `redocly lint` leaves it out
235
243
  * (upstream #2189).
236
244
  */
237
- #report(problems: readonly NormalizedProblem[]): void {
245
+ #report(problems: readonly NormalizedProblem[], rootRef: string, renaming = UNRENAMED): void {
238
246
  const errorMessages: string[] = [];
239
247
  for (const problem of problems) {
240
248
  if (problem.ignored === true) {
241
249
  this.#options.logger.debug(
242
- `Ignored by the lint ignore file: ${problemMessage(problem)}`,
250
+ `Ignored by the lint ignore file: ${problemMessage(problem, renaming, rootRef)}`,
243
251
  "lint",
244
252
  );
245
253
  continue;
246
254
  }
247
- const message = problemMessage(problem);
255
+ const message = problemMessage(problem, renaming, rootRef);
248
256
  if (problem.severity === "error") {
249
257
  errorMessages.push(message);
250
258
  this.#options.logger.error(message);
251
259
  } else {
252
- this.#options.logger.warn(lintWarningText(problem));
260
+ this.#options.logger.warn(lintWarningText(message, problem.ruleId));
253
261
  }
254
262
  }
255
263
  if (errorMessages.length > 0) {
@@ -259,16 +267,34 @@ class RedoclySchemaLoader implements SchemaLoader {
259
267
  }
260
268
 
261
269
  /** A lint warning names its rule, which `redocly.yaml` can turn off, and ends with its code. */
262
- function lintWarningText(problem: NormalizedProblem): string {
263
- return warningText(
264
- `${problemMessage(problem)}, rule ${problem.ruleId}`,
265
- WARNING_CODES.LINT_PROBLEM,
266
- );
270
+ function lintWarningText(message: string, ruleId: string): string {
271
+ return warningText(`${message}, rule ${ruleId}`, WARNING_CODES.LINT_PROBLEM);
272
+ }
273
+
274
+ /** Problems found before the bundle named any component. */
275
+ const UNRENAMED: ComponentRenaming = { pointer: (pointer) => pointer, text: (text) => text };
276
+
277
+ /** A problem location that names a JSON Pointer, not a line and column. */
278
+ type PointerLocation = Extract<LocationObject, { pointer: string }>;
279
+
280
+ /**
281
+ * Where a problem is: its pointer, and the document when it is not the root (URL secrets left
282
+ * out).
283
+ */
284
+ function locationText(location: PointerLocation, renaming: ComponentRenaming, rootRef: string) {
285
+ const pointer = renaming.pointer(location.pointer);
286
+ const documentRef = location.source.absoluteRef;
287
+ return documentRef === rootRef ? pointer : `${pointer} in ${redactUrlSecrets(documentRef)}`;
267
288
  }
268
289
 
269
- function problemMessage(problem: NormalizedProblem): string {
270
- const location = problem.location?.[0]?.pointer;
271
- return location ? `${problem.message} at ${location}` : problem.message;
290
+ function problemMessage(
291
+ problem: NormalizedProblem,
292
+ renaming: ComponentRenaming,
293
+ rootRef: string,
294
+ ): string {
295
+ const location = problem.location?.[0];
296
+ const message = renaming.text(problem.message);
297
+ return location?.pointer ? `${message} at ${locationText(location, renaming, rootRef)}` : message;
272
298
  }
273
299
 
274
300
  /** A schema loader with one Redocly config and logger, for one or more loads. */
@@ -10,9 +10,11 @@ import {
10
10
  } from "@redocly/openapi-core";
11
11
  import type { RefAccess } from "../../application/ports/schema-loader.js";
12
12
  import { ERROR_CODES, type OpenAPITypesafeError } from "../../domain/errors.js";
13
- import { redactUrlCredentials } from "../../domain/url-credentials.js";
13
+ import { redactUrlSecrets } from "../../domain/url-secrets.js";
14
14
  import { aliasExpansionFailure } from "./alias-limit.js";
15
15
  import { isHostAllowed } from "./allowed-hosts.js";
16
+ import { pointMappingNamesAtSchemas } from "./mapping-schema-names.js";
17
+ import { isParsedSource, RemoteNodeLimit } from "./remote-node-limit.js";
16
18
  import { refForbiddenError } from "./schema-load-errors.js";
17
19
 
18
20
  /**
@@ -92,15 +94,20 @@ function localFromRemoteRefusal(
92
94
  if (!isRemoteRef(base) || isRemoteRef(absoluteRef)) {
93
95
  return undefined;
94
96
  }
95
- const shownBase = redactUrlCredentials(base);
97
+ const shownBase = redactUrlSecrets(base);
96
98
  return refForbiddenError(absoluteRef, { reason: "local-ref-from-remote", base: shownBase });
97
99
  }
98
100
 
101
+ /** The scheme of an `http(s)` URL, in any case. */
102
+ const REMOTE_SCHEME_RE = /^https?:(?=\/\/)/i;
103
+
99
104
  /** The limits one resolver checks; each load gets its own resolver. */
100
105
  export interface RefAccessLimits {
101
106
  readonly access: RefAccess;
102
107
  /** Remote documents one load may fetch, the root included (threat model T2). */
103
108
  readonly maxRemoteDocuments: number;
109
+ /** Nodes the remote documents of one load may parse into together (threat model T2). */
110
+ readonly maxRemoteNodes: number;
104
111
  }
105
112
 
106
113
  /**
@@ -110,6 +117,7 @@ export interface RefAccessLimits {
110
117
  */
111
118
  export class RefAccessResolver extends BaseResolver {
112
119
  readonly #limits: RefAccessLimits;
120
+ readonly #nodeLimit: RemoteNodeLimit;
113
121
  readonly #refusals: OpenAPITypesafeError[] = [];
114
122
  /** The root document's ref: it is chosen by the developer, so it is not limited. */
115
123
  #rootRef: string | undefined;
@@ -119,6 +127,7 @@ export class RefAccessResolver extends BaseResolver {
119
127
  constructor(config: ResolveConfig, limits: RefAccessLimits) {
120
128
  super(config);
121
129
  this.#limits = limits;
130
+ this.#nodeLimit = new RemoteNodeLimit(limits.maxRemoteNodes);
122
131
  }
123
132
 
124
133
  /** The first document that was refused, if any. */
@@ -126,6 +135,17 @@ export class RefAccessResolver extends BaseResolver {
126
135
  return this.#refusals[0];
127
136
  }
128
137
 
138
+ /**
139
+ * A scheme is the same in any case (RFC 3986, section 3.1), but Redocly takes only `http://` and
140
+ * `https://` as URLs: it read `HTTP://host/x.yaml` as a file path, and its "not found" message
141
+ * showed the user info and the query of the URL, which no longer looked like one. The scheme
142
+ * is written in lowercase first, so the `$ref` loads as the URL it is, within the same limits.
143
+ */
144
+ override resolveExternalRef(base: string | null, ref: string): string {
145
+ const normalized = ref.replace(REMOTE_SCHEME_RE, (scheme) => scheme.toLowerCase());
146
+ return super.resolveExternalRef(base, normalized);
147
+ }
148
+
129
149
  override resolveDocument(
130
150
  base: string | null,
131
151
  ref: string,
@@ -143,16 +163,43 @@ export class RefAccessResolver extends BaseResolver {
143
163
  return super.resolveDocument(base, ref, isRoot);
144
164
  }
145
165
 
146
- /** Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). */
166
+ /**
167
+ * Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). A document a
168
+ * `$ref` loads has its own `components.schemas`, so its mapping names point at those schemas
169
+ * before Redocly resolves them, as the root's do (`pointMappingNamesAtSchemas`).
170
+ */
147
171
  override parseDocument(source: Source, isRoot = false): Document {
148
- const document = super.parseDocument(source, isRoot);
172
+ const document = this.#parsed(source, isRoot);
149
173
  const failure = aliasExpansionFailure(document.parsed);
150
174
  if (failure !== undefined) {
151
175
  throw new YamlParseError(failure, source);
152
176
  }
177
+ pointMappingNamesAtSchemas(document.parsed);
153
178
  return document;
154
179
  }
155
180
 
181
+ /**
182
+ * A remote document is parsed within the node limit; a local one as Redocly parses it. Whether
183
+ * a remote one is parsed at all is decided here (`isParsedSource`), since Redocly read the
184
+ * extension of a URL with its query.
185
+ */
186
+ #parsed(source: Source, isRoot: boolean): Document {
187
+ if (!isRemoteRef(source.absoluteRef)) {
188
+ return super.parseDocument(source, isRoot);
189
+ }
190
+ if (!isParsedSource(source, isRoot)) {
191
+ return { source, parsed: source.body };
192
+ }
193
+ try {
194
+ return this.#nodeLimit.parse(source);
195
+ } catch (error) {
196
+ if (isRefusal(error)) {
197
+ this.#refusals.push(error);
198
+ }
199
+ throw new YamlParseError(error as Error, source);
200
+ }
201
+ }
202
+
156
203
  override async loadExternalRef(absoluteRef: string): Promise<Source> {
157
204
  const refusal = this.#countRefusal(absoluteRef) ?? (await this.#accessRefusal(absoluteRef));
158
205
  if (refusal !== undefined) {
@@ -1,4 +1,4 @@
1
- import { escapePointerSegment } from "../../domain/openapi/json-pointer.js";
1
+ import { childPointer, ROOT_POINTER } from "../../domain/openapi/json-pointer.js";
2
2
 
3
3
  /** An object with a string `$ref`, and its JSON Pointer in the document. */
4
4
  export interface RefHolder {
@@ -6,38 +6,99 @@ export interface RefHolder {
6
6
  readonly pointer: string;
7
7
  }
8
8
 
9
+ /**
10
+ * Keywords whose value is data, not OpenAPI: a `$ref` or a `discriminator` in an example, a
11
+ * default, a `const` or an `enum` value, or an extension is part of the data and stays as written.
12
+ */
13
+ const DATA_KEYWORDS = new Set(["example", "examples", "default", "const", "enum"]);
14
+ const EXTENSION_PREFIX = "x-";
15
+
16
+ /**
17
+ * Keywords whose value maps names to objects: a property, a schema or a response may be named
18
+ * `default` or `example`, and is OpenAPI all the same.
19
+ */
20
+ const NAME_MAPS = new Set([
21
+ "properties",
22
+ "patternProperties",
23
+ "dependentSchemas",
24
+ "$defs",
25
+ "definitions",
26
+ "schemas",
27
+ "responses",
28
+ "parameters",
29
+ "requestBodies",
30
+ "headers",
31
+ "securitySchemes",
32
+ "links",
33
+ "callbacks",
34
+ "pathItems",
35
+ "mediaTypes",
36
+ "content",
37
+ "encoding",
38
+ "paths",
39
+ "webhooks",
40
+ ]);
41
+
9
42
  interface PendingNode {
10
43
  readonly value: object;
11
44
  readonly pointer: string;
45
+ /** Whether the keys of `value` are names (of properties, schemas, responses), not keywords. */
46
+ readonly hasNameKeys: boolean;
12
47
  }
13
48
 
14
- function hasStringRef(value: object): value is { $ref: string } {
15
- return !Array.isArray(value) && typeof (value as { $ref?: unknown }).$ref === "string";
49
+ function isDataKey(key: string): boolean {
50
+ return DATA_KEYWORDS.has(key) || key.startsWith(EXTENSION_PREFIX);
16
51
  }
17
52
 
18
53
  /**
19
- * Every object with a string `$ref` in a parsed document, in no particular order. The walk uses
20
- * its own stack, so a deeply nested document does not run out of call stack, and a node shared by
21
- * YAML aliases (or a cycle of them) is visited once.
54
+ * Every object of a parsed document that is OpenAPI, not data (`DATA_KEYWORDS`), with its JSON
55
+ * Pointer, in no particular order. The walk uses its own stack, so a deeply nested document does
56
+ * not run out of call stack, and a node shared by YAML aliases (or a cycle of them) is visited
57
+ * once.
22
58
  */
23
- export function findRefHolders(document: unknown): RefHolder[] {
24
- const found: RefHolder[] = [];
59
+ function openApiNodes(document: unknown): PendingNode[] {
60
+ const found: PendingNode[] = [];
25
61
  const visited = new WeakSet<object>();
26
62
  const pending: PendingNode[] = [];
27
- const enqueue = (value: unknown, pointer: string): void => {
63
+ const enqueue = (value: unknown, pointer: string, hasNameKeys: boolean): void => {
28
64
  if (typeof value === "object" && value !== null && !visited.has(value)) {
29
65
  visited.add(value);
30
- pending.push({ value, pointer });
66
+ pending.push({ value, pointer, hasNameKeys });
31
67
  }
32
68
  };
33
- enqueue(document, "#");
69
+ enqueue(document, ROOT_POINTER, false);
34
70
  for (let next = pending.pop(); next !== undefined; next = pending.pop()) {
35
- if (hasStringRef(next.value)) {
36
- found.push({ node: next.value, pointer: next.pointer });
37
- }
71
+ found.push(next);
72
+ // One push per child: spreading an array of millions of children overflows the stack.
38
73
  for (const [key, child] of Object.entries(next.value)) {
39
- enqueue(child, `${next.pointer}/${escapePointerSegment(key)}`);
74
+ if (next.hasNameKeys || !isDataKey(key)) {
75
+ enqueue(child, childPointer(next.pointer, key), !next.hasNameKeys && NAME_MAPS.has(key));
76
+ }
40
77
  }
41
78
  }
42
79
  return found;
43
80
  }
81
+
82
+ function hasStringRef(value: object): value is { $ref: string } {
83
+ return !Array.isArray(value) && typeof (value as { $ref?: unknown }).$ref === "string";
84
+ }
85
+
86
+ /** Every object with a string `$ref` in a parsed document, outside data, in no particular order. */
87
+ export function findRefHolders(document: unknown): RefHolder[] {
88
+ return openApiNodes(document).flatMap(({ value, pointer, hasNameKeys }) =>
89
+ !hasNameKeys && hasStringRef(value) ? [{ node: value, pointer }] : [],
90
+ );
91
+ }
92
+
93
+ function isMapping(value: unknown): value is Record<string, unknown> {
94
+ return typeof value === "object" && value !== null && !Array.isArray(value);
95
+ }
96
+
97
+ /** Every `discriminator.mapping` object of a parsed document, outside data. */
98
+ export function findMappings(document: unknown): Record<string, unknown>[] {
99
+ return openApiNodes(document).flatMap(({ value, hasNameKeys }) => {
100
+ const { discriminator } = value as { discriminator?: unknown };
101
+ const mapping = !hasNameKeys && isMapping(discriminator) ? discriminator.mapping : undefined;
102
+ return isMapping(mapping) ? [mapping] : [];
103
+ });
104
+ }