openapi-typesafe 0.0.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (863) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +71 -1
  3. package/bin/cli.js +4 -0
  4. package/dist/adapters/node-file-system/node-file-system.cjs +46 -0
  5. package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -0
  6. package/dist/adapters/node-file-system/node-file-system.mjs +40 -0
  7. package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -0
  8. package/dist/adapters/redocly-loader/alias-limit.cjs +16 -0
  9. package/dist/adapters/redocly-loader/alias-limit.cjs.map +1 -0
  10. package/dist/adapters/redocly-loader/alias-limit.mjs +14 -0
  11. package/dist/adapters/redocly-loader/alias-limit.mjs.map +1 -0
  12. package/dist/adapters/redocly-loader/allowed-hosts.cjs +42 -0
  13. package/dist/adapters/redocly-loader/allowed-hosts.cjs.map +1 -0
  14. package/dist/adapters/redocly-loader/allowed-hosts.mjs +40 -0
  15. package/dist/adapters/redocly-loader/allowed-hosts.mjs.map +1 -0
  16. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +53 -0
  17. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -0
  18. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +51 -0
  19. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -0
  20. package/dist/adapters/redocly-loader/malformed-refs.cjs +41 -0
  21. package/dist/adapters/redocly-loader/malformed-refs.cjs.map +1 -0
  22. package/dist/adapters/redocly-loader/malformed-refs.mjs +38 -0
  23. package/dist/adapters/redocly-loader/malformed-refs.mjs.map +1 -0
  24. package/dist/adapters/redocly-loader/redocly-config-source.cjs +61 -0
  25. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -0
  26. package/dist/adapters/redocly-loader/redocly-config-source.mjs +54 -0
  27. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -0
  28. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +179 -0
  29. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -0
  30. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +177 -0
  31. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -0
  32. package/dist/adapters/redocly-loader/ref-access.cjs +107 -0
  33. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -0
  34. package/dist/adapters/redocly-loader/ref-access.mjs +99 -0
  35. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -0
  36. package/dist/adapters/redocly-loader/ref-holders.cjs +31 -0
  37. package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -0
  38. package/dist/adapters/redocly-loader/ref-holders.mjs +29 -0
  39. package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -0
  40. package/dist/adapters/redocly-loader/remote-fetch.cjs +60 -0
  41. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -0
  42. package/dist/adapters/redocly-loader/remote-fetch.mjs +56 -0
  43. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -0
  44. package/dist/adapters/redocly-loader/schema-load-errors.cjs +87 -0
  45. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -0
  46. package/dist/adapters/redocly-loader/schema-load-errors.mjs +77 -0
  47. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -0
  48. package/dist/adapters/redocly-loader/schema-source.cjs +104 -0
  49. package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -0
  50. package/dist/adapters/redocly-loader/schema-source.mjs +98 -0
  51. package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -0
  52. package/dist/adapters/redocly-loader/unsupported-keys.cjs +62 -0
  53. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -0
  54. package/dist/adapters/redocly-loader/unsupported-keys.mjs +58 -0
  55. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -0
  56. package/dist/adapters/terminal-logger/terminal-logger.cjs +67 -0
  57. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -0
  58. package/dist/adapters/terminal-logger/terminal-logger.mjs +59 -0
  59. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -0
  60. package/dist/adapters/type-ast-bridge/footer-nodes.cjs +21 -0
  61. package/dist/adapters/type-ast-bridge/footer-nodes.cjs.map +1 -0
  62. package/dist/adapters/type-ast-bridge/footer-nodes.mjs +17 -0
  63. package/dist/adapters/type-ast-bridge/footer-nodes.mjs.map +1 -0
  64. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.cjs +75 -0
  65. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.cjs.map +1 -0
  66. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.mjs +71 -0
  67. package/dist/adapters/type-ast-bridge/ir-declarations-to-typescript.mjs.map +1 -0
  68. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +148 -0
  69. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -0
  70. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +142 -0
  71. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -0
  72. package/dist/adapters/type-ast-bridge/lazy-node.cjs +23 -0
  73. package/dist/adapters/type-ast-bridge/lazy-node.cjs.map +1 -0
  74. package/dist/adapters/type-ast-bridge/lazy-node.mjs +21 -0
  75. package/dist/adapters/type-ast-bridge/lazy-node.mjs.map +1 -0
  76. package/dist/adapters/type-ast-bridge/load-typescript.cjs +57 -0
  77. package/dist/adapters/type-ast-bridge/load-typescript.cjs.map +1 -0
  78. package/dist/adapters/type-ast-bridge/load-typescript.mjs +51 -0
  79. package/dist/adapters/type-ast-bridge/load-typescript.mjs.map +1 -0
  80. package/dist/adapters/type-ast-bridge/print-typescript.cjs +21 -0
  81. package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -0
  82. package/dist/adapters/type-ast-bridge/print-typescript.mjs +19 -0
  83. package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -0
  84. package/dist/adapters/type-ast-bridge/typescript-raw-text.cjs +33 -0
  85. package/dist/adapters/type-ast-bridge/typescript-raw-text.cjs.map +1 -0
  86. package/dist/adapters/type-ast-bridge/typescript-raw-text.mjs +29 -0
  87. package/dist/adapters/type-ast-bridge/typescript-raw-text.mjs.map +1 -0
  88. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +210 -0
  89. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -0
  90. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +207 -0
  91. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -0
  92. package/dist/api/ast-to-string.cjs +39 -0
  93. package/dist/api/ast-to-string.cjs.map +1 -0
  94. package/dist/api/ast-to-string.mjs +37 -0
  95. package/dist/api/ast-to-string.mjs.map +1 -0
  96. package/dist/api/comment-header.cjs +11 -0
  97. package/dist/api/comment-header.cjs.map +1 -0
  98. package/dist/api/comment-header.mjs +9 -0
  99. package/dist/api/comment-header.mjs.map +1 -0
  100. package/dist/api/default-ports.cjs +38 -0
  101. package/dist/api/default-ports.cjs.map +1 -0
  102. package/dist/api/default-ports.mjs +28 -0
  103. package/dist/api/default-ports.mjs.map +1 -0
  104. package/dist/api/discriminator-conflict-warnings.cjs +25 -0
  105. package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
  106. package/dist/api/discriminator-conflict-warnings.mjs +23 -0
  107. package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
  108. package/dist/api/discriminator-enum-names.cjs +19 -0
  109. package/dist/api/discriminator-enum-names.cjs.map +1 -0
  110. package/dist/api/discriminator-enum-names.mjs +17 -0
  111. package/dist/api/discriminator-enum-names.mjs.map +1 -0
  112. package/dist/api/discriminator-enum-parent.cjs +59 -0
  113. package/dist/api/discriminator-enum-parent.cjs.map +1 -0
  114. package/dist/api/discriminator-enum-parent.mjs +57 -0
  115. package/dist/api/discriminator-enum-parent.mjs.map +1 -0
  116. package/dist/api/discriminator-enum.cjs +69 -0
  117. package/dist/api/discriminator-enum.cjs.map +1 -0
  118. package/dist/api/discriminator-enum.mjs +66 -0
  119. package/dist/api/discriminator-enum.mjs.map +1 -0
  120. package/dist/api/discriminator-other-owners.cjs +67 -0
  121. package/dist/api/discriminator-other-owners.cjs.map +1 -0
  122. package/dist/api/discriminator-other-owners.mjs +64 -0
  123. package/dist/api/discriminator-other-owners.mjs.map +1 -0
  124. package/dist/api/discriminator-patch.cjs +88 -0
  125. package/dist/api/discriminator-patch.cjs.map +1 -0
  126. package/dist/api/discriminator-patch.mjs +82 -0
  127. package/dist/api/discriminator-patch.mjs.map +1 -0
  128. package/dist/api/discriminator-scan.cjs +153 -0
  129. package/dist/api/discriminator-scan.cjs.map +1 -0
  130. package/dist/api/discriminator-scan.mjs +150 -0
  131. package/dist/api/discriminator-scan.mjs.map +1 -0
  132. package/dist/api/document-declarations.cjs +28 -0
  133. package/dist/api/document-declarations.cjs.map +1 -0
  134. package/dist/api/document-declarations.mjs +26 -0
  135. package/dist/api/document-declarations.mjs.map +1 -0
  136. package/dist/api/document-refs.cjs +53 -0
  137. package/dist/api/document-refs.cjs.map +1 -0
  138. package/dist/api/document-refs.mjs +50 -0
  139. package/dist/api/document-refs.mjs.map +1 -0
  140. package/dist/api/document-run.cjs +122 -0
  141. package/dist/api/document-run.cjs.map +1 -0
  142. package/dist/api/document-run.mjs +116 -0
  143. package/dist/api/document-run.mjs.map +1 -0
  144. package/dist/api/enum-values-warnings.cjs +16 -0
  145. package/dist/api/enum-values-warnings.cjs.map +1 -0
  146. package/dist/api/enum-values-warnings.mjs +14 -0
  147. package/dist/api/enum-values-warnings.mjs.map +1 -0
  148. package/dist/api/footer-entry.cjs +18 -0
  149. package/dist/api/footer-entry.cjs.map +1 -0
  150. package/dist/api/footer-entry.mjs +15 -0
  151. package/dist/api/footer-entry.mjs.map +1 -0
  152. package/dist/api/footer-sink.cjs +53 -0
  153. package/dist/api/footer-sink.cjs.map +1 -0
  154. package/dist/api/footer-sink.mjs +51 -0
  155. package/dist/api/footer-sink.mjs.map +1 -0
  156. package/dist/api/legacy-callback-warning.cjs +25 -0
  157. package/dist/api/legacy-callback-warning.cjs.map +1 -0
  158. package/dist/api/legacy-callback-warning.mjs +22 -0
  159. package/dist/api/legacy-callback-warning.mjs.map +1 -0
  160. package/dist/api/legacy-ts-helpers.cjs +203 -0
  161. package/dist/api/legacy-ts-helpers.cjs.map +1 -0
  162. package/dist/api/legacy-ts-helpers.mjs +187 -0
  163. package/dist/api/legacy-ts-helpers.mjs.map +1 -0
  164. package/dist/api/legacy-utils.cjs +65 -0
  165. package/dist/api/legacy-utils.cjs.map +1 -0
  166. package/dist/api/legacy-utils.mjs +50 -0
  167. package/dist/api/legacy-utils.mjs.map +1 -0
  168. package/dist/api/openapi-ts.cjs +40 -0
  169. package/dist/api/openapi-ts.cjs.map +1 -0
  170. package/dist/api/openapi-ts.mjs +34 -0
  171. package/dist/api/openapi-ts.mjs.map +1 -0
  172. package/dist/api/path-template-warnings.cjs +21 -0
  173. package/dist/api/path-template-warnings.cjs.map +1 -0
  174. package/dist/api/path-template-warnings.mjs +19 -0
  175. package/dist/api/path-template-warnings.mjs.map +1 -0
  176. package/dist/api/schema-callbacks.cjs +140 -0
  177. package/dist/api/schema-callbacks.cjs.map +1 -0
  178. package/dist/api/schema-callbacks.mjs +136 -0
  179. package/dist/api/schema-callbacks.mjs.map +1 -0
  180. package/dist/api/string-to-ast.cjs +21 -0
  181. package/dist/api/string-to-ast.cjs.map +1 -0
  182. package/dist/api/string-to-ast.mjs +18 -0
  183. package/dist/api/string-to-ast.mjs.map +1 -0
  184. package/dist/api/transform-context.cjs +84 -0
  185. package/dist/api/transform-context.cjs.map +1 -0
  186. package/dist/api/transform-context.mjs +67 -0
  187. package/dist/api/transform-context.mjs.map +1 -0
  188. package/dist/api/transform-schema.cjs +80 -0
  189. package/dist/api/transform-schema.cjs.map +1 -0
  190. package/dist/api/transform-schema.mjs +75 -0
  191. package/dist/api/transform-schema.mjs.map +1 -0
  192. package/dist/api/type-helpers.cjs +85 -0
  193. package/dist/api/type-helpers.cjs.map +1 -0
  194. package/dist/api/type-helpers.mjs +66 -0
  195. package/dist/api/type-helpers.mjs.map +1 -0
  196. package/dist/api/unsupported-feature-warnings.cjs +22 -0
  197. package/dist/api/unsupported-feature-warnings.cjs.map +1 -0
  198. package/dist/api/unsupported-feature-warnings.mjs +20 -0
  199. package/dist/api/unsupported-feature-warnings.mjs.map +1 -0
  200. package/dist/application/print/comment-writer.cjs +95 -0
  201. package/dist/application/print/comment-writer.cjs.map +1 -0
  202. package/dist/application/print/comment-writer.mjs +93 -0
  203. package/dist/application/print/comment-writer.mjs.map +1 -0
  204. package/dist/application/print/declaration-printer.cjs +83 -0
  205. package/dist/application/print/declaration-printer.cjs.map +1 -0
  206. package/dist/application/print/declaration-printer.mjs +81 -0
  207. package/dist/application/print/declaration-printer.mjs.map +1 -0
  208. package/dist/application/print/literal-text.cjs +52 -0
  209. package/dist/application/print/literal-text.cjs.map +1 -0
  210. package/dist/application/print/literal-text.mjs +48 -0
  211. package/dist/application/print/literal-text.mjs.map +1 -0
  212. package/dist/application/print/print-nodes.cjs +38 -0
  213. package/dist/application/print/print-nodes.cjs.map +1 -0
  214. package/dist/application/print/print-nodes.mjs +36 -0
  215. package/dist/application/print/print-nodes.mjs.map +1 -0
  216. package/dist/application/print/print-options.cjs +6 -0
  217. package/dist/application/print/print-options.cjs.map +1 -0
  218. package/dist/application/print/print-options.mjs +4 -0
  219. package/dist/application/print/print-options.mjs.map +1 -0
  220. package/dist/application/print/text-writer.cjs +63 -0
  221. package/dist/application/print/text-writer.cjs.map +1 -0
  222. package/dist/application/print/text-writer.mjs +60 -0
  223. package/dist/application/print/text-writer.mjs.map +1 -0
  224. package/dist/application/print/type-printer.cjs +219 -0
  225. package/dist/application/print/type-printer.cjs.map +1 -0
  226. package/dist/application/print/type-printer.mjs +215 -0
  227. package/dist/application/print/type-printer.mjs.map +1 -0
  228. package/dist/application/stack-overflow.cjs +36 -0
  229. package/dist/application/stack-overflow.cjs.map +1 -0
  230. package/dist/application/stack-overflow.mjs +31 -0
  231. package/dist/application/stack-overflow.mjs.map +1 -0
  232. package/dist/application/transform/document/assignability.cjs +144 -0
  233. package/dist/application/transform/document/assignability.cjs.map +1 -0
  234. package/dist/application/transform/document/assignability.mjs +138 -0
  235. package/dist/application/transform/document/assignability.mjs.map +1 -0
  236. package/dist/application/transform/document/components.cjs +104 -0
  237. package/dist/application/transform/document/components.cjs.map +1 -0
  238. package/dist/application/transform/document/components.mjs +102 -0
  239. package/dist/application/transform/document/components.mjs.map +1 -0
  240. package/dist/application/transform/document/declared-types.cjs +66 -0
  241. package/dist/application/transform/document/declared-types.cjs.map +1 -0
  242. package/dist/application/transform/document/declared-types.mjs +63 -0
  243. package/dist/application/transform/document/declared-types.mjs.map +1 -0
  244. package/dist/application/transform/document/defs-root.cjs +18 -0
  245. package/dist/application/transform/document/defs-root.cjs.map +1 -0
  246. package/dist/application/transform/document/defs-root.mjs +16 -0
  247. package/dist/application/transform/document/defs-root.mjs.map +1 -0
  248. package/dist/application/transform/document/document-member.cjs +13 -0
  249. package/dist/application/transform/document/document-member.cjs.map +1 -0
  250. package/dist/application/transform/document/document-member.mjs +11 -0
  251. package/dist/application/transform/document/document-member.mjs.map +1 -0
  252. package/dist/application/transform/document/document.cjs +109 -0
  253. package/dist/application/transform/document/document.cjs.map +1 -0
  254. package/dist/application/transform/document/document.mjs +106 -0
  255. package/dist/application/transform/document/document.mjs.map +1 -0
  256. package/dist/application/transform/document/exploded-query.cjs +46 -0
  257. package/dist/application/transform/document/exploded-query.cjs.map +1 -0
  258. package/dist/application/transform/document/exploded-query.mjs +43 -0
  259. package/dist/application/transform/document/exploded-query.mjs.map +1 -0
  260. package/dist/application/transform/document/global-type-references.cjs +63 -0
  261. package/dist/application/transform/document/global-type-references.cjs.map +1 -0
  262. package/dist/application/transform/document/global-type-references.mjs +61 -0
  263. package/dist/application/transform/document/global-type-references.mjs.map +1 -0
  264. package/dist/application/transform/document/header.cjs +27 -0
  265. package/dist/application/transform/document/header.cjs.map +1 -0
  266. package/dist/application/transform/document/header.mjs +25 -0
  267. package/dist/application/transform/document/header.mjs.map +1 -0
  268. package/dist/application/transform/document/kept-deprecated.cjs +96 -0
  269. package/dist/application/transform/document/kept-deprecated.cjs.map +1 -0
  270. package/dist/application/transform/document/kept-deprecated.mjs +94 -0
  271. package/dist/application/transform/document/kept-deprecated.mjs.map +1 -0
  272. package/dist/application/transform/document/list-assignability.cjs +54 -0
  273. package/dist/application/transform/document/list-assignability.cjs.map +1 -0
  274. package/dist/application/transform/document/list-assignability.mjs +52 -0
  275. package/dist/application/transform/document/list-assignability.mjs.map +1 -0
  276. package/dist/application/transform/document/media-type.cjs +42 -0
  277. package/dist/application/transform/document/media-type.cjs.map +1 -0
  278. package/dist/application/transform/document/media-type.mjs +38 -0
  279. package/dist/application/transform/document/media-type.mjs.map +1 -0
  280. package/dist/application/transform/document/operation.cjs +45 -0
  281. package/dist/application/transform/document/operation.cjs.map +1 -0
  282. package/dist/application/transform/document/operation.mjs +43 -0
  283. package/dist/application/transform/document/operation.mjs.map +1 -0
  284. package/dist/application/transform/document/parameter.cjs +25 -0
  285. package/dist/application/transform/document/parameter.cjs.map +1 -0
  286. package/dist/application/transform/document/parameter.mjs +23 -0
  287. package/dist/application/transform/document/parameter.mjs.map +1 -0
  288. package/dist/application/transform/document/parameters.cjs +146 -0
  289. package/dist/application/transform/document/parameters.cjs.map +1 -0
  290. package/dist/application/transform/document/parameters.mjs +144 -0
  291. package/dist/application/transform/document/parameters.mjs.map +1 -0
  292. package/dist/application/transform/document/path-item.cjs +82 -0
  293. package/dist/application/transform/document/path-item.cjs.map +1 -0
  294. package/dist/application/transform/document/path-item.mjs +80 -0
  295. package/dist/application/transform/document/path-item.mjs.map +1 -0
  296. package/dist/application/transform/document/path-key-overlaps.cjs +107 -0
  297. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -0
  298. package/dist/application/transform/document/path-key-overlaps.mjs +105 -0
  299. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -0
  300. package/dist/application/transform/document/path-template-replace.cjs +48 -0
  301. package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
  302. package/dist/application/transform/document/path-template-replace.mjs +45 -0
  303. package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
  304. package/dist/application/transform/document/paths-enum.cjs +75 -0
  305. package/dist/application/transform/document/paths-enum.cjs.map +1 -0
  306. package/dist/application/transform/document/paths-enum.mjs +72 -0
  307. package/dist/application/transform/document/paths-enum.mjs.map +1 -0
  308. package/dist/application/transform/document/paths.cjs +153 -0
  309. package/dist/application/transform/document/paths.cjs.map +1 -0
  310. package/dist/application/transform/document/paths.mjs +149 -0
  311. package/dist/application/transform/document/paths.mjs.map +1 -0
  312. package/dist/application/transform/document/request-body.cjs +36 -0
  313. package/dist/application/transform/document/request-body.cjs.map +1 -0
  314. package/dist/application/transform/document/request-body.mjs +34 -0
  315. package/dist/application/transform/document/request-body.mjs.map +1 -0
  316. package/dist/application/transform/document/response.cjs +59 -0
  317. package/dist/application/transform/document/response.cjs.map +1 -0
  318. package/dist/application/transform/document/response.mjs +57 -0
  319. package/dist/application/transform/document/response.mjs.map +1 -0
  320. package/dist/application/transform/document/responses.cjs +23 -0
  321. package/dist/application/transform/document/responses.cjs.map +1 -0
  322. package/dist/application/transform/document/responses.mjs +21 -0
  323. package/dist/application/transform/document/responses.mjs.map +1 -0
  324. package/dist/application/transform/document/root-type-aliases.cjs +70 -0
  325. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -0
  326. package/dist/application/transform/document/root-type-aliases.mjs +67 -0
  327. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -0
  328. package/dist/application/transform/document/template-key-match.cjs +128 -0
  329. package/dist/application/transform/document/template-key-match.cjs.map +1 -0
  330. package/dist/application/transform/document/template-key-match.mjs +125 -0
  331. package/dist/application/transform/document/template-key-match.mjs.map +1 -0
  332. package/dist/application/transform/document/type-assignability.cjs +192 -0
  333. package/dist/application/transform/document/type-assignability.cjs.map +1 -0
  334. package/dist/application/transform/document/type-assignability.mjs +190 -0
  335. package/dist/application/transform/document/type-assignability.mjs.map +1 -0
  336. package/dist/application/transform/document/type-key.cjs +70 -0
  337. package/dist/application/transform/document/type-key.cjs.map +1 -0
  338. package/dist/application/transform/document/type-key.mjs +68 -0
  339. package/dist/application/transform/document/type-key.mjs.map +1 -0
  340. package/dist/application/transform/document/type-resolution.cjs +131 -0
  341. package/dist/application/transform/document/type-resolution.cjs.map +1 -0
  342. package/dist/application/transform/document/type-resolution.mjs +125 -0
  343. package/dist/application/transform/document/type-resolution.mjs.map +1 -0
  344. package/dist/application/transform/document/webhooks.cjs +19 -0
  345. package/dist/application/transform/document/webhooks.cjs.map +1 -0
  346. package/dist/application/transform/document/webhooks.mjs +17 -0
  347. package/dist/application/transform/document/webhooks.mjs.map +1 -0
  348. package/dist/application/transform/document-entries.cjs +17 -0
  349. package/dist/application/transform/document-entries.cjs.map +1 -0
  350. package/dist/application/transform/document-entries.mjs +14 -0
  351. package/dist/application/transform/document-entries.mjs.map +1 -0
  352. package/dist/application/transform/footer/document-footer.cjs +150 -0
  353. package/dist/application/transform/footer/document-footer.cjs.map +1 -0
  354. package/dist/application/transform/footer/document-footer.mjs +148 -0
  355. package/dist/application/transform/footer/document-footer.mjs.map +1 -0
  356. package/dist/application/transform/footer/enum-naming.cjs +138 -0
  357. package/dist/application/transform/footer/enum-naming.cjs.map +1 -0
  358. package/dist/application/transform/footer/enum-naming.mjs +131 -0
  359. package/dist/application/transform/footer/enum-naming.mjs.map +1 -0
  360. package/dist/application/transform/footer/enum-values-check.cjs +129 -0
  361. package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
  362. package/dist/application/transform/footer/enum-values-check.mjs +127 -0
  363. package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
  364. package/dist/application/transform/footer/evaluation.cjs +33 -0
  365. package/dist/application/transform/footer/evaluation.cjs.map +1 -0
  366. package/dist/application/transform/footer/evaluation.mjs +26 -0
  367. package/dist/application/transform/footer/evaluation.mjs.map +1 -0
  368. package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
  369. package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
  370. package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
  371. package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
  372. package/dist/application/transform/footer/type-evaluation.cjs +246 -0
  373. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
  374. package/dist/application/transform/footer/type-evaluation.mjs +244 -0
  375. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
  376. package/dist/application/transform/footer/type-rules.cjs +172 -0
  377. package/dist/application/transform/footer/type-rules.cjs.map +1 -0
  378. package/dist/application/transform/footer/type-rules.mjs +166 -0
  379. package/dist/application/transform/footer/type-rules.mjs.map +1 -0
  380. package/dist/application/transform/helper-types.cjs +68 -0
  381. package/dist/application/transform/helper-types.cjs.map +1 -0
  382. package/dist/application/transform/helper-types.mjs +65 -0
  383. package/dist/application/transform/helper-types.mjs.map +1 -0
  384. package/dist/application/transform/literal-type.cjs +36 -0
  385. package/dist/application/transform/literal-type.cjs.map +1 -0
  386. package/dist/application/transform/literal-type.mjs +34 -0
  387. package/dist/application/transform/literal-type.mjs.map +1 -0
  388. package/dist/application/transform/numbered-names.cjs +18 -0
  389. package/dist/application/transform/numbered-names.cjs.map +1 -0
  390. package/dist/application/transform/numbered-names.mjs +16 -0
  391. package/dist/application/transform/numbered-names.mjs.map +1 -0
  392. package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
  393. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
  394. package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
  395. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
  396. package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
  397. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
  398. package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
  399. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
  400. package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
  401. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
  402. package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
  403. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
  404. package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
  405. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
  406. package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
  407. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
  408. package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
  409. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
  410. package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
  411. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
  412. package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
  413. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
  414. package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
  415. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
  416. package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
  417. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
  418. package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
  419. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
  420. package/dist/application/transform/ref-type.cjs +62 -0
  421. package/dist/application/transform/ref-type.cjs.map +1 -0
  422. package/dist/application/transform/ref-type.mjs +55 -0
  423. package/dist/application/transform/ref-type.mjs.map +1 -0
  424. package/dist/application/transform/schema/access-flags.cjs +38 -0
  425. package/dist/application/transform/schema/access-flags.cjs.map +1 -0
  426. package/dist/application/transform/schema/access-flags.mjs +36 -0
  427. package/dist/application/transform/schema/access-flags.mjs.map +1 -0
  428. package/dist/application/transform/schema/array-type.cjs +136 -0
  429. package/dist/application/transform/schema/array-type.cjs.map +1 -0
  430. package/dist/application/transform/schema/array-type.mjs +134 -0
  431. package/dist/application/transform/schema/array-type.mjs.map +1 -0
  432. package/dist/application/transform/schema/composition-type.cjs +142 -0
  433. package/dist/application/transform/schema/composition-type.cjs.map +1 -0
  434. package/dist/application/transform/schema/composition-type.mjs +140 -0
  435. package/dist/application/transform/schema/composition-type.mjs.map +1 -0
  436. package/dist/application/transform/schema/core-type.cjs +86 -0
  437. package/dist/application/transform/schema/core-type.cjs.map +1 -0
  438. package/dist/application/transform/schema/core-type.mjs +84 -0
  439. package/dist/application/transform/schema/core-type.mjs.map +1 -0
  440. package/dist/application/transform/schema/discriminated-union.cjs +30 -0
  441. package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
  442. package/dist/application/transform/schema/discriminated-union.mjs +27 -0
  443. package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
  444. package/dist/application/transform/schema/discriminator-property.cjs +22 -0
  445. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -0
  446. package/dist/application/transform/schema/discriminator-property.mjs +20 -0
  447. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -0
  448. package/dist/application/transform/schema/enum-rule.cjs +163 -0
  449. package/dist/application/transform/schema/enum-rule.cjs.map +1 -0
  450. package/dist/application/transform/schema/enum-rule.mjs +160 -0
  451. package/dist/application/transform/schema/enum-rule.mjs.map +1 -0
  452. package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
  453. package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
  454. package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
  455. package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
  456. package/dist/application/transform/schema/object-type.cjs +186 -0
  457. package/dist/application/transform/schema/object-type.cjs.map +1 -0
  458. package/dist/application/transform/schema/object-type.mjs +182 -0
  459. package/dist/application/transform/schema/object-type.mjs.map +1 -0
  460. package/dist/application/transform/schema/presence-members.cjs +59 -0
  461. package/dist/application/transform/schema/presence-members.cjs.map +1 -0
  462. package/dist/application/transform/schema/presence-members.mjs +57 -0
  463. package/dist/application/transform/schema/presence-members.mjs.map +1 -0
  464. package/dist/application/transform/schema/required-variants.cjs +45 -0
  465. package/dist/application/transform/schema/required-variants.cjs.map +1 -0
  466. package/dist/application/transform/schema/required-variants.mjs +42 -0
  467. package/dist/application/transform/schema/required-variants.mjs.map +1 -0
  468. package/dist/application/transform/schema/schema-transform.cjs +72 -0
  469. package/dist/application/transform/schema/schema-transform.cjs.map +1 -0
  470. package/dist/application/transform/schema/schema-transform.mjs +68 -0
  471. package/dist/application/transform/schema/schema-transform.mjs.map +1 -0
  472. package/dist/application/transform/schema/unevaluated-properties.cjs +61 -0
  473. package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -0
  474. package/dist/application/transform/schema/unevaluated-properties.mjs +59 -0
  475. package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -0
  476. package/dist/application/transform/schema-comment.cjs +130 -0
  477. package/dist/application/transform/schema-comment.cjs.map +1 -0
  478. package/dist/application/transform/schema-comment.mjs +125 -0
  479. package/dist/application/transform/schema-comment.mjs.map +1 -0
  480. package/dist/application/transform/shared-types.cjs +8 -0
  481. package/dist/application/transform/shared-types.cjs.map +1 -0
  482. package/dist/application/transform/shared-types.mjs +6 -0
  483. package/dist/application/transform/shared-types.mjs.map +1 -0
  484. package/dist/application/transform/type-combinators.cjs +49 -0
  485. package/dist/application/transform/type-combinators.cjs.map +1 -0
  486. package/dist/application/transform/type-combinators.mjs +42 -0
  487. package/dist/application/transform/type-combinators.mjs.map +1 -0
  488. package/dist/cli/cli-arguments.cjs +145 -0
  489. package/dist/cli/cli-arguments.cjs.map +1 -0
  490. package/dist/cli/cli-arguments.mjs +137 -0
  491. package/dist/cli/cli-arguments.mjs.map +1 -0
  492. package/dist/cli/cli-errors.cjs +81 -0
  493. package/dist/cli/cli-errors.cjs.map +1 -0
  494. package/dist/cli/cli-errors.mjs +77 -0
  495. package/dist/cli/cli-errors.mjs.map +1 -0
  496. package/dist/cli/cli-output.cjs +42 -0
  497. package/dist/cli/cli-output.cjs.map +1 -0
  498. package/dist/cli/cli-output.mjs +35 -0
  499. package/dist/cli/cli-output.mjs.map +1 -0
  500. package/dist/cli/docs-links.cjs +6 -0
  501. package/dist/cli/docs-links.cjs.map +1 -0
  502. package/dist/cli/docs-links.mjs +4 -0
  503. package/dist/cli/docs-links.mjs.map +1 -0
  504. package/dist/cli/fix-option.cjs +19 -0
  505. package/dist/cli/fix-option.cjs.map +1 -0
  506. package/dist/cli/fix-option.mjs +16 -0
  507. package/dist/cli/fix-option.mjs.map +1 -0
  508. package/dist/cli/help-text.cjs +44 -0
  509. package/dist/cli/help-text.cjs.map +1 -0
  510. package/dist/cli/help-text.mjs +42 -0
  511. package/dist/cli/help-text.mjs.map +1 -0
  512. package/dist/cli/main.cjs +67 -0
  513. package/dist/cli/main.cjs.map +1 -0
  514. package/dist/cli/main.d.cts +2 -0
  515. package/dist/cli/main.d.mts +2 -0
  516. package/dist/cli/main.d.ts +2 -0
  517. package/dist/cli/main.mjs +59 -0
  518. package/dist/cli/main.mjs.map +1 -0
  519. package/dist/cli/redocly-apis.cjs +69 -0
  520. package/dist/cli/redocly-apis.cjs.map +1 -0
  521. package/dist/cli/redocly-apis.mjs +66 -0
  522. package/dist/cli/redocly-apis.mjs.map +1 -0
  523. package/dist/cli/ref-limits.cjs +14 -0
  524. package/dist/cli/ref-limits.cjs.map +1 -0
  525. package/dist/cli/ref-limits.mjs +12 -0
  526. package/dist/cli/ref-limits.mjs.map +1 -0
  527. package/dist/cli/run-cli.cjs +113 -0
  528. package/dist/cli/run-cli.cjs.map +1 -0
  529. package/dist/cli/run-cli.mjs +111 -0
  530. package/dist/cli/run-cli.mjs.map +1 -0
  531. package/dist/domain/assert-never.cjs +8 -0
  532. package/dist/domain/assert-never.cjs.map +1 -0
  533. package/dist/domain/assert-never.mjs +6 -0
  534. package/dist/domain/assert-never.mjs.map +1 -0
  535. package/dist/domain/errors.cjs +52 -0
  536. package/dist/domain/errors.cjs.map +1 -0
  537. package/dist/domain/errors.mjs +48 -0
  538. package/dist/domain/errors.mjs.map +1 -0
  539. package/dist/domain/ir/constructors.cjs +93 -0
  540. package/dist/domain/ir/constructors.cjs.map +1 -0
  541. package/dist/domain/ir/constructors.mjs +74 -0
  542. package/dist/domain/ir/constructors.mjs.map +1 -0
  543. package/dist/domain/ir/identifier-text.cjs +29 -0
  544. package/dist/domain/ir/identifier-text.cjs.map +1 -0
  545. package/dist/domain/ir/identifier-text.mjs +25 -0
  546. package/dist/domain/ir/identifier-text.mjs.map +1 -0
  547. package/dist/domain/ir/newer-identifier-ranges.cjs +109 -0
  548. package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -0
  549. package/dist/domain/ir/newer-identifier-ranges.mjs +106 -0
  550. package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -0
  551. package/dist/domain/ir/normalize.cjs +32 -0
  552. package/dist/domain/ir/normalize.cjs.map +1 -0
  553. package/dist/domain/ir/normalize.mjs +29 -0
  554. package/dist/domain/ir/normalize.mjs.map +1 -0
  555. package/dist/domain/ir/property-name.cjs +19 -0
  556. package/dist/domain/ir/property-name.cjs.map +1 -0
  557. package/dist/domain/ir/property-name.mjs +16 -0
  558. package/dist/domain/ir/property-name.mjs.map +1 -0
  559. package/dist/domain/ir/raw-text-escapes.cjs +25 -0
  560. package/dist/domain/ir/raw-text-escapes.cjs.map +1 -0
  561. package/dist/domain/ir/raw-text-escapes.mjs +22 -0
  562. package/dist/domain/ir/raw-text-escapes.mjs.map +1 -0
  563. package/dist/domain/openapi/admitted-values.cjs +75 -0
  564. package/dist/domain/openapi/admitted-values.cjs.map +1 -0
  565. package/dist/domain/openapi/admitted-values.mjs +72 -0
  566. package/dist/domain/openapi/admitted-values.mjs.map +1 -0
  567. package/dist/domain/openapi/alias-expansion.cjs +50 -0
  568. package/dist/domain/openapi/alias-expansion.cjs.map +1 -0
  569. package/dist/domain/openapi/alias-expansion.mjs +45 -0
  570. package/dist/domain/openapi/alias-expansion.mjs.map +1 -0
  571. package/dist/domain/openapi/binary-content.cjs +48 -0
  572. package/dist/domain/openapi/binary-content.cjs.map +1 -0
  573. package/dist/domain/openapi/binary-content.mjs +45 -0
  574. package/dist/domain/openapi/binary-content.mjs.map +1 -0
  575. package/dist/domain/openapi/components-object.cjs +29 -0
  576. package/dist/domain/openapi/components-object.cjs.map +1 -0
  577. package/dist/domain/openapi/components-object.mjs +24 -0
  578. package/dist/domain/openapi/components-object.mjs.map +1 -0
  579. package/dist/domain/openapi/discriminated-union.cjs +68 -0
  580. package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
  581. package/dist/domain/openapi/discriminated-union.mjs +62 -0
  582. package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
  583. package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
  584. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
  585. package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
  586. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
  587. package/dist/domain/openapi/json-pointer.cjs +31 -0
  588. package/dist/domain/openapi/json-pointer.cjs.map +1 -0
  589. package/dist/domain/openapi/json-pointer.mjs +27 -0
  590. package/dist/domain/openapi/json-pointer.mjs.map +1 -0
  591. package/dist/domain/openapi/media-type-object.cjs +14 -0
  592. package/dist/domain/openapi/media-type-object.cjs.map +1 -0
  593. package/dist/domain/openapi/media-type-object.mjs +11 -0
  594. package/dist/domain/openapi/media-type-object.mjs.map +1 -0
  595. package/dist/domain/openapi/parameter-object.cjs +13 -0
  596. package/dist/domain/openapi/parameter-object.cjs.map +1 -0
  597. package/dist/domain/openapi/parameter-object.mjs +10 -0
  598. package/dist/domain/openapi/parameter-object.mjs.map +1 -0
  599. package/dist/domain/openapi/path-item-object.cjs +35 -0
  600. package/dist/domain/openapi/path-item-object.cjs.map +1 -0
  601. package/dist/domain/openapi/path-item-object.mjs +30 -0
  602. package/dist/domain/openapi/path-item-object.mjs.map +1 -0
  603. package/dist/domain/openapi/path-templates.cjs +23 -0
  604. package/dist/domain/openapi/path-templates.cjs.map +1 -0
  605. package/dist/domain/openapi/path-templates.mjs +21 -0
  606. package/dist/domain/openapi/path-templates.mjs.map +1 -0
  607. package/dist/domain/openapi/unsupported-features.cjs +87 -0
  608. package/dist/domain/openapi/unsupported-features.cjs.map +1 -0
  609. package/dist/domain/openapi/unsupported-features.mjs +84 -0
  610. package/dist/domain/openapi/unsupported-features.mjs.map +1 -0
  611. package/dist/domain/output-fixes.cjs +101 -0
  612. package/dist/domain/output-fixes.cjs.map +1 -0
  613. package/dist/domain/output-fixes.mjs +94 -0
  614. package/dist/domain/output-fixes.mjs.map +1 -0
  615. package/dist/domain/warnings.cjs +15 -0
  616. package/dist/domain/warnings.cjs.map +1 -0
  617. package/dist/domain/warnings.mjs +12 -0
  618. package/dist/domain/warnings.mjs.map +1 -0
  619. package/dist/index.cjs +98 -0
  620. package/dist/index.cjs.map +1 -0
  621. package/dist/index.d.cts +841 -0
  622. package/dist/index.d.mts +841 -0
  623. package/dist/index.d.ts +841 -0
  624. package/dist/index.mjs +27 -0
  625. package/dist/index.mjs.map +1 -0
  626. package/dist/transform/components-object.cjs +15 -0
  627. package/dist/transform/components-object.cjs.map +1 -0
  628. package/dist/transform/components-object.mjs +11 -0
  629. package/dist/transform/components-object.mjs.map +1 -0
  630. package/dist/transform/header-object.cjs +12 -0
  631. package/dist/transform/header-object.cjs.map +1 -0
  632. package/dist/transform/header-object.mjs +10 -0
  633. package/dist/transform/header-object.mjs.map +1 -0
  634. package/dist/transform/media-type-object.cjs +12 -0
  635. package/dist/transform/media-type-object.cjs.map +1 -0
  636. package/dist/transform/media-type-object.mjs +10 -0
  637. package/dist/transform/media-type-object.mjs.map +1 -0
  638. package/dist/transform/operation-object.cjs +26 -0
  639. package/dist/transform/operation-object.cjs.map +1 -0
  640. package/dist/transform/operation-object.mjs +21 -0
  641. package/dist/transform/operation-object.mjs.map +1 -0
  642. package/dist/transform/parameter-object.cjs +12 -0
  643. package/dist/transform/parameter-object.cjs.map +1 -0
  644. package/dist/transform/parameter-object.mjs +10 -0
  645. package/dist/transform/parameter-object.mjs.map +1 -0
  646. package/dist/transform/path-item-object.cjs +12 -0
  647. package/dist/transform/path-item-object.cjs.map +1 -0
  648. package/dist/transform/path-item-object.mjs +10 -0
  649. package/dist/transform/path-item-object.mjs.map +1 -0
  650. package/dist/transform/paths-object.cjs +11 -0
  651. package/dist/transform/paths-object.cjs.map +1 -0
  652. package/dist/transform/paths-object.mjs +9 -0
  653. package/dist/transform/paths-object.mjs.map +1 -0
  654. package/dist/transform/request-body-object.cjs +12 -0
  655. package/dist/transform/request-body-object.cjs.map +1 -0
  656. package/dist/transform/request-body-object.mjs +10 -0
  657. package/dist/transform/request-body-object.mjs.map +1 -0
  658. package/dist/transform/response-object.cjs +12 -0
  659. package/dist/transform/response-object.cjs.map +1 -0
  660. package/dist/transform/response-object.mjs +10 -0
  661. package/dist/transform/response-object.mjs.map +1 -0
  662. package/dist/transform/responses-object.cjs +12 -0
  663. package/dist/transform/responses-object.cjs.map +1 -0
  664. package/dist/transform/responses-object.mjs +10 -0
  665. package/dist/transform/responses-object.mjs.map +1 -0
  666. package/dist/transform/schema-object.cjs +21 -0
  667. package/dist/transform/schema-object.cjs.map +1 -0
  668. package/dist/transform/schema-object.mjs +16 -0
  669. package/dist/transform/schema-object.mjs.map +1 -0
  670. package/package.json +115 -4
  671. package/src/adapters/node-file-system/node-file-system.ts +44 -0
  672. package/src/adapters/redocly-loader/alias-limit.ts +20 -0
  673. package/src/adapters/redocly-loader/allowed-hosts.ts +62 -0
  674. package/src/adapters/redocly-loader/bundled-ref-repair.ts +65 -0
  675. package/src/adapters/redocly-loader/malformed-refs.ts +61 -0
  676. package/src/adapters/redocly-loader/redocly-config-source.ts +78 -0
  677. package/src/adapters/redocly-loader/redocly-schema-loader.ts +262 -0
  678. package/src/adapters/redocly-loader/ref-access.ts +146 -0
  679. package/src/adapters/redocly-loader/ref-holders.ts +43 -0
  680. package/src/adapters/redocly-loader/remote-fetch.ts +104 -0
  681. package/src/adapters/redocly-loader/schema-load-errors.ts +124 -0
  682. package/src/adapters/redocly-loader/schema-source.ts +151 -0
  683. package/src/adapters/redocly-loader/unsupported-keys.ts +102 -0
  684. package/src/adapters/terminal-logger/terminal-logger.ts +98 -0
  685. package/src/adapters/type-ast-bridge/footer-nodes.ts +38 -0
  686. package/src/adapters/type-ast-bridge/ir-declarations-to-typescript.ts +100 -0
  687. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +223 -0
  688. package/src/adapters/type-ast-bridge/lazy-node.ts +24 -0
  689. package/src/adapters/type-ast-bridge/load-typescript.ts +84 -0
  690. package/src/adapters/type-ast-bridge/print-typescript.ts +33 -0
  691. package/src/adapters/type-ast-bridge/typescript-raw-text.ts +49 -0
  692. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +294 -0
  693. package/src/adapters/type-ast-bridge/typescript-types.ts +8 -0
  694. package/src/api/ast-to-string.ts +59 -0
  695. package/src/api/comment-header.ts +7 -0
  696. package/src/api/default-ports.ts +44 -0
  697. package/src/api/discriminator-conflict-warnings.ts +43 -0
  698. package/src/api/discriminator-enum-names.ts +26 -0
  699. package/src/api/discriminator-enum-parent.ts +129 -0
  700. package/src/api/discriminator-enum.ts +115 -0
  701. package/src/api/discriminator-other-owners.ts +97 -0
  702. package/src/api/discriminator-patch.ts +147 -0
  703. package/src/api/discriminator-scan.ts +260 -0
  704. package/src/api/document-declarations.ts +41 -0
  705. package/src/api/document-refs.ts +71 -0
  706. package/src/api/document-run.ts +177 -0
  707. package/src/api/enum-values-warnings.ts +21 -0
  708. package/src/api/footer-entry.ts +23 -0
  709. package/src/api/footer-sink.ts +67 -0
  710. package/src/api/legacy-callback-warning.ts +29 -0
  711. package/src/api/legacy-ts-helpers.ts +311 -0
  712. package/src/api/legacy-utils.ts +118 -0
  713. package/src/api/openapi-ts.ts +62 -0
  714. package/src/api/path-template-warnings.ts +27 -0
  715. package/src/api/schema-callbacks.ts +211 -0
  716. package/src/api/string-to-ast.ts +27 -0
  717. package/src/api/transform-context.ts +93 -0
  718. package/src/api/transform-schema.ts +123 -0
  719. package/src/api/type-helpers.ts +130 -0
  720. package/src/api/unsupported-feature-warnings.ts +33 -0
  721. package/src/application/ports/file-system.ts +12 -0
  722. package/src/application/ports/logger.ts +16 -0
  723. package/src/application/ports/redocly-config-source.ts +20 -0
  724. package/src/application/ports/schema-loader.ts +32 -0
  725. package/src/application/print/comment-writer.ts +91 -0
  726. package/src/application/print/declaration-printer.ts +100 -0
  727. package/src/application/print/literal-text.ts +62 -0
  728. package/src/application/print/print-nodes.ts +62 -0
  729. package/src/application/print/print-options.ts +11 -0
  730. package/src/application/print/text-writer.ts +83 -0
  731. package/src/application/print/type-printer.ts +287 -0
  732. package/src/application/stack-overflow.ts +54 -0
  733. package/src/application/transform/document/assignability.ts +203 -0
  734. package/src/application/transform/document/components.ts +189 -0
  735. package/src/application/transform/document/declared-types.ts +93 -0
  736. package/src/application/transform/document/defs-root.ts +25 -0
  737. package/src/application/transform/document/document-member.ts +20 -0
  738. package/src/application/transform/document/document.ts +215 -0
  739. package/src/application/transform/document/exploded-query.ts +91 -0
  740. package/src/application/transform/document/global-type-references.ts +78 -0
  741. package/src/application/transform/document/header.ts +34 -0
  742. package/src/application/transform/document/kept-deprecated.ts +135 -0
  743. package/src/application/transform/document/list-assignability.ts +87 -0
  744. package/src/application/transform/document/media-type.ts +78 -0
  745. package/src/application/transform/document/operation.ts +64 -0
  746. package/src/application/transform/document/parameter.ts +45 -0
  747. package/src/application/transform/document/parameters.ts +265 -0
  748. package/src/application/transform/document/path-item.ts +168 -0
  749. package/src/application/transform/document/path-key-overlaps.ts +201 -0
  750. package/src/application/transform/document/path-template-replace.ts +90 -0
  751. package/src/application/transform/document/paths-enum.ts +127 -0
  752. package/src/application/transform/document/paths.ts +273 -0
  753. package/src/application/transform/document/request-body.ts +50 -0
  754. package/src/application/transform/document/response.ts +109 -0
  755. package/src/application/transform/document/responses.ts +29 -0
  756. package/src/application/transform/document/root-type-aliases.ts +107 -0
  757. package/src/application/transform/document/template-key-match.ts +183 -0
  758. package/src/application/transform/document/type-assignability.ts +268 -0
  759. package/src/application/transform/document/type-key.ts +80 -0
  760. package/src/application/transform/document/type-resolution.ts +163 -0
  761. package/src/application/transform/document/webhooks.ts +22 -0
  762. package/src/application/transform/document-entries.ts +28 -0
  763. package/src/application/transform/footer/document-footer.ts +212 -0
  764. package/src/application/transform/footer/enum-naming.ts +210 -0
  765. package/src/application/transform/footer/enum-values-check.ts +171 -0
  766. package/src/application/transform/footer/evaluation.ts +47 -0
  767. package/src/application/transform/footer/shared-enum-names.ts +86 -0
  768. package/src/application/transform/footer/type-evaluation.ts +294 -0
  769. package/src/application/transform/footer/type-rules.ts +269 -0
  770. package/src/application/transform/helper-types.ts +92 -0
  771. package/src/application/transform/literal-type.ts +54 -0
  772. package/src/application/transform/numbered-names.ts +20 -0
  773. package/src/application/transform/ref-pointer/generated-location.ts +211 -0
  774. package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
  775. package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
  776. package/src/application/transform/ref-pointer/original-index.ts +95 -0
  777. package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
  778. package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
  779. package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
  780. package/src/application/transform/ref-type.ts +102 -0
  781. package/src/application/transform/schema/access-flags.ts +63 -0
  782. package/src/application/transform/schema/array-type.ts +213 -0
  783. package/src/application/transform/schema/composition-type.ts +255 -0
  784. package/src/application/transform/schema/core-type.ts +119 -0
  785. package/src/application/transform/schema/discriminated-union.ts +58 -0
  786. package/src/application/transform/schema/discriminator-property.ts +33 -0
  787. package/src/application/transform/schema/enum-rule.ts +280 -0
  788. package/src/application/transform/schema/inherited-discriminator.ts +54 -0
  789. package/src/application/transform/schema/object-type.ts +289 -0
  790. package/src/application/transform/schema/presence-members.ts +96 -0
  791. package/src/application/transform/schema/required-variants.ts +88 -0
  792. package/src/application/transform/schema/schema-context.ts +136 -0
  793. package/src/application/transform/schema/schema-rule.ts +29 -0
  794. package/src/application/transform/schema/schema-transform.ts +99 -0
  795. package/src/application/transform/schema/unevaluated-properties.ts +105 -0
  796. package/src/application/transform/schema-comment.ts +196 -0
  797. package/src/application/transform/shared-types.ts +9 -0
  798. package/src/application/transform/transform-context.ts +51 -0
  799. package/src/application/transform/type-combinators.ts +57 -0
  800. package/src/cli/cli-arguments.ts +208 -0
  801. package/src/cli/cli-dependencies.ts +47 -0
  802. package/src/cli/cli-errors.ts +127 -0
  803. package/src/cli/cli-output.ts +67 -0
  804. package/src/cli/docs-links.ts +6 -0
  805. package/src/cli/fix-option.ts +29 -0
  806. package/src/cli/help-text.ts +52 -0
  807. package/src/cli/main.ts +73 -0
  808. package/src/cli/redocly-apis.ts +95 -0
  809. package/src/cli/ref-limits.ts +16 -0
  810. package/src/cli/run-cli.ts +131 -0
  811. package/src/domain/assert-never.ts +8 -0
  812. package/src/domain/errors.ts +76 -0
  813. package/src/domain/ir/constructors.ts +142 -0
  814. package/src/domain/ir/identifier-text.ts +49 -0
  815. package/src/domain/ir/newer-identifier-ranges.ts +109 -0
  816. package/src/domain/ir/nodes.ts +225 -0
  817. package/src/domain/ir/normalize.ts +51 -0
  818. package/src/domain/ir/property-name.ts +28 -0
  819. package/src/domain/ir/raw-text-escapes.ts +37 -0
  820. package/src/domain/openapi/admitted-values.ts +113 -0
  821. package/src/domain/openapi/alias-expansion.ts +72 -0
  822. package/src/domain/openapi/binary-content.ts +74 -0
  823. package/src/domain/openapi/components-object.ts +52 -0
  824. package/src/domain/openapi/discriminated-union.ts +109 -0
  825. package/src/domain/openapi/discriminator-conflicts.ts +251 -0
  826. package/src/domain/openapi/document-object.ts +12 -0
  827. package/src/domain/openapi/header-object.ts +9 -0
  828. package/src/domain/openapi/json-pointer.ts +46 -0
  829. package/src/domain/openapi/media-type-object.ts +26 -0
  830. package/src/domain/openapi/operation-object.ts +13 -0
  831. package/src/domain/openapi/parameter-object.ts +34 -0
  832. package/src/domain/openapi/path-item-object.ts +70 -0
  833. package/src/domain/openapi/path-templates.ts +31 -0
  834. package/src/domain/openapi/request-body-object.ts +7 -0
  835. package/src/domain/openapi/response-object.ts +14 -0
  836. package/src/domain/openapi/schema-object.ts +61 -0
  837. package/src/domain/openapi/unsupported-features.ts +139 -0
  838. package/src/domain/output-fixes.ts +136 -0
  839. package/src/domain/warnings.ts +20 -0
  840. package/src/index.ts +67 -0
  841. package/src/transform/components-object.ts +27 -0
  842. package/src/transform/header-object.ts +19 -0
  843. package/src/transform/media-type-object.ts +19 -0
  844. package/src/transform/operation-object.ts +36 -0
  845. package/src/transform/parameter-object.ts +19 -0
  846. package/src/transform/parameters-array.ts +19 -0
  847. package/src/transform/path-item-object.ts +22 -0
  848. package/src/transform/paths-enum.ts +8 -0
  849. package/src/transform/paths-object.ts +15 -0
  850. package/src/transform/request-body-object.ts +19 -0
  851. package/src/transform/response-object.ts +19 -0
  852. package/src/transform/responses-object.ts +19 -0
  853. package/src/transform/schema-object.ts +36 -0
  854. package/src/transform/webhooks-object.ts +15 -0
  855. package/src/types/generator-options.ts +278 -0
  856. package/src/types/openapi-common.ts +100 -0
  857. package/src/types/openapi-document.ts +196 -0
  858. package/src/types/openapi-path-item.ts +130 -0
  859. package/src/types/openapi-request.ts +209 -0
  860. package/src/types/openapi-response.ts +81 -0
  861. package/src/types/openapi-schema.ts +169 -0
  862. package/src/types/openapi-security.ts +116 -0
  863. package/src/types.ts +12 -0
