openapi-typesafe 0.0.0 → 1.0.0-rc.0

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 (678) 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 +42 -0
  25. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -0
  26. package/dist/adapters/redocly-loader/redocly-config-source.mjs +35 -0
  27. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -0
  28. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +169 -0
  29. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -0
  30. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +167 -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 +145 -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 +139 -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 +204 -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 +201 -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-enum.cjs +44 -0
  105. package/dist/api/discriminator-enum.cjs.map +1 -0
  106. package/dist/api/discriminator-enum.mjs +42 -0
  107. package/dist/api/discriminator-enum.mjs.map +1 -0
  108. package/dist/api/discriminator-scan.cjs +168 -0
  109. package/dist/api/discriminator-scan.cjs.map +1 -0
  110. package/dist/api/discriminator-scan.mjs +165 -0
  111. package/dist/api/discriminator-scan.mjs.map +1 -0
  112. package/dist/api/document-declarations.cjs +28 -0
  113. package/dist/api/document-declarations.cjs.map +1 -0
  114. package/dist/api/document-declarations.mjs +26 -0
  115. package/dist/api/document-declarations.mjs.map +1 -0
  116. package/dist/api/document-refs.cjs +53 -0
  117. package/dist/api/document-refs.cjs.map +1 -0
  118. package/dist/api/document-refs.mjs +50 -0
  119. package/dist/api/document-refs.mjs.map +1 -0
  120. package/dist/api/document-run.cjs +107 -0
  121. package/dist/api/document-run.cjs.map +1 -0
  122. package/dist/api/document-run.mjs +101 -0
  123. package/dist/api/document-run.mjs.map +1 -0
  124. package/dist/api/footer-entry.cjs +18 -0
  125. package/dist/api/footer-entry.cjs.map +1 -0
  126. package/dist/api/footer-entry.mjs +15 -0
  127. package/dist/api/footer-entry.mjs.map +1 -0
  128. package/dist/api/footer-sink.cjs +53 -0
  129. package/dist/api/footer-sink.cjs.map +1 -0
  130. package/dist/api/footer-sink.mjs +51 -0
  131. package/dist/api/footer-sink.mjs.map +1 -0
  132. package/dist/api/legacy-callback-warning.cjs +25 -0
  133. package/dist/api/legacy-callback-warning.cjs.map +1 -0
  134. package/dist/api/legacy-callback-warning.mjs +22 -0
  135. package/dist/api/legacy-callback-warning.mjs.map +1 -0
  136. package/dist/api/legacy-ts-helpers.cjs +203 -0
  137. package/dist/api/legacy-ts-helpers.cjs.map +1 -0
  138. package/dist/api/legacy-ts-helpers.mjs +187 -0
  139. package/dist/api/legacy-ts-helpers.mjs.map +1 -0
  140. package/dist/api/legacy-utils.cjs +65 -0
  141. package/dist/api/legacy-utils.cjs.map +1 -0
  142. package/dist/api/legacy-utils.mjs +50 -0
  143. package/dist/api/legacy-utils.mjs.map +1 -0
  144. package/dist/api/openapi-ts.cjs +40 -0
  145. package/dist/api/openapi-ts.cjs.map +1 -0
  146. package/dist/api/openapi-ts.mjs +34 -0
  147. package/dist/api/openapi-ts.mjs.map +1 -0
  148. package/dist/api/schema-callbacks.cjs +140 -0
  149. package/dist/api/schema-callbacks.cjs.map +1 -0
  150. package/dist/api/schema-callbacks.mjs +136 -0
  151. package/dist/api/schema-callbacks.mjs.map +1 -0
  152. package/dist/api/string-to-ast.cjs +21 -0
  153. package/dist/api/string-to-ast.cjs.map +1 -0
  154. package/dist/api/string-to-ast.mjs +18 -0
  155. package/dist/api/string-to-ast.mjs.map +1 -0
  156. package/dist/api/transform-context.cjs +82 -0
  157. package/dist/api/transform-context.cjs.map +1 -0
  158. package/dist/api/transform-context.mjs +65 -0
  159. package/dist/api/transform-context.mjs.map +1 -0
  160. package/dist/api/transform-schema.cjs +31 -0
  161. package/dist/api/transform-schema.cjs.map +1 -0
  162. package/dist/api/transform-schema.mjs +26 -0
  163. package/dist/api/transform-schema.mjs.map +1 -0
  164. package/dist/api/type-helpers.cjs +85 -0
  165. package/dist/api/type-helpers.cjs.map +1 -0
  166. package/dist/api/type-helpers.mjs +66 -0
  167. package/dist/api/type-helpers.mjs.map +1 -0
  168. package/dist/api/unsupported-feature-warnings.cjs +17 -0
  169. package/dist/api/unsupported-feature-warnings.cjs.map +1 -0
  170. package/dist/api/unsupported-feature-warnings.mjs +15 -0
  171. package/dist/api/unsupported-feature-warnings.mjs.map +1 -0
  172. package/dist/application/print/comment-writer.cjs +95 -0
  173. package/dist/application/print/comment-writer.cjs.map +1 -0
  174. package/dist/application/print/comment-writer.mjs +93 -0
  175. package/dist/application/print/comment-writer.mjs.map +1 -0
  176. package/dist/application/print/declaration-printer.cjs +83 -0
  177. package/dist/application/print/declaration-printer.cjs.map +1 -0
  178. package/dist/application/print/declaration-printer.mjs +81 -0
  179. package/dist/application/print/declaration-printer.mjs.map +1 -0
  180. package/dist/application/print/literal-text.cjs +52 -0
  181. package/dist/application/print/literal-text.cjs.map +1 -0
  182. package/dist/application/print/literal-text.mjs +48 -0
  183. package/dist/application/print/literal-text.mjs.map +1 -0
  184. package/dist/application/print/print-nodes.cjs +38 -0
  185. package/dist/application/print/print-nodes.cjs.map +1 -0
  186. package/dist/application/print/print-nodes.mjs +36 -0
  187. package/dist/application/print/print-nodes.mjs.map +1 -0
  188. package/dist/application/print/print-options.cjs +6 -0
  189. package/dist/application/print/print-options.cjs.map +1 -0
  190. package/dist/application/print/print-options.mjs +4 -0
  191. package/dist/application/print/print-options.mjs.map +1 -0
  192. package/dist/application/print/text-writer.cjs +63 -0
  193. package/dist/application/print/text-writer.cjs.map +1 -0
  194. package/dist/application/print/text-writer.mjs +60 -0
  195. package/dist/application/print/text-writer.mjs.map +1 -0
  196. package/dist/application/print/type-printer.cjs +214 -0
  197. package/dist/application/print/type-printer.cjs.map +1 -0
  198. package/dist/application/print/type-printer.mjs +210 -0
  199. package/dist/application/print/type-printer.mjs.map +1 -0
  200. package/dist/application/stack-overflow.cjs +36 -0
  201. package/dist/application/stack-overflow.cjs.map +1 -0
  202. package/dist/application/stack-overflow.mjs +31 -0
  203. package/dist/application/stack-overflow.mjs.map +1 -0
  204. package/dist/application/transform/document/components.cjs +104 -0
  205. package/dist/application/transform/document/components.cjs.map +1 -0
  206. package/dist/application/transform/document/components.mjs +102 -0
  207. package/dist/application/transform/document/components.mjs.map +1 -0
  208. package/dist/application/transform/document/defs-root.cjs +18 -0
  209. package/dist/application/transform/document/defs-root.cjs.map +1 -0
  210. package/dist/application/transform/document/defs-root.mjs +16 -0
  211. package/dist/application/transform/document/defs-root.mjs.map +1 -0
  212. package/dist/application/transform/document/document-member.cjs +13 -0
  213. package/dist/application/transform/document/document-member.cjs.map +1 -0
  214. package/dist/application/transform/document/document-member.mjs +11 -0
  215. package/dist/application/transform/document/document-member.mjs.map +1 -0
  216. package/dist/application/transform/document/document.cjs +86 -0
  217. package/dist/application/transform/document/document.cjs.map +1 -0
  218. package/dist/application/transform/document/document.mjs +83 -0
  219. package/dist/application/transform/document/document.mjs.map +1 -0
  220. package/dist/application/transform/document/header.cjs +27 -0
  221. package/dist/application/transform/document/header.cjs.map +1 -0
  222. package/dist/application/transform/document/header.mjs +25 -0
  223. package/dist/application/transform/document/header.mjs.map +1 -0
  224. package/dist/application/transform/document/kept-deprecated.cjs +96 -0
  225. package/dist/application/transform/document/kept-deprecated.cjs.map +1 -0
  226. package/dist/application/transform/document/kept-deprecated.mjs +94 -0
  227. package/dist/application/transform/document/kept-deprecated.mjs.map +1 -0
  228. package/dist/application/transform/document/media-type.cjs +42 -0
  229. package/dist/application/transform/document/media-type.cjs.map +1 -0
  230. package/dist/application/transform/document/media-type.mjs +38 -0
  231. package/dist/application/transform/document/media-type.mjs.map +1 -0
  232. package/dist/application/transform/document/operation.cjs +45 -0
  233. package/dist/application/transform/document/operation.cjs.map +1 -0
  234. package/dist/application/transform/document/operation.mjs +43 -0
  235. package/dist/application/transform/document/operation.mjs.map +1 -0
  236. package/dist/application/transform/document/parameter.cjs +25 -0
  237. package/dist/application/transform/document/parameter.cjs.map +1 -0
  238. package/dist/application/transform/document/parameter.mjs +23 -0
  239. package/dist/application/transform/document/parameter.mjs.map +1 -0
  240. package/dist/application/transform/document/parameters.cjs +114 -0
  241. package/dist/application/transform/document/parameters.cjs.map +1 -0
  242. package/dist/application/transform/document/parameters.mjs +112 -0
  243. package/dist/application/transform/document/parameters.mjs.map +1 -0
  244. package/dist/application/transform/document/path-item-conflicts.cjs +51 -0
  245. package/dist/application/transform/document/path-item-conflicts.cjs.map +1 -0
  246. package/dist/application/transform/document/path-item-conflicts.mjs +49 -0
  247. package/dist/application/transform/document/path-item-conflicts.mjs.map +1 -0
  248. package/dist/application/transform/document/path-item.cjs +82 -0
  249. package/dist/application/transform/document/path-item.cjs.map +1 -0
  250. package/dist/application/transform/document/path-item.mjs +80 -0
  251. package/dist/application/transform/document/path-item.mjs.map +1 -0
  252. package/dist/application/transform/document/path-key-overlaps.cjs +57 -0
  253. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -0
  254. package/dist/application/transform/document/path-key-overlaps.mjs +55 -0
  255. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -0
  256. package/dist/application/transform/document/paths-enum.cjs +75 -0
  257. package/dist/application/transform/document/paths-enum.cjs.map +1 -0
  258. package/dist/application/transform/document/paths-enum.mjs +72 -0
  259. package/dist/application/transform/document/paths-enum.mjs.map +1 -0
  260. package/dist/application/transform/document/paths.cjs +127 -0
  261. package/dist/application/transform/document/paths.cjs.map +1 -0
  262. package/dist/application/transform/document/paths.mjs +125 -0
  263. package/dist/application/transform/document/paths.mjs.map +1 -0
  264. package/dist/application/transform/document/request-body.cjs +36 -0
  265. package/dist/application/transform/document/request-body.cjs.map +1 -0
  266. package/dist/application/transform/document/request-body.mjs +34 -0
  267. package/dist/application/transform/document/request-body.mjs.map +1 -0
  268. package/dist/application/transform/document/response.cjs +59 -0
  269. package/dist/application/transform/document/response.cjs.map +1 -0
  270. package/dist/application/transform/document/response.mjs +57 -0
  271. package/dist/application/transform/document/response.mjs.map +1 -0
  272. package/dist/application/transform/document/responses.cjs +23 -0
  273. package/dist/application/transform/document/responses.cjs.map +1 -0
  274. package/dist/application/transform/document/responses.mjs +21 -0
  275. package/dist/application/transform/document/responses.mjs.map +1 -0
  276. package/dist/application/transform/document/root-type-aliases.cjs +69 -0
  277. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -0
  278. package/dist/application/transform/document/root-type-aliases.mjs +65 -0
  279. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -0
  280. package/dist/application/transform/document/webhooks.cjs +19 -0
  281. package/dist/application/transform/document/webhooks.cjs.map +1 -0
  282. package/dist/application/transform/document/webhooks.mjs +17 -0
  283. package/dist/application/transform/document/webhooks.mjs.map +1 -0
  284. package/dist/application/transform/document-entries.cjs +17 -0
  285. package/dist/application/transform/document-entries.cjs.map +1 -0
  286. package/dist/application/transform/document-entries.mjs +14 -0
  287. package/dist/application/transform/document-entries.mjs.map +1 -0
  288. package/dist/application/transform/footer/document-footer.cjs +88 -0
  289. package/dist/application/transform/footer/document-footer.cjs.map +1 -0
  290. package/dist/application/transform/footer/document-footer.mjs +86 -0
  291. package/dist/application/transform/footer/document-footer.mjs.map +1 -0
  292. package/dist/application/transform/footer/enum-naming.cjs +121 -0
  293. package/dist/application/transform/footer/enum-naming.cjs.map +1 -0
  294. package/dist/application/transform/footer/enum-naming.mjs +115 -0
  295. package/dist/application/transform/footer/enum-naming.mjs.map +1 -0
  296. package/dist/application/transform/helper-types.cjs +68 -0
  297. package/dist/application/transform/helper-types.cjs.map +1 -0
  298. package/dist/application/transform/helper-types.mjs +65 -0
  299. package/dist/application/transform/helper-types.mjs.map +1 -0
  300. package/dist/application/transform/literal-type.cjs +36 -0
  301. package/dist/application/transform/literal-type.cjs.map +1 -0
  302. package/dist/application/transform/literal-type.mjs +34 -0
  303. package/dist/application/transform/literal-type.mjs.map +1 -0
  304. package/dist/application/transform/numbered-names.cjs +18 -0
  305. package/dist/application/transform/numbered-names.cjs.map +1 -0
  306. package/dist/application/transform/numbered-names.mjs +16 -0
  307. package/dist/application/transform/numbered-names.mjs.map +1 -0
  308. package/dist/application/transform/ref-type.cjs +57 -0
  309. package/dist/application/transform/ref-type.cjs.map +1 -0
  310. package/dist/application/transform/ref-type.mjs +54 -0
  311. package/dist/application/transform/ref-type.mjs.map +1 -0
  312. package/dist/application/transform/schema/array-type.cjs +105 -0
  313. package/dist/application/transform/schema/array-type.cjs.map +1 -0
  314. package/dist/application/transform/schema/array-type.mjs +103 -0
  315. package/dist/application/transform/schema/array-type.mjs.map +1 -0
  316. package/dist/application/transform/schema/composition-type.cjs +107 -0
  317. package/dist/application/transform/schema/composition-type.cjs.map +1 -0
  318. package/dist/application/transform/schema/composition-type.mjs +105 -0
  319. package/dist/application/transform/schema/composition-type.mjs.map +1 -0
  320. package/dist/application/transform/schema/core-type.cjs +84 -0
  321. package/dist/application/transform/schema/core-type.cjs.map +1 -0
  322. package/dist/application/transform/schema/core-type.mjs +82 -0
  323. package/dist/application/transform/schema/core-type.mjs.map +1 -0
  324. package/dist/application/transform/schema/discriminator-property.cjs +21 -0
  325. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -0
  326. package/dist/application/transform/schema/discriminator-property.mjs +19 -0
  327. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -0
  328. package/dist/application/transform/schema/enum-rule.cjs +107 -0
  329. package/dist/application/transform/schema/enum-rule.cjs.map +1 -0
  330. package/dist/application/transform/schema/enum-rule.mjs +105 -0
  331. package/dist/application/transform/schema/enum-rule.mjs.map +1 -0
  332. package/dist/application/transform/schema/object-type.cjs +173 -0
  333. package/dist/application/transform/schema/object-type.cjs.map +1 -0
  334. package/dist/application/transform/schema/object-type.mjs +170 -0
  335. package/dist/application/transform/schema/object-type.mjs.map +1 -0
  336. package/dist/application/transform/schema/presence-members.cjs +59 -0
  337. package/dist/application/transform/schema/presence-members.cjs.map +1 -0
  338. package/dist/application/transform/schema/presence-members.mjs +57 -0
  339. package/dist/application/transform/schema/presence-members.mjs.map +1 -0
  340. package/dist/application/transform/schema/schema-transform.cjs +72 -0
  341. package/dist/application/transform/schema/schema-transform.cjs.map +1 -0
  342. package/dist/application/transform/schema/schema-transform.mjs +68 -0
  343. package/dist/application/transform/schema/schema-transform.mjs.map +1 -0
  344. package/dist/application/transform/schema/unevaluated-properties.cjs +61 -0
  345. package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -0
  346. package/dist/application/transform/schema/unevaluated-properties.mjs +59 -0
  347. package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -0
  348. package/dist/application/transform/schema-comment.cjs +84 -0
  349. package/dist/application/transform/schema-comment.cjs.map +1 -0
  350. package/dist/application/transform/schema-comment.mjs +81 -0
  351. package/dist/application/transform/schema-comment.mjs.map +1 -0
  352. package/dist/application/transform/shared-types.cjs +8 -0
  353. package/dist/application/transform/shared-types.cjs.map +1 -0
  354. package/dist/application/transform/shared-types.mjs +6 -0
  355. package/dist/application/transform/shared-types.mjs.map +1 -0
  356. package/dist/application/transform/type-combinators.cjs +49 -0
  357. package/dist/application/transform/type-combinators.cjs.map +1 -0
  358. package/dist/application/transform/type-combinators.mjs +42 -0
  359. package/dist/application/transform/type-combinators.mjs.map +1 -0
  360. package/dist/cli/cli-arguments.cjs +137 -0
  361. package/dist/cli/cli-arguments.cjs.map +1 -0
  362. package/dist/cli/cli-arguments.mjs +129 -0
  363. package/dist/cli/cli-arguments.mjs.map +1 -0
  364. package/dist/cli/cli-errors.cjs +80 -0
  365. package/dist/cli/cli-errors.cjs.map +1 -0
  366. package/dist/cli/cli-errors.mjs +76 -0
  367. package/dist/cli/cli-errors.mjs.map +1 -0
  368. package/dist/cli/cli-output.cjs +37 -0
  369. package/dist/cli/cli-output.cjs.map +1 -0
  370. package/dist/cli/cli-output.mjs +30 -0
  371. package/dist/cli/cli-output.mjs.map +1 -0
  372. package/dist/cli/docs-links.cjs +6 -0
  373. package/dist/cli/docs-links.cjs.map +1 -0
  374. package/dist/cli/docs-links.mjs +4 -0
  375. package/dist/cli/docs-links.mjs.map +1 -0
  376. package/dist/cli/fix-option.cjs +19 -0
  377. package/dist/cli/fix-option.cjs.map +1 -0
  378. package/dist/cli/fix-option.mjs +16 -0
  379. package/dist/cli/fix-option.mjs.map +1 -0
  380. package/dist/cli/help-text.cjs +44 -0
  381. package/dist/cli/help-text.cjs.map +1 -0
  382. package/dist/cli/help-text.mjs +42 -0
  383. package/dist/cli/help-text.mjs.map +1 -0
  384. package/dist/cli/main.cjs +62 -0
  385. package/dist/cli/main.cjs.map +1 -0
  386. package/dist/cli/main.d.cts +2 -0
  387. package/dist/cli/main.d.mts +2 -0
  388. package/dist/cli/main.d.ts +2 -0
  389. package/dist/cli/main.mjs +54 -0
  390. package/dist/cli/main.mjs.map +1 -0
  391. package/dist/cli/redocly-apis.cjs +65 -0
  392. package/dist/cli/redocly-apis.cjs.map +1 -0
  393. package/dist/cli/redocly-apis.mjs +62 -0
  394. package/dist/cli/redocly-apis.mjs.map +1 -0
  395. package/dist/cli/ref-limits.cjs +14 -0
  396. package/dist/cli/ref-limits.cjs.map +1 -0
  397. package/dist/cli/ref-limits.mjs +12 -0
  398. package/dist/cli/ref-limits.mjs.map +1 -0
  399. package/dist/cli/run-cli.cjs +100 -0
  400. package/dist/cli/run-cli.cjs.map +1 -0
  401. package/dist/cli/run-cli.mjs +98 -0
  402. package/dist/cli/run-cli.mjs.map +1 -0
  403. package/dist/domain/assert-never.cjs +8 -0
  404. package/dist/domain/assert-never.cjs.map +1 -0
  405. package/dist/domain/assert-never.mjs +6 -0
  406. package/dist/domain/assert-never.mjs.map +1 -0
  407. package/dist/domain/errors.cjs +50 -0
  408. package/dist/domain/errors.cjs.map +1 -0
  409. package/dist/domain/errors.mjs +46 -0
  410. package/dist/domain/errors.mjs.map +1 -0
  411. package/dist/domain/ir/constructors.cjs +89 -0
  412. package/dist/domain/ir/constructors.cjs.map +1 -0
  413. package/dist/domain/ir/constructors.mjs +71 -0
  414. package/dist/domain/ir/constructors.mjs.map +1 -0
  415. package/dist/domain/ir/identifier-text.cjs +29 -0
  416. package/dist/domain/ir/identifier-text.cjs.map +1 -0
  417. package/dist/domain/ir/identifier-text.mjs +25 -0
  418. package/dist/domain/ir/identifier-text.mjs.map +1 -0
  419. package/dist/domain/ir/newer-identifier-ranges.cjs +109 -0
  420. package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -0
  421. package/dist/domain/ir/newer-identifier-ranges.mjs +106 -0
  422. package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -0
  423. package/dist/domain/ir/normalize.cjs +32 -0
  424. package/dist/domain/ir/normalize.cjs.map +1 -0
  425. package/dist/domain/ir/normalize.mjs +29 -0
  426. package/dist/domain/ir/normalize.mjs.map +1 -0
  427. package/dist/domain/ir/property-name.cjs +19 -0
  428. package/dist/domain/ir/property-name.cjs.map +1 -0
  429. package/dist/domain/ir/property-name.mjs +16 -0
  430. package/dist/domain/ir/property-name.mjs.map +1 -0
  431. package/dist/domain/ir/raw-text-escapes.cjs +25 -0
  432. package/dist/domain/ir/raw-text-escapes.cjs.map +1 -0
  433. package/dist/domain/ir/raw-text-escapes.mjs +22 -0
  434. package/dist/domain/ir/raw-text-escapes.mjs.map +1 -0
  435. package/dist/domain/openapi/alias-expansion.cjs +50 -0
  436. package/dist/domain/openapi/alias-expansion.cjs.map +1 -0
  437. package/dist/domain/openapi/alias-expansion.mjs +45 -0
  438. package/dist/domain/openapi/alias-expansion.mjs.map +1 -0
  439. package/dist/domain/openapi/binary-content.cjs +48 -0
  440. package/dist/domain/openapi/binary-content.cjs.map +1 -0
  441. package/dist/domain/openapi/binary-content.mjs +45 -0
  442. package/dist/domain/openapi/binary-content.mjs.map +1 -0
  443. package/dist/domain/openapi/components-object.cjs +29 -0
  444. package/dist/domain/openapi/components-object.cjs.map +1 -0
  445. package/dist/domain/openapi/components-object.mjs +24 -0
  446. package/dist/domain/openapi/components-object.mjs.map +1 -0
  447. package/dist/domain/openapi/json-pointer.cjs +31 -0
  448. package/dist/domain/openapi/json-pointer.cjs.map +1 -0
  449. package/dist/domain/openapi/json-pointer.mjs +27 -0
  450. package/dist/domain/openapi/json-pointer.mjs.map +1 -0
  451. package/dist/domain/openapi/media-type-object.cjs +14 -0
  452. package/dist/domain/openapi/media-type-object.cjs.map +1 -0
  453. package/dist/domain/openapi/media-type-object.mjs +11 -0
  454. package/dist/domain/openapi/media-type-object.mjs.map +1 -0
  455. package/dist/domain/openapi/parameter-object.cjs +13 -0
  456. package/dist/domain/openapi/parameter-object.cjs.map +1 -0
  457. package/dist/domain/openapi/parameter-object.mjs +10 -0
  458. package/dist/domain/openapi/parameter-object.mjs.map +1 -0
  459. package/dist/domain/openapi/path-item-object.cjs +35 -0
  460. package/dist/domain/openapi/path-item-object.cjs.map +1 -0
  461. package/dist/domain/openapi/path-item-object.mjs +30 -0
  462. package/dist/domain/openapi/path-item-object.mjs.map +1 -0
  463. package/dist/domain/openapi/unsupported-features.cjs +87 -0
  464. package/dist/domain/openapi/unsupported-features.cjs.map +1 -0
  465. package/dist/domain/openapi/unsupported-features.mjs +84 -0
  466. package/dist/domain/openapi/unsupported-features.mjs.map +1 -0
  467. package/dist/domain/output-fixes.cjs +66 -0
  468. package/dist/domain/output-fixes.cjs.map +1 -0
  469. package/dist/domain/output-fixes.mjs +59 -0
  470. package/dist/domain/output-fixes.mjs.map +1 -0
  471. package/dist/index.cjs +98 -0
  472. package/dist/index.cjs.map +1 -0
  473. package/dist/index.d.cts +812 -0
  474. package/dist/index.d.mts +812 -0
  475. package/dist/index.d.ts +812 -0
  476. package/dist/index.mjs +27 -0
  477. package/dist/index.mjs.map +1 -0
  478. package/dist/transform/components-object.cjs +14 -0
  479. package/dist/transform/components-object.cjs.map +1 -0
  480. package/dist/transform/components-object.mjs +10 -0
  481. package/dist/transform/components-object.mjs.map +1 -0
  482. package/dist/transform/header-object.cjs +12 -0
  483. package/dist/transform/header-object.cjs.map +1 -0
  484. package/dist/transform/header-object.mjs +10 -0
  485. package/dist/transform/header-object.mjs.map +1 -0
  486. package/dist/transform/media-type-object.cjs +12 -0
  487. package/dist/transform/media-type-object.cjs.map +1 -0
  488. package/dist/transform/media-type-object.mjs +10 -0
  489. package/dist/transform/media-type-object.mjs.map +1 -0
  490. package/dist/transform/operation-object.cjs +26 -0
  491. package/dist/transform/operation-object.cjs.map +1 -0
  492. package/dist/transform/operation-object.mjs +21 -0
  493. package/dist/transform/operation-object.mjs.map +1 -0
  494. package/dist/transform/parameter-object.cjs +12 -0
  495. package/dist/transform/parameter-object.cjs.map +1 -0
  496. package/dist/transform/parameter-object.mjs +10 -0
  497. package/dist/transform/parameter-object.mjs.map +1 -0
  498. package/dist/transform/path-item-object.cjs +12 -0
  499. package/dist/transform/path-item-object.cjs.map +1 -0
  500. package/dist/transform/path-item-object.mjs +10 -0
  501. package/dist/transform/path-item-object.mjs.map +1 -0
  502. package/dist/transform/paths-object.cjs +11 -0
  503. package/dist/transform/paths-object.cjs.map +1 -0
  504. package/dist/transform/paths-object.mjs +9 -0
  505. package/dist/transform/paths-object.mjs.map +1 -0
  506. package/dist/transform/request-body-object.cjs +12 -0
  507. package/dist/transform/request-body-object.cjs.map +1 -0
  508. package/dist/transform/request-body-object.mjs +10 -0
  509. package/dist/transform/request-body-object.mjs.map +1 -0
  510. package/dist/transform/response-object.cjs +12 -0
  511. package/dist/transform/response-object.cjs.map +1 -0
  512. package/dist/transform/response-object.mjs +10 -0
  513. package/dist/transform/response-object.mjs.map +1 -0
  514. package/dist/transform/responses-object.cjs +12 -0
  515. package/dist/transform/responses-object.cjs.map +1 -0
  516. package/dist/transform/responses-object.mjs +10 -0
  517. package/dist/transform/responses-object.mjs.map +1 -0
  518. package/dist/transform/schema-object.cjs +21 -0
  519. package/dist/transform/schema-object.cjs.map +1 -0
  520. package/dist/transform/schema-object.mjs +16 -0
  521. package/dist/transform/schema-object.mjs.map +1 -0
  522. package/package.json +115 -4
  523. package/src/adapters/node-file-system/node-file-system.ts +44 -0
  524. package/src/adapters/redocly-loader/alias-limit.ts +20 -0
  525. package/src/adapters/redocly-loader/allowed-hosts.ts +62 -0
  526. package/src/adapters/redocly-loader/bundled-ref-repair.ts +65 -0
  527. package/src/adapters/redocly-loader/malformed-refs.ts +61 -0
  528. package/src/adapters/redocly-loader/redocly-config-source.ts +43 -0
  529. package/src/adapters/redocly-loader/redocly-schema-loader.ts +246 -0
  530. package/src/adapters/redocly-loader/ref-access.ts +146 -0
  531. package/src/adapters/redocly-loader/ref-holders.ts +43 -0
  532. package/src/adapters/redocly-loader/remote-fetch.ts +104 -0
  533. package/src/adapters/redocly-loader/schema-load-errors.ts +124 -0
  534. package/src/adapters/redocly-loader/schema-source.ts +151 -0
  535. package/src/adapters/redocly-loader/unsupported-keys.ts +102 -0
  536. package/src/adapters/terminal-logger/terminal-logger.ts +98 -0
  537. package/src/adapters/type-ast-bridge/footer-nodes.ts +38 -0
  538. package/src/adapters/type-ast-bridge/ir-declarations-to-typescript.ts +100 -0
  539. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +220 -0
  540. package/src/adapters/type-ast-bridge/lazy-node.ts +24 -0
  541. package/src/adapters/type-ast-bridge/load-typescript.ts +84 -0
  542. package/src/adapters/type-ast-bridge/print-typescript.ts +33 -0
  543. package/src/adapters/type-ast-bridge/typescript-raw-text.ts +49 -0
  544. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +280 -0
  545. package/src/adapters/type-ast-bridge/typescript-types.ts +8 -0
  546. package/src/api/ast-to-string.ts +59 -0
  547. package/src/api/comment-header.ts +7 -0
  548. package/src/api/default-ports.ts +44 -0
  549. package/src/api/discriminator-enum.ts +76 -0
  550. package/src/api/discriminator-scan.ts +272 -0
  551. package/src/api/document-declarations.ts +41 -0
  552. package/src/api/document-refs.ts +71 -0
  553. package/src/api/document-run.ts +159 -0
  554. package/src/api/footer-entry.ts +23 -0
  555. package/src/api/footer-sink.ts +67 -0
  556. package/src/api/legacy-callback-warning.ts +29 -0
  557. package/src/api/legacy-ts-helpers.ts +311 -0
  558. package/src/api/legacy-utils.ts +118 -0
  559. package/src/api/openapi-ts.ts +62 -0
  560. package/src/api/schema-callbacks.ts +211 -0
  561. package/src/api/string-to-ast.ts +27 -0
  562. package/src/api/transform-context.ts +87 -0
  563. package/src/api/transform-schema.ts +39 -0
  564. package/src/api/type-helpers.ts +130 -0
  565. package/src/api/unsupported-feature-warnings.ts +26 -0
  566. package/src/application/ports/file-system.ts +12 -0
  567. package/src/application/ports/logger.ts +16 -0
  568. package/src/application/ports/redocly-config-source.ts +16 -0
  569. package/src/application/ports/schema-loader.ts +32 -0
  570. package/src/application/print/comment-writer.ts +91 -0
  571. package/src/application/print/declaration-printer.ts +100 -0
  572. package/src/application/print/literal-text.ts +62 -0
  573. package/src/application/print/print-nodes.ts +62 -0
  574. package/src/application/print/print-options.ts +11 -0
  575. package/src/application/print/text-writer.ts +83 -0
  576. package/src/application/print/type-printer.ts +281 -0
  577. package/src/application/stack-overflow.ts +54 -0
  578. package/src/application/transform/document/components.ts +189 -0
  579. package/src/application/transform/document/defs-root.ts +25 -0
  580. package/src/application/transform/document/document-member.ts +20 -0
  581. package/src/application/transform/document/document.ts +157 -0
  582. package/src/application/transform/document/header.ts +34 -0
  583. package/src/application/transform/document/kept-deprecated.ts +135 -0
  584. package/src/application/transform/document/media-type.ts +78 -0
  585. package/src/application/transform/document/operation.ts +64 -0
  586. package/src/application/transform/document/parameter.ts +45 -0
  587. package/src/application/transform/document/parameters.ts +200 -0
  588. package/src/application/transform/document/path-item-conflicts.ts +79 -0
  589. package/src/application/transform/document/path-item.ts +168 -0
  590. package/src/application/transform/document/path-key-overlaps.ts +112 -0
  591. package/src/application/transform/document/paths-enum.ts +127 -0
  592. package/src/application/transform/document/paths.ts +211 -0
  593. package/src/application/transform/document/request-body.ts +50 -0
  594. package/src/application/transform/document/response.ts +109 -0
  595. package/src/application/transform/document/responses.ts +29 -0
  596. package/src/application/transform/document/root-type-aliases.ts +106 -0
  597. package/src/application/transform/document/webhooks.ts +22 -0
  598. package/src/application/transform/document-entries.ts +28 -0
  599. package/src/application/transform/footer/document-footer.ts +127 -0
  600. package/src/application/transform/footer/enum-naming.ts +181 -0
  601. package/src/application/transform/helper-types.ts +92 -0
  602. package/src/application/transform/literal-type.ts +54 -0
  603. package/src/application/transform/numbered-names.ts +20 -0
  604. package/src/application/transform/ref-type.ts +97 -0
  605. package/src/application/transform/schema/array-type.ts +152 -0
  606. package/src/application/transform/schema/composition-type.ts +183 -0
  607. package/src/application/transform/schema/core-type.ts +115 -0
  608. package/src/application/transform/schema/discriminator-property.ts +28 -0
  609. package/src/application/transform/schema/enum-rule.ts +157 -0
  610. package/src/application/transform/schema/object-type.ts +271 -0
  611. package/src/application/transform/schema/presence-members.ts +96 -0
  612. package/src/application/transform/schema/schema-context.ts +110 -0
  613. package/src/application/transform/schema/schema-rule.ts +29 -0
  614. package/src/application/transform/schema/schema-transform.ts +99 -0
  615. package/src/application/transform/schema/unevaluated-properties.ts +105 -0
  616. package/src/application/transform/schema-comment.ts +116 -0
  617. package/src/application/transform/shared-types.ts +9 -0
  618. package/src/application/transform/transform-context.ts +51 -0
  619. package/src/application/transform/type-combinators.ts +57 -0
  620. package/src/cli/cli-arguments.ts +198 -0
  621. package/src/cli/cli-dependencies.ts +42 -0
  622. package/src/cli/cli-errors.ts +125 -0
  623. package/src/cli/cli-output.ts +53 -0
  624. package/src/cli/docs-links.ts +6 -0
  625. package/src/cli/fix-option.ts +29 -0
  626. package/src/cli/help-text.ts +52 -0
  627. package/src/cli/main.ts +67 -0
  628. package/src/cli/redocly-apis.ts +91 -0
  629. package/src/cli/ref-limits.ts +16 -0
  630. package/src/cli/run-cli.ts +114 -0
  631. package/src/domain/assert-never.ts +8 -0
  632. package/src/domain/errors.ts +74 -0
  633. package/src/domain/ir/constructors.ts +137 -0
  634. package/src/domain/ir/identifier-text.ts +49 -0
  635. package/src/domain/ir/newer-identifier-ranges.ts +109 -0
  636. package/src/domain/ir/nodes.ts +224 -0
  637. package/src/domain/ir/normalize.ts +51 -0
  638. package/src/domain/ir/property-name.ts +28 -0
  639. package/src/domain/ir/raw-text-escapes.ts +37 -0
  640. package/src/domain/openapi/alias-expansion.ts +72 -0
  641. package/src/domain/openapi/binary-content.ts +74 -0
  642. package/src/domain/openapi/components-object.ts +52 -0
  643. package/src/domain/openapi/document-object.ts +12 -0
  644. package/src/domain/openapi/header-object.ts +9 -0
  645. package/src/domain/openapi/json-pointer.ts +46 -0
  646. package/src/domain/openapi/media-type-object.ts +26 -0
  647. package/src/domain/openapi/operation-object.ts +13 -0
  648. package/src/domain/openapi/parameter-object.ts +30 -0
  649. package/src/domain/openapi/path-item-object.ts +70 -0
  650. package/src/domain/openapi/request-body-object.ts +7 -0
  651. package/src/domain/openapi/response-object.ts +14 -0
  652. package/src/domain/openapi/schema-object.ts +59 -0
  653. package/src/domain/openapi/unsupported-features.ts +139 -0
  654. package/src/domain/output-fixes.ts +95 -0
  655. package/src/index.ts +67 -0
  656. package/src/transform/components-object.ts +25 -0
  657. package/src/transform/header-object.ts +19 -0
  658. package/src/transform/media-type-object.ts +19 -0
  659. package/src/transform/operation-object.ts +36 -0
  660. package/src/transform/parameter-object.ts +19 -0
  661. package/src/transform/parameters-array.ts +19 -0
  662. package/src/transform/path-item-object.ts +22 -0
  663. package/src/transform/paths-enum.ts +8 -0
  664. package/src/transform/paths-object.ts +15 -0
  665. package/src/transform/request-body-object.ts +19 -0
  666. package/src/transform/response-object.ts +19 -0
  667. package/src/transform/responses-object.ts +19 -0
  668. package/src/transform/schema-object.ts +36 -0
  669. package/src/transform/webhooks-object.ts +15 -0
  670. package/src/types/generator-options.ts +267 -0
  671. package/src/types/openapi-common.ts +100 -0
  672. package/src/types/openapi-document.ts +196 -0
  673. package/src/types/openapi-path-item.ts +130 -0
  674. package/src/types/openapi-request.ts +209 -0
  675. package/src/types/openapi-response.ts +81 -0
  676. package/src/types/openapi-schema.ts +169 -0
  677. package/src/types/openapi-security.ts +116 -0
  678. package/src/types.ts +12 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * YAML aliases (`*name`) make the parsed document share objects. A "billion laughs" document,
