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,181 @@
1
+ import { ERROR_CODES, OpenAPITypesafeError } from "../../../domain/errors.js";
2
+ import type { IrComment, IrEnumDeclaration } from "../../../domain/ir/nodes.js";
3
+ import { withNumberedRepeats } from "../numbered-names.js";
4
+
5
+ const IDENTIFIER_RE = /^[A-Za-z_$][A-Za-z_$0-9]*$/;
6
+ /** A run of invalid characters and the character after it, which starts the next word. */
7
+ const INVALID_RUN_THEN_CHARACTER_RE = /[^A-Za-z_$0-9]+(.)?/g;
8
+ const INVALID_RUN_RE = /[^A-Za-z_$0-9]+/;
9
+ const INVALID_RUNS_RE = /[^A-Za-z_$0-9]+/g;
10
+ const INVALID_CHARACTER_RE = /[^A-Za-z_$0-9]/;
11
+ const STARTS_WITH_DIGIT_RE = /^[0-9]/;
12
+ /** Invalid character runs with a readable replacement; any other run becomes `_`. */
13
+ const SPECIAL_CHARACTERS: ReadonlyMap<string, string> = new Map([["+", "Plus"]]);
14
+ const NUMBER_PREFIX = "Value";
15
+ const NEGATIVE_PREFIX = "ValueMinus";
16
+
17
+ export class EmptyEnumNameError extends OpenAPITypesafeError {
18
+ constructor(name: string) {
19
+ super({
20
+ code: ERROR_CODES.ENUM_NAME_EMPTY,
21
+ message: `Cannot build an enum or enum values name from "${name}": no valid characters`,
22
+ details: { name },
23
+ });
24
+ this.name = "EmptyEnumNameError";
25
+ }
26
+ }
27
+
28
+ /** Metadata of one enum member (`x-enum-varnames`, `x-enum-descriptions`). */
29
+ export interface EnumMemberNaming {
30
+ readonly name?: string | undefined;
31
+ readonly description?: string | null | undefined;
32
+ }
33
+
34
+ /**
35
+ * Names of `--enum` declarations, their members and `--enum-values` arrays, as the original
36
+ * builds them. One instance per run.
37
+ *
38
+ * The original checks the character after an invalid run with a global regex and `.test()`,
39
+ * which keeps `lastIndex`: after a check that finds an invalid character, the next check fails,
40
+ * and a later member name with invalid characters resets it. `isNextCheckSkipped` keeps that
41
+ * behavior within a run (research/legacy-bugs.md, item 2; fixed in Phase 7).
42
+ */
43
+ export class EnumNaming {
44
+ private isNextCheckSkipped = false;
45
+
46
+ /** `my-status` → `MyStatus`. */
47
+ enumName(name: string): string {
48
+ const sanitized = this.sanitize(name);
49
+ return `${firstCharacter(sanitized, name).toUpperCase()}${sanitized.substring(1)}`;
50
+ }
51
+
52
+ /** `MyStatusValues` → `myStatusValues`. */
53
+ arrayName(name: string): string {
54
+ const sanitized = this.sanitize(name);
55
+ return `${firstCharacter(sanitized, name).toLowerCase()}${sanitized.substring(1)}`;
56
+ }
57
+
58
+ /** A member name: a valid identifier, a rewritten one, or a quoted name. */
59
+ memberName(value: string | number, metadata: EnumMemberNaming = {}): string {
60
+ const name = metadata.name ?? String(value);
61
+ if (IDENTIFIER_RE.test(name)) {
62
+ return name;
63
+ }
64
+ // The original runs a global `match` here, which resets the regex state.
65
+ this.isNextCheckSkipped = false;
66
+ const prefixed = prefixedMemberName(name);
67
+ const invalidRun = INVALID_RUN_RE.exec(prefixed);
68
+ if (!invalidRun) {
69
+ // Only the empty name has no invalid run and is no identifier (upstream #2807).
70
+ return prefixed === "" ? quotedMemberName(prefixed) : prefixed;
71
+ }
72
+ return invalidRun[0] === prefixed
73
+ ? quotedMemberName(prefixed)
74
+ : prefixed.replace(INVALID_RUNS_RE, (run) => SPECIAL_CHARACTERS.get(run) ?? "_");
75
+ }
76
+
77
+ private sanitize(name: string): string {
78
+ const sanitized = name.replace(INVALID_RUN_THEN_CHARACTER_RE, (run) => {
79
+ const next = run.charAt(run.length - 1);
80
+ return this.isInvalid(next) ? "" : next.toUpperCase();
81
+ });
82
+ // The original prefixed the unsanitized name, which kept invalid characters after a leading
83
+ // digit, and missed a digit that only became first after sanitizing (research/legacy-bugs.md,
84
+ // item 15). Prefixing the sanitized name gives the same name wherever the original was valid.
85
+ return STARTS_WITH_DIGIT_RE.test(sanitized) ? `${NUMBER_PREFIX}${sanitized}` : sanitized;
86
+ }
87
+
88
+ private isInvalid(character: string): boolean {
89
+ if (this.isNextCheckSkipped) {
90
+ this.isNextCheckSkipped = false;
91
+ return false;
92
+ }
93
+ this.isNextCheckSkipped = INVALID_CHARACTER_RE.test(character);
94
+ return this.isNextCheckSkipped;
95
+ }
96
+ }
97
+
98
+ function firstCharacter(sanitized: string, name: string): string {
99
+ const first = sanitized[0];
100
+ if (first === undefined) {
101
+ throw new EmptyEnumNameError(name);
102
+ }
103
+ return first;
104
+ }
105
+
106
+ /**
107
+ * A string-literal member name. The original wrapped the name in quotes without escaping, so `\`
108
+ * and `"` gave invalid output (upstream #2614); a JSON string is a valid TypeScript string.
109
+ */
110
+ export function quotedMemberName(name: string): string {
111
+ return JSON.stringify(name);
112
+ }
113
+
114
+ function prefixedMemberName(name: string): string {
115
+ if (Number(name[0]) >= 0) {
116
+ // Only the first dot: `1.5` → `Value1_5`.
117
+ return `${NUMBER_PREFIX}${name}`.replace(".", "_");
118
+ }
119
+ return name[0] === "-" ? `${NEGATIVE_PREFIX}${name.slice(1)}` : name;
120
+ }
121
+
122
+ /** Every line terminator of JavaScript, which would end a `//` comment. */
123
+ const LINE_TERMINATORS_RE = /\r\n|[\n\r\u2028\u2029]/g;
124
+
125
+ /** The text of a member's `//` comment: trimmed, on one line; empty when there is none. */
126
+ export function enumMemberDescription(description: string | null | undefined): string {
127
+ return description?.trim().replace(LINE_TERMINATORS_RE, " ") ?? "";
128
+ }
129
+
130
+ /**
131
+ * The member comment: the trimmed description as a line comment, as in the original. Line breaks
132
+ * become spaces: in a `//` comment they ended the comment early (upstream #2838).
133
+ */
134
+ function enumMemberComments(metadata: EnumMemberNaming = {}): IrComment[] {
135
+ const description = enumMemberDescription(metadata.description);
136
+ return description ? [{ kind: "line", text: ` ${description}` }] : [];
137
+ }
138
+
139
+ /** The members of an enum, by value, with optional metadata at the same index. */
140
+ export interface EnumMembers {
141
+ readonly values: readonly (string | number)[];
142
+ readonly metadata: readonly (EnumMemberNaming | undefined)[];
143
+ }
144
+
145
+ /** Separates a repeated member name from its number: `reactions_1` → `reactions_1_2`. */
146
+ const MEMBER_NUMBER_SEPARATOR = "_";
147
+
148
+ /** The `count`-th use of a member name; a quoted name gets the number inside the quotes. */
149
+ function numberedMemberName(name: string, count: number): string {
150
+ const isQuoted = name.startsWith('"');
151
+ const raw = isQuoted ? (JSON.parse(name) as string) : name;
152
+ const numbered = `${raw}${MEMBER_NUMBER_SEPARATOR}${count}`;
153
+ return isQuoted ? quotedMemberName(numbered) : numbered;
154
+ }
155
+
156
+ /**
157
+ * An exported enum with an already built `name`; member names advance the naming state. Values
158
+ * whose names come out the same (`reactions-+1` and `reactions--1` are both `reactions_1`) would
159
+ * not compile, so a repeated name gets a number (`reactions_1_2`).
160
+ */
161
+ export function enumDeclaration(
162
+ name: string,
163
+ members: EnumMembers,
164
+ naming: EnumNaming,
165
+ ): IrEnumDeclaration {
166
+ const names = members.values.map((value, index) =>
167
+ naming.memberName(value, members.metadata[index]),
168
+ );
169
+ const uniqueNames = withNumberedRepeats(names, numberedMemberName);
170
+ return {
171
+ kind: "enum",
172
+ name,
173
+ isExported: true,
174
+ members: members.values.map((value, index) => ({
175
+ name: uniqueNames[index] as string,
176
+ value,
177
+ comments: enumMemberComments(members.metadata[index]),
178
+ })),
179
+ comments: [],
180
+ };
181
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The helper type aliases the generator adds to the footer, declared once each. The text is the
3
+ * original's source text as the TypeScript printer printed it, so printing it as written gives
4
+ * the original output (ENGINEERING_PLAN 6.2 and 6.6), except for the fixes noted below.
5
+ */
6
+ export interface HelperType {
7
+ readonly name: string;
8
+ readonly text: string;
9
+ }
10
+
11
+ function lines(...parts: readonly string[]): string {
12
+ return parts.join("\n");
13
+ }
14
+
15
+ export const HELPER_TYPES = {
16
+ withRequired: {
17
+ name: "WithRequired",
18
+ text: lines("type WithRequired<T, K extends keyof T> = T & {", " [P in K]-?: T[P];", "};"),
19
+ },
20
+ // `unevaluated-properties` (roadmap R11): the value types of every member of a union, so a
21
+ // `$ref` to a `oneOf` schema gives the values of each variant, not only of the shared keys.
22
+ propertyValues: {
23
+ name: "PropertyValues",
24
+ text: "type PropertyValues<T> = T extends unknown ? T[keyof T] : never;",
25
+ },
26
+ // Task 7.4 changes the original text on purpose: `readonly unknown[]` also flattens the arrays
27
+ // of `--immutable` (upstream #2714, #2749), and `NonNullable` looks through nullable parents
28
+ // (upstream #2737). The old text did not compile for those schemas.
29
+ flattenedDeepRequired: {
30
+ name: "FlattenedDeepRequired",
31
+ text: lines(
32
+ "type FlattenedDeepRequired<T> = {",
33
+ " [K in keyof T]-?: FlattenedDeepRequired<T[K] extends readonly unknown[] | undefined | " +
34
+ "null ? Extract<T[K], readonly unknown[]>[number] : NonNullable<T[K]>>;",
35
+ "};",
36
+ ),
37
+ },
38
+ // `readonly unknown[]`: a readonly array value type stays as is (upstream #2749).
39
+ readonlyArray: {
40
+ name: "ReadonlyArray",
41
+ text: lines(
42
+ "type ReadonlyArray<T> = [",
43
+ " Exclude<T, undefined>",
44
+ "] extends [",
45
+ " readonly unknown[]",
46
+ "] ? Readonly<Exclude<T, undefined>> : Readonly<Exclude<T, undefined>[]>;",
47
+ ),
48
+ },
49
+ } as const satisfies Readonly<Record<string, HelperType>>;
50
+
51
+ /**
52
+ * The `--read-write-markers` helper types, written before the root types. Task 7.6 replaces the
53
+ * original text on purpose (ADR-014): primitives (also branded), readonly arrays, tuples,
54
+ * intersected arrays and null-only properties keep their types (upstream #2615, #2620, #2632,
55
+ * #2717, #2765). The declarations equal `Readable` / `Writable` of openapi-typesafe-helpers
56
+ * (`test/api/read-write-marker-types.test.ts`); the text is what the TypeScript printer prints.
57
+ */
58
+ export const READ_WRITE_MARKER_TYPES = lines(
59
+ "export type $Read<T> = {",
60
+ " readonly $read: T;",
61
+ "};",
62
+ "export type $Write<T> = {",
63
+ " readonly $write: T;",
64
+ "};",
65
+ "type ReadWritePrimitive = string | number | boolean | bigint | symbol | null | undefined;",
66
+ "type ReadWriteLeaf = ReadWritePrimitive | ((...args: never) => unknown);",
67
+ "type ReadWriteMarkedKeys<T, Marker> = {",
68
+ " [K in keyof T]-?: NonNullable<T[K]> extends never ? never : NonNullable<T[K]> " +
69
+ "extends Marker ? K : never;",
70
+ "}[keyof T];",
71
+ 'type ReadWriteResolveArray<T extends readonly unknown[], Resolved extends "read" | ' +
72
+ '"write"> = T[number][] extends T ? T extends unknown[] ? ReadWriteResolve<T[number], ' +
73
+ "Resolved>[] : readonly ReadWriteResolve<T[number], Resolved>[] : {",
74
+ " [K in keyof T]: ReadWriteResolve<T[K], Resolved>;",
75
+ "};",
76
+ 'type ReadWriteResolve<T, Resolved extends "read" | "write"> = Resolved extends "read" ? ' +
77
+ "Readable<T> : Writable<T>;",
78
+ "export type Readable<T> = T extends $Write<any> ? never : T extends $Read<infer U> ? " +
79
+ "Readable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? " +
80
+ 'ReadWriteResolveArray<T, "read"> : T extends object ? {',
81
+ " [K in keyof T as K extends ReadWriteMarkedKeys<T, $Write<any>> ? never : K]: " +
82
+ "Readable<T[K]>;",
83
+ "} : T;",
84
+ "export type Writable<T> = T extends $Read<any> ? never : T extends $Write<infer U> ? " +
85
+ "Writable<U> : T extends ReadWriteLeaf ? T : T extends readonly unknown[] ? " +
86
+ 'ReadWriteResolveArray<T, "write"> : T extends object ? {',
87
+ " [K in keyof T as K extends ReadWriteMarkedKeys<T, $Read<any>> ? never : K]: " +
88
+ "Writable<T[K]>;",
89
+ "} & {",
90
+ " [K in ReadWriteMarkedKeys<T, $Read<any>>]?: never;",
91
+ "} : T;",
92
+ );
@@ -0,0 +1,54 @@
1
+ import {
2
+ irArray,
3
+ irBoolean,
4
+ irKeyword,
5
+ irNumber,
6
+ irObject,
7
+ irProperty,
8
+ irRaw,
9
+ irRecord,
10
+ irString,
11
+ irTuple,
12
+ irTupleElement,
13
+ } from "../../domain/ir/constructors.js";
14
+ import type { IrType } from "../../domain/ir/nodes.js";
15
+ import { toPropertyName } from "../../domain/ir/property-name.js";
16
+ import { UNKNOWN_TYPE } from "./shared-types.js";
17
+
18
+ function objectLiteralType(value: object): IrType {
19
+ const members = Object.entries(value).map(([key, entry]) =>
20
+ irProperty(toPropertyName(key), literalType(entry)),
21
+ );
22
+ return members.length > 0 ? irObject(members) : irRecord(irKeyword("string"), irKeyword("never"));
23
+ }
24
+
25
+ function arrayLiteralType(value: readonly unknown[]): IrType {
26
+ return value.length === 0
27
+ ? irArray(irKeyword("never"))
28
+ : irTuple(value.map((item) => irTupleElement(literalType(item))));
29
+ }
30
+
31
+ /**
32
+ * The literal type of a JSON value (the original `tsLiteral`): strings as JSON text, arrays as
33
+ * tuples (an empty one as `never[]`), objects as object types (an empty one as
34
+ * `Record<string, never>`), and anything else (`undefined`, functions) as `unknown`.
35
+ */
36
+ export function literalType(value: unknown): IrType {
37
+ if (typeof value === "string") {
38
+ return irString(value, "json");
39
+ }
40
+ if (typeof value === "number") {
41
+ // YAML `.nan` and `.inf` have no literal type; the original prints them as `NaN`, `-Infinity`.
42
+ return Number.isFinite(value) ? irNumber(value) : irRaw(String(value));
43
+ }
44
+ if (typeof value === "boolean") {
45
+ return irBoolean(value);
46
+ }
47
+ if (value === null) {
48
+ return irKeyword("null");
49
+ }
50
+ if (Array.isArray(value)) {
51
+ return arrayLiteralType(value);
52
+ }
53
+ return typeof value === "object" ? objectLiteralType(value) : UNKNOWN_TYPE;
54
+ }
@@ -0,0 +1,20 @@
1
+ /** Builds the name for the `count`-th use of `name` (2, 3…). */
2
+ export type NumberedName = (name: string, count: number) => string;
3
+
4
+ /**
5
+ * Names made unique, in order: the first use of a name keeps it, each repeat gets the lowest
6
+ * number from 2 whose name is not written anywhere in the list.
7
+ */
8
+ export function withNumberedRepeats(names: readonly string[], numbered: NumberedName): string[] {
9
+ const written = new Set(names);
10
+ const taken = new Set<string>();
11
+ return names.map((name) => {
12
+ let unique = name;
13
+ for (let count = 2; taken.has(unique); count += 1) {
14
+ const candidate = numbered(name, count);
15
+ unique = written.has(candidate) ? unique : candidate;
16
+ }
17
+ taken.add(unique);
18
+ return unique;
19
+ });
20
+ }
@@ -0,0 +1,97 @@
1
+ import { ERROR_CODES, OpenAPITypesafeError } from "../../domain/errors.js";
2
+ import {
3
+ irIndexedAccess,
4
+ irKeyword,
5
+ irObject,
6
+ irProperty,
7
+ irReference,
8
+ irString,
9
+ } from "../../domain/ir/constructors.js";
10
+ import type { IrType } from "../../domain/ir/nodes.js";
11
+ import { parseRefPointer } from "../../domain/openapi/json-pointer.js";
12
+
13
+ /** Where a referenced parameter lives in the generated `parameters` type. */
14
+ export interface RefParameterTarget {
15
+ readonly in: string;
16
+ readonly name: string;
17
+ }
18
+
19
+ export interface RefTypeOptions {
20
+ /** Wrap the root in `FlattenedDeepRequired<…>`. */
21
+ readonly isDeep?: boolean;
22
+ /** Segments to narrow with `Extract<T, { segment: unknown }>` before indexing. */
23
+ readonly extractProperties?: readonly string[];
24
+ /** Set when the `$ref` resolves to a parameter object: its last segment indexes `in`, `name`. */
25
+ readonly parameter?: RefParameterTarget | null;
26
+ }
27
+
28
+ export class InvalidRefError extends OpenAPITypesafeError {
29
+ constructor(ref: string) {
30
+ super({
31
+ code: ERROR_CODES.SCHEMA_REF_INVALID,
32
+ message: `Error parsing $ref: ${ref}. Is this a valid $ref?`,
33
+ details: { ref },
34
+ });
35
+ this.name = "InvalidRefError";
36
+ }
37
+ }
38
+
39
+ /** Segments that index into the root type, always as escaped string literal types. */
40
+ function indexBy(type: IrType, ...segments: readonly string[]): IrType {
41
+ return segments.reduce<IrType>(
42
+ (object, segment) => irIndexedAccess(object, irString(segment, "escaped")),
43
+ type,
44
+ );
45
+ }
46
+
47
+ /** `Extract<T, { name: unknown }>`; the name is written as an identifier, as in the original. */
48
+ function extractVariantsWith(type: IrType, propertyName: string): IrType {
49
+ const probe = irProperty({ kind: "identifier", text: propertyName }, irKeyword("unknown"));
50
+ return irReference("Extract", [type, irObject([probe])]);
51
+ }
52
+
53
+ const DEFS_KEYWORD = "$defs";
54
+
55
+ /**
56
+ * Index by `segment`. A `$defs` member is optional (it is a keyword, not data), so when more
57
+ * segments follow it is wrapped in `NonNullable<…>` first; otherwise the next index fails on
58
+ * `undefined` (upstream #2664).
59
+ */
60
+ function indexKeyword(type: IrType, segment: string, isLast: boolean): IrType {
61
+ const indexed = indexBy(type, segment);
62
+ return segment === DEFS_KEYWORD && !isLast ? irReference("NonNullable", [indexed]) : indexed;
63
+ }
64
+
65
+ function rootType(rootSegment: string, isDeep: boolean): IrType {
66
+ return irReference(isDeep ? `FlattenedDeepRequired<${rootSegment}>` : rootSegment);
67
+ }
68
+
69
+ /**
70
+ * The indexed-access type of a `$ref` into the generated types (the original `oapiRef`), for
71
+ * example `components["schemas"]["Foo"]`. The first three segments index directly. After them,
72
+ * `properties` segments are skipped (objects are flattened, upstream issue 1742), a parameter's
73
+ * last segment becomes `[in][name]`, and listed segments are narrowed with `Extract` first.
74
+ *
75
+ * Throws InvalidRefError when the `$ref` has no pointer.
76
+ */
77
+ export function refType(ref: string, options: RefTypeOptions = {}): IrType {
78
+ const [rootSegment, ...pointer] = parseRefPointer(ref);
79
+ if (rootSegment === undefined) {
80
+ throw new InvalidRefError(ref);
81
+ }
82
+ const extracted = new Set(options.extractProperties ?? []);
83
+ const lastIndex = pointer.length - 1;
84
+ const leading = indexBy(rootType(rootSegment, options.isDeep ?? false), ...pointer.slice(0, 2));
85
+ return pointer.slice(2).reduce<IrType>((type, segment, offset) => {
86
+ if (segment === "properties") {
87
+ return type;
88
+ }
89
+ if (options.parameter && offset + 2 === lastIndex) {
90
+ return indexBy(type, options.parameter.in, options.parameter.name);
91
+ }
92
+ const isLast = offset + 2 === lastIndex;
93
+ return extracted.has(segment)
94
+ ? indexBy(extractVariantsWith(type, segment), segment)
95
+ : indexKeyword(type, segment, isLast);
96
+ }, leading);
97
+ }
@@ -0,0 +1,152 @@
1
+ import { irArray, irReadonly, irTuple, irTupleElement } from "../../../domain/ir/constructors.js";
2
+ import type { IrType } from "../../../domain/ir/nodes.js";
3
+ import type { SchemaObject } from "../../../domain/openapi/schema-object.js";
4
+ import { OutputFix } from "../../../domain/output-fixes.js";
5
+ import { UNKNOWN_TYPE } from "../shared-types.js";
6
+ import { unionOf } from "../type-combinators.js";
7
+ import type { SchemaRequest } from "./schema-rule.js";
8
+
9
+ /**
10
+ * `--array-length` writes tuples only while the estimated number of tuple elements stays below
11
+ * this; the original chose it as roughly where TypeScript starts to struggle with tuple inference.
12
+ */
13
+ const MAX_LENGTH_TUPLE_ELEMENTS = 30;
14
+
15
+ /** The tuple of `prefixItems` (or of an `items` list); null without either. */
16
+ function prefixTupleType(schema: SchemaObject, request: SchemaRequest): IrType | null {
17
+ const { items } = schema;
18
+ if (!schema.prefixItems && !Array.isArray(items)) {
19
+ return null;
20
+ }
21
+ const prefixItems = schema.prefixItems ?? (items as SchemaObject[]);
22
+ return irTuple(
23
+ prefixItems.map((item) => irTupleElement(request.transformNested(item, request.location))),
24
+ );
25
+ }
26
+
27
+ /** The type of one item; `unknown` without `items`. */
28
+ function singleItemType(schema: SchemaObject, request: SchemaRequest): IrType {
29
+ const { items } = schema;
30
+ return items ? request.transformNested(items as SchemaObject, request.location) : UNKNOWN_TYPE;
31
+ }
32
+
33
+ /**
34
+ * The item type as the original returns it: a tuple stands for the whole array, and a nested
35
+ * `type: array` item is wrapped in an array here already.
36
+ */
37
+ function itemType(schema: SchemaObject, request: SchemaRequest): IrType {
38
+ const tuple = prefixTupleType(schema, request);
39
+ if (tuple !== null) {
40
+ return tuple;
41
+ }
42
+ const { items } = schema;
43
+ // Checked first: the `in` test below throws for `items: null`.
44
+ if (!items) {
45
+ return UNKNOWN_TYPE;
46
+ }
47
+ const nested = singleItemType(schema, request);
48
+ const isNestedArray = typeof items === "object" && "type" in items && items.type === "array";
49
+ return isNestedArray ? irArray(nested) : nested;
50
+ }
51
+
52
+ function repeat(type: IrType, count: number): IrType[] {
53
+ return Array.from({ length: count }, () => type);
54
+ }
55
+
56
+ interface LengthBounds {
57
+ readonly min: number;
58
+ readonly max: number | undefined;
59
+ }
60
+
61
+ function lengthBounds(schema: SchemaObject): LengthBounds {
62
+ const { minItems, maxItems } = schema;
63
+ const min = typeof minItems === "number" && minItems >= 0 ? minItems : 0;
64
+ const isMaxValid = typeof maxItems === "number" && maxItems >= 0 && min <= maxItems;
65
+ return { min, max: isMaxValid ? maxItems : undefined };
66
+ }
67
+
68
+ /**
69
+ * Tuples for `--array-length`, as the original builds them. With both bounds it emits tuples of
70
+ * length 0 to `max - min` (not `min` to `max`); the `array-length-tuples` fix corrects it.
71
+ */
72
+ function lengthTupleType(schema: SchemaObject, item: IrType, bounds: LengthBounds): IrType {
73
+ const { min, max } = bounds;
74
+ if (min === max) {
75
+ return unionOf([irTuple(repeat(item, min).map((type) => irTupleElement(type)))]);
76
+ }
77
+ if ((schema.maxItems as number) > 0) {
78
+ const lengths = Array.from({ length: Math.max(0, (max ?? 0) - min + 1) }, (_, index) => index);
79
+ return unionOf(
80
+ lengths.map((length) => irTuple(repeat(item, length).map((type) => irTupleElement(type)))),
81
+ );
82
+ }
83
+ const elements = repeat(item, min).map((type) => irTupleElement(type));
84
+ return irTuple([...elements, irTupleElement(irArray(item), true)]);
85
+ }
86
+
87
+ function isLengthTupleWanted(bounds: LengthBounds, request: SchemaRequest): boolean {
88
+ const { min, max } = bounds;
89
+ const estimatedSize = max === undefined ? min : (max * (max + 1) - min * (min - 1)) / 2;
90
+ const hasBounds = min !== 0 || max !== undefined;
91
+ return (
92
+ request.context.options.arrayLength && hasBounds && estimatedSize < MAX_LENGTH_TUPLE_ELEMENTS
93
+ );
94
+ }
95
+
96
+ /** Applies `--immutable` to one array or tuple type. */
97
+ type ArrayWrapper = (type: IrType) => IrType;
98
+
99
+ function tupleOf(item: IrType, length: number, isOpen: boolean): IrType {
100
+ const elements = repeat(item, length).map((type) => irTupleElement(type));
101
+ return irTuple(isOpen ? [...elements, irTupleElement(irArray(item), true)] : elements);
102
+ }
103
+
104
+ /** Tuples of every length from `min` to `max`; without `max`, `min` items and a rest element. */
105
+ function fixedLengthTupleType(item: IrType, bounds: LengthBounds, wrap: ArrayWrapper): IrType {
106
+ const { min, max } = bounds;
107
+ if (max === undefined) {
108
+ return wrap(tupleOf(item, min, true));
109
+ }
110
+ const lengths = Array.from({ length: max - min + 1 }, (_, index) => min + index);
111
+ return unionOf(lengths.map((length) => wrap(tupleOf(item, length, false))));
112
+ }
113
+
114
+ /**
115
+ * `type: array` with `--array-length` and the `array-length-tuples` fix (#2048, #2330, #2546):
116
+ * the tuples have `min` to `max` items, the item type is used as it is (a nested array stays one
117
+ * level deep), a `prefixItems` tuple gets no length tuples around it, and `--immutable` makes
118
+ * every tuple `readonly`.
119
+ */
120
+ function fixedArrayType(schema: SchemaObject, request: SchemaRequest): IrType {
121
+ const wrap: ArrayWrapper = (type) =>
122
+ request.context.options.immutable ? irReadonly(type) : type;
123
+ const tuple = prefixTupleType(schema, request);
124
+ if (tuple !== null) {
125
+ return wrap(tuple);
126
+ }
127
+ const item = singleItemType(schema, request);
128
+ const bounds = lengthBounds(schema);
129
+ return isLengthTupleWanted(bounds, request)
130
+ ? fixedLengthTupleType(item, bounds, wrap)
131
+ : wrap(irArray(item));
132
+ }
133
+
134
+ function isArrayLengthFixed(request: SchemaRequest): boolean {
135
+ const { arrayLength, fixes } = request.context.options;
136
+ return arrayLength && fixes.has(OutputFix.ARRAY_LENGTH_TUPLES);
137
+ }
138
+
139
+ /** `type: array`, including tuples (`prefixItems`, array `items`) and `--array-length`. */
140
+ export function arrayType(schema: SchemaObject, request: SchemaRequest): IrType {
141
+ if (isArrayLengthFixed(request)) {
142
+ return fixedArrayType(schema, request);
143
+ }
144
+ const item = itemType(schema, request);
145
+ const bounds = lengthBounds(schema);
146
+ if (isLengthTupleWanted(bounds, request)) {
147
+ return lengthTupleType(schema, item, bounds);
148
+ }
149
+ // A tuple or an array item is used as the array type itself.
150
+ const type = item.kind === "tuple" || item.kind === "array" ? item : irArray(item);
151
+ return request.context.options.immutable ? irReadonly(type) : type;
152
+ }