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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/CHANGELOG.md +1831 -0
  2. package/dist/adapters/node-file-system/file-claims.cjs +105 -0
  3. package/dist/adapters/node-file-system/file-claims.cjs.map +1 -0
  4. package/dist/adapters/node-file-system/file-claims.mjs +95 -0
  5. package/dist/adapters/node-file-system/file-claims.mjs.map +1 -0
  6. package/dist/adapters/node-file-system/file-identity.cjs +82 -0
  7. package/dist/adapters/node-file-system/file-identity.cjs.map +1 -0
  8. package/dist/adapters/node-file-system/file-identity.mjs +74 -0
  9. package/dist/adapters/node-file-system/file-identity.mjs.map +1 -0
  10. package/dist/adapters/node-file-system/node-file-system.cjs +90 -14
  11. package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -1
  12. package/dist/adapters/node-file-system/node-file-system.mjs +90 -14
  13. package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +75 -0
  15. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -0
  16. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +72 -0
  17. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -0
  18. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs +1 -1
  19. package/dist/adapters/redocly-loader/bundled-ref-repair.cjs.map +1 -1
  20. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs +2 -2
  21. package/dist/adapters/redocly-loader/bundled-ref-repair.mjs.map +1 -1
  22. package/dist/adapters/redocly-loader/loaded-documents.cjs +28 -0
  23. package/dist/adapters/redocly-loader/loaded-documents.cjs.map +1 -0
  24. package/dist/adapters/redocly-loader/loaded-documents.mjs +21 -0
  25. package/dist/adapters/redocly-loader/loaded-documents.mjs.map +1 -0
  26. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +14 -15
  27. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  28. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +12 -13
  29. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  30. package/dist/adapters/redocly-loader/ref-access.cjs +31 -3
  31. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  32. package/dist/adapters/redocly-loader/ref-access.mjs +31 -3
  33. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  34. package/dist/adapters/redocly-loader/ref-holders.cjs +2 -2
  35. package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
  36. package/dist/adapters/redocly-loader/ref-holders.mjs +3 -3
  37. package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
  38. package/dist/adapters/redocly-loader/remote-body-limit.cjs +50 -0
  39. package/dist/adapters/redocly-loader/remote-body-limit.cjs.map +1 -0
  40. package/dist/adapters/redocly-loader/remote-body-limit.mjs +48 -0
  41. package/dist/adapters/redocly-loader/remote-body-limit.mjs.map +1 -0
  42. package/dist/adapters/redocly-loader/remote-fetch.cjs +35 -6
  43. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  44. package/dist/adapters/redocly-loader/remote-fetch.mjs +35 -6
  45. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  46. package/dist/adapters/redocly-loader/remote-node-limit.cjs +47 -0
  47. package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -0
  48. package/dist/adapters/redocly-loader/remote-node-limit.mjs +44 -0
  49. package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -0
  50. package/dist/adapters/redocly-loader/schema-load-errors.cjs +32 -8
  51. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
  52. package/dist/adapters/redocly-loader/schema-load-errors.mjs +32 -9
  53. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
  54. package/dist/adapters/redocly-loader/schema-source.cjs +11 -7
  55. package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
  56. package/dist/adapters/redocly-loader/schema-source.mjs +12 -8
  57. package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
  58. package/dist/adapters/redocly-loader/unsupported-keys.cjs +3 -5
  59. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
  60. package/dist/adapters/redocly-loader/unsupported-keys.mjs +3 -5
  61. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
  62. package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
  63. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  64. package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
  65. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  66. package/dist/api/default-ports.cjs +14 -2
  67. package/dist/api/default-ports.cjs.map +1 -1
  68. package/dist/api/default-ports.mjs +14 -2
  69. package/dist/api/default-ports.mjs.map +1 -1
  70. package/dist/api/discriminator-enum-parent.cjs +2 -2
  71. package/dist/api/discriminator-enum-parent.cjs.map +1 -1
  72. package/dist/api/discriminator-enum-parent.mjs +3 -3
  73. package/dist/api/discriminator-enum-parent.mjs.map +1 -1
  74. package/dist/api/discriminator-other-owners.cjs +5 -3
  75. package/dist/api/discriminator-other-owners.cjs.map +1 -1
  76. package/dist/api/discriminator-other-owners.mjs +5 -3
  77. package/dist/api/discriminator-other-owners.mjs.map +1 -1
  78. package/dist/api/discriminator-patch.cjs +5 -1
  79. package/dist/api/discriminator-patch.cjs.map +1 -1
  80. package/dist/api/discriminator-patch.mjs +5 -1
  81. package/dist/api/discriminator-patch.mjs.map +1 -1
  82. package/dist/api/discriminator-scan.cjs +15 -8
  83. package/dist/api/discriminator-scan.cjs.map +1 -1
  84. package/dist/api/discriminator-scan.mjs +15 -8
  85. package/dist/api/discriminator-scan.mjs.map +1 -1
  86. package/dist/api/document-run.cjs +2 -2
  87. package/dist/api/document-run.cjs.map +1 -1
  88. package/dist/api/document-run.mjs +2 -2
  89. package/dist/api/document-run.mjs.map +1 -1
  90. package/dist/api/legacy-utils.cjs.map +1 -1
  91. package/dist/api/legacy-utils.mjs.map +1 -1
  92. package/dist/api/openapi-ts.cjs +8 -4
  93. package/dist/api/openapi-ts.cjs.map +1 -1
  94. package/dist/api/openapi-ts.mjs +8 -5
  95. package/dist/api/openapi-ts.mjs.map +1 -1
  96. package/dist/api/schema-callbacks.cjs +36 -12
  97. package/dist/api/schema-callbacks.cjs.map +1 -1
  98. package/dist/api/schema-callbacks.mjs +36 -12
  99. package/dist/api/schema-callbacks.mjs.map +1 -1
  100. package/dist/api/transform-context.cjs +7 -3
  101. package/dist/api/transform-context.cjs.map +1 -1
  102. package/dist/api/transform-context.mjs +7 -3
  103. package/dist/api/transform-context.mjs.map +1 -1
  104. package/dist/api/transform-schema.cjs +40 -10
  105. package/dist/api/transform-schema.cjs.map +1 -1
  106. package/dist/api/transform-schema.mjs +41 -11
  107. package/dist/api/transform-schema.mjs.map +1 -1
  108. package/dist/application/print/text-writer.cjs +10 -3
  109. package/dist/application/print/text-writer.cjs.map +1 -1
  110. package/dist/application/print/text-writer.mjs +10 -3
  111. package/dist/application/print/text-writer.mjs.map +1 -1
  112. package/dist/application/stack-overflow.cjs +2 -1
  113. package/dist/application/stack-overflow.cjs.map +1 -1
  114. package/dist/application/stack-overflow.mjs +2 -1
  115. package/dist/application/stack-overflow.mjs.map +1 -1
  116. package/dist/application/transform/document/components.cjs +1 -1
  117. package/dist/application/transform/document/components.cjs.map +1 -1
  118. package/dist/application/transform/document/components.mjs +2 -2
  119. package/dist/application/transform/document/components.mjs.map +1 -1
  120. package/dist/application/transform/document/declared-type-names.cjs +23 -0
  121. package/dist/application/transform/document/declared-type-names.cjs.map +1 -0
  122. package/dist/application/transform/document/declared-type-names.mjs +20 -0
  123. package/dist/application/transform/document/declared-type-names.mjs.map +1 -0
  124. package/dist/application/transform/document/defs-root.cjs +1 -1
  125. package/dist/application/transform/document/defs-root.cjs.map +1 -1
  126. package/dist/application/transform/document/defs-root.mjs +2 -2
  127. package/dist/application/transform/document/defs-root.mjs.map +1 -1
  128. package/dist/application/transform/document/document.cjs +4 -1
  129. package/dist/application/transform/document/document.cjs.map +1 -1
  130. package/dist/application/transform/document/document.mjs +3 -2
  131. package/dist/application/transform/document/document.mjs.map +1 -1
  132. package/dist/application/transform/document/enum-names-given-back.cjs +62 -0
  133. package/dist/application/transform/document/enum-names-given-back.cjs.map +1 -0
  134. package/dist/application/transform/document/enum-names-given-back.mjs +58 -0
  135. package/dist/application/transform/document/enum-names-given-back.mjs.map +1 -0
  136. package/dist/application/transform/document/global-type-references.cjs +1 -0
  137. package/dist/application/transform/document/global-type-references.cjs.map +1 -1
  138. package/dist/application/transform/document/global-type-references.mjs +1 -1
  139. package/dist/application/transform/document/global-type-references.mjs.map +1 -1
  140. package/dist/application/transform/document/media-type.cjs +2 -2
  141. package/dist/application/transform/document/media-type.cjs.map +1 -1
  142. package/dist/application/transform/document/media-type.mjs +3 -3
  143. package/dist/application/transform/document/media-type.mjs.map +1 -1
  144. package/dist/application/transform/document/operation-keys-written.cjs +26 -0
  145. package/dist/application/transform/document/operation-keys-written.cjs.map +1 -0
  146. package/dist/application/transform/document/operation-keys-written.mjs +24 -0
  147. package/dist/application/transform/document/operation-keys-written.mjs.map +1 -0
  148. package/dist/application/transform/document/operation.cjs +1 -1
  149. package/dist/application/transform/document/operation.cjs.map +1 -1
  150. package/dist/application/transform/document/operation.mjs +2 -2
  151. package/dist/application/transform/document/operation.mjs.map +1 -1
  152. package/dist/application/transform/document/parameter-entries.cjs +34 -0
  153. package/dist/application/transform/document/parameter-entries.cjs.map +1 -0
  154. package/dist/application/transform/document/parameter-entries.mjs +30 -0
  155. package/dist/application/transform/document/parameter-entries.mjs.map +1 -0
  156. package/dist/application/transform/document/parameter.cjs +12 -4
  157. package/dist/application/transform/document/parameter.cjs.map +1 -1
  158. package/dist/application/transform/document/parameter.mjs +13 -5
  159. package/dist/application/transform/document/parameter.mjs.map +1 -1
  160. package/dist/application/transform/document/parameters.cjs +6 -29
  161. package/dist/application/transform/document/parameters.cjs.map +1 -1
  162. package/dist/application/transform/document/parameters.mjs +6 -29
  163. package/dist/application/transform/document/parameters.mjs.map +1 -1
  164. package/dist/application/transform/document/path-item.cjs +11 -14
  165. package/dist/application/transform/document/path-item.cjs.map +1 -1
  166. package/dist/application/transform/document/path-item.mjs +12 -16
  167. package/dist/application/transform/document/path-item.mjs.map +1 -1
  168. package/dist/application/transform/document/paths-enum.cjs +1 -0
  169. package/dist/application/transform/document/paths-enum.cjs.map +1 -1
  170. package/dist/application/transform/document/paths-enum.mjs +1 -1
  171. package/dist/application/transform/document/paths-enum.mjs.map +1 -1
  172. package/dist/application/transform/document/paths.cjs +5 -1
  173. package/dist/application/transform/document/paths.cjs.map +1 -1
  174. package/dist/application/transform/document/paths.mjs +6 -2
  175. package/dist/application/transform/document/paths.mjs.map +1 -1
  176. package/dist/application/transform/document/referenced-parameter.cjs +80 -0
  177. package/dist/application/transform/document/referenced-parameter.cjs.map +1 -0
  178. package/dist/application/transform/document/referenced-parameter.mjs +78 -0
  179. package/dist/application/transform/document/referenced-parameter.mjs.map +1 -0
  180. package/dist/application/transform/document/request-body.cjs +1 -1
  181. package/dist/application/transform/document/request-body.cjs.map +1 -1
  182. package/dist/application/transform/document/request-body.mjs +2 -2
  183. package/dist/application/transform/document/request-body.mjs.map +1 -1
  184. package/dist/application/transform/document/response.cjs +2 -2
  185. package/dist/application/transform/document/response.cjs.map +1 -1
  186. package/dist/application/transform/document/response.mjs +3 -3
  187. package/dist/application/transform/document/response.mjs.map +1 -1
  188. package/dist/application/transform/document/responses.cjs +1 -1
  189. package/dist/application/transform/document/responses.cjs.map +1 -1
  190. package/dist/application/transform/document/responses.mjs +2 -2
  191. package/dist/application/transform/document/responses.mjs.map +1 -1
  192. package/dist/application/transform/document/root-type-aliases.cjs +8 -23
  193. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  194. package/dist/application/transform/document/root-type-aliases.mjs +8 -24
  195. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  196. package/dist/application/transform/document/type-resolution.cjs +3 -1
  197. package/dist/application/transform/document/type-resolution.cjs.map +1 -1
  198. package/dist/application/transform/document/type-resolution.mjs +3 -1
  199. package/dist/application/transform/document/type-resolution.mjs.map +1 -1
  200. package/dist/application/transform/document/webhooks.cjs +1 -1
  201. package/dist/application/transform/document/webhooks.cjs.map +1 -1
  202. package/dist/application/transform/document/webhooks.mjs +2 -2
  203. package/dist/application/transform/document/webhooks.mjs.map +1 -1
  204. package/dist/application/transform/footer/document-footer.cjs +10 -2
  205. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  206. package/dist/application/transform/footer/document-footer.mjs +10 -2
  207. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  208. package/dist/application/transform/footer/enum-name-claims.cjs +48 -0
  209. package/dist/application/transform/footer/enum-name-claims.cjs.map +1 -0
  210. package/dist/application/transform/footer/enum-name-claims.mjs +46 -0
  211. package/dist/application/transform/footer/enum-name-claims.mjs.map +1 -0
  212. package/dist/application/transform/footer/operation-keys.cjs +23 -0
  213. package/dist/application/transform/footer/operation-keys.cjs.map +1 -0
  214. package/dist/application/transform/footer/operation-keys.mjs +21 -0
  215. package/dist/application/transform/footer/operation-keys.mjs.map +1 -0
  216. package/dist/application/transform/footer/type-evaluation.cjs +4 -4
  217. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -1
  218. package/dist/application/transform/footer/type-evaluation.mjs +4 -4
  219. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -1
  220. package/dist/application/transform/helper-types.cjs +1 -1
  221. package/dist/application/transform/helper-types.cjs.map +1 -1
  222. package/dist/application/transform/helper-types.mjs +1 -1
  223. package/dist/application/transform/helper-types.mjs.map +1 -1
  224. package/dist/application/transform/numbered-names.cjs +9 -0
  225. package/dist/application/transform/numbered-names.cjs.map +1 -1
  226. package/dist/application/transform/numbered-names.mjs +9 -1
  227. package/dist/application/transform/numbered-names.mjs.map +1 -1
  228. package/dist/application/transform/ref-pointer/generated-location.cjs +1 -1
  229. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
  230. package/dist/application/transform/ref-pointer/generated-location.mjs +2 -2
  231. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
  232. package/dist/application/transform/ref-type.cjs +2 -1
  233. package/dist/application/transform/ref-type.cjs.map +1 -1
  234. package/dist/application/transform/ref-type.mjs +2 -1
  235. package/dist/application/transform/ref-type.mjs.map +1 -1
  236. package/dist/application/transform/schema/composition-type.cjs +1 -1
  237. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  238. package/dist/application/transform/schema/composition-type.mjs +2 -2
  239. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  240. package/dist/application/transform/schema/enum-rule.cjs +1 -1
  241. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  242. package/dist/application/transform/schema/enum-rule.mjs +2 -2
  243. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  244. package/dist/application/transform/schema/object-type.cjs +3 -3
  245. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  246. package/dist/application/transform/schema/object-type.mjs +4 -4
  247. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  248. package/dist/application/transform/schema/ref-siblings.cjs +47 -0
  249. package/dist/application/transform/schema/ref-siblings.cjs.map +1 -0
  250. package/dist/application/transform/schema/ref-siblings.mjs +45 -0
  251. package/dist/application/transform/schema/ref-siblings.mjs.map +1 -0
  252. package/dist/application/transform/schema/schema-transform.cjs +4 -2
  253. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  254. package/dist/application/transform/schema/schema-transform.mjs +4 -2
  255. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  256. package/dist/application/transform/schema-comment.cjs +5 -1
  257. package/dist/application/transform/schema-comment.cjs.map +1 -1
  258. package/dist/application/transform/schema-comment.mjs +5 -1
  259. package/dist/application/transform/schema-comment.mjs.map +1 -1
  260. package/dist/cli/api-settings.cjs +62 -6
  261. package/dist/cli/api-settings.cjs.map +1 -1
  262. package/dist/cli/api-settings.mjs +60 -7
  263. package/dist/cli/api-settings.mjs.map +1 -1
  264. package/dist/cli/api-writes.cjs +72 -0
  265. package/dist/cli/api-writes.cjs.map +1 -0
  266. package/dist/cli/api-writes.mjs +69 -0
  267. package/dist/cli/api-writes.mjs.map +1 -0
  268. package/dist/cli/cli-errors.cjs +12 -1
  269. package/dist/cli/cli-errors.cjs.map +1 -1
  270. package/dist/cli/cli-errors.mjs +12 -1
  271. package/dist/cli/cli-errors.mjs.map +1 -1
  272. package/dist/cli/cli-output.cjs +106 -1
  273. package/dist/cli/cli-output.cjs.map +1 -1
  274. package/dist/cli/cli-output.mjs +99 -2
  275. package/dist/cli/cli-output.mjs.map +1 -1
  276. package/dist/cli/main.cjs +5 -1
  277. package/dist/cli/main.cjs.map +1 -1
  278. package/dist/cli/main.mjs +6 -2
  279. package/dist/cli/main.mjs.map +1 -1
  280. package/dist/cli/redocly-apis.cjs +82 -36
  281. package/dist/cli/redocly-apis.cjs.map +1 -1
  282. package/dist/cli/redocly-apis.mjs +85 -39
  283. package/dist/cli/redocly-apis.mjs.map +1 -1
  284. package/dist/cli/run-cli.cjs +13 -7
  285. package/dist/cli/run-cli.cjs.map +1 -1
  286. package/dist/cli/run-cli.mjs +14 -8
  287. package/dist/cli/run-cli.mjs.map +1 -1
  288. package/dist/domain/append-all.cjs +10 -0
  289. package/dist/domain/append-all.cjs.map +1 -0
  290. package/dist/domain/append-all.mjs +8 -0
  291. package/dist/domain/append-all.mjs.map +1 -0
  292. package/dist/domain/cause-secrets.cjs +37 -0
  293. package/dist/domain/cause-secrets.cjs.map +1 -0
  294. package/dist/domain/cause-secrets.mjs +35 -0
  295. package/dist/domain/cause-secrets.mjs.map +1 -0
  296. package/dist/domain/errors.cjs +9 -3
  297. package/dist/domain/errors.cjs.map +1 -1
  298. package/dist/domain/errors.mjs +9 -3
  299. package/dist/domain/errors.mjs.map +1 -1
  300. package/dist/domain/ir/identifier-text.cjs.map +1 -1
  301. package/dist/domain/ir/identifier-text.mjs +1 -1
  302. package/dist/domain/ir/identifier-text.mjs.map +1 -1
  303. package/dist/domain/ir/ir-shape.cjs +187 -0
  304. package/dist/domain/ir/ir-shape.cjs.map +1 -0
  305. package/dist/domain/ir/ir-shape.mjs +184 -0
  306. package/dist/domain/ir/ir-shape.mjs.map +1 -0
  307. package/dist/domain/ir/newer-identifier-ranges.cjs +182 -29
  308. package/dist/domain/ir/newer-identifier-ranges.cjs.map +1 -1
  309. package/dist/domain/ir/newer-identifier-ranges.mjs +182 -29
  310. package/dist/domain/ir/newer-identifier-ranges.mjs.map +1 -1
  311. package/dist/domain/openapi/alias-expansion.cjs +3 -1
  312. package/dist/domain/openapi/alias-expansion.cjs.map +1 -1
  313. package/dist/domain/openapi/alias-expansion.mjs +3 -1
  314. package/dist/domain/openapi/alias-expansion.mjs.map +1 -1
  315. package/dist/domain/openapi/discriminated-union.cjs +3 -3
  316. package/dist/domain/openapi/discriminated-union.cjs.map +1 -1
  317. package/dist/domain/openapi/discriminated-union.mjs +4 -4
  318. package/dist/domain/openapi/discriminated-union.mjs.map +1 -1
  319. package/dist/domain/openapi/discriminator-conflicts.cjs +10 -6
  320. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -1
  321. package/dist/domain/openapi/discriminator-conflicts.mjs +11 -7
  322. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -1
  323. package/dist/domain/openapi/json-pointer.cjs +43 -1
  324. package/dist/domain/openapi/json-pointer.cjs.map +1 -1
  325. package/dist/domain/openapi/json-pointer.mjs +40 -2
  326. package/dist/domain/openapi/json-pointer.mjs.map +1 -1
  327. package/dist/domain/openapi/schema-dialect.cjs +15 -0
  328. package/dist/domain/openapi/schema-dialect.cjs.map +1 -0
  329. package/dist/domain/openapi/schema-dialect.mjs +12 -0
  330. package/dist/domain/openapi/schema-dialect.mjs.map +1 -0
  331. package/dist/domain/openapi/unsupported-features.cjs +1 -1
  332. package/dist/domain/openapi/unsupported-features.cjs.map +1 -1
  333. package/dist/domain/openapi/unsupported-features.mjs +2 -2
  334. package/dist/domain/openapi/unsupported-features.mjs.map +1 -1
  335. package/dist/domain/output-fixes.cjs +14 -0
  336. package/dist/domain/output-fixes.cjs.map +1 -1
  337. package/dist/domain/output-fixes.mjs +14 -0
  338. package/dist/domain/output-fixes.mjs.map +1 -1
  339. package/dist/domain/url-secrets.cjs +48 -0
  340. package/dist/domain/url-secrets.cjs.map +1 -0
  341. package/dist/domain/url-secrets.mjs +45 -0
  342. package/dist/domain/url-secrets.mjs.map +1 -0
  343. package/dist/index.d.cts +22 -4
  344. package/dist/index.d.mts +22 -4
  345. package/dist/index.d.ts +22 -4
  346. package/package.json +4 -5
  347. package/src/adapters/node-file-system/file-claims.ts +138 -0
  348. package/src/adapters/node-file-system/file-identity.ts +137 -0
  349. package/src/adapters/node-file-system/node-file-system.ts +145 -18
  350. package/src/adapters/redocly-loader/bundled-mapping-copies.ts +95 -0
  351. package/src/adapters/redocly-loader/bundled-ref-repair.ts +2 -2
  352. package/src/adapters/redocly-loader/loaded-documents.ts +46 -0
  353. package/src/adapters/redocly-loader/redocly-schema-loader.ts +18 -24
  354. package/src/adapters/redocly-loader/ref-access.ts +37 -3
  355. package/src/adapters/redocly-loader/ref-holders.ts +3 -3
  356. package/src/adapters/redocly-loader/remote-body-limit.ts +66 -0
  357. package/src/adapters/redocly-loader/remote-fetch.ts +74 -11
  358. package/src/adapters/redocly-loader/remote-node-limit.ts +62 -0
  359. package/src/adapters/redocly-loader/schema-load-errors.ts +52 -13
  360. package/src/adapters/redocly-loader/schema-source.ts +20 -8
  361. package/src/adapters/redocly-loader/unsupported-keys.ts +3 -7
  362. package/src/adapters/terminal-logger/terminal-logger.ts +10 -5
  363. package/src/api/default-ports.ts +33 -4
  364. package/src/api/discriminator-enum-parent.ts +3 -3
  365. package/src/api/discriminator-other-owners.ts +5 -3
  366. package/src/api/discriminator-patch.ts +5 -1
  367. package/src/api/discriminator-scan.ts +16 -8
  368. package/src/api/document-run.ts +4 -3
  369. package/src/api/legacy-utils.ts +5 -1
  370. package/src/api/openapi-ts.ts +20 -5
  371. package/src/api/run-context.ts +3 -0
  372. package/src/api/schema-callbacks.ts +60 -17
  373. package/src/api/transform-context.ts +7 -3
  374. package/src/api/transform-schema.ts +64 -12
  375. package/src/application/ports/file-system.ts +39 -0
  376. package/src/application/ports/schema-loader.ts +11 -1
  377. package/src/application/print/text-writer.ts +10 -3
  378. package/src/application/stack-overflow.ts +9 -5
  379. package/src/application/transform/document/components.ts +2 -2
  380. package/src/application/transform/document/declared-type-names.ts +36 -0
  381. package/src/application/transform/document/defs-root.ts +2 -2
  382. package/src/application/transform/document/document.ts +4 -3
  383. package/src/application/transform/document/enum-names-given-back.ts +91 -0
  384. package/src/application/transform/document/global-type-references.ts +1 -1
  385. package/src/application/transform/document/media-type.ts +4 -3
  386. package/src/application/transform/document/operation-keys-written.ts +27 -0
  387. package/src/application/transform/document/operation.ts +2 -2
  388. package/src/application/transform/document/parameter-entries.ts +70 -0
  389. package/src/application/transform/document/parameter.ts +21 -9
  390. package/src/application/transform/document/parameters.ts +11 -56
  391. package/src/application/transform/document/path-item.ts +13 -31
  392. package/src/application/transform/document/paths-enum.ts +1 -1
  393. package/src/application/transform/document/paths.ts +6 -2
  394. package/src/application/transform/document/referenced-parameter.ts +146 -0
  395. package/src/application/transform/document/request-body.ts +2 -2
  396. package/src/application/transform/document/response.ts +3 -3
  397. package/src/application/transform/document/responses.ts +2 -2
  398. package/src/application/transform/document/root-type-aliases.ts +17 -38
  399. package/src/application/transform/document/type-resolution.ts +2 -1
  400. package/src/application/transform/document/webhooks.ts +2 -2
  401. package/src/application/transform/footer/document-footer.ts +18 -1
  402. package/src/application/transform/footer/enum-name-claims.ts +62 -0
  403. package/src/application/transform/footer/operation-keys.ts +28 -0
  404. package/src/application/transform/footer/type-evaluation.ts +4 -4
  405. package/src/application/transform/helper-types.ts +6 -5
  406. package/src/application/transform/numbered-names.ts +15 -0
  407. package/src/application/transform/ref-pointer/generated-location.ts +2 -2
  408. package/src/application/transform/ref-type.ts +2 -1
  409. package/src/application/transform/schema/composition-type.ts +2 -2
  410. package/src/application/transform/schema/enum-rule.ts +6 -2
  411. package/src/application/transform/schema/object-type.ts +4 -4
  412. package/src/application/transform/schema/ref-siblings.ts +76 -0
  413. package/src/application/transform/schema/schema-context.ts +3 -0
  414. package/src/application/transform/schema/schema-transform.ts +4 -2
  415. package/src/application/transform/schema-comment.ts +5 -1
  416. package/src/application/transform/transform-context.ts +5 -0
  417. package/src/cli/api-settings.ts +82 -7
  418. package/src/cli/api-writes.ts +117 -0
  419. package/src/cli/cli-dependencies.ts +21 -4
  420. package/src/cli/cli-errors.ts +20 -1
  421. package/src/cli/cli-output.ts +186 -7
  422. package/src/cli/main.ts +6 -3
  423. package/src/cli/redocly-apis.ts +153 -48
  424. package/src/cli/run-cli.ts +37 -8
  425. package/src/domain/append-all.ts +10 -0
  426. package/src/domain/cause-secrets.ts +52 -0
  427. package/src/domain/errors.ts +14 -5
  428. package/src/domain/ir/identifier-text.ts +6 -5
  429. package/src/domain/ir/ir-shape.ts +299 -0
  430. package/src/domain/ir/newer-identifier-ranges.ts +183 -30
  431. package/src/domain/openapi/alias-expansion.ts +4 -1
  432. package/src/domain/openapi/discriminated-union.ts +6 -4
  433. package/src/domain/openapi/discriminator-conflicts.ts +21 -7
  434. package/src/domain/openapi/document-object.ts +2 -0
  435. package/src/domain/openapi/json-pointer.ts +96 -7
  436. package/src/domain/openapi/schema-dialect.ts +22 -0
  437. package/src/domain/openapi/unsupported-features.ts +2 -2
  438. package/src/domain/output-fixes.ts +21 -2
  439. package/src/domain/url-secrets.ts +72 -0
  440. package/src/types/generator-options.ts +1 -1
  441. package/dist/cli/main.d.cts +0 -2
  442. package/dist/cli/main.d.mts +0 -2
  443. package/dist/cli/main.d.ts +0 -2
  444. package/dist/domain/url-credentials.cjs +0 -10
  445. package/dist/domain/url-credentials.cjs.map +0 -1
  446. package/dist/domain/url-credentials.mjs +0 -8
  447. package/dist/domain/url-credentials.mjs.map +0 -1
  448. package/src/domain/url-credentials.ts +0 -18