@@ -0,0 +1,107 @@
1
+ 'use strict';
2
+
3
+ const promises = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const node_url = require('node:url');
6
+ const openapiCore = require('@redocly/openapi-core');
7
+ const errors = require('../../domain/errors.cjs');
8
+ const aliasLimit = require('./alias-limit.cjs');
9
+ const allowedHosts = require('./allowed-hosts.cjs');
10
+ const schemaLoadErrors = require('./schema-load-errors.cjs');
11
+
12
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
13
+
14
+ const path__default = /*#__PURE__*/_interopDefaultCompat(path);
15
+
16
+ function isRemoteRef(absoluteRef) {
17
+ return absoluteRef.startsWith("http://") || absoluteRef.startsWith("https://");
18
+ }
19
+ function isInsideDirectory(target, root) {
20
+ const relative = path__default.relative(root, target);
21
+ const isParent = relative === ".." || relative.startsWith(`..${path__default.sep}`);
22
+ return !isParent && !path__default.isAbsolute(relative);
23
+ }
24
+ async function realPathOrSelf(file) {
25
+ const absolute = path__default.resolve(file);
26
+ try {
27
+ return await promises.realpath(absolute);
28
+ } catch (error) {
29
+ const parent = path__default.dirname(absolute);
30
+ if (error.code === "ENOENT" && parent !== absolute) {
31
+ return path__default.join(await realPathOrSelf(parent), path__default.basename(absolute));
32
+ }
33
+ throw error;
34
+ }
35
+ }
36
+ async function localRefusal(absoluteRef, localRoot) {
37
+ const root = await realPathOrSelf(node_url.fileURLToPath(localRoot));
38
+ if (isInsideDirectory(await realPathOrSelf(absoluteRef), root)) {
39
+ return void 0;
40
+ }
41
+ return schemaLoadErrors.refForbiddenError(absoluteRef, { reason: "outside-local-root", localRoot: root });
42
+ }
43
+ async function refusalOf(absoluteRef, access) {
44
+ if (!isRemoteRef(absoluteRef)) {
45
+ return access.localRoot === void 0 ? void 0 : localRefusal(absoluteRef, access.localRoot);
46
+ }
47
+ if (access.remoteHosts === void 0 || allowedHosts.isHostAllowed(new URL(absoluteRef), access.remoteHosts)) {
48
+ return void 0;
49
+ }
50
+ return schemaLoadErrors.refForbiddenError(absoluteRef, {
51
+ reason: "host-not-allowed",
52
+ allowedHosts: [...access.remoteHosts]
53
+ });
54
+ }
55
+ class RefAccessResolver extends openapiCore.BaseResolver {
56
+ #access;
57
+ #refusals = [];
58
+ /** The root document's ref: it is chosen by the developer, so it is not limited. */
59
+ #rootRef;
60
+ constructor(config, access) {
61
+ super(config);
62
+ this.#access = access;
63
+ }
64
+ /** The first document that was refused, if any. */
65
+ get firstRefusal() {
66
+ return this.#refusals[0];
67
+ }
68
+ resolveDocument(base, ref, isRoot = false) {
69
+ if (isRoot) {
70
+ this.#rootRef = this.resolveExternalRef(base, ref);
71
+ }
72
+ return super.resolveDocument(base, ref, isRoot);
73
+ }
74
+ /** Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). */
75
+ parseDocument(source, isRoot = false) {
76
+ const document = super.parseDocument(source, isRoot);
77
+ const failure = aliasLimit.aliasExpansionFailure(document.parsed);
78
+ if (failure !== void 0) {
79
+ throw new openapiCore.YamlParseError(failure, source);
80
+ }
81
+ return document;
82
+ }
83
+ async loadExternalRef(absoluteRef) {
84
+ const refusal = absoluteRef === this.#rootRef ? void 0 : await refusalOf(absoluteRef, this.#access);
85
+ if (refusal !== void 0) {
86
+ this.#refusals.push(refusal);
87
+ throw refusal;
88
+ }
89
+ try {
90
+ return await super.loadExternalRef(absoluteRef);
91
+ } catch (error) {
92
+ const cause = error.originalError;
93
+ if (isRefusal(cause)) {
94
+ this.#refusals.push(cause);
95
+ }
96
+ throw error;
97
+ }
98
+ }
99
+ }
100
+ function isRefusal(value) {
101
+ return value?.code === errors.ERROR_CODES.SCHEMA_REF_FORBIDDEN;
102
+ }
103
+
104
+ exports.RefAccessResolver = RefAccessResolver;
105
+ exports.isInsideDirectory = isInsideDirectory;
106
+ exports.refusalOf = refusalOf;
107
+ //# sourceMappingURL=ref-access.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-access.cjs","sources":["../../../src/adapters/redocly-loader/ref-access.ts"],"sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n BaseResolver,\n type Document,\n type Config as RedoclyConfig,\n type Source,\n YamlParseError,\n} from \"@redocly/openapi-core\";\nimport type { RefAccess } from \"../../application/ports/schema-loader.js\";\nimport { ERROR_CODES, type OpenAPITypesafeError } from \"../../domain/errors.js\";\nimport { aliasExpansionFailure } from \"./alias-limit.js\";\nimport { isHostAllowed } from \"./allowed-hosts.js\";\nimport { refForbiddenError } from \"./schema-load-errors.js\";\n\n/**\n * Limits on where `$ref` documents may be loaded from (threat model R1 and R2, ADR-017). The root\n * document is chosen by the developer and is always loaded; every other document must pass.\n */\n\ntype ResolveConfig = RedoclyConfig[\"resolve\"];\n\n/** Redocly treats only these prefixes as remote; any other `$ref` is a local file path. */\nfunction isRemoteRef(absoluteRef: string): boolean {\n return absoluteRef.startsWith(\"http://\") || absoluteRef.startsWith(\"https://\");\n}\n\n/** Whether `target` is `root` or below it; both are absolute paths. */\nexport function isInsideDirectory(target: string, root: string): boolean {\n const relative = path.relative(root, target);\n // Compare the first segment: a directory named `..hidden` is inside, `../x` is not.\n const isParent = relative === \"..\" || relative.startsWith(`..${path.sep}`);\n return !isParent && !path.isAbsolute(relative);\n}\n\n/** The real path, so a link inside the root that points outside it is caught. */\nasync function realPathOrSelf(file: string): Promise<string> {\n const absolute = path.resolve(file);\n try {\n return await realpath(absolute);\n } catch (error) {\n // A missing file is never read, and Redocly reports it. Resolve its nearest existing\n // directory instead, so it compares with the root's real path: the root may be reached\n // through a link (macOS `/tmp` is one), and the missing file must not look outside it.\n const parent = path.dirname(absolute);\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\" && parent !== absolute) {\n return path.join(await realPathOrSelf(parent), path.basename(absolute));\n }\n throw error;\n }\n}\n\nasync function localRefusal(\n absoluteRef: string,\n localRoot: URL,\n): Promise<OpenAPITypesafeError | undefined> {\n const root = await realPathOrSelf(fileURLToPath(localRoot));\n if (isInsideDirectory(await realPathOrSelf(absoluteRef), root)) {\n return undefined;\n }\n return refForbiddenError(absoluteRef, { reason: \"outside-local-root\", localRoot: root });\n}\n\n/** The refusal for one document, or undefined when the limits allow it. */\nexport async function refusalOf(\n absoluteRef: string,\n access: RefAccess,\n): Promise<OpenAPITypesafeError | undefined> {\n if (!isRemoteRef(absoluteRef)) {\n return access.localRoot === undefined ? undefined : localRefusal(absoluteRef, access.localRoot);\n }\n if (access.remoteHosts === undefined || isHostAllowed(new URL(absoluteRef), access.remoteHosts)) {\n return undefined;\n }\n return refForbiddenError(absoluteRef, {\n reason: \"host-not-allowed\",\n allowedHosts: [...access.remoteHosts],\n });\n}\n\n/**\n * A Redocly resolver that checks each document before it loads it. Redocly turns a failed load\n * into an unresolved-`$ref` problem, so the refusals are also kept for the loader to report as\n * the typed error.\n */\nexport class RefAccessResolver extends BaseResolver {\n readonly #access: RefAccess;\n readonly #refusals: OpenAPITypesafeError[] = [];\n /** The root document's ref: it is chosen by the developer, so it is not limited. */\n #rootRef: string | undefined;\n\n constructor(config: ResolveConfig, access: RefAccess) {\n super(config);\n this.#access = access;\n }\n\n /** The first document that was refused, if any. */\n get firstRefusal(): OpenAPITypesafeError | undefined {\n return this.#refusals[0];\n }\n\n override resolveDocument(\n base: string | null,\n ref: string,\n isRoot = false,\n ): ReturnType<BaseResolver[\"resolveDocument\"]> {\n if (isRoot) {\n this.#rootRef = this.resolveExternalRef(base, ref);\n }\n return super.resolveDocument(base, ref, isRoot);\n }\n\n /** Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). */\n override parseDocument(source: Source, isRoot = false): Document {\n const document = super.parseDocument(source, isRoot);\n const failure = aliasExpansionFailure(document.parsed);\n if (failure !== undefined) {\n throw new YamlParseError(failure, source);\n }\n return document;\n }\n\n override async loadExternalRef(absoluteRef: string): Promise<Source> {\n const refusal =\n absoluteRef === this.#rootRef ? undefined : await refusalOf(absoluteRef, this.#access);\n if (refusal !== undefined) {\n this.#refusals.push(refusal);\n throw refusal;\n }\n try {\n return await super.loadExternalRef(absoluteRef);\n } catch (error) {\n // A refused redirect throws inside the fetch, and Redocly wraps it in a ResolveError.\n const cause = (error as { originalError?: unknown }).originalError;\n if (isRefusal(cause)) {\n this.#refusals.push(cause);\n }\n throw error;\n }\n }\n}\n\nfunction isRefusal(value: unknown): value is OpenAPITypesafeError {\n return (value as { code?: unknown } | null)?.code === ERROR_CODES.SCHEMA_REF_FORBIDDEN;\n}\n"],"names":["path","realpath","fileURLToPath","refForbiddenError","isHostAllowed","BaseResolver","aliasExpansionFailure","YamlParseError","ERROR_CODES"],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { realpath } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { BaseResolver, YamlParseError } from '@redocly/openapi-core';
5
+ import { ERROR_CODES } from '../../domain/errors.mjs';
6
+ import { aliasExpansionFailure } from './alias-limit.mjs';
7
+ import { isHostAllowed } from './allowed-hosts.mjs';
8
+ import { refForbiddenError } from './schema-load-errors.mjs';
9
+
10
+ function isRemoteRef(absoluteRef) {
11
+ return absoluteRef.startsWith("http://") || absoluteRef.startsWith("https://");
12
+ }
13
+ function isInsideDirectory(target, root) {
14
+ const relative = path.relative(root, target);
15
+ const isParent = relative === ".." || relative.startsWith(`..${path.sep}`);
16
+ return !isParent && !path.isAbsolute(relative);
17
+ }
18
+ async function realPathOrSelf(file) {
19
+ const absolute = path.resolve(file);
20
+ try {
21
+ return await realpath(absolute);
22
+ } catch (error) {
23
+ const parent = path.dirname(absolute);
24
+ if (error.code === "ENOENT" && parent !== absolute) {
25
+ return path.join(await realPathOrSelf(parent), path.basename(absolute));
26
+ }
27
+ throw error;
28
+ }
29
+ }
30
+ async function localRefusal(absoluteRef, localRoot) {
31
+ const root = await realPathOrSelf(fileURLToPath(localRoot));
32
+ if (isInsideDirectory(await realPathOrSelf(absoluteRef), root)) {
33
+ return void 0;
34
+ }
35
+ return refForbiddenError(absoluteRef, { reason: "outside-local-root", localRoot: root });
36
+ }
37
+ async function refusalOf(absoluteRef, access) {
38
+ if (!isRemoteRef(absoluteRef)) {
39
+ return access.localRoot === void 0 ? void 0 : localRefusal(absoluteRef, access.localRoot);
40
+ }
41
+ if (access.remoteHosts === void 0 || isHostAllowed(new URL(absoluteRef), access.remoteHosts)) {
42
+ return void 0;
43
+ }
44
+ return refForbiddenError(absoluteRef, {
45
+ reason: "host-not-allowed",
46
+ allowedHosts: [...access.remoteHosts]
47
+ });
48
+ }
49
+ class RefAccessResolver extends BaseResolver {
50
+ #access;
51
+ #refusals = [];
52
+ /** The root document's ref: it is chosen by the developer, so it is not limited. */
53
+ #rootRef;
54
+ constructor(config, access) {
55
+ super(config);
56
+ this.#access = access;
57
+ }
58
+ /** The first document that was refused, if any. */
59
+ get firstRefusal() {
60
+ return this.#refusals[0];
61
+ }
62
+ resolveDocument(base, ref, isRoot = false) {
63
+ if (isRoot) {
64
+ this.#rootRef = this.resolveExternalRef(base, ref);
65
+ }
66
+ return super.resolveDocument(base, ref, isRoot);
67
+ }
68
+ /** Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). */
69
+ parseDocument(source, isRoot = false) {
70
+ const document = super.parseDocument(source, isRoot);
71
+ const failure = aliasExpansionFailure(document.parsed);
72
+ if (failure !== void 0) {
73
+ throw new YamlParseError(failure, source);
74
+ }
75
+ return document;
76
+ }
77
+ async loadExternalRef(absoluteRef) {
78
+ const refusal = absoluteRef === this.#rootRef ? void 0 : await refusalOf(absoluteRef, this.#access);
79
+ if (refusal !== void 0) {
80
+ this.#refusals.push(refusal);
81
+ throw refusal;
82
+ }
83
+ try {
84
+ return await super.loadExternalRef(absoluteRef);
85
+ } catch (error) {
86
+ const cause = error.originalError;
87
+ if (isRefusal(cause)) {
88
+ this.#refusals.push(cause);
89
+ }
90
+ throw error;
91
+ }
92
+ }
93
+ }
94
+ function isRefusal(value) {
95
+ return value?.code === ERROR_CODES.SCHEMA_REF_FORBIDDEN;
96
+ }
97
+
98
+ export { RefAccessResolver, isInsideDirectory, refusalOf };
99
+ //# sourceMappingURL=ref-access.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-access.mjs","sources":["../../../src/adapters/redocly-loader/ref-access.ts"],"sourcesContent":["import { realpath } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n BaseResolver,\n type Document,\n type Config as RedoclyConfig,\n type Source,\n YamlParseError,\n} from \"@redocly/openapi-core\";\nimport type { RefAccess } from \"../../application/ports/schema-loader.js\";\nimport { ERROR_CODES, type OpenAPITypesafeError } from \"../../domain/errors.js\";\nimport { aliasExpansionFailure } from \"./alias-limit.js\";\nimport { isHostAllowed } from \"./allowed-hosts.js\";\nimport { refForbiddenError } from \"./schema-load-errors.js\";\n\n/**\n * Limits on where `$ref` documents may be loaded from (threat model R1 and R2, ADR-017). The root\n * document is chosen by the developer and is always loaded; every other document must pass.\n */\n\ntype ResolveConfig = RedoclyConfig[\"resolve\"];\n\n/** Redocly treats only these prefixes as remote; any other `$ref` is a local file path. */\nfunction isRemoteRef(absoluteRef: string): boolean {\n return absoluteRef.startsWith(\"http://\") || absoluteRef.startsWith(\"https://\");\n}\n\n/** Whether `target` is `root` or below it; both are absolute paths. */\nexport function isInsideDirectory(target: string, root: string): boolean {\n const relative = path.relative(root, target);\n // Compare the first segment: a directory named `..hidden` is inside, `../x` is not.\n const isParent = relative === \"..\" || relative.startsWith(`..${path.sep}`);\n return !isParent && !path.isAbsolute(relative);\n}\n\n/** The real path, so a link inside the root that points outside it is caught. */\nasync function realPathOrSelf(file: string): Promise<string> {\n const absolute = path.resolve(file);\n try {\n return await realpath(absolute);\n } catch (error) {\n // A missing file is never read, and Redocly reports it. Resolve its nearest existing\n // directory instead, so it compares with the root's real path: the root may be reached\n // through a link (macOS `/tmp` is one), and the missing file must not look outside it.\n const parent = path.dirname(absolute);\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\" && parent !== absolute) {\n return path.join(await realPathOrSelf(parent), path.basename(absolute));\n }\n throw error;\n }\n}\n\nasync function localRefusal(\n absoluteRef: string,\n localRoot: URL,\n): Promise<OpenAPITypesafeError | undefined> {\n const root = await realPathOrSelf(fileURLToPath(localRoot));\n if (isInsideDirectory(await realPathOrSelf(absoluteRef), root)) {\n return undefined;\n }\n return refForbiddenError(absoluteRef, { reason: \"outside-local-root\", localRoot: root });\n}\n\n/** The refusal for one document, or undefined when the limits allow it. */\nexport async function refusalOf(\n absoluteRef: string,\n access: RefAccess,\n): Promise<OpenAPITypesafeError | undefined> {\n if (!isRemoteRef(absoluteRef)) {\n return access.localRoot === undefined ? undefined : localRefusal(absoluteRef, access.localRoot);\n }\n if (access.remoteHosts === undefined || isHostAllowed(new URL(absoluteRef), access.remoteHosts)) {\n return undefined;\n }\n return refForbiddenError(absoluteRef, {\n reason: \"host-not-allowed\",\n allowedHosts: [...access.remoteHosts],\n });\n}\n\n/**\n * A Redocly resolver that checks each document before it loads it. Redocly turns a failed load\n * into an unresolved-`$ref` problem, so the refusals are also kept for the loader to report as\n * the typed error.\n */\nexport class RefAccessResolver extends BaseResolver {\n readonly #access: RefAccess;\n readonly #refusals: OpenAPITypesafeError[] = [];\n /** The root document's ref: it is chosen by the developer, so it is not limited. */\n #rootRef: string | undefined;\n\n constructor(config: ResolveConfig, access: RefAccess) {\n super(config);\n this.#access = access;\n }\n\n /** The first document that was refused, if any. */\n get firstRefusal(): OpenAPITypesafeError | undefined {\n return this.#refusals[0];\n }\n\n override resolveDocument(\n base: string | null,\n ref: string,\n isRoot = false,\n ): ReturnType<BaseResolver[\"resolveDocument\"]> {\n if (isRoot) {\n this.#rootRef = this.resolveExternalRef(base, ref);\n }\n return super.resolveDocument(base, ref, isRoot);\n }\n\n /** Refuse a YAML alias bomb before Redocly walks it (pre-beta test plan 10.2). */\n override parseDocument(source: Source, isRoot = false): Document {\n const document = super.parseDocument(source, isRoot);\n const failure = aliasExpansionFailure(document.parsed);\n if (failure !== undefined) {\n throw new YamlParseError(failure, source);\n }\n return document;\n }\n\n override async loadExternalRef(absoluteRef: string): Promise<Source> {\n const refusal =\n absoluteRef === this.#rootRef ? undefined : await refusalOf(absoluteRef, this.#access);\n if (refusal !== undefined) {\n this.#refusals.push(refusal);\n throw refusal;\n }\n try {\n return await super.loadExternalRef(absoluteRef);\n } catch (error) {\n // A refused redirect throws inside the fetch, and Redocly wraps it in a ResolveError.\n const cause = (error as { originalError?: unknown }).originalError;\n if (isRefusal(cause)) {\n this.#refusals.push(cause);\n }\n throw error;\n }\n }\n}\n\nfunction isRefusal(value: unknown): value is OpenAPITypesafeError {\n return (value as { code?: unknown } | null)?.code === ERROR_CODES.SCHEMA_REF_FORBIDDEN;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const jsonPointer = require('../../domain/openapi/json-pointer.cjs');
4
+
5
+ function hasStringRef(value) {
6
+ return !Array.isArray(value) && typeof value.$ref === "string";
7
+ }
8
+ function findRefHolders(document) {
9
+ const found = [];
10
+ const visited = /* @__PURE__ */ new WeakSet();
11
+ const pending = [];
12
+ const enqueue = (value, pointer) => {
13
+ if (typeof value === "object" && value !== null && !visited.has(value)) {
14
+ visited.add(value);
15
+ pending.push({ value, pointer });
16
+ }
17
+ };
18
+ enqueue(document, "#");
19
+ for (let next = pending.pop(); next !== void 0; next = pending.pop()) {
20
+ if (hasStringRef(next.value)) {
21
+ found.push({ node: next.value, pointer: next.pointer });
22
+ }
23
+ for (const [key, child] of Object.entries(next.value)) {
24
+ enqueue(child, `${next.pointer}/${jsonPointer.escapePointerSegment(key)}`);
25
+ }
26
+ }
27
+ return found;
28
+ }
29
+
30
+ exports.findRefHolders = findRefHolders;
31
+ //# sourceMappingURL=ref-holders.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-holders.cjs","sources":["../../../src/adapters/redocly-loader/ref-holders.ts"],"sourcesContent":["import { escapePointerSegment } from \"../../domain/openapi/json-pointer.js\";\n\n/** An object with a string `$ref`, and its JSON Pointer in the document. */\nexport interface RefHolder {\n readonly node: { $ref: string };\n readonly pointer: string;\n}\n\ninterface PendingNode {\n readonly value: object;\n readonly pointer: string;\n}\n\nfunction hasStringRef(value: object): value is { $ref: string } {\n return !Array.isArray(value) && typeof (value as { $ref?: unknown }).$ref === \"string\";\n}\n\n/**\n * Every object with a string `$ref` in a parsed document, in no particular order. The walk uses\n * its own stack, so a deeply nested document does not run out of call stack, and a node shared by\n * YAML aliases (or a cycle of them) is visited once.\n */\nexport function findRefHolders(document: unknown): RefHolder[] {\n const found: RefHolder[] = [];\n const visited = new WeakSet<object>();\n const pending: PendingNode[] = [];\n const enqueue = (value: unknown, pointer: string): void => {\n if (typeof value === \"object\" && value !== null && !visited.has(value)) {\n visited.add(value);\n pending.push({ value, pointer });\n }\n };\n enqueue(document, \"#\");\n for (let next = pending.pop(); next !== undefined; next = pending.pop()) {\n if (hasStringRef(next.value)) {\n found.push({ node: next.value, pointer: next.pointer });\n }\n for (const [key, child] of Object.entries(next.value)) {\n enqueue(child, `${next.pointer}/${escapePointerSegment(key)}`);\n }\n }\n return found;\n}\n"],"names":["escapePointerSegment"],"mappings":";;;;AAaA,SAAS,aAAa,KAAA,EAA0C;AAC9D,EAAA,OAAO,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAQ,MAA6B,IAAA,KAAS,QAAA;AAChF;AAOO,SAAS,eAAe,QAAA,EAAgC;AAC7D,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,MAAM,OAAA,uBAAc,OAAA,EAAgB;AACpC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAM,OAAA,GAAU,CAAC,KAAA,EAAgB,OAAA,KAA0B;AACzD,IAAA,IAAI,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACtE,MAAA,OAAA,CAAQ,IAAI,KAAK,CAAA;AACjB,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,IACjC;AAAA,EACF,CAAA;AACA,EAAA,OAAA,CAAQ,UAAU,GAAG,CAAA;AACrB,EAAA,KAAA,IAAS,IAAA,GAAO,QAAQ,GAAA,EAAI,EAAG,SAAS,MAAA,EAAW,IAAA,GAAO,OAAA,CAAQ,GAAA,EAAI,EAAG;AACvE,IAAA,IAAI,YAAA,CAAa,IAAA,CAAK,KAAK,CAAA,EAAG;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,CAAK,OAAO,OAAA,EAAS,IAAA,CAAK,SAAS,CAAA;AAAA,IACxD;AACA,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AACrD,MAAA,OAAA,CAAQ,KAAA,EAAO,GAAG,IAAA,CAAK,OAAO,IAAIA,gCAAA,CAAqB,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,IAC/D;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;;"}
@@ -0,0 +1,29 @@
1
+ import { escapePointerSegment } from '../../domain/openapi/json-pointer.mjs';
2
+
3
+ function hasStringRef(value) {
4
+ return !Array.isArray(value) && typeof value.$ref === "string";
5
+ }
6
+ function findRefHolders(document) {
7
+ const found = [];
8
+ const visited = /* @__PURE__ */ new WeakSet();
9
+ const pending = [];
10
+ const enqueue = (value, pointer) => {
11
+ if (typeof value === "object" && value !== null && !visited.has(value)) {
12
+ visited.add(value);
13
+ pending.push({ value, pointer });
14
+ }
15
+ };
16
+ enqueue(document, "#");
17
+ for (let next = pending.pop(); next !== void 0; next = pending.pop()) {
18
+ if (hasStringRef(next.value)) {
19
+ found.push({ node: next.value, pointer: next.pointer });
20
+ }
21
+ for (const [key, child] of Object.entries(next.value)) {
22
+ enqueue(child, `${next.pointer}/${escapePointerSegment(key)}`);
23
+ }
24
+ }
25
+ return found;
26
+ }
27
+
28
+ export { findRefHolders };
29
+ //# sourceMappingURL=ref-holders.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-holders.mjs","sources":["../../../src/adapters/redocly-loader/ref-holders.ts"],"sourcesContent":["import { escapePointerSegment } from \"../../domain/openapi/json-pointer.js\";\n\n/** An object with a string `$ref`, and its JSON Pointer in the document. */\nexport interface RefHolder {\n readonly node: { $ref: string };\n readonly pointer: string;\n}\n\ninterface PendingNode {\n readonly value: object;\n readonly pointer: string;\n}\n\nfunction hasStringRef(value: object): value is { $ref: string } {\n return !Array.isArray(value) && typeof (value as { $ref?: unknown }).$ref === \"string\";\n}\n\n/**\n * Every object with a string `$ref` in a parsed document, in no particular order. The walk uses\n * its own stack, so a deeply nested document does not run out of call stack, and a node shared by\n * YAML aliases (or a cycle of them) is visited once.\n */\nexport function findRefHolders(document: unknown): RefHolder[] {\n const found: RefHolder[] = [];\n const visited = new WeakSet<object>();\n const pending: PendingNode[] = [];\n const enqueue = (value: unknown, pointer: string): void => {\n if (typeof value === \"object\" && value !== null && !visited.has(value)) {\n visited.add(value);\n pending.push({ value, pointer });\n }\n };\n enqueue(document, \"#\");\n for (let next = pending.pop(); next !== undefined; next = pending.pop()) {\n if (hasStringRef(next.value)) {\n found.push({ node: next.value, pointer: next.pointer });\n }\n for (const [key, child] of Object.entries(next.value)) {\n enqueue(child, `${next.pointer}/${escapePointerSegment(key)}`);\n }\n }\n return found;\n}\n"],"names":[],"mappings":";;AAaA,SAAS,aAAa,KAAA,EAA0C;AAC9D,EAAA,OAAO,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,OAAQ,MAA6B,IAAA,KAAS,QAAA;AAChF;AAOO,SAAS,eAAe,QAAA,EAAgC;AAC7D,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,MAAM,OAAA,uBAAc,OAAA,EAAgB;AACpC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAM,OAAA,GAAU,CAAC,KAAA,EAAgB,OAAA,KAA0B;AACzD,IAAA,IAAI,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACtE,MAAA,OAAA,CAAQ,IAAI,KAAK,CAAA;AACjB,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,IACjC;AAAA,EACF,CAAA;AACA,EAAA,OAAA,CAAQ,UAAU,GAAG,CAAA;AACrB,EAAA,KAAA,IAAS,IAAA,GAAO,QAAQ,GAAA,EAAI,EAAG,SAAS,MAAA,EAAW,IAAA,GAAO,OAAA,CAAQ,GAAA,EAAI,EAAG;AACvE,IAAA,IAAI,YAAA,CAAa,IAAA,CAAK,KAAK,CAAA,EAAG;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,CAAK,OAAO,OAAA,EAAS,IAAA,CAAK,SAAS,CAAA;AAAA,IACxD;AACA,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AACrD,MAAA,OAAA,CAAQ,KAAA,EAAO,GAAG,IAAA,CAAK,OAAO,IAAI,oBAAA,CAAqB,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,IAC/D;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;;"}
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ const allowedHosts = require('./allowed-hosts.cjs');
4
+ const schemaLoadErrors = require('./schema-load-errors.cjs');
5
+
6
+ const MAX_CHECKED_REDIRECTS = 5;
7
+ const REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
8
+ const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([101, 103, 204, 205, 304]);
9
+ async function bufferedResponse(response) {
10
+ const body = await response.arrayBuffer();
11
+ const { status, statusText, headers } = response;
12
+ return new Response(NULL_BODY_STATUSES.has(status) ? null : body, {
13
+ status,
14
+ statusText,
15
+ headers
16
+ });
17
+ }
18
+ function fetchWithTimeout(timeoutMs) {
19
+ return async (input, init = {}) => {
20
+ try {
21
+ const response = await fetch(input, { ...init, signal: AbortSignal.timeout(timeoutMs) });
22
+ return await bufferedResponse(response);
23
+ } catch (cause) {
24
+ const isTimeout = cause instanceof Error && cause.name === "TimeoutError";
25
+ throw isTimeout ? new Error(`Timed out after ${timeoutMs} ms loading ${input}`) : cause;
26
+ }
27
+ };
28
+ }
29
+ function fetchWithCheckedRedirects(fetchImpl, hosts) {
30
+ return async (input, init = {}) => {
31
+ const firstOrigin = new URL(input).origin;
32
+ let url = new URL(input);
33
+ for (let hop = 0; hop <= MAX_CHECKED_REDIRECTS; hop += 1) {
34
+ if (hop > 0 && !allowedHosts.isHostAllowed(url, hosts)) {
35
+ throw schemaLoadErrors.refForbiddenError(url.href, { reason: "host-not-allowed", allowedHosts: [...hosts] });
36
+ }
37
+ const { headers, ...rest } = init;
38
+ const hopInit = url.origin === firstOrigin && headers !== void 0 ? { ...rest, headers } : rest;
39
+ const response = await fetchImpl(url.href, { ...hopInit, redirect: "manual" });
40
+ const location = response.headers.get("location");
41
+ if (!REDIRECT_STATUSES.has(response.status) || location === null) {
42
+ return response;
43
+ }
44
+ url = new URL(location, url);
45
+ }
46
+ throw new Error(`More than ${MAX_CHECKED_REDIRECTS} redirects loading ${input}`);
47
+ };
48
+ }
49
+ function resolveConfigWithAccess(resolve, options) {
50
+ const configured = resolve.http.customFetch;
51
+ const base = configured ?? fetchWithTimeout(options.timeoutMs);
52
+ const hosts = options.access.remoteHosts;
53
+ const customFetch = hosts === void 0 ? base : fetchWithCheckedRedirects(base, hosts);
54
+ return { ...resolve, http: { ...resolve.http, customFetch } };
55
+ }
56
+
57
+ exports.MAX_CHECKED_REDIRECTS = MAX_CHECKED_REDIRECTS;
58
+ exports.fetchWithCheckedRedirects = fetchWithCheckedRedirects;
59
+ exports.resolveConfigWithAccess = resolveConfigWithAccess;
60
+ //# sourceMappingURL=remote-fetch.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-fetch.cjs","sources":["../../../src/adapters/redocly-loader/remote-fetch.ts"],"sourcesContent":["import type { Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport type { RefAccess } from \"../../application/ports/schema-loader.js\";\nimport { isHostAllowed } from \"./allowed-hosts.js\";\nimport { refForbiddenError } from \"./schema-load-errors.js\";\n\n/** How the loader fetches remote documents: a time limit, and the host limit on redirects. */\n\ntype ResolveConfig = RedoclyConfig[\"resolve\"];\n\n/** The fetch Redocly calls for a remote document (`resolve.http.customFetch`). */\nexport type RemoteFetch = (input: string, init?: RequestInit) => Promise<Response>;\n\n/**\n * Redirects followed for a remote `$ref` when hosts are limited. Each hop is checked, so fetch\n * cannot follow them on its own; 5 covers http → https plus a moved file, and a loop stops early.\n */\nexport const MAX_CHECKED_REDIRECTS = 5;\n\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\n\n/** Statuses whose responses have no body; `new Response()` refuses a body for them. */\nconst NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);\n\n/** A response whose body is already read, so that reading it again cannot wait or fail. */\nasync function bufferedResponse(response: Response): Promise<Response> {\n const body = await response.arrayBuffer();\n const { status, statusText, headers } = response;\n return new Response(NULL_BODY_STATUSES.has(status) ? null : body, {\n status,\n statusText,\n headers,\n });\n}\n\n/**\n * Fetch with a time limit for the whole response, body included: Node's own fetch waits five\n * minutes for a server that never answers, and a server that sends its body one byte at a time\n * never finishes. The body is read here, inside the limit; when Redocly read it, the abort\n * surfaced as a `DOMException` whose read-only `message` Redocly tried to change, which gave\n * \"Cannot set property message of which has only a getter\" instead of the time limit.\n */\nfunction fetchWithTimeout(timeoutMs: number): RemoteFetch {\n return async (input, init = {}) => {\n try {\n const response = await fetch(input, { ...init, signal: AbortSignal.timeout(timeoutMs) });\n return await bufferedResponse(response);\n } catch (cause) {\n const isTimeout = cause instanceof Error && cause.name === \"TimeoutError\";\n throw isTimeout ? new Error(`Timed out after ${timeoutMs} ms loading ${input}`) : cause;\n }\n };\n}\n\n/**\n * Follow redirects one by one, and refuse a redirect to a host that is not listed. The first URL\n * was checked by the resolver (or is the root document). As fetch does, the configured headers\n * (often credentials) are not sent on to another origin.\n */\nexport function fetchWithCheckedRedirects(\n fetchImpl: RemoteFetch,\n hosts: readonly string[],\n): RemoteFetch {\n return async (input, init = {}) => {\n const firstOrigin = new URL(input).origin;\n let url = new URL(input);\n for (let hop = 0; hop <= MAX_CHECKED_REDIRECTS; hop += 1) {\n if (hop > 0 && !isHostAllowed(url, hosts)) {\n throw refForbiddenError(url.href, { reason: \"host-not-allowed\", allowedHosts: [...hosts] });\n }\n const { headers, ...rest } = init;\n const hopInit: RequestInit =\n url.origin === firstOrigin && headers !== undefined ? { ...rest, headers } : rest;\n const response = await fetchImpl(url.href, { ...hopInit, redirect: \"manual\" });\n const location = response.headers.get(\"location\");\n if (!REDIRECT_STATUSES.has(response.status) || location === null) {\n return response;\n }\n url = new URL(location, url);\n }\n throw new Error(`More than ${MAX_CHECKED_REDIRECTS} redirects loading ${input}`);\n };\n}\n\nexport interface RemoteFetchOptions {\n /** Time limit of one fetch and its body, unless the Redocly config has its own `customFetch`. */\n readonly timeoutMs: number;\n readonly access: RefAccess;\n}\n\n/**\n * The resolve config with the fetch the loader uses. A `customFetch` of the Redocly config is\n * kept; with a host limit, it is wrapped so that each redirect is checked.\n */\nexport function resolveConfigWithAccess(\n resolve: ResolveConfig,\n options: RemoteFetchOptions,\n): ResolveConfig {\n // Redocly types `customFetch` as `Function`; it is called as fetch is.\n const configured = resolve.http.customFetch as RemoteFetch | undefined;\n const base = configured ?? fetchWithTimeout(options.timeoutMs);\n const hosts = options.access.remoteHosts;\n const customFetch = hosts === undefined ? base : fetchWithCheckedRedirects(base, hosts);\n return { ...resolve, http: { ...resolve.http, customFetch } };\n}\n"],"names":["isHostAllowed","refForbiddenError"],"mappings":";;;;;AAgBO,MAAM,qBAAA,GAAwB;AAErC,MAAM,iBAAA,uBAAwB,GAAA,CAAI,CAAC,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAG3D,MAAM,kBAAA,uBAAyB,GAAA,CAAI,CAAC,KAAK,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAC,CAAA;AAG5D,eAAe,iBAAiB,QAAA,EAAuC;AACrE,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,WAAA,EAAY;AACxC,EAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAY,OAAA,EAAQ,GAAI,QAAA;AACxC,EAAA,OAAO,IAAI,QAAA,CAAS,kBAAA,CAAmB,IAAI,MAAM,CAAA,GAAI,OAAO,IAAA,EAAM;AAAA,IAChE,MAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AASA,SAAS,iBAAiB,SAAA,EAAgC;AACxD,EAAA,OAAO,OAAO,KAAA,EAAO,IAAA,GAAO,EAAC,KAAM;AACjC,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,KAAA,EAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,SAAS,CAAA,EAAG,CAAA;AACvF,MAAA,OAAO,MAAM,iBAAiB,QAAQ,CAAA;AAAA,IACxC,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,SAAA,GAAY,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,cAAA;AAC3D,MAAA,MAAM,SAAA,GAAY,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,SAAS,CAAA,YAAA,EAAe,KAAK,EAAE,CAAA,GAAI,KAAA;AAAA,IACpF;AAAA,EACF,CAAA;AACF;AAOO,SAAS,yBAAA,CACd,WACA,KAAA,EACa;AACb,EAAA,OAAO,OAAO,KAAA,EAAO,IAAA,GAAO,EAAC,KAAM;AACjC,IAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,KAAK,CAAA,CAAE,MAAA;AACnC,IAAA,IAAI,GAAA,GAAM,IAAI,GAAA,CAAI,KAAK,CAAA;AACvB,IAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,IAAO,qBAAA,EAAuB,OAAO,CAAA,EAAG;AACxD,MAAA,IAAI,MAAM,CAAA,IAAK,CAACA,0BAAA,CAAc,GAAA,EAAK,KAAK,CAAA,EAAG;AACzC,QAAA,MAAMC,kCAAA,CAAkB,GAAA,CAAI,IAAA,EAAM,EAAE,MAAA,EAAQ,kBAAA,EAAoB,YAAA,EAAc,CAAC,GAAG,KAAK,CAAA,EAAG,CAAA;AAAA,MAC5F;AACA,MAAA,MAAM,EAAE,OAAA,EAAS,GAAG,IAAA,EAAK,GAAI,IAAA;AAC7B,MAAA,MAAM,OAAA,GACJ,GAAA,CAAI,MAAA,KAAW,WAAA,IAAe,OAAA,KAAY,SAAY,EAAE,GAAG,IAAA,EAAM,OAAA,EAAQ,GAAI,IAAA;AAC/E,MAAA,MAAM,QAAA,GAAW,MAAM,SAAA,CAAU,GAAA,CAAI,IAAA,EAAM,EAAE,GAAG,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU,CAAA;AAC7E,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AAChD,MAAA,IAAI,CAAC,iBAAA,CAAkB,GAAA,CAAI,SAAS,MAAM,CAAA,IAAK,aAAa,IAAA,EAAM;AAChE,QAAA,OAAO,QAAA;AAAA,MACT;AACA,MAAA,GAAA,GAAM,IAAI,GAAA,CAAI,QAAA,EAAU,GAAG,CAAA;AAAA,IAC7B;AACA,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,UAAA,EAAa,qBAAqB,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,EACjF,CAAA;AACF;AAYO,SAAS,uBAAA,CACd,SACA,OAAA,EACe;AAEf,EAAA,MAAM,UAAA,GAAa,QAAQ,IAAA,CAAK,WAAA;AAChC,EAAA,MAAM,IAAA,GAAO,UAAA,IAAc,gBAAA,CAAiB,OAAA,CAAQ,SAAS,CAAA;AAC7D,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAAA,CAAO,WAAA;AAC7B,EAAA,MAAM,cAAc,KAAA,KAAU,MAAA,GAAY,IAAA,GAAO,yBAAA,CAA0B,MAAM,KAAK,CAAA;AACtF,EAAA,OAAO,EAAE,GAAG,OAAA,EAAS,IAAA,EAAM,EAAE,GAAG,OAAA,CAAQ,IAAA,EAAM,WAAA,EAAY,EAAE;AAC9D;;;;"}
@@ -0,0 +1,56 @@
1
+ import { isHostAllowed } from './allowed-hosts.mjs';
2
+ import { refForbiddenError } from './schema-load-errors.mjs';
3
+
4
+ const MAX_CHECKED_REDIRECTS = 5;
5
+ const REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
6
+ const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([101, 103, 204, 205, 304]);
7
+ async function bufferedResponse(response) {
8
+ const body = await response.arrayBuffer();
9
+ const { status, statusText, headers } = response;
10
+ return new Response(NULL_BODY_STATUSES.has(status) ? null : body, {
11
+ status,
12
+ statusText,
13
+ headers
14
+ });
15
+ }
16
+ function fetchWithTimeout(timeoutMs) {
17
+ return async (input, init = {}) => {
18
+ try {
19
+ const response = await fetch(input, { ...init, signal: AbortSignal.timeout(timeoutMs) });
20
+ return await bufferedResponse(response);
21
+ } catch (cause) {
22
+ const isTimeout = cause instanceof Error && cause.name === "TimeoutError";
23
+ throw isTimeout ? new Error(`Timed out after ${timeoutMs} ms loading ${input}`) : cause;
24
+ }
25
+ };
26
+ }
27
+ function fetchWithCheckedRedirects(fetchImpl, hosts) {
28
+ return async (input, init = {}) => {
29
+ const firstOrigin = new URL(input).origin;
30
+ let url = new URL(input);
31
+ for (let hop = 0; hop <= MAX_CHECKED_REDIRECTS; hop += 1) {
32
+ if (hop > 0 && !isHostAllowed(url, hosts)) {
33
+ throw refForbiddenError(url.href, { reason: "host-not-allowed", allowedHosts: [...hosts] });
34
+ }
35
+ const { headers, ...rest } = init;
36
+ const hopInit = url.origin === firstOrigin && headers !== void 0 ? { ...rest, headers } : rest;
37
+ const response = await fetchImpl(url.href, { ...hopInit, redirect: "manual" });
38
+ const location = response.headers.get("location");
39
+ if (!REDIRECT_STATUSES.has(response.status) || location === null) {
40
+ return response;
41
+ }
42
+ url = new URL(location, url);
43
+ }
44
+ throw new Error(`More than ${MAX_CHECKED_REDIRECTS} redirects loading ${input}`);
45
+ };
46
+ }
47
+ function resolveConfigWithAccess(resolve, options) {
48
+ const configured = resolve.http.customFetch;
49
+ const base = configured ?? fetchWithTimeout(options.timeoutMs);
50
+ const hosts = options.access.remoteHosts;
51
+ const customFetch = hosts === void 0 ? base : fetchWithCheckedRedirects(base, hosts);
52
+ return { ...resolve, http: { ...resolve.http, customFetch } };
53
+ }
54
+
55
+ export { MAX_CHECKED_REDIRECTS, fetchWithCheckedRedirects, resolveConfigWithAccess };
56
+ //# sourceMappingURL=remote-fetch.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-fetch.mjs","sources":["../../../src/adapters/redocly-loader/remote-fetch.ts"],"sourcesContent":["import type { Config as RedoclyConfig } from \"@redocly/openapi-core\";\nimport type { RefAccess } from \"../../application/ports/schema-loader.js\";\nimport { isHostAllowed } from \"./allowed-hosts.js\";\nimport { refForbiddenError } from \"./schema-load-errors.js\";\n\n/** How the loader fetches remote documents: a time limit, and the host limit on redirects. */\n\ntype ResolveConfig = RedoclyConfig[\"resolve\"];\n\n/** The fetch Redocly calls for a remote document (`resolve.http.customFetch`). */\nexport type RemoteFetch = (input: string, init?: RequestInit) => Promise<Response>;\n\n/**\n * Redirects followed for a remote `$ref` when hosts are limited. Each hop is checked, so fetch\n * cannot follow them on its own; 5 covers http → https plus a moved file, and a loop stops early.\n */\nexport const MAX_CHECKED_REDIRECTS = 5;\n\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\n\n/** Statuses whose responses have no body; `new Response()` refuses a body for them. */\nconst NULL_BODY_STATUSES = new Set([101, 103, 204, 205, 304]);\n\n/** A response whose body is already read, so that reading it again cannot wait or fail. */\nasync function bufferedResponse(response: Response): Promise<Response> {\n const body = await response.arrayBuffer();\n const { status, statusText, headers } = response;\n return new Response(NULL_BODY_STATUSES.has(status) ? null : body, {\n status,\n statusText,\n headers,\n });\n}\n\n/**\n * Fetch with a time limit for the whole response, body included: Node's own fetch waits five\n * minutes for a server that never answers, and a server that sends its body one byte at a time\n * never finishes. The body is read here, inside the limit; when Redocly read it, the abort\n * surfaced as a `DOMException` whose read-only `message` Redocly tried to change, which gave\n * \"Cannot set property message of which has only a getter\" instead of the time limit.\n */\nfunction fetchWithTimeout(timeoutMs: number): RemoteFetch {\n return async (input, init = {}) => {\n try {\n const response = await fetch(input, { ...init, signal: AbortSignal.timeout(timeoutMs) });\n return await bufferedResponse(response);\n } catch (cause) {\n const isTimeout = cause instanceof Error && cause.name === \"TimeoutError\";\n throw isTimeout ? new Error(`Timed out after ${timeoutMs} ms loading ${input}`) : cause;\n }\n };\n}\n\n/**\n * Follow redirects one by one, and refuse a redirect to a host that is not listed. The first URL\n * was checked by the resolver (or is the root document). As fetch does, the configured headers\n * (often credentials) are not sent on to another origin.\n */\nexport function fetchWithCheckedRedirects(\n fetchImpl: RemoteFetch,\n hosts: readonly string[],\n): RemoteFetch {\n return async (input, init = {}) => {\n const firstOrigin = new URL(input).origin;\n let url = new URL(input);\n for (let hop = 0; hop <= MAX_CHECKED_REDIRECTS; hop += 1) {\n if (hop > 0 && !isHostAllowed(url, hosts)) {\n throw refForbiddenError(url.href, { reason: \"host-not-allowed\", allowedHosts: [...hosts] });\n }\n const { headers, ...rest } = init;\n const hopInit: RequestInit =\n url.origin === firstOrigin && headers !== undefined ? { ...rest, headers } : rest;\n const response = await fetchImpl(url.href, { ...hopInit, redirect: \"manual\" });\n const location = response.headers.get(\"location\");\n if (!REDIRECT_STATUSES.has(response.status) || location === null) {\n return response;\n }\n url = new URL(location, url);\n }\n throw new Error(`More than ${MAX_CHECKED_REDIRECTS} redirects loading ${input}`);\n };\n}\n\nexport interface RemoteFetchOptions {\n /** Time limit of one fetch and its body, unless the Redocly config has its own `customFetch`. */\n readonly timeoutMs: number;\n readonly access: RefAccess;\n}\n\n/**\n * The resolve config with the fetch the loader uses. A `customFetch` of the Redocly config is\n * kept; with a host limit, it is wrapped so that each redirect is checked.\n */\nexport function resolveConfigWithAccess(\n resolve: ResolveConfig,\n options: RemoteFetchOptions,\n): ResolveConfig {\n // Redocly types `customFetch` as `Function`; it is called as fetch is.\n const configured = resolve.http.customFetch as RemoteFetch | undefined;\n const base = configured ?? fetchWithTimeout(options.timeoutMs);\n const hosts = options.access.remoteHosts;\n const customFetch = hosts === undefined ? base : fetchWithCheckedRedirects(base, hosts);\n return { ...resolve, http: { ...resolve.http, customFetch } };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ 'use strict';
2
+
3
+ const errors = require('../../domain/errors.cjs');
4
+
5
+ function sourceEmptyError(message) {
6
+ return new errors.OpenAPITypesafeError({ code: errors.ERROR_CODES.SCHEMA_SOURCE_EMPTY, message });
7
+ }
8
+ function sourceInvalidError(source) {
9
+ const received = Array.isArray(source) ? "Array" : typeof source;
10
+ return new errors.OpenAPITypesafeError({
11
+ code: errors.ERROR_CODES.SCHEMA_SOURCE_INVALID,
12
+ message: `Expected string, object, or Buffer. Got ${received}`,
13
+ details: { received }
14
+ });
15
+ }
16
+ function causeMessage(cause) {
17
+ return cause instanceof Error ? cause.message : String(cause);
18
+ }
19
+ const SOURCE_TEXT_IN_MESSAGE = 200;
20
+ function pathStringError(text) {
21
+ const shown = text.length > SOURCE_TEXT_IN_MESSAGE ? `${text.slice(0, SOURCE_TEXT_IN_MESSAGE)}\u2026` : text;
22
+ return new errors.OpenAPITypesafeError({
23
+ code: errors.ERROR_CODES.SCHEMA_SOURCE_INVALID,
24
+ message: `The string "${shown}" was parsed as YAML text, not loaded as a file. To load a file, pass a URL: openapiTS(pathToFileURL(path)) from node:url.`,
25
+ details: { reason: "path", received: "string" }
26
+ });
27
+ }
28
+ function loadFailedError(absoluteRef, cause) {
29
+ return new errors.OpenAPITypesafeError({
30
+ code: errors.ERROR_CODES.SCHEMA_LOAD_FAILED,
31
+ message: causeMessage(cause),
32
+ details: { source: absoluteRef },
33
+ cause
34
+ });
35
+ }
36
+ function parseFailedError(format, absoluteRef, cause) {
37
+ return new errors.OpenAPITypesafeError({
38
+ code: errors.ERROR_CODES.SCHEMA_PARSE_FAILED,
39
+ message: causeMessage(cause),
40
+ details: { format, source: absoluteRef },
41
+ cause
42
+ });
43
+ }
44
+ function versionUnsupportedError(message, parsed) {
45
+ return new errors.OpenAPITypesafeError({
46
+ code: errors.ERROR_CODES.SCHEMA_VERSION_UNSUPPORTED,
47
+ message,
48
+ details: { openapi: parsed.openapi, swagger: parsed.swagger }
49
+ });
50
+ }
51
+ function schemaInvalidError(problems) {
52
+ return new errors.OpenAPITypesafeError({
53
+ code: errors.ERROR_CODES.SCHEMA_INVALID,
54
+ message: problems.at(-1) ?? "",
55
+ details: { problems: [...problems] }
56
+ });
57
+ }
58
+ function refCycleError(cause) {
59
+ return new errors.OpenAPITypesafeError({
60
+ code: errors.ERROR_CODES.SCHEMA_REF_INVALID,
61
+ message: cause.message,
62
+ details: { reason: "cycle" },
63
+ cause
64
+ });
65
+ }
66
+ function hostListText(hosts) {
67
+ return hosts.length === 0 ? "none" : hosts.join(", ");
68
+ }
69
+ function refForbiddenError(ref, details) {
70
+ const limit = details.reason === "outside-local-root" ? `it is outside the local $ref root ${details.localRoot}` : `its host is not in the allowed remote $ref hosts (${hostListText(details.allowedHosts)})`;
71
+ return new errors.OpenAPITypesafeError({
72
+ code: errors.ERROR_CODES.SCHEMA_REF_FORBIDDEN,
73
+ message: `Refused to load ${ref}: ${limit}`,
74
+ details: { ref, ...details }
75
+ });
76
+ }
77
+
78
+ exports.loadFailedError = loadFailedError;
79
+ exports.parseFailedError = parseFailedError;
80
+ exports.pathStringError = pathStringError;
81
+ exports.refCycleError = refCycleError;
82
+ exports.refForbiddenError = refForbiddenError;
83
+ exports.schemaInvalidError = schemaInvalidError;
84
+ exports.sourceEmptyError = sourceEmptyError;
85
+ exports.sourceInvalidError = sourceInvalidError;
86
+ exports.versionUnsupportedError = versionUnsupportedError;
87
+ //# sourceMappingURL=schema-load-errors.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-load-errors.cjs","sources":["../../../src/adapters/redocly-loader/schema-load-errors.ts"],"sourcesContent":["import { ERROR_CODES, OpenAPITypesafeError } from \"../../domain/errors.js\";\n\n/**\n * The typed errors of loading, validating and bundling a document (ADR-011). Messages are the\n * original messages, so Node API users who match on them keep working.\n */\n\n/** No source was given, or the source is empty. */\nexport function sourceEmptyError(message: string): OpenAPITypesafeError {\n return new OpenAPITypesafeError({ code: ERROR_CODES.SCHEMA_SOURCE_EMPTY, message });\n}\n\n/** The source is neither a URL, text, buffer, stream nor plain object. */\nexport function sourceInvalidError(source: unknown): OpenAPITypesafeError {\n const received = Array.isArray(source) ? \"Array\" : typeof source;\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_SOURCE_INVALID,\n message: `Expected string, object, or Buffer. Got ${received}`,\n details: { received },\n });\n}\n\nfunction causeMessage(cause: unknown): string {\n return cause instanceof Error ? cause.message : String(cause);\n}\n\n/** Enough of a source string to recognise it in the message. */\nconst SOURCE_TEXT_IN_MESSAGE = 200;\n\n/**\n * A string source is document text, so a file path parses as a YAML string scalar, not as a\n * document (docs/node.md). The message says how to load the file instead.\n */\nexport function pathStringError(text: string): OpenAPITypesafeError {\n const shown =\n text.length > SOURCE_TEXT_IN_MESSAGE ? `${text.slice(0, SOURCE_TEXT_IN_MESSAGE)}…` : text;\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_SOURCE_INVALID,\n message:\n `The string \"${shown}\" was parsed as YAML text, not loaded as a file. ` +\n \"To load a file, pass a URL: openapiTS(pathToFileURL(path)) from node:url.\",\n details: { reason: \"path\", received: \"string\" },\n });\n}\n\n/** Reading the document from a file or URL failed; the message is the reader's message. */\nexport function loadFailedError(absoluteRef: string, cause: unknown): OpenAPITypesafeError {\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_LOAD_FAILED,\n message: causeMessage(cause),\n details: { source: absoluteRef },\n cause,\n });\n}\n\n/** The document text is not valid JSON or YAML; the message is the parser's message. */\nexport function parseFailedError(\n format: \"json\" | \"yaml\",\n absoluteRef: string,\n cause: unknown,\n): OpenAPITypesafeError {\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_PARSE_FAILED,\n message: causeMessage(cause),\n details: { format, source: absoluteRef },\n cause,\n });\n}\n\n/** The document is not OpenAPI 3.x. */\nexport function versionUnsupportedError(\n message: string,\n parsed: Readonly<Record<string, unknown>>,\n): OpenAPITypesafeError {\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_VERSION_UNSUPPORTED,\n message,\n details: { openapi: parsed.openapi, swagger: parsed.swagger },\n });\n}\n\n/**\n * Linting or bundling found errors. The message is the last error, as in the original; all error\n * messages are in `details.problems`.\n */\nexport function schemaInvalidError(problems: readonly string[]): OpenAPITypesafeError {\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_INVALID,\n message: problems.at(-1) ?? \"\",\n details: { problems: [...problems] },\n });\n}\n\n/** A `$ref` chain points back to itself with no schema in between (`A: $ref B`, `B: $ref A`). */\nexport function refCycleError(cause: Error): OpenAPITypesafeError {\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_REF_INVALID,\n message: cause.message,\n details: { reason: \"cycle\" },\n cause,\n });\n}\n\nfunction hostListText(hosts: readonly string[]): string {\n return hosts.length === 0 ? \"none\" : hosts.join(\", \");\n}\n\n/** Why a `$ref` document was refused, with the limit it broke (ADR-017). */\nexport type RefRefusalDetails =\n | { readonly reason: \"outside-local-root\"; readonly localRoot: string }\n | { readonly reason: \"host-not-allowed\"; readonly allowedHosts: readonly string[] };\n\n/** A `$ref` is outside the local root, or its host is not allowed (threat model R1, R2). */\nexport function refForbiddenError(ref: string, details: RefRefusalDetails): OpenAPITypesafeError {\n const limit =\n details.reason === \"outside-local-root\"\n ? `it is outside the local $ref root ${details.localRoot}`\n : `its host is not in the allowed remote $ref hosts (${hostListText(details.allowedHosts)})`;\n return new OpenAPITypesafeError({\n code: ERROR_CODES.SCHEMA_REF_FORBIDDEN,\n message: `Refused to load ${ref}: ${limit}`,\n details: { ref, ...details },\n });\n}\n"],"names":["OpenAPITypesafeError","ERROR_CODES"],"mappings":"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"}