3
+ * where each level refers to the previous one ten times, parses into a few hundred objects that
4
+ * every walk over the document (Redocly's resolver, the generator) visits as 10^9 nodes: the run
5
+ * took minutes and ended with "RangeError: Set maximum size exceeded" (pre-beta test plan 10.2).
6
+ * A document is refused when its aliases expand it far beyond what it stores.
7
+ */
8
+
9
+ /** Expansion below this many nodes is allowed whatever the ratio: large real documents pass. */
10
+ export const ALIAS_EXPANSION_MIN_NODES = 1_000_000;
11
+ /** Real documents reuse anchors a few times; a bomb multiplies its size by orders of magnitude. */
12
+ export const ALIAS_EXPANSION_MAX_RATIO = 100;
13
+
14
+ export interface NodeCounts {
15
+ /** Nodes of the document as written: each object once, with its entries. */
16
+ readonly stored: number;
17
+ /** Nodes a walk visits when it follows every shared object again. */
18
+ readonly expanded: number;
19
+ }
20
+
21
+ function childrenOf(node: object): unknown[] {
22
+ return Array.isArray(node) ? node : Object.values(node);
23
+ }
24
+
25
+ function isContainer(value: unknown): value is object {
26
+ return typeof value === "object" && value !== null;
27
+ }
28
+
29
+ /** The expanded size of `node`, whose container children are all sized (or in a cycle). */
30
+ function sizeOf(node: object, sizes: ReadonlyMap<object, number>): number {
31
+ return childrenOf(node).reduce<number>(
32
+ (total, child) => total + (isContainer(child) ? (sizes.get(child) ?? 1) : 1),
33
+ 1,
34
+ );
35
+ }
36
+
37
+ /**
38
+ * Count stored and expanded nodes without recursion (documents can be thousands of levels deep)
39
+ * and without expanding: each shared object is sized once. A cycle counts its back edge once.
40
+ */
41
+ export function countNodes(root: unknown): NodeCounts {
42
+ if (!isContainer(root)) {
43
+ return { stored: 1, expanded: 1 };
44
+ }
45
+ const sizes = new Map<object, number>();
46
+ const entered = new Set<object>();
47
+ const stack: object[] = [root];
48
+ while (stack.length > 0) {
49
+ const node = stack[stack.length - 1] as object;
50
+ const isFirstVisit = !entered.has(node);
51
+ entered.add(node);
52
+ const pending = isFirstVisit
53
+ ? childrenOf(node).filter((child) => isContainer(child) && !entered.has(child))
54
+ : [];
55
+ if (pending.length > 0) {
56
+ stack.push(...(pending as object[]));
57
+ continue;
58
+ }
59
+ stack.pop();
60
+ sizes.set(node, sizeOf(node, sizes));
61
+ }
62
+ let stored = 0;
63
+ for (const node of sizes.keys()) {
64
+ stored += 1 + childrenOf(node).filter((child) => !isContainer(child)).length;
65
+ }
66
+ return { stored, expanded: sizes.get(root) ?? 1 };
67
+ }
68
+
69
+ /** Whether the aliases of a parsed document expand it beyond the limits above. */
70
+ export function isAliasExpansionExcessive({ stored, expanded }: NodeCounts): boolean {
71
+ return expanded > Math.max(ALIAS_EXPANSION_MIN_NODES, stored * ALIAS_EXPANSION_MAX_RATIO);
72
+ }
@@ -0,0 +1,74 @@
1
+ import type { SchemaObject } from "./schema-object.js";
2
+
3
+ /**
4
+ * Which string schemas describe raw binary data, following "Working with Binary Data" of the
5
+ * OpenAPI specification (3.1): `format: binary` in 3.0, a `contentMediaType` without a
6
+ * `contentEncoding` in 3.1. `--binary-as-blob` types these as `Blob`.
7
+ * https://spec.openapis.org/oas/v3.1.1.html#working-with-binary-data
8
+ */
9
+
10
+ /** The OpenAPI 3.0 format of unencoded octets (`byte` is base64 text). */
11
+ const BINARY_FORMAT = "binary";
12
+
13
+ /** The top-level media type whose contents are always text (RFC 2046). */
14
+ const TEXT_TOP_LEVEL_TYPE = "text";
15
+
16
+ /** The top-level media type of the text formats in `TEXT_APPLICATION_SUBTYPES`. */
17
+ const APPLICATION_TOP_LEVEL_TYPE = "application";
18
+
19
+ /**
20
+ * Text syntaxes, as a subtype (`application/json`) or a structured syntax suffix
21
+ * (`application/problem+json`, `image/svg+xml`; RFC 6839, RFC 9512).
22
+ */
23
+ const TEXT_STRUCTURED_SYNTAXES: ReadonlySet<string> = new Set(["json", "xml", "yaml"]);
24
+
25
+ /** Other text formats under `application/`, registered or in common use. */
26
+ const TEXT_APPLICATION_SUBTYPES: ReadonlySet<string> = new Set([
27
+ "ecmascript",
28
+ "graphql",
29
+ "javascript",
30
+ "json-seq",
31
+ "jsonl",
32
+ "sql",
33
+ "x-ndjson",
34
+ "x-www-form-urlencoded",
35
+ "x-yaml",
36
+ ]);
37
+
38
+ const PARAMETER_SEPARATOR = ";";
39
+ const SUBTYPE_SEPARATOR = "/";
40
+ const SUFFIX_SEPARATOR = "+";
41
+
42
+ /**
43
+ * Whether a media type's contents are text, so a string schema with it holds the text itself.
44
+ * Parameters (`; charset=utf-8`) and case are ignored; a value without a subtype is not text.
45
+ */
46
+ export function isTextualMediaType(mediaType: string): boolean {
47
+ const essence = (mediaType.split(PARAMETER_SEPARATOR)[0] ?? "").trim().toLowerCase();
48
+ const [topLevelType, subtype] = essence.split(SUBTYPE_SEPARATOR);
49
+ if (topLevelType === undefined || subtype === undefined) {
50
+ return false;
51
+ }
52
+ if (topLevelType === TEXT_TOP_LEVEL_TYPE) {
53
+ return true;
54
+ }
55
+ const suffix = subtype.slice(subtype.lastIndexOf(SUFFIX_SEPARATOR) + 1);
56
+ if (TEXT_STRUCTURED_SYNTAXES.has(subtype) || TEXT_STRUCTURED_SYNTAXES.has(suffix)) {
57
+ return true;
58
+ }
59
+ return topLevelType === APPLICATION_TOP_LEVEL_TYPE && TEXT_APPLICATION_SUBTYPES.has(subtype);
60
+ }
61
+
62
+ /**
63
+ * Whether a schema describes raw (unencoded) binary data. Any `contentEncoding` means the value
64
+ * is encoded text, so it wins over `format: binary`.
65
+ */
66
+ export function isRawBinarySchema(schema: SchemaObject): boolean {
67
+ if (schema.contentEncoding !== undefined) {
68
+ return false;
69
+ }
70
+ if (schema.format === BINARY_FORMAT) {
71
+ return true;
72
+ }
73
+ return schema.contentMediaType !== undefined && !isTextualMediaType(schema.contentMediaType);
74
+ }
@@ -0,0 +1,52 @@
1
+ import { MEDIA_TYPES_COMPONENT_KIND } from "./media-type-object.js";
2
+
3
+ /**
4
+ * The component maps the generator always writes, in output order (OpenAPI 3.1 §4.8.7); a kind the
5
+ * document lacks is `never`.
6
+ */
7
+ export const COMPONENT_KINDS = Object.freeze([
8
+ "schemas",
9
+ "responses",
10
+ "parameters",
11
+ "requestBodies",
12
+ "headers",
13
+ "pathItems",
14
+ ] as const);
15
+
16
+ /**
17
+ * OpenAPI 3.2 component maps, written after `COMPONENT_KINDS` and only when the document has them,
18
+ * so documents without them keep their output (ADR-020).
19
+ */
20
+ export const DECLARED_COMPONENT_KINDS = Object.freeze([MEDIA_TYPES_COMPONENT_KIND] as const);
21
+
22
+ export type ComponentKind =
23
+ | (typeof COMPONENT_KINDS)[number]
24
+ | (typeof DECLARED_COMPONENT_KINDS)[number];
25
+
26
+ /** Components by kind and name; entries are read by each kind's transformer. */
27
+ export type ComponentsObject = {
28
+ readonly [kind in ComponentKind]?: Readonly<Record<string, unknown>>;
29
+ };
30
+
31
+ /** `requestBodies` → `requestBody`; other kinds drop the final `s`. */
32
+ export function singularizeComponentKind(kind: ComponentKind | `x-${string}`): string {
33
+ return kind === "requestBodies" ? "requestBody" : kind.slice(0, -1);
34
+ }
35
+
36
+ /**
37
+ * Whether a schema is an enum that `--enum` turns into a TypeScript enum. With `--root-types`
38
+ * such schemas get no root alias, because the enum is already exported under that name.
39
+ */
40
+ export function isEnumSchema(schema: unknown): boolean {
41
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema)) {
42
+ return false;
43
+ }
44
+ const record = schema as Record<string, unknown>;
45
+ return (
46
+ "enum" in record &&
47
+ Array.isArray(record.enum) &&
48
+ (!("type" in record) || record.type !== "object") &&
49
+ !("properties" in record) &&
50
+ !("additionalProperties" in record)
51
+ );
52
+ }
@@ -0,0 +1,12 @@
1
+ import type { ComponentsObject } from "./components-object.js";
2
+ import type { PathsObject } from "./path-item-object.js";
3
+ import type { Schema } from "./schema-object.js";
4
+
5
+ /** The parts of an OpenAPI document that get a root type (OpenAPI 3.1 §4.8.1). */
6
+ export interface DocumentObject {
7
+ readonly paths?: PathsObject;
8
+ readonly webhooks?: PathsObject;
9
+ readonly components?: ComponentsObject;
10
+ /** JSON Schema definitions at the document root: named subschemas. */
11
+ readonly $defs?: Readonly<Record<string, Schema>>;
12
+ }
@@ -0,0 +1,9 @@
1
+ import type { ContentMap } from "./media-type-object.js";
2
+ import type { Schema } from "./schema-object.js";
3
+
4
+ /** The parts of a Header Object the generator reads (OpenAPI 3.1 §4.8.21). */
5
+ export interface HeaderObject {
6
+ readonly required?: boolean;
7
+ readonly schema?: Schema;
8
+ readonly content?: ContentMap;
9
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The JSON Pointer of a `$ref` as path segments, with the semantics of Redocly's `parseRef`, which
3
+ * the original generator used: the part after the first `#/`, split at `/`, each segment unescaped
4
+ * (`~1` → `/`, `~0` → `~`, then percent-decoding), and empty segments dropped.
5
+ *
6
+ * Throws URIError for a malformed percent escape, as the original does.
7
+ */
8
+ export function parseRefPointer(ref: string): string[] {
9
+ const [, pointer = ""] = ref.split("#/");
10
+ return pointer
11
+ .split("/")
12
+ .map(unescapePointerSegment)
13
+ .filter((segment) => segment.length > 0);
14
+ }
15
+
16
+ function unescapePointerSegment(segment: string): string {
17
+ return decodeURIComponent(segment.replaceAll("~1", "/").replaceAll("~0", "~"));
18
+ }
19
+
20
+ /**
21
+ * Escape one segment for a JSON Pointer in a `$ref` fragment: `~` → `~0`, `/` → `~1`, and `%` →
22
+ * `%25`, because reading a pointer back percent-decodes it. The original did not escape `%`, so a
23
+ * name like `50%` threw URIError and `a%2Fb` read back as `a/b` (upstream #2251, #2828).
24
+ */
25
+ export function escapePointerSegment(segment: string): string {
26
+ return segment.replaceAll("~", "~0").replaceAll("/", "~1").replaceAll("%", "%25");
27
+ }
28
+
29
+ /**
30
+ * Join parts into a local `$ref` (the original `createRef`). Empty parts are skipped. A part that
31
+ * is itself a `$ref` contributes its segments; any other part is one segment.
32
+ */
33
+ export function createRef(parts: readonly (string | number | null | undefined)[]): string {
34
+ let ref = "#";
35
+ for (const part of parts) {
36
+ if (part === undefined || part === null || part === "") {
37
+ continue;
38
+ }
39
+ const text = String(part);
40
+ const segments = parseRefPointer(text);
41
+ for (const segment of segments.length > 0 ? segments : [text]) {
42
+ ref += `/${escapePointerSegment(segment)}`;
43
+ }
44
+ }
45
+ return ref;
46
+ }
@@ -0,0 +1,26 @@
1
+ import { parseRefPointer } from "./json-pointer.js";
2
+ import type { ReferenceSchema, Schema } from "./schema-object.js";
3
+
4
+ /** The parts of a Media Type Object the generator reads (OpenAPI 3.2 §4.8.14). */
5
+ export interface MediaTypeObject {
6
+ /** The complete content. */
7
+ readonly schema?: Schema;
8
+ /** Each item of a sequential media type such as `application/jsonl` (OpenAPI 3.2). */
9
+ readonly itemSchema?: Schema;
10
+ }
11
+
12
+ /** A `content` map: media type name to a Media Type Object or a `$ref` to one. */
13
+ export type ContentMap = Readonly<Record<string, MediaTypeObject | ReferenceSchema>>;
14
+
15
+ const COMPONENTS_SEGMENT = "components";
16
+ /** The OpenAPI 3.2 component map of reusable Media Type Objects. */
17
+ export const MEDIA_TYPES_COMPONENT_KIND = "mediaTypes";
18
+
19
+ /**
20
+ * Whether a `content` entry's `$ref` points into `components.mediaTypes` (OpenAPI 3.2). Other
21
+ * `$ref`s in `content` keep the output they had before 3.2 (ADR-020).
22
+ */
23
+ export function isMediaTypeComponentRef(ref: string): boolean {
24
+ const [root, kind] = parseRefPointer(ref);
25
+ return ref.startsWith("#/") && root === COMPONENTS_SEGMENT && kind === MEDIA_TYPES_COMPONENT_KIND;
26
+ }
@@ -0,0 +1,13 @@
1
+ import type { ParameterOrReference } from "./parameter-object.js";
2
+ import type { RequestBodyObject } from "./request-body-object.js";
3
+ import type { ResponsesObject } from "./response-object.js";
4
+ import type { ReferenceSchema } from "./schema-object.js";
5
+
6
+ /** The parts of an Operation Object the generator reads (OpenAPI 3.1 §4.8.10). */
7
+ export interface OperationObject {
8
+ readonly operationId?: string;
9
+ readonly deprecated?: boolean;
10
+ readonly parameters?: readonly ParameterOrReference[];
11
+ readonly requestBody?: RequestBodyObject | ReferenceSchema;
12
+ readonly responses?: ResponsesObject;
13
+ }
@@ -0,0 +1,30 @@
1
+ import type { ContentMap } from "./media-type-object.js";
2
+ import type { ReferenceSchema, Schema } from "./schema-object.js";
3
+
4
+ export type ParameterLocation = "query" | "header" | "path" | "cookie";
5
+
6
+ /** Every parameter location, in the order the generated `parameters` type lists them. */
7
+ export const PARAMETER_LOCATIONS: readonly ParameterLocation[] = Object.freeze([
8
+ "query",
9
+ "header",
10
+ "path",
11
+ "cookie",
12
+ ]);
13
+
14
+ /**
15
+ * The OpenAPI 3.2 location of a parameter that is the whole query string, described by `content`.
16
+ * Its type becomes the `query` member of `parameters` (ADR-020).
17
+ */
18
+ export const QUERYSTRING_LOCATION = "querystring";
19
+
20
+ /** The parts of a Parameter Object the generator reads (OpenAPI 3.2 §4.8.12). */
21
+ export interface ParameterObject {
22
+ readonly name: string;
23
+ readonly in: ParameterLocation | typeof QUERYSTRING_LOCATION;
24
+ readonly required?: boolean;
25
+ readonly deprecated?: boolean;
26
+ readonly schema?: Schema;
27
+ readonly content?: ContentMap;
28
+ }
29
+
30
+ export type ParameterOrReference = ParameterObject | ReferenceSchema;
@@ -0,0 +1,70 @@
1
+ import type { OperationObject } from "./operation-object.js";
2
+ import type { ParameterOrReference } from "./parameter-object.js";
3
+ import type { ReferenceSchema } from "./schema-object.js";
4
+
5
+ /** The methods every generated path item lists, with `?: never` when the document has none. */
6
+ export type HttpMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace";
7
+
8
+ /** The operation fields of a path item, in the order the generated types list them. */
9
+ export const HTTP_METHODS: readonly HttpMethod[] = Object.freeze([
10
+ "get",
11
+ "put",
12
+ "post",
13
+ "delete",
14
+ "options",
15
+ "head",
16
+ "patch",
17
+ "trace",
18
+ ]);
19
+
20
+ /**
21
+ * The OpenAPI 3.2 QUERY method. Its member is written only when the path item declares it, so
22
+ * documents without it keep their output (ADR-020).
23
+ */
24
+ export const QUERY_METHOD = "query";
25
+
26
+ /** Every operation field of a path item. */
27
+ export type PathItemMethod = HttpMethod | typeof QUERY_METHOD;
28
+
29
+ /** The OpenAPI 3.2 path item field for methods other than the fixed fields, by exact name. */
30
+ export const ADDITIONAL_OPERATIONS_KEY = "additionalOperations";
31
+
32
+ export type OperationEntry = OperationObject | ReferenceSchema;
33
+
34
+ /** The parts of a Path Item Object the generator reads (OpenAPI 3.2 §4.8.9). */
35
+ export type PathItemObject = {
36
+ readonly parameters?: readonly ParameterOrReference[];
37
+ readonly additionalOperations?: Readonly<Record<string, OperationEntry>>;
38
+ } & { readonly [method in PathItemMethod]?: OperationEntry };
39
+
40
+ /** Path items by URL template (OpenAPI 3.1 §4.8.8); webhooks use the same shape by name. */
41
+ export type PathsObject = Readonly<Record<string, PathItemObject | ReferenceSchema>>;
42
+
43
+ /** One operation of a path item and the method it is declared under. */
44
+ export interface PathItemOperation {
45
+ /** A fixed field (`get`, `query`, …) or an `additionalOperations` name (`SUBSCRIBE`). */
46
+ readonly method: string;
47
+ readonly operation: OperationEntry;
48
+ /** JSON Pointer segments from the path item to the operation. */
49
+ readonly segments: readonly string[];
50
+ }
51
+
52
+ /**
53
+ * Every operation of a path item: the fixed methods in output order, then `query`, then
54
+ * `additionalOperations` in document order.
55
+ */
56
+ export function pathItemOperations(pathItem: PathItemObject): PathItemOperation[] {
57
+ const methods: readonly PathItemMethod[] = [...HTTP_METHODS, QUERY_METHOD];
58
+ const fixed = methods.flatMap((method) => {
59
+ const operation = pathItem[method];
60
+ return operation ? [{ method, operation, segments: [method] }] : [];
61
+ });
62
+ const additional = Object.entries(pathItem.additionalOperations ?? {}).map(
63
+ ([method, operation]) => ({
64
+ method,
65
+ operation,
66
+ segments: [ADDITIONAL_OPERATIONS_KEY, method],
67
+ }),
68
+ );
69
+ return [...fixed, ...additional];
70
+ }
@@ -0,0 +1,7 @@
1
+ import type { ContentMap } from "./media-type-object.js";
2
+
3
+ /** The parts of a Request Body Object the generator reads (OpenAPI 3.1 §4.8.13). */
4
+ export interface RequestBodyObject {
5
+ readonly required?: boolean;
6
+ readonly content?: ContentMap;
7
+ }
@@ -0,0 +1,14 @@
1
+ import type { HeaderObject } from "./header-object.js";
2
+ import type { ContentMap } from "./media-type-object.js";
3
+ import type { ReferenceSchema } from "./schema-object.js";
4
+
5
+ /** The parts of a Response Object the generator reads (OpenAPI 3.1 §4.8.17). */
6
+ export interface ResponseObject {
7
+ /** Written into the JSDoc of the response's member. */
8
+ readonly description?: string;
9
+ readonly headers?: Readonly<Record<string, HeaderObject | ReferenceSchema>>;
10
+ readonly content?: ContentMap;
11
+ }
12
+
13
+ /** Responses by status code or `default` (OpenAPI 3.1 §4.8.16). */
14
+ export type ResponsesObject = Readonly<Record<string, ResponseObject | ReferenceSchema>>;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The parts of an OpenAPI / JSON Schema object that the schema transformer reads. Documents are
3
+ * validated by the loader, so fields are typed as the specification defines them; places where the
4
+ * original generator tolerates other input check the value at run time.
5
+ */
6
+
7
+ export interface ReferenceSchema {
8
+ readonly $ref: string;
9
+ }
10
+
11
+ /** A schema: an object, a reference, or a boolean schema (`true` allows anything). */
12
+ export type Schema = SchemaObject | ReferenceSchema | boolean;
13
+
14
+ export type SchemaTypeName =
15
+ | "string"
16
+ | "number"
17
+ | "integer"
18
+ | "boolean"
19
+ | "null"
20
+ | "array"
21
+ | "object";
22
+
23
+ export interface SchemaDiscriminator {
24
+ /** Optional since OpenAPI 3.2; a discriminator without it adds no property type. */
25
+ readonly propertyName?: string;
26
+ readonly mapping?: Readonly<Record<string, string>>;
27
+ }
28
+
29
+ export interface SchemaObject {
30
+ readonly type?: SchemaTypeName | readonly (SchemaTypeName | null)[];
31
+ readonly const?: unknown;
32
+ readonly enum?: readonly unknown[];
33
+ readonly nullable?: boolean;
34
+ readonly format?: string;
35
+ readonly contentMediaType?: string;
36
+ readonly contentEncoding?: string;
37
+ readonly properties?: Readonly<Record<string, Schema>>;
38
+ readonly required?: readonly string[];
39
+ readonly additionalProperties?: Schema | Readonly<Record<string, never>>;
40
+ readonly patternProperties?: Readonly<Record<string, Schema>>;
41
+ readonly unevaluatedProperties?: Schema | Readonly<Record<string, never>>;
42
+ readonly $defs?: Readonly<Record<string, SchemaObject>>;
43
+ readonly items?: Schema | readonly Schema[];
44
+ readonly prefixItems?: readonly Schema[];
45
+ readonly minItems?: number;
46
+ readonly maxItems?: number;
47
+ readonly allOf?: readonly Schema[];
48
+ readonly anyOf?: readonly Schema[];
49
+ readonly oneOf?: readonly Schema[];
50
+ readonly discriminator?: SchemaDiscriminator;
51
+ readonly readOnly?: boolean;
52
+ readonly writeOnly?: boolean;
53
+ readonly default?: unknown;
54
+ readonly deprecated?: boolean;
55
+ readonly "x-enum-varnames"?: readonly string[];
56
+ readonly "x-enumNames"?: readonly string[];
57
+ readonly "x-enum-descriptions"?: readonly string[];
58
+ readonly "x-enumDescriptions"?: readonly string[];
59
+ }
@@ -0,0 +1,139 @@
1
+ import { createRef, parseRefPointer } from "./json-pointer.js";
2
+ import { QUERYSTRING_LOCATION } from "./parameter-object.js";
3
+ import { type PathItemObject, pathItemOperations } from "./path-item-object.js";
4
+
5
+ /**
6
+ * OpenAPI 3.2 uses that the generated types leave out, so each one gets a warning. The 3.2
7
+ * features are typed (ADR-020); what is left is an `in: querystring` parameter next to
8
+ * `in: query` parameters of the same operation, which 3.2 does not allow: the `query`
9
+ * parameters keep their types and the `querystring` parameter is not in the output.
10
+ */
11
+ export const UnsupportedFeature = {
12
+ QUERYSTRING_NEXT_TO_QUERY: "querystring",
13
+ } as const;
14
+ export type UnsupportedFeature = (typeof UnsupportedFeature)[keyof typeof UnsupportedFeature];
15
+
16
+ /** One place in the document that uses a feature the output leaves out. */
17
+ export interface UnsupportedFeatureUse {
18
+ readonly feature: UnsupportedFeature;
19
+ /** A JSON Pointer to the object that has the feature's key, such as `#/paths/~1items`. */
20
+ readonly pointer: string;
21
+ }
22
+
23
+ const QUERY_LOCATION = "query";
24
+ const LOCAL_REF_PREFIX = "#/";
25
+
26
+ type JsonObject = Readonly<Record<string, unknown>>;
27
+
28
+ function isObject(value: unknown): value is JsonObject {
29
+ return typeof value === "object" && value !== null && !Array.isArray(value);
30
+ }
31
+
32
+ /** The value at a local `$ref` (`#/...`) of the document; null for other or broken `$ref`s. */
33
+ function resolveLocal(document: JsonObject, value: unknown): unknown {
34
+ if (!isObject(value) || typeof value.$ref !== "string") {
35
+ return value;
36
+ }
37
+ if (!value.$ref.startsWith(LOCAL_REF_PREFIX)) {
38
+ return null;
39
+ }
40
+ let node: unknown = document;
41
+ for (const segment of parseRefPointer(value.$ref)) {
42
+ node = isObject(node) || Array.isArray(node) ? (node as JsonObject)[segment] : undefined;
43
+ }
44
+ return node ?? null;
45
+ }
46
+
47
+ /** A parameter where it is written, with the object its `$ref` points to. */
48
+ interface LocatedParameter {
49
+ readonly pointer: string;
50
+ readonly parameter: JsonObject;
51
+ }
52
+
53
+ function locatedParameters(
54
+ document: JsonObject,
55
+ parameters: unknown,
56
+ segments: readonly string[],
57
+ ): LocatedParameter[] {
58
+ if (!Array.isArray(parameters)) {
59
+ return [];
60
+ }
61
+ return parameters.flatMap((entry, index) => {
62
+ const parameter = resolveLocal(document, entry);
63
+ const pointer = createRef([...segments, String(index)]);
64
+ return isObject(parameter) ? [{ pointer, parameter }] : [];
65
+ });
66
+ }
67
+
68
+ /** Path item parameters, then the operation's, which replace those of the same `in` and name. */
69
+ function mergedParameters(
70
+ shared: readonly LocatedParameter[],
71
+ own: readonly LocatedParameter[],
72
+ ): LocatedParameter[] {
73
+ const byKey = new Map<string, LocatedParameter>();
74
+ for (const located of [...shared, ...own]) {
75
+ byKey.set(`${String(located.parameter.in)}-${String(located.parameter.name)}`, located);
76
+ }
77
+ return [...byKey.values()];
78
+ }
79
+
80
+ /** The `querystring` parameters of one operation that has `in: query` parameters as well. */
81
+ function querystringPointers(parameters: readonly LocatedParameter[]): string[] {
82
+ const hasQuery = parameters.some(({ parameter }) => parameter.in === QUERY_LOCATION);
83
+ return hasQuery
84
+ ? parameters
85
+ .filter(({ parameter }) => parameter.in === QUERYSTRING_LOCATION)
86
+ .map(({ pointer }) => pointer)
87
+ : [];
88
+ }
89
+
90
+ /** Pointers of `querystring` parameters next to `query` ones in the operations of a path item. */
91
+ function pathItemPointers(
92
+ document: JsonObject,
93
+ pathItem: JsonObject,
94
+ segments: readonly string[],
95
+ ): string[] {
96
+ const shared = locatedParameters(document, pathItem.parameters, [...segments, "parameters"]);
97
+ return pathItemOperations(pathItem as PathItemObject).flatMap((entry) => {
98
+ const operation = resolveLocal(document, entry.operation);
99
+ if (!isObject(operation)) {
100
+ return [];
101
+ }
102
+ const operationSegments = [...segments, ...entry.segments, "parameters"];
103
+ const own = locatedParameters(document, operation.parameters, operationSegments);
104
+ return querystringPointers(mergedParameters(shared, own));
105
+ });
106
+ }
107
+
108
+ function pathItemsPointers(
109
+ document: JsonObject,
110
+ pathItems: unknown,
111
+ root: readonly string[],
112
+ ): string[] {
113
+ if (!isObject(pathItems)) {
114
+ return [];
115
+ }
116
+ return Object.entries(pathItems).flatMap(([key, pathItem]) =>
117
+ isObject(pathItem) ? pathItemPointers(document, pathItem, [...root, key]) : [],
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Every use of a feature in `UnsupportedFeature`, once per pointer, in document order: `paths`,
123
+ * then `webhooks`, then `components.pathItems`.
124
+ */
125
+ export function findUnsupportedFeatures(document: unknown): UnsupportedFeatureUse[] {
126
+ if (!isObject(document)) {
127
+ return [];
128
+ }
129
+ const components = isObject(document.components) ? document.components : {};
130
+ const pointers = [
131
+ ...pathItemsPointers(document, document.paths, ["paths"]),
132
+ ...pathItemsPointers(document, document.webhooks, ["webhooks"]),
133
+ ...pathItemsPointers(document, components.pathItems, ["components", "pathItems"]),
134
+ ];
135
+ return [...new Set(pointers)].map((pointer) => ({
136
+ feature: UnsupportedFeature.QUERYSTRING_NEXT_TO_QUERY,
137
+ pointer,
138
+ }));
139
+ }