@@ -17,6 +17,8 @@ import {
17
17
  pathStringError,
18
18
  sourceEmptyError,
19
19
  sourceInvalidError,
20
+ type TextOrigin,
21
+ urlInvalidError,
20
22
  } from "./schema-load-errors.js";
21
23
 
22
24
  /** Parse a schema source of any supported type into a Redocly document (ENGINEERING_PLAN 4.5). */
@@ -24,6 +26,8 @@ import {
24
26
  export interface ParseSchemaOptions {
25
27
  absoluteRef: string;
26
28
  resolver: BaseResolver;
29
+ /** Where document text came from, for the message of text that is only a string. */
30
+ textOrigin?: TextOrigin;
27
31
  }
28
32
 
29
33
  /**
@@ -38,21 +42,28 @@ async function readStream(stream: Readable, absoluteRef: string): Promise<string
38
42
  }
39
43
  }
40
44
 
41
- const URL_PREFIXES = ["http://", "https://", "file://"] as const;
45
+ /** A URL source string; a scheme is the same in any case (RFC 3986, section 3.1). */
46
+ const URL_PREFIX_RE = /^(?:https?|file):\/\//i;
42
47
 
43
- /** A string is a URL, JSON (starts with `{`) or YAML. */
48
+ /**
49
+ * A string is a URL, JSON (starts with `{`) or YAML. A string that starts like a URL but does not
50
+ * parse as one fails with `SCHEMA_SOURCE_INVALID`, not the parser's `TypeError`.
51
+ */
44
52
  function parseSchemaText(
45
53
  schema: string,
46
54
  options: ParseSchemaOptions,
47
55
  ): Promise<Document> | Document {
48
- if (URL_PREFIXES.some((prefix) => schema.startsWith(prefix))) {
49
- const url = new URL(schema);
56
+ if (URL_PREFIX_RE.test(schema)) {
57
+ const url = URL.parse(schema);
58
+ if (url === null) {
59
+ throw urlInvalidError(schema);
60
+ }
50
61
  const absoluteRef = url.protocol === "file:" ? fileURLToPath(url) : url.href;
51
62
  return parseSchema(url, { absoluteRef, resolver: options.resolver });
52
63
  }
53
64
  return schema[0] === "{"
54
65
  ? parseJsonText(schema, options.absoluteRef)
55
- : parseYamlText(schema, options.absoluteRef);
66
+ : parseYamlText(schema, options.absoluteRef, options.textOrigin ?? "string");
56
67
  }
57
68
 
58
69
  function parseJsonText(text: string, absoluteRef: string): Document {
@@ -63,7 +74,7 @@ function parseJsonText(text: string, absoluteRef: string): Document {
63
74
  }
64
75
  }
65
76
 
66
- function parseYamlText(text: string, absoluteRef: string): Document {
77
+ function parseYamlText(text: string, absoluteRef: string, origin: TextOrigin): Document {
67
78
  let document: Document;
68
79
  try {
69
80
  document = makeDocumentFromString(text, absoluteRef);
@@ -72,7 +83,7 @@ function parseYamlText(text: string, absoluteRef: string): Document {
72
83
  }
73
84
  // Text that is only a YAML string scalar, such as "./openapi.yaml", was meant as a file path.
74
85
  if (typeof document.parsed === "string") {
75
- throw pathStringError(text);
86
+ throw pathStringError(text, origin);
76
87
  }
77
88
  const failure = aliasExpansionFailure(document.parsed);
78
89
  if (failure !== undefined) {
@@ -139,7 +150,8 @@ export async function parseSchema(schema: unknown, options: ParseSchemaOptions):
139
150
  return resolveSchemaURL(options);
140
151
  }
141
152
  if (schema instanceof Readable) {
142
- return parseSchema(await readStream(schema, options.absoluteRef), options);
153
+ const text = await readStream(schema, options.absoluteRef);
154
+ return parseSchema(text, { ...options, textOrigin: "stream" });
143
155
  }
144
156
  if (schema instanceof Buffer) {
145
157
  return parseSchema(schema.toString("utf8"), options);
@@ -1,4 +1,5 @@
1
1
  import { ERROR_CODES, OpenAPITypesafeError } from "../../domain/errors.js";
2
+ import { childPointer, ROOT_POINTER } from "../../domain/openapi/json-pointer.js";
2
3
 
3
4
  /**
4
5
  * Keys Redocly 1.34 cannot walk. It looks up the type of every key with `type.properties[key]`,
@@ -57,11 +58,6 @@ interface PendingNode {
57
58
  readonly pointer: string;
58
59
  }
59
60
 
60
- /** RFC 6901: `~` becomes `~0` and `/` becomes `~1`. */
61
- function escapePointerSegment(segment: string): string {
62
- return segment.replaceAll("~", "~0").replaceAll("/", "~1");
63
- }
64
-
65
61
  /**
66
62
  * The unsupported keys of one parsed document. The walk uses its own stack, so a deeply nested
67
63
  * document is checked without running out of call stack; nodes shared by YAML aliases are checked
@@ -77,10 +73,10 @@ function unsupportedKeysOf(document: LoadedDocument): UnsupportedKey[] {
77
73
  pending.push({ value, pointer });
78
74
  }
79
75
  };
80
- enqueue(document.parsed, "#");
76
+ enqueue(document.parsed, ROOT_POINTER);
81
77
  for (let node = pending.pop(); node !== undefined; node = pending.pop()) {
82
78
  for (const [key, child] of Object.entries(node.value)) {
83
- const pointer = `${node.pointer}/${escapePointerSegment(key)}`;
79
+ const pointer = childPointer(node.pointer, key);
84
80
  if (isUnsupportedEntry(key, child)) {
85
81
  found.push({ key, pointer, source: document.source });
86
82
  }
@@ -1,6 +1,6 @@
1
1
  import colors from "ansi-colors";
2
2
  import type { DebugGroup, Logger } from "../../application/ports/logger.js";
3
- import { redactUrlCredentials } from "../../domain/url-credentials.js";
3
+ import { redactUrlSecrets } from "../../domain/url-secrets.js";
4
4
 
5
5
  /**
6
6
  * The Logger port on a terminal, with the original output format: ` ⚠ ` warnings, ` ✘ `
@@ -16,7 +16,10 @@ export interface TerminalSink {
16
16
  }
17
17
 
18
18
  export interface TerminalLoggerOptions {
19
- /** Drop warnings (errors and debug lines are still written). */
19
+ /**
20
+ * Drop warnings and error lines; debug lines, which `DEBUG` asks for, are still written. The
21
+ * error lines are the problems of a document that fails to load, which the thrown error lists.
22
+ */
20
23
  readonly silent: boolean;
21
24
  /** The value of `DEBUG`: `*`, `openapi-ts:*` or `openapi-ts:<group>` turn debug lines on. */
22
25
  readonly debugFilter: string | undefined;
@@ -81,18 +84,20 @@ class TerminalLogger implements Logger {
81
84
  // The original wrote no space without a duration (`openapi-ts:lintIgnored …`).
82
85
  const time =
83
86
  durationMs === undefined ? " " : this.#palette.green(` ${formatDuration(durationMs)} `);
84
- const text = redactUrlCredentials(message);
87
+ const text = redactUrlSecrets(message);
85
88
  this.#options.sink.debug(` ${this.#palette.bold(name)}${time}${text}`);
86
89
  }
87
90
 
88
91
  warn(message: string): void {
89
92
  if (!this.#options.silent) {
90
- this.#options.sink.warn(this.#palette.yellow(` ⚠ ${redactUrlCredentials(message)}`));
93
+ this.#options.sink.warn(this.#palette.yellow(` ⚠ ${redactUrlSecrets(message)}`));
91
94
  }
92
95
  }
93
96
 
94
97
  error(message: string): void {
95
- this.#options.sink.error(this.#palette.red(` ✘ ${redactUrlCredentials(message)}`));
98
+ if (!this.#options.silent) {
99
+ this.#options.sink.error(this.#palette.red(` ✘ ${redactUrlSecrets(message)}`));
100
+ }
96
101
  }
97
102
  }
98
103
 
@@ -3,7 +3,10 @@ import { createConfig, type Config as RedoclyConfig } from "@redocly/openapi-cor
3
3
  import supportsColor from "supports-color";
4
4
  import { createNodeDeprecationReporter } from "../adapters/node-deprecations/node-deprecations.js";
5
5
  import type { RemoteDocumentLimits } from "../adapters/redocly-loader/remote-fetch.js";
6
- import { createTerminalLogger } from "../adapters/terminal-logger/terminal-logger.js";
6
+ import {
7
+ createTerminalLogger,
8
+ type TerminalSink,
9
+ } from "../adapters/terminal-logger/terminal-logger.js";
7
10
  import type { DeprecationReporter } from "../application/ports/deprecation-reporter.js";
8
11
  import type { Logger } from "../application/ports/logger.js";
9
12
 
@@ -18,13 +21,26 @@ export function terminalSupportsColor(): boolean {
18
21
  return Boolean(stdout) && stdout !== false && stdout.hasBasic !== false;
19
22
  }
20
23
 
21
- /** The terminal logger with `DEBUG` from the environment, writing to the console. */
24
+ /**
25
+ * Every line of the logger goes to stderr: the CLI writes the types to stdout, and `console.debug`
26
+ * writes there too, so debug lines would end up inside the generated file.
27
+ */
28
+ const STDERR_SINK: TerminalSink = {
29
+ // biome-ignore lint/suspicious/noConsole: the terminal logger's own channel
30
+ debug: (line) => console.error(line),
31
+ // biome-ignore lint/suspicious/noConsole: the terminal logger's own channel
32
+ warn: (line) => console.warn(line),
33
+ // biome-ignore lint/suspicious/noConsole: the terminal logger's own channel
34
+ error: (line) => console.error(line),
35
+ };
36
+
37
+ /** The terminal logger with `DEBUG` from the environment, writing to stderr. */
22
38
  export function defaultLogger(silent: boolean): Logger {
23
39
  return createTerminalLogger({
24
40
  silent,
25
41
  debugFilter: process.env.DEBUG,
26
42
  useColors: terminalSupportsColor(),
27
- sink: console,
43
+ sink: STDERR_SINK,
28
44
  });
29
45
  }
30
46
 
@@ -40,14 +56,27 @@ export function defaultDeprecationReporter(): DeprecationReporter {
40
56
  */
41
57
  export const REMOTE_REF_TIMEOUT_MS = 60_000;
42
58
 
59
+ const MEBIBYTE = 1024 * 1024;
60
+
43
61
  /**
44
- * Bounds on the remote documents of one run (ADR-033). Large split documents have a few thousand
62
+ * Bounds on the remote documents of one schema (ADR-033). Large split documents have a few thousand
45
63
  * files, so 10,000 leaves room and still ends an endless fan-out. 16 parallel fetches keep a
46
64
  * multi-file document fast without exhausting local ports.
65
+ *
66
+ * The size limits count decoded bytes and parsed nodes (threat model T2, ADR-033 decision 6).
67
+ * The largest document of the 1,820-entry compatibility corpus is Microsoft Graph beta: 71 MiB,
68
+ * 2.65 million nodes (keys and values), 1.6 GB peak memory when loaded from a URL. A remote body
69
+ * took about 7 bytes of memory per byte of text and 110 per node in our measurements, so 128 MiB
70
+ * per document (1.8 times Graph beta), 256 MiB per schema (a split document may be twice as
71
+ * large) and 8 million nodes per schema (3 times Graph beta) let crafted documents finish within
72
+ * a heap of 2 GB; with the default heap of 4 GB they peak at about 1.2 to 2.3 GB.
47
73
  */
48
74
  export const DEFAULT_REMOTE_DOCUMENT_LIMITS: RemoteDocumentLimits = {
49
75
  maxDocuments: 10_000,
50
76
  maxParallelFetches: 16,
77
+ maxDocumentBytes: 128 * MEBIBYTE,
78
+ maxTotalBytes: 256 * MEBIBYTE,
79
+ maxNodes: 8_000_000,
51
80
  };
52
81
 
53
82
  /** The working directory of the process: the default `cwd` of an inline source. */
@@ -1,4 +1,4 @@
1
- import { createRef, parseRefPointer } from "../domain/openapi/json-pointer.js";
1
+ import { appendPointer, parseRefPointer, ROOT_POINTER } from "../domain/openapi/json-pointer.js";
2
2
  import type { SchemaObject } from "../types.js";
3
3
  import type { EnumPatch } from "./discriminator-enum.js";
4
4
 
@@ -31,7 +31,7 @@ const ROOT_SEGMENTS = 3;
31
31
  function typedAt(ref: string): string {
32
32
  const segments = parseRefPointer(ref);
33
33
  const nested = segments.slice(ROOT_SEGMENTS).filter((segment) => segment !== PROPERTIES_KEYWORD);
34
- return createRef([...segments.slice(0, ROOT_SEGMENTS), ...nested]);
34
+ return appendPointer(ROOT_POINTER, [...segments.slice(0, ROOT_SEGMENTS), ...nested]);
35
35
  }
36
36
 
37
37
  function isSchemaObject(value: unknown): value is SchemaObject {
@@ -41,7 +41,7 @@ function isSchemaObject(value: unknown): value is SchemaObject {
41
41
  /** The property `name` of a schema object typed at `ref`. */
42
42
  function ownProperty(item: SchemaObject, ref: string, name: string): DeclaredProperty | undefined {
43
43
  const property = ("properties" in item ? item.properties : undefined)?.[name];
44
- return property === undefined ? undefined : { property, path: createRef([ref, name]) };
44
+ return property === undefined ? undefined : { property, path: appendPointer(ref, [name]) };
45
45
  }
46
46
 
47
47
  /** The property `name` of the schema at `ref`, its own or from an `allOf` item, depth first. */
@@ -1,3 +1,5 @@
1
+ import { appendAll } from "../domain/append-all.js";
2
+ import { canonicalRef } from "../domain/openapi/json-pointer.js";
1
3
  import type { DiscriminatorObject, ReferenceObject, SchemaObject } from "../types.js";
2
4
  import type { EnumPatch } from "./discriminator-enum.js";
3
5
  import { enumKey, patchDiscriminatorEnum, type ScanState } from "./discriminator-patch.js";
@@ -22,7 +24,7 @@ function allOfRefs(state: ScanState, ref: string): string[] {
22
24
  const schema = resolveDocumentRef<SchemaObject>(state.schema, ref, { silent, logger });
23
25
  const items = (schema?.allOf ?? []) as (SchemaObject | ReferenceObject)[];
24
26
  return items.flatMap((item) =>
25
- "$ref" in item && typeof item.$ref === "string" ? [item.$ref] : [],
27
+ "$ref" in item && typeof item.$ref === "string" ? [canonicalRef(item.$ref)] : [],
26
28
  );
27
29
  }
28
30
 
@@ -45,7 +47,7 @@ function otherOwners(state: ScanState, parentRef: string): OtherOwner[] {
45
47
  if (discriminator && name !== undefined && name !== own && !found.has(name)) {
46
48
  found.set(name, { discriminator, ownerRef: ref });
47
49
  }
48
- queue.push(...allOfRefs(state, ref));
50
+ appendAll(queue, allOfRefs(state, ref));
49
51
  }
50
52
  return [...found.values()];
51
53
  }
@@ -75,7 +77,7 @@ export function inheritOtherOwners(state: ScanState, parentRef: string, ref: str
75
77
  }
76
78
  recordOtherProperty(state, ref, discriminator.propertyName);
77
79
  const mapped = Object.entries(discriminator.mapping ?? {})
78
- .filter(([, target]) => target === ref)
80
+ .filter(([, target]) => canonicalRef(target) === ref)
79
81
  .map(([value]) => value);
80
82
  const name = ref.slice(ref.lastIndexOf("/") + 1);
81
83
  const patch: EnumPatch = { ref, values: mapped, discriminator, discriminatorRef: ownerRef };
@@ -1,4 +1,5 @@
1
1
  import type { Logger } from "../application/ports/logger.js";
2
+ import { appendAll } from "../domain/append-all.js";
2
3
  import { FIX, type OutputFix } from "../domain/output-fixes.js";
3
4
  import { WARNING_CODES, warningText } from "../domain/warnings.js";
4
5
  import type { DiscriminatorObject, OpenAPI3, SchemaObject } from "../types.js";
@@ -104,7 +105,10 @@ function mergeIntoPatchedEnum(state: ScanState, key: string, values: readonly st
104
105
  return false;
105
106
  }
106
107
  const merged = patched.enum as unknown[];
107
- merged.push(...values.filter((value) => !merged.includes(value)));
108
+ appendAll(
109
+ merged,
110
+ values.filter((value) => !merged.includes(value)),
111
+ );
108
112
  return true;
109
113
  }
110
114
 
@@ -1,5 +1,6 @@
1
1
  import type { Logger } from "../application/ports/logger.js";
2
2
  import { isUnionMember, unionAt } from "../domain/openapi/discriminated-union.js";
3
+ import { appendPointer, canonicalRef, ROOT_POINTER } from "../domain/openapi/json-pointer.js";
3
4
  import { FIX } from "../domain/output-fixes.js";
4
5
  import type {
5
6
  DiscriminatorObject,
@@ -22,7 +23,6 @@ import {
22
23
  type ScanState,
23
24
  } from "./discriminator-patch.js";
24
25
  import { resolveDocumentRef, walkDocument } from "./document-refs.js";
25
- import { createRef } from "./legacy-utils.js";
26
26
 
27
27
  /**
28
28
  * The inherited discriminator pre-pass. It finds every discriminator in the bundled document and
@@ -39,9 +39,11 @@ function inferredMapping(oneOf: (SchemaObject | ReferenceObject)[]): Discriminat
39
39
  if (!("$ref" in item)) {
40
40
  continue;
41
41
  }
42
+ // The value is the name as the `$ref` writes it, as in the original.
42
43
  const value = item.$ref.split("/").pop();
44
+ const ref = canonicalRef(item.$ref);
43
45
  if (value) {
44
- mapping[item.$ref] = { ...mapping[item.$ref], inferred: value };
46
+ mapping[ref] = { ...mapping[ref], inferred: value };
45
47
  }
46
48
  }
47
49
  return mapping;
@@ -52,10 +54,11 @@ function addDefinedMapping(
52
54
  mapping: DiscriminatorMapping,
53
55
  defined: Readonly<Record<string, string>>,
54
56
  ): void {
55
- for (const [mappedValue, mappedRef] of Object.entries(defined)) {
56
- if (!mappedRef) {
57
+ for (const [mappedValue, target] of Object.entries(defined)) {
58
+ if (!target) {
57
59
  continue;
58
60
  }
61
+ const mappedRef = canonicalRef(target);
59
62
  if (!mapping[mappedRef]?.defined) {
60
63
  mapping[mappedRef] = { defined: [] };
61
64
  }
@@ -94,7 +97,7 @@ function collectDiscriminator(
94
97
  if (!discriminator?.propertyName) {
95
98
  return;
96
99
  }
97
- const discriminatorRef = createRef(path);
100
+ const discriminatorRef = appendPointer(ROOT_POINTER, path);
98
101
  state.objects[discriminatorRef] = discriminator;
99
102
  state.owners.add(discriminatorRef);
100
103
  if (!Array.isArray(value.oneOf)) {
@@ -110,7 +113,7 @@ function collectDiscriminator(
110
113
  /** The mapping keys of `discriminator` that point at `ref`. */
111
114
  function valuesMappedTo(discriminator: DiscriminatorObject, ref: string): string[] {
112
115
  return Object.entries(discriminator.mapping ?? {})
113
- .filter(([, mappedRef]) => mappedRef === ref)
116
+ .filter(([, mappedRef]) => canonicalRef(mappedRef) === ref)
114
117
  .map(([mappedValue]) => mappedValue);
115
118
  }
116
119
 
@@ -184,12 +187,17 @@ function inheritDiscriminators(
184
187
  }
185
188
  for (const item of value.allOf as (SchemaObject | ReferenceObject)[]) {
186
189
  if ("$ref" in item) {
187
- if (!inheritFromRef(state, item.$ref, createRef(path))) {
190
+ if (!inheritFromRef(state, canonicalRef(item.$ref), appendPointer(ROOT_POINTER, path))) {
188
191
  return;
189
192
  }
190
193
  } else if (item.discriminator?.propertyName) {
191
194
  // The inline item is typed at the schema's own location.
192
- recordInherited(state, createRef(path), item.discriminator, createRef(path));
195
+ recordInherited(
196
+ state,
197
+ appendPointer(ROOT_POINTER, path),
198
+ item.discriminator,
199
+ appendPointer(ROOT_POINTER, path),
200
+ );
193
201
  }
194
202
  }
195
203
  }
@@ -34,9 +34,10 @@ export interface GeneratorPorts {
34
34
  readonly now: () => number;
35
35
  }
36
36
 
37
- /** A validated, bundled document and the context of one generator run. */
37
+ /** A validated, bundled document, the local files it was read from, and the run's context. */
38
38
  export interface DocumentRun {
39
39
  readonly schema: OpenAPI3;
40
+ readonly localFiles: readonly URL[];
40
41
  readonly ctx: RunContext;
41
42
  }
42
43
 
@@ -156,7 +157,7 @@ export async function createDocumentRun(
156
157
  const fix = outputFixesOf(options, logger);
157
158
  const silent = options.silent ?? false;
158
159
  const cwd = sourceCwd(options);
159
- const schema = await ports.loader.load({
160
+ const { document: schema, localFiles } = await ports.loader.load({
160
161
  source,
161
162
  cwd,
162
163
  shouldLint: options.lint ?? true,
@@ -181,5 +182,5 @@ export async function createDocumentRun(
181
182
  logger,
182
183
  deprecations: ports.deprecations,
183
184
  };
184
- return { schema, ctx };
185
+ return { schema, localFiles, ctx };
185
186
  }
@@ -36,7 +36,11 @@ export function createDiscriminatorProperty(
36
36
  return discriminatorProperty(discriminator, path, readonly);
37
37
  }
38
38
 
39
- /** Create a $ref pointer (even from other $refs) */
39
+ /**
40
+ * Create a $ref pointer (even from other $refs). A part that contains `#/` is read as a `$ref`
41
+ * and contributes its decoded segments, so it throws URIError for a malformed percent escape; any
42
+ * other part is one segment. To append raw document keys, escape each one instead.
43
+ */
40
44
  export function createRef(parts: (number | string | undefined | null)[]): string {
41
45
  return createDomainRef(parts);
42
46
  }
@@ -18,21 +18,36 @@ import transformSchema from "./transform-schema.js";
18
18
  * `generateDeclarations` runs with any ports, which is how the CLI calls it.
19
19
  */
20
20
 
21
+ /** The declarations of one document, and the local files it was read from. */
22
+ export interface GeneratedDocument {
23
+ readonly declarations: IrDeclaration[];
24
+ readonly localFiles: readonly URL[];
25
+ }
26
+
21
27
  /** Load, validate and bundle the source, then transform it into IR declarations. */
22
- export async function generateDeclarations(
28
+ export async function generateDocument(
23
29
  source: SchemaSource,
24
30
  options: GeneratorOptions,
25
31
  ports: GeneratorPorts,
26
- ): Promise<IrDeclaration[]> {
27
- const { schema, ctx } = await createDocumentRun(source, options, ports);
32
+ ): Promise<GeneratedDocument> {
33
+ const { schema, localFiles, ctx } = await createDocumentRun(source, options, ports);
28
34
  const startedAt = ports.now();
29
- const result = withStackOverflowReported("transform", () => transformSchema(schema, ctx));
35
+ const declarations = withStackOverflowReported("transform", () => transformSchema(schema, ctx));
30
36
  ports.logger.debug(
31
37
  "Completed AST transformation for entire document",
32
38
  "ts",
33
39
  ports.now() - startedAt,
34
40
  );
35
- return result;
41
+ return { declarations, localFiles };
42
+ }
43
+
44
+ /** As `generateDocument`, the declarations only. */
45
+ export async function generateDeclarations(
46
+ source: SchemaSource,
47
+ options: GeneratorOptions,
48
+ ports: GeneratorPorts,
49
+ ): Promise<IrDeclaration[]> {
50
+ return (await generateDocument(source, options, ports)).declarations;
36
51
  }
37
52
 
38
53
  /**
@@ -1,6 +1,7 @@
1
1
  import type { DeprecationReporter } from "../application/ports/deprecation-reporter.js";
2
2
  import type { Logger } from "../application/ports/logger.js";
3
3
  import type { DocumentFooter } from "../application/transform/transform-context.js";
4
+ import type { SchemaDialect } from "../domain/openapi/schema-dialect.js";
4
5
  import type { GlobalContext, LegacyCallbackName, SchemaObject } from "../types.js";
5
6
 
6
7
  /**
@@ -26,6 +27,8 @@ export interface RunContext extends GlobalContext {
26
27
  */
27
28
  readonly otherProperties?: Readonly<Record<string, readonly string[]>>;
28
29
  };
30
+ /** The schema dialect of the run's document; without it, OpenAPI 3.0 (`schemaDialectOf`). */
31
+ schemaDialect?: SchemaDialect;
29
32
  /** Footer state of this run (enum registry and enum naming), created on first use. */
30
33
  runFooter?: DocumentFooter;
31
34
  /** The deprecated callback forms this run has warned about (once each). */
@@ -9,10 +9,10 @@ import type {
9
9
  } from "../application/transform/schema/schema-context.js";
10
10
  import { ERROR_CODES, OpenAPITypesafeError } from "../domain/errors.js";
11
11
  import { irRaw } from "../domain/ir/constructors.js";
12
+ import { isPrintableIrProperty, isPrintableIrType } from "../domain/ir/ir-shape.js";
12
13
  import type { IrPropertySignature, IrType } from "../domain/ir/nodes.js";
13
14
  import type {
14
15
  GlobalContext,
15
- IrCallbackType,
16
16
  IrPostTransform,
17
17
  IrTransform,
18
18
  IrTransformProperty,
@@ -29,13 +29,15 @@ import { toIrType } from "./type-helpers.js";
29
29
  * their results are read by the bridge.
30
30
  */
31
31
 
32
+ /** What a legacy `transformProperty` result fails to be. */
33
+ const LEGACY_PROPERTY_PROBLEM = "a property with syntax the generator cannot read";
34
+
35
+ /** A `transformProperty` result the generator cannot print as a property. */
32
36
  export class UnreadablePropertyError extends OpenAPITypesafeError {
33
- constructor(path: string | undefined) {
37
+ constructor(path: string | undefined, problem = LEGACY_PROPERTY_PROBLEM) {
34
38
  super({
35
39
  code: ERROR_CODES.CALLBACK_RESULT_UNREADABLE,
36
- message:
37
- `transformProperty at ${path} returned a property ` +
38
- "with syntax the generator cannot read",
40
+ message: `transformProperty at ${path} returned ${problem}`,
39
41
  details: { callback: "transformProperty", path },
40
42
  });
41
43
  this.name = "UnreadablePropertyError";
@@ -44,16 +46,26 @@ export class UnreadablePropertyError extends OpenAPITypesafeError {
44
46
 
45
47
  /** A `transform` or `postTransform` result that is neither IR nor a TypeScript node. */
46
48
  export class UnreadableTypeError extends OpenAPITypesafeError {
47
- constructor(callback: "transform" | "postTransform", path: string | undefined) {
49
+ constructor(
50
+ callback: "transform" | "postTransform",
51
+ path: string | undefined,
52
+ expected = "a TypeScript node",
53
+ ) {
48
54
  super({
49
55
  code: ERROR_CODES.CALLBACK_RESULT_UNREADABLE,
50
- message: `${callback} at ${path} returned a value that is not a TypeScript node`,
56
+ message: `${callback} at ${path} returned a value that is not ${expected}`,
51
57
  details: { callback, path },
52
58
  });
53
59
  this.name = "UnreadableTypeError";
54
60
  }
55
61
  }
56
62
 
63
+ /** What an IR type result must be (docs/node.md, IR callbacks). */
64
+ const IR_TYPE_EXPECTED = "an IR type or non-empty type text";
65
+
66
+ /** What an IR property result must be. */
67
+ const IR_PROPERTY_PROBLEM = "a value that is not an IR property the generator can print";
68
+
57
69
  function nodeOptions(ctx: GlobalContext, location: SchemaLocation): TransformNodeOptions {
58
70
  return { ...location, ctx } as TransformNodeOptions;
59
71
  }
@@ -63,24 +75,50 @@ export function schemaCallbacks(ctx: GlobalContext): SchemaCallbacks {
63
75
  return ctx.irCallbacks ? irSchemaCallbacks(ctx) : legacySchemaCallbacks(ctx);
64
76
  }
65
77
 
66
- /** An IR callback type; text is a raw type, printed as written. */
67
- function fromCallbackType(type: IrCallbackType): IrType {
68
- return typeof type === "string" ? irRaw(type) : type;
78
+ /**
79
+ * An IR callback type; text is a raw type, printed as written. Any other value, and IR the
80
+ * printer cannot write as TypeScript, fails with `CALLBACK_RESULT_UNREADABLE` (`ir-shape.ts`).
81
+ */
82
+ function fromCallbackType(
83
+ callback: "transform" | "postTransform",
84
+ type: unknown,
85
+ location: SchemaLocation,
86
+ ): IrType {
87
+ const candidate = typeof type === "string" ? irRaw(type) : type;
88
+ if (!isPrintableIrType(candidate)) {
89
+ throw new UnreadableTypeError(callback, location.path, IR_TYPE_EXPECTED);
90
+ }
91
+ return candidate;
69
92
  }
70
93
 
71
- function irCustomType(result: ReturnType<IrTransform>): CustomType | null {
94
+ function irCustomType(result: unknown, location: SchemaLocation): CustomType | null {
72
95
  if (result === undefined || result === null) {
73
96
  return null;
74
97
  }
75
98
  if (typeof result === "object" && "schema" in result) {
76
- return { type: fromCallbackType(result.schema), isOptional: Boolean(result.questionToken) };
99
+ const { schema, questionToken } = result as { schema: unknown; questionToken?: unknown };
100
+ return {
101
+ type: fromCallbackType("transform", schema, location),
102
+ isOptional: Boolean(questionToken),
103
+ };
77
104
  }
78
- return { type: fromCallbackType(result), isOptional: false };
105
+ return { type: fromCallbackType("transform", result, location), isOptional: false };
106
+ }
107
+
108
+ function irProperty(result: unknown, location: SchemaLocation): IrPropertySignature | null {
109
+ if (result === undefined || result === null) {
110
+ return null;
111
+ }
112
+ if (!isPrintableIrProperty(result)) {
113
+ throw new UnreadablePropertyError(location.path, IR_PROPERTY_PROBLEM);
114
+ }
115
+ return result;
79
116
  }
80
117
 
81
118
  /**
82
119
  * The context fields hold either callback form; `irCallbacks` says which one, so the casts below
83
- * only name the form the user declared with `OpenAPITSIrOptions`.
120
+ * only name the form the user declared with `OpenAPITSIrOptions`. The results are checked, since
121
+ * JavaScript callers can return any value.
84
122
  */
85
123
  function irSchemaCallbacks(ctx: GlobalContext): SchemaCallbacks {
86
124
  const transform = ctx.transform as IrTransform | undefined;
@@ -89,14 +127,19 @@ function irSchemaCallbacks(ctx: GlobalContext): SchemaCallbacks {
89
127
  return {
90
128
  transform: (schema, location) =>
91
129
  transform
92
- ? irCustomType(transform(schema as SchemaObject, nodeOptions(ctx, location)))
130
+ ? irCustomType(transform(schema as SchemaObject, nodeOptions(ctx, location)), location)
93
131
  : null,
94
132
  postTransform(type, location) {
95
133
  const result = postTransform?.(type, nodeOptions(ctx, location));
96
- return result === undefined ? null : fromCallbackType(result);
134
+ return result === undefined ? null : fromCallbackType("postTransform", result, location);
97
135
  },
98
136
  transformProperty: (property, schema, location) =>
99
- transformProperty?.(property, schema as SchemaObject, nodeOptions(ctx, location)) ?? null,
137
+ transformProperty
138
+ ? irProperty(
139
+ transformProperty(property, schema as SchemaObject, nodeOptions(ctx, location)),
140
+ location,
141
+ )
142
+ : null,
100
143
  };
101
144
  }
102
145
 
@@ -11,6 +11,8 @@ import type {
11
11
  TransformDiagnostics,
12
12
  TransformOptions,
13
13
  } from "../application/transform/transform-context.js";
14
+ import { canonicalRef } from "../domain/openapi/json-pointer.js";
15
+ import { SCHEMA_DIALECTS } from "../domain/openapi/schema-dialect.js";
14
16
  import type { TransformNodeOptions } from "../types.js";
15
17
  import { defaultLogger, monotonicNow } from "./default-ports.js";
16
18
  import { ContextFooterSink } from "./footer-sink.js";
@@ -40,6 +42,7 @@ function transformOptions(ctx: RunContext): TransformOptions {
40
42
  immutable: ctx.immutable,
41
43
  propertiesRequiredByDefault: ctx.propertiesRequiredByDefault,
42
44
  readWriteMarkers: ctx.readWriteMarkers,
45
+ schemaDialect: ctx.schemaDialect ?? SCHEMA_DIALECTS.OPENAPI_3_0,
43
46
  generatePathParams: ctx.generatePathParams,
44
47
  pathParamsAsTypes: ctx.pathParamsAsTypes,
45
48
  rootTypes: ctx.rootTypes,
@@ -76,9 +79,10 @@ export function createTransformContext(ctx: RunContext): TransformContext {
76
79
  options: transformOptions(ctx),
77
80
  refs: { resolve: (ref) => ctx.resolve(ref) },
78
81
  discriminators: {
79
- objectAt: (ref) => ctx.discriminators.objects[ref],
80
- isHandled: (ref) => ctx.discriminators.refsHandled.includes(ref),
81
- otherPropertiesAt: (ref) => ctx.discriminators.otherProperties?.[ref] ?? [],
82
+ // The scan keys pointers canonically; a caller may pass a `$ref` as the document writes it.
83
+ objectAt: (ref) => ctx.discriminators.objects[canonicalRef(ref)],
84
+ isHandled: (ref) => ctx.discriminators.refsHandled.includes(canonicalRef(ref)),
85
+ otherPropertiesAt: (ref) => ctx.discriminators.otherProperties?.[canonicalRef(ref)] ?? [],
82
86
  enumParentOf: (schema) =>
83
87
  ctx.discriminators.enumParents?.get(schema) as DiscriminatorEnumParent | undefined,
84
88
  },