openapi-typesafe 1.0.0-rc.0 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
  2. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
  3. package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
  4. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
  5. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +15 -5
  6. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  7. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +15 -5
  8. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  9. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +3 -0
  10. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
  11. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +3 -0
  12. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
  13. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
  14. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
  15. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
  16. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
  17. package/dist/api/discriminator-conflict-warnings.cjs +25 -0
  18. package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
  19. package/dist/api/discriminator-conflict-warnings.mjs +23 -0
  20. package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
  21. package/dist/api/discriminator-enum-names.cjs +19 -0
  22. package/dist/api/discriminator-enum-names.cjs.map +1 -0
  23. package/dist/api/discriminator-enum-names.mjs +17 -0
  24. package/dist/api/discriminator-enum-names.mjs.map +1 -0
  25. package/dist/api/discriminator-enum-parent.cjs +59 -0
  26. package/dist/api/discriminator-enum-parent.cjs.map +1 -0
  27. package/dist/api/discriminator-enum-parent.mjs +57 -0
  28. package/dist/api/discriminator-enum-parent.mjs.map +1 -0
  29. package/dist/api/discriminator-enum.cjs +25 -0
  30. package/dist/api/discriminator-enum.cjs.map +1 -1
  31. package/dist/api/discriminator-enum.mjs +25 -1
  32. package/dist/api/discriminator-enum.mjs.map +1 -1
  33. package/dist/api/discriminator-other-owners.cjs +67 -0
  34. package/dist/api/discriminator-other-owners.cjs.map +1 -0
  35. package/dist/api/discriminator-other-owners.mjs +64 -0
  36. package/dist/api/discriminator-other-owners.mjs.map +1 -0
  37. package/dist/api/discriminator-patch.cjs +88 -0
  38. package/dist/api/discriminator-patch.cjs.map +1 -0
  39. package/dist/api/discriminator-patch.mjs +82 -0
  40. package/dist/api/discriminator-patch.mjs.map +1 -0
  41. package/dist/api/discriminator-scan.cjs +50 -65
  42. package/dist/api/discriminator-scan.cjs.map +1 -1
  43. package/dist/api/discriminator-scan.mjs +44 -59
  44. package/dist/api/discriminator-scan.mjs.map +1 -1
  45. package/dist/api/document-run.cjs +18 -3
  46. package/dist/api/document-run.cjs.map +1 -1
  47. package/dist/api/document-run.mjs +19 -4
  48. package/dist/api/document-run.mjs.map +1 -1
  49. package/dist/api/enum-values-warnings.cjs +16 -0
  50. package/dist/api/enum-values-warnings.cjs.map +1 -0
  51. package/dist/api/enum-values-warnings.mjs +14 -0
  52. package/dist/api/enum-values-warnings.mjs.map +1 -0
  53. package/dist/api/path-template-warnings.cjs +21 -0
  54. package/dist/api/path-template-warnings.cjs.map +1 -0
  55. package/dist/api/path-template-warnings.mjs +19 -0
  56. package/dist/api/path-template-warnings.mjs.map +1 -0
  57. package/dist/api/transform-context.cjs +3 -1
  58. package/dist/api/transform-context.cjs.map +1 -1
  59. package/dist/api/transform-context.mjs +3 -1
  60. package/dist/api/transform-context.mjs.map +1 -1
  61. package/dist/api/transform-schema.cjs +52 -3
  62. package/dist/api/transform-schema.cjs.map +1 -1
  63. package/dist/api/transform-schema.mjs +53 -4
  64. package/dist/api/transform-schema.mjs.map +1 -1
  65. package/dist/api/unsupported-feature-warnings.cjs +6 -1
  66. package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
  67. package/dist/api/unsupported-feature-warnings.mjs +6 -1
  68. package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
  69. package/dist/application/print/type-printer.cjs +5 -0
  70. package/dist/application/print/type-printer.cjs.map +1 -1
  71. package/dist/application/print/type-printer.mjs +5 -0
  72. package/dist/application/print/type-printer.mjs.map +1 -1
  73. package/dist/application/transform/document/assignability.cjs +144 -0
  74. package/dist/application/transform/document/assignability.cjs.map +1 -0
  75. package/dist/application/transform/document/assignability.mjs +138 -0
  76. package/dist/application/transform/document/assignability.mjs.map +1 -0
  77. package/dist/application/transform/document/components.cjs +2 -2
  78. package/dist/application/transform/document/components.cjs.map +1 -1
  79. package/dist/application/transform/document/components.mjs +4 -4
  80. package/dist/application/transform/document/components.mjs.map +1 -1
  81. package/dist/application/transform/document/declared-types.cjs +66 -0
  82. package/dist/application/transform/document/declared-types.cjs.map +1 -0
  83. package/dist/application/transform/document/declared-types.mjs +63 -0
  84. package/dist/application/transform/document/declared-types.mjs.map +1 -0
  85. package/dist/application/transform/document/document.cjs +32 -9
  86. package/dist/application/transform/document/document.cjs.map +1 -1
  87. package/dist/application/transform/document/document.mjs +34 -11
  88. package/dist/application/transform/document/document.mjs.map +1 -1
  89. package/dist/application/transform/document/exploded-query.cjs +46 -0
  90. package/dist/application/transform/document/exploded-query.cjs.map +1 -0
  91. package/dist/application/transform/document/exploded-query.mjs +43 -0
  92. package/dist/application/transform/document/exploded-query.mjs.map +1 -0
  93. package/dist/application/transform/document/global-type-references.cjs +63 -0
  94. package/dist/application/transform/document/global-type-references.cjs.map +1 -0
  95. package/dist/application/transform/document/global-type-references.mjs +61 -0
  96. package/dist/application/transform/document/global-type-references.mjs.map +1 -0
  97. package/dist/application/transform/document/list-assignability.cjs +54 -0
  98. package/dist/application/transform/document/list-assignability.cjs.map +1 -0
  99. package/dist/application/transform/document/list-assignability.mjs +52 -0
  100. package/dist/application/transform/document/list-assignability.mjs.map +1 -0
  101. package/dist/application/transform/document/parameters.cjs +40 -8
  102. package/dist/application/transform/document/parameters.cjs.map +1 -1
  103. package/dist/application/transform/document/parameters.mjs +41 -9
  104. package/dist/application/transform/document/parameters.mjs.map +1 -1
  105. package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
  106. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
  107. package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
  108. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
  109. package/dist/application/transform/document/path-template-replace.cjs +48 -0
  110. package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
  111. package/dist/application/transform/document/path-template-replace.mjs +45 -0
  112. package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
  113. package/dist/application/transform/document/paths.cjs +54 -28
  114. package/dist/application/transform/document/paths.cjs.map +1 -1
  115. package/dist/application/transform/document/paths.mjs +53 -29
  116. package/dist/application/transform/document/paths.mjs.map +1 -1
  117. package/dist/application/transform/document/root-type-aliases.cjs +15 -14
  118. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  119. package/dist/application/transform/document/root-type-aliases.mjs +15 -13
  120. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  121. package/dist/application/transform/document/template-key-match.cjs +128 -0
  122. package/dist/application/transform/document/template-key-match.cjs.map +1 -0
  123. package/dist/application/transform/document/template-key-match.mjs +125 -0
  124. package/dist/application/transform/document/template-key-match.mjs.map +1 -0
  125. package/dist/application/transform/document/type-assignability.cjs +192 -0
  126. package/dist/application/transform/document/type-assignability.cjs.map +1 -0
  127. package/dist/application/transform/document/type-assignability.mjs +190 -0
  128. package/dist/application/transform/document/type-assignability.mjs.map +1 -0
  129. package/dist/application/transform/document/type-key.cjs +70 -0
  130. package/dist/application/transform/document/type-key.cjs.map +1 -0
  131. package/dist/application/transform/document/type-key.mjs +68 -0
  132. package/dist/application/transform/document/type-key.mjs.map +1 -0
  133. package/dist/application/transform/document/type-resolution.cjs +131 -0
  134. package/dist/application/transform/document/type-resolution.cjs.map +1 -0
  135. package/dist/application/transform/document/type-resolution.mjs +125 -0
  136. package/dist/application/transform/document/type-resolution.mjs.map +1 -0
  137. package/dist/application/transform/footer/document-footer.cjs +66 -4
  138. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  139. package/dist/application/transform/footer/document-footer.mjs +67 -5
  140. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  141. package/dist/application/transform/footer/enum-naming.cjs +17 -0
  142. package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
  143. package/dist/application/transform/footer/enum-naming.mjs +17 -1
  144. package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
  145. package/dist/application/transform/footer/enum-values-check.cjs +129 -0
  146. package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
  147. package/dist/application/transform/footer/enum-values-check.mjs +127 -0
  148. package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
  149. package/dist/application/transform/footer/evaluation.cjs +33 -0
  150. package/dist/application/transform/footer/evaluation.cjs.map +1 -0
  151. package/dist/application/transform/footer/evaluation.mjs +26 -0
  152. package/dist/application/transform/footer/evaluation.mjs.map +1 -0
  153. package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
  154. package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
  155. package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
  156. package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
  157. package/dist/application/transform/footer/type-evaluation.cjs +246 -0
  158. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
  159. package/dist/application/transform/footer/type-evaluation.mjs +244 -0
  160. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
  161. package/dist/application/transform/footer/type-rules.cjs +172 -0
  162. package/dist/application/transform/footer/type-rules.cjs.map +1 -0
  163. package/dist/application/transform/footer/type-rules.mjs +166 -0
  164. package/dist/application/transform/footer/type-rules.mjs.map +1 -0
  165. package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
  166. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
  167. package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
  168. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
  169. package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
  170. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
  171. package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
  172. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
  173. package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
  174. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
  175. package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
  176. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
  177. package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
  178. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
  179. package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
  180. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
  181. package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
  182. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
  183. package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
  184. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
  185. package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
  186. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
  187. package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
  188. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
  189. package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
  190. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
  191. package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
  192. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
  193. package/dist/application/transform/ref-type.cjs +7 -2
  194. package/dist/application/transform/ref-type.cjs.map +1 -1
  195. package/dist/application/transform/ref-type.mjs +3 -2
  196. package/dist/application/transform/ref-type.mjs.map +1 -1
  197. package/dist/application/transform/schema/access-flags.cjs +38 -0
  198. package/dist/application/transform/schema/access-flags.cjs.map +1 -0
  199. package/dist/application/transform/schema/access-flags.mjs +36 -0
  200. package/dist/application/transform/schema/access-flags.mjs.map +1 -0
  201. package/dist/application/transform/schema/array-type.cjs +32 -1
  202. package/dist/application/transform/schema/array-type.cjs.map +1 -1
  203. package/dist/application/transform/schema/array-type.mjs +33 -2
  204. package/dist/application/transform/schema/array-type.mjs.map +1 -1
  205. package/dist/application/transform/schema/composition-type.cjs +50 -15
  206. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  207. package/dist/application/transform/schema/composition-type.mjs +50 -15
  208. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  209. package/dist/application/transform/schema/core-type.cjs +3 -1
  210. package/dist/application/transform/schema/core-type.cjs.map +1 -1
  211. package/dist/application/transform/schema/core-type.mjs +3 -1
  212. package/dist/application/transform/schema/core-type.mjs.map +1 -1
  213. package/dist/application/transform/schema/discriminated-union.cjs +30 -0
  214. package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
  215. package/dist/application/transform/schema/discriminated-union.mjs +27 -0
  216. package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
  217. package/dist/application/transform/schema/discriminator-property.cjs +3 -2
  218. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
  219. package/dist/application/transform/schema/discriminator-property.mjs +3 -2
  220. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
  221. package/dist/application/transform/schema/enum-rule.cjs +66 -10
  222. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  223. package/dist/application/transform/schema/enum-rule.mjs +67 -12
  224. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  225. package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
  226. package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
  227. package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
  228. package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
  229. package/dist/application/transform/schema/object-type.cjs +38 -25
  230. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  231. package/dist/application/transform/schema/object-type.mjs +39 -27
  232. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  233. package/dist/application/transform/schema/required-variants.cjs +45 -0
  234. package/dist/application/transform/schema/required-variants.cjs.map +1 -0
  235. package/dist/application/transform/schema/required-variants.mjs +42 -0
  236. package/dist/application/transform/schema/required-variants.mjs.map +1 -0
  237. package/dist/application/transform/schema/schema-transform.cjs +2 -2
  238. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  239. package/dist/application/transform/schema/schema-transform.mjs +2 -2
  240. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  241. package/dist/application/transform/schema-comment.cjs +51 -5
  242. package/dist/application/transform/schema-comment.cjs.map +1 -1
  243. package/dist/application/transform/schema-comment.mjs +50 -6
  244. package/dist/application/transform/schema-comment.mjs.map +1 -1
  245. package/dist/application/transform/type-combinators.mjs +1 -1
  246. package/dist/cli/cli-arguments.cjs +11 -3
  247. package/dist/cli/cli-arguments.cjs.map +1 -1
  248. package/dist/cli/cli-arguments.mjs +11 -3
  249. package/dist/cli/cli-arguments.mjs.map +1 -1
  250. package/dist/cli/cli-errors.cjs +3 -2
  251. package/dist/cli/cli-errors.cjs.map +1 -1
  252. package/dist/cli/cli-errors.mjs +3 -2
  253. package/dist/cli/cli-errors.mjs.map +1 -1
  254. package/dist/cli/cli-output.cjs +8 -3
  255. package/dist/cli/cli-output.cjs.map +1 -1
  256. package/dist/cli/cli-output.mjs +9 -4
  257. package/dist/cli/cli-output.mjs.map +1 -1
  258. package/dist/cli/main.cjs +5 -0
  259. package/dist/cli/main.cjs.map +1 -1
  260. package/dist/cli/main.mjs +5 -0
  261. package/dist/cli/main.mjs.map +1 -1
  262. package/dist/cli/redocly-apis.cjs +7 -3
  263. package/dist/cli/redocly-apis.cjs.map +1 -1
  264. package/dist/cli/redocly-apis.mjs +8 -4
  265. package/dist/cli/redocly-apis.mjs.map +1 -1
  266. package/dist/cli/ref-limits.cjs +1 -1
  267. package/dist/cli/ref-limits.cjs.map +1 -1
  268. package/dist/cli/ref-limits.mjs +2 -2
  269. package/dist/cli/ref-limits.mjs.map +1 -1
  270. package/dist/cli/run-cli.cjs +15 -2
  271. package/dist/cli/run-cli.cjs.map +1 -1
  272. package/dist/cli/run-cli.mjs +16 -3
  273. package/dist/cli/run-cli.mjs.map +1 -1
  274. package/dist/domain/errors.cjs +2 -0
  275. package/dist/domain/errors.cjs.map +1 -1
  276. package/dist/domain/errors.mjs +2 -0
  277. package/dist/domain/errors.mjs.map +1 -1
  278. package/dist/domain/ir/constructors.cjs +5 -1
  279. package/dist/domain/ir/constructors.cjs.map +1 -1
  280. package/dist/domain/ir/constructors.mjs +5 -2
  281. package/dist/domain/ir/constructors.mjs.map +1 -1
  282. package/dist/domain/openapi/admitted-values.cjs +75 -0
  283. package/dist/domain/openapi/admitted-values.cjs.map +1 -0
  284. package/dist/domain/openapi/admitted-values.mjs +72 -0
  285. package/dist/domain/openapi/admitted-values.mjs.map +1 -0
  286. package/dist/domain/openapi/discriminated-union.cjs +68 -0
  287. package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
  288. package/dist/domain/openapi/discriminated-union.mjs +62 -0
  289. package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
  290. package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
  291. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
  292. package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
  293. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
  294. package/dist/domain/openapi/parameter-object.cjs.map +1 -1
  295. package/dist/domain/openapi/parameter-object.mjs.map +1 -1
  296. package/dist/domain/openapi/path-templates.cjs +23 -0
  297. package/dist/domain/openapi/path-templates.cjs.map +1 -0
  298. package/dist/domain/openapi/path-templates.mjs +21 -0
  299. package/dist/domain/openapi/path-templates.mjs.map +1 -0
  300. package/dist/domain/output-fixes.cjs +36 -1
  301. package/dist/domain/output-fixes.cjs.map +1 -1
  302. package/dist/domain/output-fixes.mjs +36 -1
  303. package/dist/domain/output-fixes.mjs.map +1 -1
  304. package/dist/domain/warnings.cjs +15 -0
  305. package/dist/domain/warnings.cjs.map +1 -0
  306. package/dist/domain/warnings.mjs +12 -0
  307. package/dist/domain/warnings.mjs.map +1 -0
  308. package/dist/index.d.cts +29 -0
  309. package/dist/index.d.mts +29 -0
  310. package/dist/index.d.ts +29 -0
  311. package/dist/transform/components-object.cjs +2 -1
  312. package/dist/transform/components-object.cjs.map +1 -1
  313. package/dist/transform/components-object.mjs +2 -1
  314. package/dist/transform/components-object.mjs.map +1 -1
  315. package/package.json +1 -1
  316. package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
  317. package/src/adapters/redocly-loader/redocly-schema-loader.ts +22 -6
  318. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +3 -0
  319. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
  320. package/src/api/discriminator-conflict-warnings.ts +43 -0
  321. package/src/api/discriminator-enum-names.ts +26 -0
  322. package/src/api/discriminator-enum-parent.ts +129 -0
  323. package/src/api/discriminator-enum.ts +39 -0
  324. package/src/api/discriminator-other-owners.ts +97 -0
  325. package/src/api/discriminator-patch.ts +147 -0
  326. package/src/api/discriminator-scan.ts +78 -90
  327. package/src/api/document-run.ts +24 -6
  328. package/src/api/enum-values-warnings.ts +21 -0
  329. package/src/api/path-template-warnings.ts +27 -0
  330. package/src/api/transform-context.ts +7 -1
  331. package/src/api/transform-schema.ts +88 -4
  332. package/src/api/unsupported-feature-warnings.ts +8 -1
  333. package/src/application/ports/redocly-config-source.ts +5 -1
  334. package/src/application/print/type-printer.ts +6 -0
  335. package/src/application/transform/document/assignability.ts +203 -0
  336. package/src/application/transform/document/components.ts +6 -6
  337. package/src/application/transform/document/declared-types.ts +93 -0
  338. package/src/application/transform/document/document.ts +71 -13
  339. package/src/application/transform/document/exploded-query.ts +91 -0
  340. package/src/application/transform/document/global-type-references.ts +78 -0
  341. package/src/application/transform/document/list-assignability.ts +87 -0
  342. package/src/application/transform/document/parameters.ts +76 -11
  343. package/src/application/transform/document/path-key-overlaps.ts +148 -59
  344. package/src/application/transform/document/path-template-replace.ts +90 -0
  345. package/src/application/transform/document/paths.ts +99 -37
  346. package/src/application/transform/document/root-type-aliases.ts +29 -28
  347. package/src/application/transform/document/template-key-match.ts +183 -0
  348. package/src/application/transform/document/type-assignability.ts +268 -0
  349. package/src/application/transform/document/type-key.ts +80 -0
  350. package/src/application/transform/document/type-resolution.ts +163 -0
  351. package/src/application/transform/footer/document-footer.ts +91 -6
  352. package/src/application/transform/footer/enum-naming.ts +29 -0
  353. package/src/application/transform/footer/enum-values-check.ts +171 -0
  354. package/src/application/transform/footer/evaluation.ts +47 -0
  355. package/src/application/transform/footer/shared-enum-names.ts +86 -0
  356. package/src/application/transform/footer/type-evaluation.ts +294 -0
  357. package/src/application/transform/footer/type-rules.ts +269 -0
  358. package/src/application/transform/ref-pointer/generated-location.ts +211 -0
  359. package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
  360. package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
  361. package/src/application/transform/ref-pointer/original-index.ts +95 -0
  362. package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
  363. package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
  364. package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
  365. package/src/application/transform/ref-type.ts +11 -6
  366. package/src/application/transform/schema/access-flags.ts +63 -0
  367. package/src/application/transform/schema/array-type.ts +66 -5
  368. package/src/application/transform/schema/composition-type.ts +96 -24
  369. package/src/application/transform/schema/core-type.ts +8 -4
  370. package/src/application/transform/schema/discriminated-union.ts +58 -0
  371. package/src/application/transform/schema/discriminator-property.ts +8 -3
  372. package/src/application/transform/schema/enum-rule.ts +136 -13
  373. package/src/application/transform/schema/inherited-discriminator.ts +54 -0
  374. package/src/application/transform/schema/object-type.ts +51 -33
  375. package/src/application/transform/schema/required-variants.ts +88 -0
  376. package/src/application/transform/schema/schema-context.ts +26 -0
  377. package/src/application/transform/schema/schema-transform.ts +2 -2
  378. package/src/application/transform/schema-comment.ts +84 -4
  379. package/src/cli/cli-arguments.ts +13 -3
  380. package/src/cli/cli-dependencies.ts +5 -0
  381. package/src/cli/cli-errors.ts +4 -2
  382. package/src/cli/cli-output.ts +18 -4
  383. package/src/cli/main.ts +6 -0
  384. package/src/cli/redocly-apis.ts +8 -4
  385. package/src/cli/ref-limits.ts +2 -2
  386. package/src/cli/run-cli.ts +20 -3
  387. package/src/domain/errors.ts +2 -0
  388. package/src/domain/ir/constructors.ts +6 -1
  389. package/src/domain/ir/nodes.ts +2 -1
  390. package/src/domain/openapi/admitted-values.ts +113 -0
  391. package/src/domain/openapi/discriminated-union.ts +109 -0
  392. package/src/domain/openapi/discriminator-conflicts.ts +251 -0
  393. package/src/domain/openapi/parameter-object.ts +4 -0
  394. package/src/domain/openapi/path-templates.ts +31 -0
  395. package/src/domain/openapi/schema-object.ts +2 -0
  396. package/src/domain/output-fixes.ts +43 -2
  397. package/src/domain/warnings.ts +20 -0
  398. package/src/transform/components-object.ts +3 -1
  399. package/src/types/generator-options.ts +11 -0
  400. package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
  401. package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
  402. package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
  403. package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
  404. package/src/application/transform/document/path-item-conflicts.ts +0 -79
@@ -1 +1 @@
1
- {"version":3,"file":"type-printer.mjs","sources":["../../../src/application/print/type-printer.ts"],"sourcesContent":["import { assertNever } from \"../../domain/assert-never.js\";\nimport type {\n IrIndexedAccessType,\n IrMember,\n IrPropertyName,\n IrRawType,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport { writeLeadingComment } from \"./comment-writer.js\";\nimport { printEscapedString, printNumberLiteral, printStringLiteral } from \"./literal-text.js\";\nimport type { TextWriter } from \"./text-writer.js\";\n\n/**\n * Parenthesization contexts. Each predicate says when a child type needs parentheses; together they\n * reproduce the TypeScript factory's parenthesizer rules for the node kinds of the IR, so output\n * matches the original even when unions are nested (`A | (B | C)`).\n */\nconst isUnionOrIntersection = (type: IrType): boolean =>\n type.kind === \"union\" || type.kind === \"intersection\";\n/** Union and intersection members (`parenthesizeConstituentTypeOf{Union,Intersection}Type`). */\nconst needsParensAsConstituent = isUnionOrIntersection;\n/** Array element and indexed-access object (`parenthesizeNonArrayTypeOfPostfixType`). */\nconst needsParensAsPostfixOperand = (type: IrType): boolean =>\n type.kind === \"readonly\" || isUnionOrIntersection(type);\n/** Operand of `readonly` (`parenthesizeOperandOfReadonlyTypeOperator`). */\nconst needsParensAsReadonlyOperand = needsParensAsPostfixOperand;\n\nfunction writeTypeIn(\n writer: TextWriter,\n type: IrType,\n needsParens: (type: IrType) => boolean,\n): void {\n if (!needsParens(type)) {\n writeType(writer, type);\n return;\n }\n writer.write(\"(\");\n writeType(writer, type);\n writer.write(\")\");\n}\n\n/** Write a single-line list: `separator` between items, nothing for an empty list. */\nfunction writeInlineList<T>(\n writer: TextWriter,\n items: readonly T[],\n separator: string,\n writeItem: (item: T) => void,\n) {\n items.forEach((item, index) => {\n if (index > 0) {\n writer.write(separator);\n }\n writeItem(item);\n });\n}\n\n/**\n * Write a multi-line list the way the TypeScript printer does: a line break after the opening\n * token, one item per indented line, `delimiter` after every item but the last, and a line break\n * before the closing token. An empty list prints the line break only when `isLineBreakWhenEmpty`\n * (interfaces, enums and tuples do; object type literals print `{}`).\n */\nexport function writeMultiLineList<T>(\n writer: TextWriter,\n items: readonly T[],\n format: { readonly delimiter: string; readonly isLineBreakWhenEmpty: boolean },\n writeItem: (item: T) => void,\n): void {\n if (items.length === 0) {\n if (format.isLineBreakWhenEmpty) {\n writer.writeLine();\n }\n return;\n }\n writer.writeLine();\n writer.increaseIndent();\n items.forEach((item, index) => {\n if (index > 0) {\n writer.write(format.delimiter);\n writer.writeLine();\n }\n writeItem(item);\n });\n writer.decreaseIndent();\n writer.writeLine();\n}\n\nfunction writePropertyName(writer: TextWriter, name: IrPropertyName): void {\n switch (name.kind) {\n case \"identifier\":\n case \"number\":\n writer.write(name.text);\n break;\n case \"string\":\n writer.write(printEscapedString(name.value));\n break;\n default:\n assertNever(name);\n }\n}\n\n/**\n * `[name: type]`. TypeScript prints index signature parameters as an indented list, so a multi-line\n * parameter type (an object or tuple) is indented one level deeper than the member.\n */\nfunction writeIndexSignatureParameter(writer: TextWriter, name: string, type: IrType): void {\n writer.write(`[${name}: `);\n writer.increaseIndent();\n writeType(writer, type);\n writer.decreaseIndent();\n writer.write(\"]\");\n}\n\n/** Write one member of an interface or object type, with its comment and trailing semicolon. */\nexport function writeMember(writer: TextWriter, member: IrMember): void {\n for (const comment of member.comments) {\n writeLeadingComment(writer, comment);\n }\n if (member.isReadonly) {\n writer.write(\"readonly \");\n }\n if (member.kind === \"property\") {\n writePropertyName(writer, member.name);\n writer.write(member.isOptional ? \"?: \" : \": \");\n } else {\n writeIndexSignatureParameter(writer, member.parameterName, member.parameterType);\n writer.write(\": \");\n }\n writeType(writer, member.type);\n writer.write(\";\");\n}\n\nfunction writeTupleElement(writer: TextWriter, element: IrTupleElement): void {\n if (element.isRest) {\n writer.write(\"...\");\n }\n writeType(writer, element.type);\n}\n\nfunction writeObjectType(writer: TextWriter, members: readonly IrMember[]): void {\n writer.write(\"{\");\n writeMultiLineList(writer, members, { delimiter: \"\", isLineBreakWhenEmpty: false }, (member) =>\n writeMember(writer, member),\n );\n writer.write(\"}\");\n}\n\nfunction writeTupleType(writer: TextWriter, elements: readonly IrTupleElement[]): void {\n writer.write(\"[\");\n writeMultiLineList(writer, elements, { delimiter: \",\", isLineBreakWhenEmpty: true }, (element) =>\n writeTupleElement(writer, element),\n );\n writer.write(\"]\");\n}\n\nfunction writeReferenceType(\n writer: TextWriter,\n name: string,\n typeArguments: readonly IrType[],\n): void {\n writer.write(name);\n if (typeArguments.length > 0) {\n writer.write(\"<\");\n writeInlineList(writer, typeArguments, \", \", (argument) => writeType(writer, argument));\n writer.write(\">\");\n }\n}\n\nfunction writeIndexedAccessType(writer: TextWriter, type: IrIndexedAccessType): void {\n writeTypeIn(writer, type.object, needsParensAsPostfixOperand);\n writer.write(\"[\");\n writeType(writer, type.index);\n writer.write(\"]\");\n}\n\nfunction writeConstituents(writer: TextWriter, types: readonly IrType[], separator: string): void {\n writeInlineList(writer, types, separator, (member) =>\n writeTypeIn(writer, member, needsParensAsConstituent),\n );\n}\n\ntype IrLeafType = Extract<\n IrType,\n { kind: \"keyword\" | \"stringLiteral\" | \"numberLiteral\" | \"booleanLiteral\" }\n>;\n\nfunction printLeafType(type: IrLeafType): string {\n switch (type.kind) {\n case \"keyword\":\n return type.keyword;\n case \"stringLiteral\":\n return printStringLiteral(type.value, type.encoding);\n case \"numberLiteral\":\n return printNumberLiteral(type.value);\n case \"booleanLiteral\":\n return String(type.value);\n default:\n return assertNever(type);\n }\n}\n\n/**\n * Raw text is printed as if it started at column 0, so its continuation lines get the current\n * indentation, as the TypeScript printer indents a nested node.\n */\nfunction writeRawType(writer: TextWriter, text: string): void {\n text.split(\"\\n\").forEach((line, index) => {\n if (index > 0) {\n writer.rawWrite(writer.options.newLine);\n }\n writer.write(line);\n });\n}\n\nfunction writeArrayType(writer: TextWriter, element: IrType): void {\n writeTypeIn(writer, element, needsParensAsPostfixOperand);\n writer.write(\"[]\");\n}\n\nfunction writeReadonlyType(writer: TextWriter, operand: IrType): void {\n writer.write(\"readonly \");\n writeTypeIn(writer, operand, needsParensAsReadonlyOperand);\n}\n\ntype IrOperatorType = Extract<IrType, { kind: \"array\" | \"indexedAccess\" | \"readonly\" }>;\n\n/** Types built with a type operator: `T[]`, `T[K]` and `readonly T`. */\nfunction writeOperatorType(writer: TextWriter, type: IrOperatorType): void {\n if (type.kind === \"array\") {\n writeArrayType(writer, type.element);\n } else if (type.kind === \"indexedAccess\") {\n writeIndexedAccessType(writer, type);\n } else {\n writeReadonlyType(writer, type.type);\n }\n}\n\nconst CONSTITUENT_SEPARATORS = { union: \" | \", intersection: \" & \" } as const;\n\n/** A raw type may span lines and is re-indented; any other leaf prints on one line. */\nfunction writeLeafType(writer: TextWriter, type: IrLeafType | IrRawType): void {\n if (type.kind === \"raw\") {\n writeRawType(writer, type.text);\n } else {\n writer.write(printLeafType(type));\n }\n}\n\n/** Write a type at the writer's current position. */\nexport function writeType(writer: TextWriter, type: IrType): void {\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n case \"raw\":\n writeLeafType(writer, type);\n break;\n case \"reference\":\n writeReferenceType(writer, type.name, type.typeArguments);\n break;\n case \"array\":\n case \"indexedAccess\":\n case \"readonly\":\n writeOperatorType(writer, type);\n break;\n case \"union\":\n case \"intersection\":\n writeConstituents(writer, type.types, CONSTITUENT_SEPARATORS[type.kind]);\n break;\n case \"object\":\n writeObjectType(writer, type.members);\n break;\n case \"tuple\":\n writeTupleType(writer, type.elements);\n break;\n default:\n assertNever(type);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"type-printer.mjs","sources":["../../../src/application/print/type-printer.ts"],"sourcesContent":["import { assertNever } from \"../../domain/assert-never.js\";\nimport type {\n IrIndexedAccessType,\n IrMember,\n IrPropertyName,\n IrRawType,\n IrTupleElement,\n IrType,\n} from \"../../domain/ir/nodes.js\";\nimport { writeLeadingComment } from \"./comment-writer.js\";\nimport { printEscapedString, printNumberLiteral, printStringLiteral } from \"./literal-text.js\";\nimport type { TextWriter } from \"./text-writer.js\";\n\n/**\n * Parenthesization contexts. Each predicate says when a child type needs parentheses; together they\n * reproduce the TypeScript factory's parenthesizer rules for the node kinds of the IR, so output\n * matches the original even when unions are nested (`A | (B | C)`).\n */\nconst isUnionOrIntersection = (type: IrType): boolean =>\n type.kind === \"union\" || type.kind === \"intersection\";\n/** Union and intersection members (`parenthesizeConstituentTypeOf{Union,Intersection}Type`). */\nconst needsParensAsConstituent = isUnionOrIntersection;\n/** Array element and indexed-access object (`parenthesizeNonArrayTypeOfPostfixType`). */\nconst needsParensAsPostfixOperand = (type: IrType): boolean =>\n type.kind === \"readonly\" || isUnionOrIntersection(type);\n/** Operand of `readonly` (`parenthesizeOperandOfReadonlyTypeOperator`). */\nconst needsParensAsReadonlyOperand = needsParensAsPostfixOperand;\n\nfunction writeTypeIn(\n writer: TextWriter,\n type: IrType,\n needsParens: (type: IrType) => boolean,\n): void {\n if (!needsParens(type)) {\n writeType(writer, type);\n return;\n }\n writer.write(\"(\");\n writeType(writer, type);\n writer.write(\")\");\n}\n\n/** Write a single-line list: `separator` between items, nothing for an empty list. */\nfunction writeInlineList<T>(\n writer: TextWriter,\n items: readonly T[],\n separator: string,\n writeItem: (item: T) => void,\n) {\n items.forEach((item, index) => {\n if (index > 0) {\n writer.write(separator);\n }\n writeItem(item);\n });\n}\n\n/**\n * Write a multi-line list the way the TypeScript printer does: a line break after the opening\n * token, one item per indented line, `delimiter` after every item but the last, and a line break\n * before the closing token. An empty list prints the line break only when `isLineBreakWhenEmpty`\n * (interfaces, enums and tuples do; object type literals print `{}`).\n */\nexport function writeMultiLineList<T>(\n writer: TextWriter,\n items: readonly T[],\n format: { readonly delimiter: string; readonly isLineBreakWhenEmpty: boolean },\n writeItem: (item: T) => void,\n): void {\n if (items.length === 0) {\n if (format.isLineBreakWhenEmpty) {\n writer.writeLine();\n }\n return;\n }\n writer.writeLine();\n writer.increaseIndent();\n items.forEach((item, index) => {\n if (index > 0) {\n writer.write(format.delimiter);\n writer.writeLine();\n }\n writeItem(item);\n });\n writer.decreaseIndent();\n writer.writeLine();\n}\n\nfunction writePropertyName(writer: TextWriter, name: IrPropertyName): void {\n switch (name.kind) {\n case \"identifier\":\n case \"number\":\n writer.write(name.text);\n break;\n case \"string\":\n writer.write(printEscapedString(name.value));\n break;\n default:\n assertNever(name);\n }\n}\n\n/**\n * `[name: type]`. TypeScript prints index signature parameters as an indented list, so a multi-line\n * parameter type (an object or tuple) is indented one level deeper than the member.\n */\nfunction writeIndexSignatureParameter(writer: TextWriter, name: string, type: IrType): void {\n writer.write(`[${name}: `);\n writer.increaseIndent();\n writeType(writer, type);\n writer.decreaseIndent();\n writer.write(\"]\");\n}\n\n/** Write one member of an interface or object type, with its comment and trailing semicolon. */\nexport function writeMember(writer: TextWriter, member: IrMember): void {\n for (const comment of member.comments) {\n writeLeadingComment(writer, comment);\n }\n if (member.isReadonly) {\n writer.write(\"readonly \");\n }\n if (member.kind === \"property\") {\n writePropertyName(writer, member.name);\n writer.write(member.isOptional ? \"?: \" : \": \");\n } else {\n writeIndexSignatureParameter(writer, member.parameterName, member.parameterType);\n writer.write(\": \");\n }\n writeType(writer, member.type);\n writer.write(\";\");\n}\n\nfunction writeTupleElement(writer: TextWriter, element: IrTupleElement): void {\n if (element.isRest) {\n writer.write(\"...\");\n }\n if (element.isOptional) {\n // TypeScript parenthesizes an optional element as a postfix operand (`(A | B)?`).\n writeTypeIn(writer, element.type, needsParensAsPostfixOperand);\n writer.write(\"?\");\n return;\n }\n writeType(writer, element.type);\n}\n\nfunction writeObjectType(writer: TextWriter, members: readonly IrMember[]): void {\n writer.write(\"{\");\n writeMultiLineList(writer, members, { delimiter: \"\", isLineBreakWhenEmpty: false }, (member) =>\n writeMember(writer, member),\n );\n writer.write(\"}\");\n}\n\nfunction writeTupleType(writer: TextWriter, elements: readonly IrTupleElement[]): void {\n writer.write(\"[\");\n writeMultiLineList(writer, elements, { delimiter: \",\", isLineBreakWhenEmpty: true }, (element) =>\n writeTupleElement(writer, element),\n );\n writer.write(\"]\");\n}\n\nfunction writeReferenceType(\n writer: TextWriter,\n name: string,\n typeArguments: readonly IrType[],\n): void {\n writer.write(name);\n if (typeArguments.length > 0) {\n writer.write(\"<\");\n writeInlineList(writer, typeArguments, \", \", (argument) => writeType(writer, argument));\n writer.write(\">\");\n }\n}\n\nfunction writeIndexedAccessType(writer: TextWriter, type: IrIndexedAccessType): void {\n writeTypeIn(writer, type.object, needsParensAsPostfixOperand);\n writer.write(\"[\");\n writeType(writer, type.index);\n writer.write(\"]\");\n}\n\nfunction writeConstituents(writer: TextWriter, types: readonly IrType[], separator: string): void {\n writeInlineList(writer, types, separator, (member) =>\n writeTypeIn(writer, member, needsParensAsConstituent),\n );\n}\n\ntype IrLeafType = Extract<\n IrType,\n { kind: \"keyword\" | \"stringLiteral\" | \"numberLiteral\" | \"booleanLiteral\" }\n>;\n\nfunction printLeafType(type: IrLeafType): string {\n switch (type.kind) {\n case \"keyword\":\n return type.keyword;\n case \"stringLiteral\":\n return printStringLiteral(type.value, type.encoding);\n case \"numberLiteral\":\n return printNumberLiteral(type.value);\n case \"booleanLiteral\":\n return String(type.value);\n default:\n return assertNever(type);\n }\n}\n\n/**\n * Raw text is printed as if it started at column 0, so its continuation lines get the current\n * indentation, as the TypeScript printer indents a nested node.\n */\nfunction writeRawType(writer: TextWriter, text: string): void {\n text.split(\"\\n\").forEach((line, index) => {\n if (index > 0) {\n writer.rawWrite(writer.options.newLine);\n }\n writer.write(line);\n });\n}\n\nfunction writeArrayType(writer: TextWriter, element: IrType): void {\n writeTypeIn(writer, element, needsParensAsPostfixOperand);\n writer.write(\"[]\");\n}\n\nfunction writeReadonlyType(writer: TextWriter, operand: IrType): void {\n writer.write(\"readonly \");\n writeTypeIn(writer, operand, needsParensAsReadonlyOperand);\n}\n\ntype IrOperatorType = Extract<IrType, { kind: \"array\" | \"indexedAccess\" | \"readonly\" }>;\n\n/** Types built with a type operator: `T[]`, `T[K]` and `readonly T`. */\nfunction writeOperatorType(writer: TextWriter, type: IrOperatorType): void {\n if (type.kind === \"array\") {\n writeArrayType(writer, type.element);\n } else if (type.kind === \"indexedAccess\") {\n writeIndexedAccessType(writer, type);\n } else {\n writeReadonlyType(writer, type.type);\n }\n}\n\nconst CONSTITUENT_SEPARATORS = { union: \" | \", intersection: \" & \" } as const;\n\n/** A raw type may span lines and is re-indented; any other leaf prints on one line. */\nfunction writeLeafType(writer: TextWriter, type: IrLeafType | IrRawType): void {\n if (type.kind === \"raw\") {\n writeRawType(writer, type.text);\n } else {\n writer.write(printLeafType(type));\n }\n}\n\n/** Write a type at the writer's current position. */\nexport function writeType(writer: TextWriter, type: IrType): void {\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n case \"raw\":\n writeLeafType(writer, type);\n break;\n case \"reference\":\n writeReferenceType(writer, type.name, type.typeArguments);\n break;\n case \"array\":\n case \"indexedAccess\":\n case \"readonly\":\n writeOperatorType(writer, type);\n break;\n case \"union\":\n case \"intersection\":\n writeConstituents(writer, type.types, CONSTITUENT_SEPARATORS[type.kind]);\n break;\n case \"object\":\n writeObjectType(writer, type.members);\n break;\n case \"tuple\":\n writeTupleType(writer, type.elements);\n break;\n default:\n assertNever(type);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ 'use strict';
2
+
3
+ const typeResolution = require('./type-resolution.cjs');
4
+
5
+ function everyOf(items, relate) {
6
+ let result = "assignable";
7
+ for (const [index, item] of items.entries()) {
8
+ const each = relate(item, index);
9
+ if (each === "rejected") {
10
+ return "rejected";
11
+ }
12
+ if (each === "undecided") {
13
+ result = "undecided";
14
+ }
15
+ }
16
+ return result;
17
+ }
18
+ function someOf(items, relate) {
19
+ let result = "rejected";
20
+ for (const item of items) {
21
+ const each = relate(item);
22
+ if (each === "assignable") {
23
+ return "assignable";
24
+ }
25
+ if (each === "undecided") {
26
+ result = "undecided";
27
+ }
28
+ }
29
+ return result;
30
+ }
31
+ function provenBy(condition) {
32
+ return condition ? "assignable" : "rejected";
33
+ }
34
+ function categoryOf(type) {
35
+ switch (type.kind) {
36
+ case "keyword":
37
+ case "stringLiteral":
38
+ case "numberLiteral":
39
+ case "booleanLiteral":
40
+ return "primitive";
41
+ case "array":
42
+ case "tuple":
43
+ case "readonly":
44
+ return "list";
45
+ case "object":
46
+ return "object";
47
+ default:
48
+ return "opaque";
49
+ }
50
+ }
51
+ const NO_OBJECT_KEYWORDS = /* @__PURE__ */ new Set(["null", "undefined", "unknown", "never"]);
52
+ const ARRAY_MEMBER_NAMES = /* @__PURE__ */ new Set([
53
+ "length",
54
+ "toString",
55
+ "toLocaleString",
56
+ "pop",
57
+ "push",
58
+ "concat",
59
+ "join",
60
+ "reverse",
61
+ "shift",
62
+ "slice",
63
+ "sort",
64
+ "splice",
65
+ "unshift",
66
+ "indexOf",
67
+ "lastIndexOf",
68
+ "every",
69
+ "some",
70
+ "forEach",
71
+ "map",
72
+ "filter",
73
+ "reduce",
74
+ "reduceRight",
75
+ "find",
76
+ "findIndex",
77
+ "fill",
78
+ "copyWithin",
79
+ "entries",
80
+ "keys",
81
+ "values",
82
+ "includes",
83
+ "flatMap",
84
+ "flat",
85
+ "at",
86
+ "findLast",
87
+ "findLastIndex",
88
+ "toReversed",
89
+ "toSorted",
90
+ "toSpliced",
91
+ "with"
92
+ ]);
93
+ const ARRAY_LENGTH = "length";
94
+ const ELEMENT_NAME_RE = /^\d+$/;
95
+ function isListMemberName(name) {
96
+ return ARRAY_MEMBER_NAMES.has(name) || ELEMENT_NAME_RE.test(name);
97
+ }
98
+ function listToObject(target) {
99
+ const properties = [...typeResolution.propertiesOf(target).values()];
100
+ const isForeign = (property) => !isListMemberName(typeResolution.nameOf(property));
101
+ const needsForeign = properties.some((property) => !property.isOptional && isForeign(property));
102
+ const isWeak = properties.length > 0 && typeResolution.indexSignaturesOf(target).length === 0 && properties.every((property) => property.isOptional);
103
+ return needsForeign || isWeak && properties.every(isForeign) ? "rejected" : "undecided";
104
+ }
105
+ function primitiveToObject(source) {
106
+ const isNoObject = source.kind === "keyword" && NO_OBJECT_KEYWORDS.has(source.keyword);
107
+ return isNoObject ? "rejected" : "undecided";
108
+ }
109
+ function objectToList(source) {
110
+ return typeResolution.propertiesOf(source).has(ARRAY_LENGTH) ? "undecided" : "rejected";
111
+ }
112
+ function crossCategoryRelation(source, target) {
113
+ const from = categoryOf(source);
114
+ const to = categoryOf(target);
115
+ if (from === "opaque" || to === "opaque") {
116
+ return "undecided";
117
+ }
118
+ if (from === to) {
119
+ return null;
120
+ }
121
+ if (to !== "object") {
122
+ return source.kind === "object" && to === "list" ? objectToList(source) : "rejected";
123
+ }
124
+ return from === "primitive" ? primitiveToObject(source) : listToObject(target);
125
+ }
126
+ const LITERAL_KEYWORDS = {
127
+ stringLiteral: "string",
128
+ numberLiteral: "number",
129
+ booleanLiteral: "boolean"
130
+ };
131
+ function primitiveRelation(source, target) {
132
+ if (target.kind !== "keyword" || source.kind === "keyword") {
133
+ return "rejected";
134
+ }
135
+ const keyword = LITERAL_KEYWORDS[source.kind];
136
+ return provenBy(keyword === target.keyword);
137
+ }
138
+
139
+ exports.crossCategoryRelation = crossCategoryRelation;
140
+ exports.everyOf = everyOf;
141
+ exports.primitiveRelation = primitiveRelation;
142
+ exports.provenBy = provenBy;
143
+ exports.someOf = someOf;
144
+ //# sourceMappingURL=assignability.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignability.cjs","sources":["../../../../src/application/transform/document/assignability.ts"],"sourcesContent":["import type { IrObjectType, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { indexSignaturesOf, nameOf, propertiesOf } from \"./type-resolution.js\";\n\n/**\n * What the `--path-params-as-types` overlap check knows about one type where another is expected.\n * `assignable` and `rejected` are proofs of what TypeScript decides (`strict`, without\n * `exactOptionalPropertyTypes`); `undecided` is a pair the check does not model, such as a utility\n * type or raw text. Only a rejection changes the output, so an undecided pair keeps the original.\n */\nexport type Assignability = \"assignable\" | \"rejected\" | \"undecided\";\n\n/**\n * All of the relations: rejected when one is, assignable when each is. The relations are computed\n * lazily, so a rejection stops the rest.\n */\nexport function everyOf<T>(\n items: readonly T[],\n relate: (item: T, index: number) => Assignability,\n): Assignability {\n let result: Assignability = \"assignable\";\n for (const [index, item] of items.entries()) {\n const each = relate(item, index);\n if (each === \"rejected\") {\n return \"rejected\";\n }\n if (each === \"undecided\") {\n result = \"undecided\";\n }\n }\n return result;\n}\n\n/** One of the relations: assignable when one is, rejected when each is. */\nexport function someOf<T>(items: readonly T[], relate: (item: T) => Assignability): Assignability {\n let result: Assignability = \"rejected\";\n for (const item of items) {\n const each = relate(item);\n if (each === \"assignable\") {\n return \"assignable\";\n }\n if (each === \"undecided\") {\n result = \"undecided\";\n }\n }\n return result;\n}\n\n/** Assignable when the condition holds, rejected when it does not. */\nexport function provenBy(condition: boolean): Assignability {\n return condition ? \"assignable\" : \"rejected\";\n}\n\n/**\n * The kinds of resolved types the check tells apart. A type of one kind is never assignable to a\n * type of another, except that a primitive or a list may fit an object type (`string` fits\n * `{ length: number }`), which the check models only in part. `opaque` is any type it cannot\n * read.\n */\ntype TypeCategory = \"primitive\" | \"list\" | \"object\" | \"opaque\";\n\nfunction categoryOf(type: IrType): TypeCategory {\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n return \"primitive\";\n case \"array\":\n case \"tuple\":\n case \"readonly\":\n return \"list\";\n case \"object\":\n return \"object\";\n default:\n return \"opaque\";\n }\n}\n\n/** Keywords that are no object: `{}` rejects them under `strictNullChecks`. */\nconst NO_OBJECT_KEYWORDS: ReadonlySet<string> = new Set([\"null\", \"undefined\", \"unknown\", \"never\"]);\n\n/**\n * The members of `ReadonlyArray` and `Array` in the TypeScript libraries up to ESNext. An object\n * type that needs a property of another name is no list; a numeric name may be a tuple element.\n */\nconst ARRAY_MEMBER_NAMES: ReadonlySet<string> = new Set([\n \"length\",\n \"toString\",\n \"toLocaleString\",\n \"pop\",\n \"push\",\n \"concat\",\n \"join\",\n \"reverse\",\n \"shift\",\n \"slice\",\n \"sort\",\n \"splice\",\n \"unshift\",\n \"indexOf\",\n \"lastIndexOf\",\n \"every\",\n \"some\",\n \"forEach\",\n \"map\",\n \"filter\",\n \"reduce\",\n \"reduceRight\",\n \"find\",\n \"findIndex\",\n \"fill\",\n \"copyWithin\",\n \"entries\",\n \"keys\",\n \"values\",\n \"includes\",\n \"flatMap\",\n \"flat\",\n \"at\",\n \"findLast\",\n \"findLastIndex\",\n \"toReversed\",\n \"toSorted\",\n \"toSpliced\",\n \"with\",\n]);\n\nconst ARRAY_LENGTH = \"length\";\n/** A tuple element's name: `\"0\"`, `\"1\"`. */\nconst ELEMENT_NAME_RE = /^\\d+$/;\n\nfunction isListMemberName(name: string): boolean {\n return ARRAY_MEMBER_NAMES.has(name) || ELEMENT_NAME_RE.test(name);\n}\n\n/**\n * Whether a list fits an object type. It does not when the object needs a property no list has\n * (TS2741), or when the object is a weak type and no list has one of its properties (TS2559).\n */\nfunction listToObject(target: IrObjectType): Assignability {\n const properties = [...propertiesOf(target).values()];\n const isForeign = (property: IrPropertySignature) => !isListMemberName(nameOf(property));\n const needsForeign = properties.some((property) => !property.isOptional && isForeign(property));\n const isWeak =\n properties.length > 0 &&\n indexSignaturesOf(target).length === 0 &&\n properties.every((property) => property.isOptional);\n return needsForeign || (isWeak && properties.every(isForeign)) ? \"rejected\" : \"undecided\";\n}\n\n/**\n * Whether a primitive fits an object type: `null`, `undefined` and `unknown` never do; any other\n * may (`{}`, `{ length: number }`), which is not modelled.\n */\nfunction primitiveToObject(source: IrType): Assignability {\n const isNoObject = source.kind === \"keyword\" && NO_OBJECT_KEYWORDS.has(source.keyword);\n return isNoObject ? \"rejected\" : \"undecided\";\n}\n\n/** An object type fits an array only with all of its members; `length` is the first it needs. */\nfunction objectToList(source: IrObjectType): Assignability {\n return propertiesOf(source).has(ARRAY_LENGTH) ? \"undecided\" : \"rejected\";\n}\n\n/**\n * The relation of two types of different categories, or null when they are of the same one.\n * Primitive and list targets accept nothing of another category; see `TypeCategory`.\n */\nexport function crossCategoryRelation(source: IrType, target: IrType): Assignability | null {\n const from = categoryOf(source);\n const to = categoryOf(target);\n if (from === \"opaque\" || to === \"opaque\") {\n return \"undecided\";\n }\n if (from === to) {\n return null;\n }\n if (to !== \"object\") {\n return source.kind === \"object\" && to === \"list\" ? objectToList(source) : \"rejected\";\n }\n return from === \"primitive\" ? primitiveToObject(source) : listToObject(target as IrObjectType);\n}\n\n/** The keyword a literal type belongs to. */\nconst LITERAL_KEYWORDS = {\n stringLiteral: \"string\",\n numberLiteral: \"number\",\n booleanLiteral: \"boolean\",\n} as const;\n\n/**\n * The relation of two primitive types written differently (the same text is assignable). A\n * literal fits its keyword; any other pair is rejected: different keywords, different literals,\n * a keyword for one literal (a union of literals is compared in `type-assignability.ts`), and\n * anything for `never`.\n */\nexport function primitiveRelation(source: IrType, target: IrType): Assignability {\n if (target.kind !== \"keyword\" || source.kind === \"keyword\") {\n return \"rejected\";\n }\n const keyword = (LITERAL_KEYWORDS as Partial<Record<IrType[\"kind\"], string>>)[source.kind];\n return provenBy(keyword === target.keyword);\n}\n"],"names":["propertiesOf","nameOf","indexSignaturesOf"],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import { propertiesOf, indexSignaturesOf, nameOf } from './type-resolution.mjs';
2
+
3
+ function everyOf(items, relate) {
4
+ let result = "assignable";
5
+ for (const [index, item] of items.entries()) {
6
+ const each = relate(item, index);
7
+ if (each === "rejected") {
8
+ return "rejected";
9
+ }
10
+ if (each === "undecided") {
11
+ result = "undecided";
12
+ }
13
+ }
14
+ return result;
15
+ }
16
+ function someOf(items, relate) {
17
+ let result = "rejected";
18
+ for (const item of items) {
19
+ const each = relate(item);
20
+ if (each === "assignable") {
21
+ return "assignable";
22
+ }
23
+ if (each === "undecided") {
24
+ result = "undecided";
25
+ }
26
+ }
27
+ return result;
28
+ }
29
+ function provenBy(condition) {
30
+ return condition ? "assignable" : "rejected";
31
+ }
32
+ function categoryOf(type) {
33
+ switch (type.kind) {
34
+ case "keyword":
35
+ case "stringLiteral":
36
+ case "numberLiteral":
37
+ case "booleanLiteral":
38
+ return "primitive";
39
+ case "array":
40
+ case "tuple":
41
+ case "readonly":
42
+ return "list";
43
+ case "object":
44
+ return "object";
45
+ default:
46
+ return "opaque";
47
+ }
48
+ }
49
+ const NO_OBJECT_KEYWORDS = /* @__PURE__ */ new Set(["null", "undefined", "unknown", "never"]);
50
+ const ARRAY_MEMBER_NAMES = /* @__PURE__ */ new Set([
51
+ "length",
52
+ "toString",
53
+ "toLocaleString",
54
+ "pop",
55
+ "push",
56
+ "concat",
57
+ "join",
58
+ "reverse",
59
+ "shift",
60
+ "slice",
61
+ "sort",
62
+ "splice",
63
+ "unshift",
64
+ "indexOf",
65
+ "lastIndexOf",
66
+ "every",
67
+ "some",
68
+ "forEach",
69
+ "map",
70
+ "filter",
71
+ "reduce",
72
+ "reduceRight",
73
+ "find",
74
+ "findIndex",
75
+ "fill",
76
+ "copyWithin",
77
+ "entries",
78
+ "keys",
79
+ "values",
80
+ "includes",
81
+ "flatMap",
82
+ "flat",
83
+ "at",
84
+ "findLast",
85
+ "findLastIndex",
86
+ "toReversed",
87
+ "toSorted",
88
+ "toSpliced",
89
+ "with"
90
+ ]);
91
+ const ARRAY_LENGTH = "length";
92
+ const ELEMENT_NAME_RE = /^\d+$/;
93
+ function isListMemberName(name) {
94
+ return ARRAY_MEMBER_NAMES.has(name) || ELEMENT_NAME_RE.test(name);
95
+ }
96
+ function listToObject(target) {
97
+ const properties = [...propertiesOf(target).values()];
98
+ const isForeign = (property) => !isListMemberName(nameOf(property));
99
+ const needsForeign = properties.some((property) => !property.isOptional && isForeign(property));
100
+ const isWeak = properties.length > 0 && indexSignaturesOf(target).length === 0 && properties.every((property) => property.isOptional);
101
+ return needsForeign || isWeak && properties.every(isForeign) ? "rejected" : "undecided";
102
+ }
103
+ function primitiveToObject(source) {
104
+ const isNoObject = source.kind === "keyword" && NO_OBJECT_KEYWORDS.has(source.keyword);
105
+ return isNoObject ? "rejected" : "undecided";
106
+ }
107
+ function objectToList(source) {
108
+ return propertiesOf(source).has(ARRAY_LENGTH) ? "undecided" : "rejected";
109
+ }
110
+ function crossCategoryRelation(source, target) {
111
+ const from = categoryOf(source);
112
+ const to = categoryOf(target);
113
+ if (from === "opaque" || to === "opaque") {
114
+ return "undecided";
115
+ }
116
+ if (from === to) {
117
+ return null;
118
+ }
119
+ if (to !== "object") {
120
+ return source.kind === "object" && to === "list" ? objectToList(source) : "rejected";
121
+ }
122
+ return from === "primitive" ? primitiveToObject(source) : listToObject(target);
123
+ }
124
+ const LITERAL_KEYWORDS = {
125
+ stringLiteral: "string",
126
+ numberLiteral: "number",
127
+ booleanLiteral: "boolean"
128
+ };
129
+ function primitiveRelation(source, target) {
130
+ if (target.kind !== "keyword" || source.kind === "keyword") {
131
+ return "rejected";
132
+ }
133
+ const keyword = LITERAL_KEYWORDS[source.kind];
134
+ return provenBy(keyword === target.keyword);
135
+ }
136
+
137
+ export { crossCategoryRelation, everyOf, primitiveRelation, provenBy, someOf };
138
+ //# sourceMappingURL=assignability.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignability.mjs","sources":["../../../../src/application/transform/document/assignability.ts"],"sourcesContent":["import type { IrObjectType, IrPropertySignature, IrType } from \"../../../domain/ir/nodes.js\";\nimport { indexSignaturesOf, nameOf, propertiesOf } from \"./type-resolution.js\";\n\n/**\n * What the `--path-params-as-types` overlap check knows about one type where another is expected.\n * `assignable` and `rejected` are proofs of what TypeScript decides (`strict`, without\n * `exactOptionalPropertyTypes`); `undecided` is a pair the check does not model, such as a utility\n * type or raw text. Only a rejection changes the output, so an undecided pair keeps the original.\n */\nexport type Assignability = \"assignable\" | \"rejected\" | \"undecided\";\n\n/**\n * All of the relations: rejected when one is, assignable when each is. The relations are computed\n * lazily, so a rejection stops the rest.\n */\nexport function everyOf<T>(\n items: readonly T[],\n relate: (item: T, index: number) => Assignability,\n): Assignability {\n let result: Assignability = \"assignable\";\n for (const [index, item] of items.entries()) {\n const each = relate(item, index);\n if (each === \"rejected\") {\n return \"rejected\";\n }\n if (each === \"undecided\") {\n result = \"undecided\";\n }\n }\n return result;\n}\n\n/** One of the relations: assignable when one is, rejected when each is. */\nexport function someOf<T>(items: readonly T[], relate: (item: T) => Assignability): Assignability {\n let result: Assignability = \"rejected\";\n for (const item of items) {\n const each = relate(item);\n if (each === \"assignable\") {\n return \"assignable\";\n }\n if (each === \"undecided\") {\n result = \"undecided\";\n }\n }\n return result;\n}\n\n/** Assignable when the condition holds, rejected when it does not. */\nexport function provenBy(condition: boolean): Assignability {\n return condition ? \"assignable\" : \"rejected\";\n}\n\n/**\n * The kinds of resolved types the check tells apart. A type of one kind is never assignable to a\n * type of another, except that a primitive or a list may fit an object type (`string` fits\n * `{ length: number }`), which the check models only in part. `opaque` is any type it cannot\n * read.\n */\ntype TypeCategory = \"primitive\" | \"list\" | \"object\" | \"opaque\";\n\nfunction categoryOf(type: IrType): TypeCategory {\n switch (type.kind) {\n case \"keyword\":\n case \"stringLiteral\":\n case \"numberLiteral\":\n case \"booleanLiteral\":\n return \"primitive\";\n case \"array\":\n case \"tuple\":\n case \"readonly\":\n return \"list\";\n case \"object\":\n return \"object\";\n default:\n return \"opaque\";\n }\n}\n\n/** Keywords that are no object: `{}` rejects them under `strictNullChecks`. */\nconst NO_OBJECT_KEYWORDS: ReadonlySet<string> = new Set([\"null\", \"undefined\", \"unknown\", \"never\"]);\n\n/**\n * The members of `ReadonlyArray` and `Array` in the TypeScript libraries up to ESNext. An object\n * type that needs a property of another name is no list; a numeric name may be a tuple element.\n */\nconst ARRAY_MEMBER_NAMES: ReadonlySet<string> = new Set([\n \"length\",\n \"toString\",\n \"toLocaleString\",\n \"pop\",\n \"push\",\n \"concat\",\n \"join\",\n \"reverse\",\n \"shift\",\n \"slice\",\n \"sort\",\n \"splice\",\n \"unshift\",\n \"indexOf\",\n \"lastIndexOf\",\n \"every\",\n \"some\",\n \"forEach\",\n \"map\",\n \"filter\",\n \"reduce\",\n \"reduceRight\",\n \"find\",\n \"findIndex\",\n \"fill\",\n \"copyWithin\",\n \"entries\",\n \"keys\",\n \"values\",\n \"includes\",\n \"flatMap\",\n \"flat\",\n \"at\",\n \"findLast\",\n \"findLastIndex\",\n \"toReversed\",\n \"toSorted\",\n \"toSpliced\",\n \"with\",\n]);\n\nconst ARRAY_LENGTH = \"length\";\n/** A tuple element's name: `\"0\"`, `\"1\"`. */\nconst ELEMENT_NAME_RE = /^\\d+$/;\n\nfunction isListMemberName(name: string): boolean {\n return ARRAY_MEMBER_NAMES.has(name) || ELEMENT_NAME_RE.test(name);\n}\n\n/**\n * Whether a list fits an object type. It does not when the object needs a property no list has\n * (TS2741), or when the object is a weak type and no list has one of its properties (TS2559).\n */\nfunction listToObject(target: IrObjectType): Assignability {\n const properties = [...propertiesOf(target).values()];\n const isForeign = (property: IrPropertySignature) => !isListMemberName(nameOf(property));\n const needsForeign = properties.some((property) => !property.isOptional && isForeign(property));\n const isWeak =\n properties.length > 0 &&\n indexSignaturesOf(target).length === 0 &&\n properties.every((property) => property.isOptional);\n return needsForeign || (isWeak && properties.every(isForeign)) ? \"rejected\" : \"undecided\";\n}\n\n/**\n * Whether a primitive fits an object type: `null`, `undefined` and `unknown` never do; any other\n * may (`{}`, `{ length: number }`), which is not modelled.\n */\nfunction primitiveToObject(source: IrType): Assignability {\n const isNoObject = source.kind === \"keyword\" && NO_OBJECT_KEYWORDS.has(source.keyword);\n return isNoObject ? \"rejected\" : \"undecided\";\n}\n\n/** An object type fits an array only with all of its members; `length` is the first it needs. */\nfunction objectToList(source: IrObjectType): Assignability {\n return propertiesOf(source).has(ARRAY_LENGTH) ? \"undecided\" : \"rejected\";\n}\n\n/**\n * The relation of two types of different categories, or null when they are of the same one.\n * Primitive and list targets accept nothing of another category; see `TypeCategory`.\n */\nexport function crossCategoryRelation(source: IrType, target: IrType): Assignability | null {\n const from = categoryOf(source);\n const to = categoryOf(target);\n if (from === \"opaque\" || to === \"opaque\") {\n return \"undecided\";\n }\n if (from === to) {\n return null;\n }\n if (to !== \"object\") {\n return source.kind === \"object\" && to === \"list\" ? objectToList(source) : \"rejected\";\n }\n return from === \"primitive\" ? primitiveToObject(source) : listToObject(target as IrObjectType);\n}\n\n/** The keyword a literal type belongs to. */\nconst LITERAL_KEYWORDS = {\n stringLiteral: \"string\",\n numberLiteral: \"number\",\n booleanLiteral: \"boolean\",\n} as const;\n\n/**\n * The relation of two primitive types written differently (the same text is assignable). A\n * literal fits its keyword; any other pair is rejected: different keywords, different literals,\n * a keyword for one literal (a union of literals is compared in `type-assignability.ts`), and\n * anything for `never`.\n */\nexport function primitiveRelation(source: IrType, target: IrType): Assignability {\n if (target.kind !== \"keyword\" || source.kind === \"keyword\") {\n return \"rejected\";\n }\n const keyword = (LITERAL_KEYWORDS as Partial<Record<IrType[\"kind\"], string>>)[source.kind];\n return provenBy(keyword === target.keyword);\n}\n"],"names":[],"mappings":"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"}
@@ -34,7 +34,7 @@ function componentMember(kind, name, item, context) {
34
34
  isOptional: custom?.isOptional ?? false,
35
35
  isReadonly: context.options.immutable
36
36
  });
37
- return schemaComment.withSchemaComment(property, item);
37
+ return schemaComment.withSchemaComment(property, item, schemaComment.schemaCommentOptionsOf(context.options.fixes));
38
38
  }
39
39
  function rootTypeName(kind, name, aliases, context) {
40
40
  const { options, casing } = context;
@@ -96,7 +96,7 @@ function componentsType(components, context, kept = /* @__PURE__ */ new Set()) {
96
96
  const rootTypes = Object.values(aliases);
97
97
  return {
98
98
  type: constructors.irObject(members),
99
- rootTypes: [...rootTypes, ...rootTypeAliases.numberDisplacedAliases(displaced ?? [], rootTypes)]
99
+ rootTypes: [...rootTypes, ...displaced ?? []]
100
100
  };
101
101
  }
102
102
 
@@ -1 +1 @@
1
- {"version":3,"file":"components.cjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { numberDisplacedAliases, rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item);\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and numbered\n * at the end.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(OutputFix.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...numberDisplacedAliases(displaced ?? [], rootTypes)],\n };\n}\n"],"names":["transformSchema","responseType","parameterType","requestBodyType","headerType","pathItemType","contentEntryType","createRef","irProperty","toPropertyName","withSchemaComment","singularizeComponentKind","withIdentifierParts","alias","hasIdentifierStart","isReservedTypeName","isEnumSchema","documentEntries","rootTypeAlias","irObject","irKeyword","OutputFix","DECLARED_COMPONENT_KINDS","COMPONENT_KINDS","numberDisplacedAliases"],"mappings":"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"}
1
+ {"version":3,"file":"components.cjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(OutputFix.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["transformSchema","responseType","parameterType","requestBodyType","headerType","pathItemType","contentEntryType","createRef","irProperty","toPropertyName","withSchemaComment","schemaCommentOptionsOf","singularizeComponentKind","withIdentifierParts","alias","hasIdentifierStart","isReservedTypeName","isEnumSchema","documentEntries","rootTypeAlias","irObject","irKeyword","OutputFix","DECLARED_COMPONENT_KINDS","COMPONENT_KINDS"],"mappings":";;;;;;;;;;;;;;;;;;;AAyCA,MAAM,oBAAA,GAA4E;AAAA,EAChF,OAAA,EAASA,+BAAA;AAAA,EACT,SAAA,EAAWC,qBAAA;AAAA,EACX,UAAA,EAAYC,uBAAA;AAAA,EACZ,aAAA,EAAeC,2BAAA;AAAA,EACf,OAAA,EAASC,iBAAA;AAAA,EACT,SAAA,EAAWC,qBAAA;AAAA,EACX,UAAA,EAAYC;AACd,CAAA;AASA,SAAS,eAAA,CACP,IAAA,EACA,IAAA,EACA,IAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,QAAA,GAAW,EAAE,IAAA,EAAMC,qBAAA,CAAU,CAAC,YAAA,EAAc,IAAA,EAAM,IAAI,CAAC,CAAA,EAAG,MAAA,EAAQ,IAAA,EAAK;AAC7E,EAAA,MAAM,OAAO,oBAAA,CAAqB,IAAI,CAAA,CAAE,IAAA,EAAe,UAAU,OAAO,CAAA;AACxE,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,SAAA,CAAU,MAAM,QAAQ,CAAA;AACzD,EAAA,MAAM,WAAWC,uBAAA,CAAWC,2BAAA,CAAe,IAAI,CAAA,EAAG,MAAA,EAAQ,QAAQ,IAAA,EAAM;AAAA,IACtE,UAAA,EAAY,QAAQ,UAAA,IAAc,KAAA;AAAA,IAClC,UAAA,EAAY,QAAQ,OAAA,CAAQ;AAAA,GAC7B,CAAA;AACD,EAAA,OAAOC,gCAAkB,QAAA,EAAU,IAAA,EAAMC,qCAAuB,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAC,CAAA;AACxF;AAaA,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,OAAA,EACA,OAAA,EACQ;AACR,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAO,GAAI,OAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,UAAA,CAAWC,yCAAA,CAAyB,IAAI,CAAC,CAAA;AAC/D,EAAA,MAAM,WAAW,IAAA,KAAS,SAAA;AAC1B,EAAA,MAAM,IAAA,GAAOC,kCAAA;AAAA,IACX,QAAQ,mBAAA,IAAuB,QAAA,GAAW,IAAA,GAAO,MAAA,CAAO,WAAW,IAAI;AAAA,GACzE;AACA,EAAA,MAAM,YAAA,GAAe,CAACC,MAAAA,KAA0B;AAC9C,IAAA,MAAM,UAAA,GAAaA,MAAAA,CAAM,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC3C,IAAA,MAAM,YAAA,GAAe,QAAQ,uBAAA,IAA2B,QAAA;AACxD,IAAA,MAAM,aAAaC,iCAAA,CAAmB,UAAU,CAAA,IAAK,CAACC,kCAAmB,UAAU,CAAA;AACnF,IAAA,OAAO,YAAA,IAAgB,aAAa,UAAA,GAAaF,MAAAA;AAAA,EACnD,CAAA;AACA,EAAA,IAAI,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,CAAA,CAAA;AAC5B,EAAA,KAAA,IAAS,UAAU,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA,KAAM,QAAW,OAAA,EAAA,EAAW;AAC7D,IAAA,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,EAAG,IAAI,IAAI,OAAO,CAAA,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,aAAa,KAAK,CAAA;AAC3B;AASA,SAAS,YAAA,CAAa,SAA4B,KAAA,EAAqC;AACrF,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAU,GAAI,OAAA;AAC/B,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AACnC,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,SAAA,KAAc,IAAA,EAAM;AAChD,IAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,EACzB;AACA,EAAA,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA;AACxB;AAGA,SAAS,WAAA,CAAY,IAAA,EAAqB,IAAA,EAAe,OAAA,EAAoC;AAC3F,EAAA,MAAM,EAAE,SAAQ,GAAI,OAAA;AACpB,EAAA,OAAO,OAAA,CAAQ,aAAa,EAAE,OAAA,CAAQ,QAAQ,IAAA,KAAS,SAAA,IAAaG,8BAAa,IAAI,CAAA,CAAA;AACvF;AAWA,SAAS,UAAA,CACP,IAAA,EACA,OAAA,EACA,OAAA,EACqB;AACrB,EAAA,MAAM,EAAE,UAAA,EAAY,MAAA,EAAQ,OAAA,EAAQ,GAAI,OAAA;AACxC,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI;AAC1C,EAAA,MAAM,QAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAKC,+BAAA,CAAgB,UAAA,CAAW,IAAI,CAAA,IAAK,EAAC,EAAG,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAA,EAAG;AAC3F,IAAA,KAAA,CAAM,KAAK,eAAA,CAAgB,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,OAAO,CAAC,CAAA;AACrD,IAAA,IAAI,WAAA,CAAY,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA,EAAG;AACpC,MAAA,YAAA,CAAa,OAAA,EAASC,6BAAA,CAAc,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,SAAS,OAAO,CAAA,EAAG,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,IAC7F;AAAA,EACF;AACA,EAAA,MAAM,IAAA,GAAO,MAAM,MAAA,GAAS,CAAA,GAAIC,sBAAS,KAAK,CAAA,GAAIC,uBAAU,OAAO,CAAA;AACnE,EAAA,OAAA,CAAQ,WAAA,CAAY,KAAA;AAAA,IAClB,iCAA4B,IAAI,CAAA,CAAA;AAAA,IAChC,OAAA,CAAQ,WAAA,CAAY,GAAA,EAAI,GAAI;AAAA,GAC9B;AACA,EAAA,OAAOb,uBAAA,CAAWC,2BAAA,CAAe,IAAI,CAAA,EAAG,IAAI,CAAA;AAC9C;AAOO,SAAS,eACd,UAAA,EACA,OAAA,EACA,IAAA,mBAA4B,IAAI,KAAI,EAClB;AAGlB,EAAA,MAAM,UAAkD,EAAC;AACzD,EAAA,MAAM,SAAA,GAAY,QAAQ,OAAA,CAAQ,KAAA,CAAM,IAAIa,qBAAA,CAAU,mBAAmB,CAAA,GAAI,EAAC,GAAI,IAAA;AAClF,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAkB,IAAA,CAAK,IAAI,IAAc,CAAA;AACzD,EAAA,MAAM,OAAA,GAAU,EAAE,UAAA,EAAY,MAAA,EAAQ,SAAS,SAAA,EAAU;AACzD,EAAA,MAAM,aAAA,GAAgBC,0CAAyB,MAAA,CAAO,CAAC,SAAS,UAAA,CAAW,IAAI,MAAM,MAAS,CAAA;AAC9F,EAAA,MAAM,UAAU,CAAC,GAAGC,gCAAA,EAAiB,GAAG,aAAa,CAAA,CAAE,GAAA;AAAA,IAAI,CAAC,IAAA,KAC1D,UAAA,CAAW,IAAA,EAAM,SAAS,OAAO;AAAA,GACnC;AACA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAMJ,sBAAS,OAAO,CAAA;AAAA,IACtB,WAAW,CAAC,GAAG,WAAW,GAAI,SAAA,IAAa,EAAG;AAAA,GAChD;AACF;;"}
@@ -6,14 +6,14 @@ import { createRef } from '../../../domain/openapi/json-pointer.mjs';
6
6
  import { OutputFix } from '../../../domain/output-fixes.mjs';
7
7
  import { documentEntries } from '../document-entries.mjs';
8
8
  import { transformSchema } from '../schema/schema-transform.mjs';
9
- import { withSchemaComment } from '../schema-comment.mjs';
9
+ import { withSchemaComment, schemaCommentOptionsOf } from '../schema-comment.mjs';
10
10
  import { headerType } from './header.mjs';
11
11
  import { contentEntryType } from './media-type.mjs';
12
12
  import { parameterType } from './parameter.mjs';
13
13
  import { pathItemType } from './path-item.mjs';
14
14
  import { requestBodyType } from './request-body.mjs';
15
15
  import { responseType } from './response.mjs';
16
- import { numberDisplacedAliases, rootTypeAlias } from './root-type-aliases.mjs';
16
+ import { rootTypeAlias } from './root-type-aliases.mjs';
17
17
 
18
18
  const COMPONENT_TRANSFORMS = {
19
19
  schemas: transformSchema,
@@ -32,7 +32,7 @@ function componentMember(kind, name, item, context) {
32
32
  isOptional: custom?.isOptional ?? false,
33
33
  isReadonly: context.options.immutable
34
34
  });
35
- return withSchemaComment(property, item);
35
+ return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));
36
36
  }
37
37
  function rootTypeName(kind, name, aliases, context) {
38
38
  const { options, casing } = context;
@@ -94,7 +94,7 @@ function componentsType(components, context, kept = /* @__PURE__ */ new Set()) {
94
94
  const rootTypes = Object.values(aliases);
95
95
  return {
96
96
  type: irObject(members),
97
- rootTypes: [...rootTypes, ...numberDisplacedAliases(displaced ?? [], rootTypes)]
97
+ rootTypes: [...rootTypes, ...displaced ?? []]
98
98
  };
99
99
  }
100
100
 
@@ -1 +1 @@
1
- {"version":3,"file":"components.mjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { numberDisplacedAliases, rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item);\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and numbered\n * at the end.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(OutputFix.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...numberDisplacedAliases(displaced ?? [], rootTypes)],\n };\n}\n"],"names":["alias"],"mappings":"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"}
1
+ {"version":3,"file":"components.mjs","sources":["../../../../src/application/transform/document/components.ts"],"sourcesContent":["import { irKeyword, irObject, irProperty } from \"../../../domain/ir/constructors.js\";\nimport {\n hasIdentifierStart,\n isReservedTypeName,\n withIdentifierParts,\n} from \"../../../domain/ir/identifier-text.js\";\nimport type {\n IrPropertySignature,\n IrType,\n IrTypeAliasDeclaration,\n} from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport {\n COMPONENT_KINDS,\n type ComponentKind,\n type ComponentsObject,\n DECLARED_COMPONENT_KINDS,\n isEnumSchema,\n singularizeComponentKind,\n} from \"../../../domain/openapi/components-object.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { type DeprecatedEntryFilter, documentEntries } from \"../document-entries.js\";\nimport type { SchemaLocation } from \"../schema/schema-context.js\";\nimport { transformSchema } from \"../schema/schema-transform.js\";\nimport { schemaCommentOptionsOf, withSchemaComment } from \"../schema-comment.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { headerType } from \"./header.js\";\nimport { contentEntryType } from \"./media-type.js\";\nimport { parameterType } from \"./parameter.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { requestBodyType } from \"./request-body.js\";\nimport { responseType } from \"./response.js\";\nimport { rootTypeAlias } from \"./root-type-aliases.js\";\n\ntype ComponentTransform = (\n item: never,\n location: SchemaLocation,\n context: TransformContext,\n) => IrType;\n\nconst COMPONENT_TRANSFORMS: Readonly<Record<ComponentKind, ComponentTransform>> = {\n schemas: transformSchema,\n responses: responseType,\n parameters: parameterType,\n requestBodies: requestBodyType,\n headers: headerType,\n pathItems: pathItemType,\n mediaTypes: contentEntryType,\n};\n\n/** The `components` type and the `--root-types` aliases. */\nexport interface ComponentsResult {\n readonly type: IrType;\n readonly rootTypes: readonly IrTypeAliasDeclaration[];\n}\n\n/** One component; the `transform` callback may replace its type, as for nested schemas. */\nfunction componentMember(\n kind: ComponentKind,\n name: string,\n item: unknown,\n context: TransformContext,\n): IrPropertySignature {\n const location = { path: createRef([\"components\", kind, name]), schema: item };\n const type = COMPONENT_TRANSFORMS[kind](item as never, location, context);\n const custom = context.callbacks.transform(item, location);\n const property = irProperty(toPropertyName(name), custom?.type ?? type, {\n isOptional: custom?.isOptional ?? false,\n isReadonly: context.options.immutable,\n });\n return withSchemaComment(property, item, schemaCommentOptionsOf(context.options.fixes));\n}\n\n/**\n * The root alias name: `SchemaPet`, `ResponseNotFound`, … A taken name gets `_2`, `_3`, … The\n * original checks for conflicts before it removes the schema prefix, and so does this; for a clash\n * of exported names see `addRootAlias`.\n *\n * The original could build a name that is no identifier, so the generated file did not parse\n * (research/legacy-bugs.md, item 16): a kept casing keeps spaces and symbols, which become `_`;\n * and a name without the prefix can start with a digit, so it keeps the prefix (`Schema1`). A\n * kept casing without the prefix can also give a reserved name (`void`, `class`), which keeps the\n * prefix too (`Schemavoid`).\n */\nfunction rootTypeName(\n kind: ComponentKind,\n name: string,\n aliases: Readonly<Record<string, IrTypeAliasDeclaration>>,\n context: TransformContext,\n): string {\n const { options, casing } = context;\n const prefix = casing.pascalCase(singularizeComponentKind(kind));\n const isSchema = kind === \"schemas\";\n const base = withIdentifierParts(\n options.rootTypesKeepCasing && isSchema ? name : casing.pascalCase(name),\n );\n const exportedName = (alias: string): string => {\n const unprefixed = alias.replace(prefix, \"\");\n const isUnprefixed = options.rootTypesNoSchemaPrefix && isSchema;\n const isTypeName = hasIdentifierStart(unprefixed) && !isReservedTypeName(unprefixed);\n return isUnprefixed && isTypeName ? unprefixed : alias;\n };\n let alias = `${prefix}${base}`;\n for (let counter = 2; aliases[alias] !== undefined; counter++) {\n alias = `${prefix}${base}_${counter}`;\n }\n return exportedName(alias);\n}\n\n/**\n * Add a root alias. When its exported name is taken (two schemas of one PascalCase name without\n * the prefix), the later schema takes the name, as in the original. Without the\n * `root-type-numbering` fix the earlier one then has no alias: that output is valid, so a number\n * for it would change it (backlog 30). With the fix the earlier alias is kept aside and follows\n * the others under the same name; `renameTakenAliases` numbers it once every name is known.\n */\nfunction addRootAlias(request: ComponentsRequest, alias: IrTypeAliasDeclaration): void {\n const { aliases, displaced } = request;\n const previous = aliases[alias.name];\n if (previous !== undefined && displaced !== null) {\n displaced.push(previous);\n }\n aliases[alias.name] = alias;\n}\n\n/** `--root-types` skips enum schemas under `--enum`: the enum itself is exported. */\nfunction hasRootType(kind: ComponentKind, item: unknown, context: TransformContext): boolean {\n const { options } = context;\n return options.rootTypes && !(options.enum && kind === \"schemas\" && isEnumSchema(item));\n}\n\n/** The components of one run, and the deprecated ones that kept output still references. */\ninterface ComponentsRequest {\n readonly components: ComponentsObject;\n readonly isKept: DeprecatedEntryFilter;\n readonly aliases: Record<string, IrTypeAliasDeclaration>;\n /** With the `root-type-numbering` fix: the aliases a later schema took the name of, in order. */\n readonly displaced: IrTypeAliasDeclaration[] | null;\n}\n\nfunction kindMember(\n kind: ComponentKind,\n request: ComponentsRequest,\n context: TransformContext,\n): IrPropertySignature {\n const { components, isKept, aliases } = request;\n const startedAt = context.diagnostics.now();\n const items: IrPropertySignature[] = [];\n for (const [name, item] of documentEntries(components[kind] ?? {}, context.options, isKept)) {\n items.push(componentMember(kind, name, item, context));\n if (hasRootType(kind, item, context)) {\n addRootAlias(request, rootTypeAlias(rootTypeName(kind, name, aliases, context), kind, name));\n }\n }\n const type = items.length > 0 ? irObject(items) : irKeyword(\"never\");\n context.diagnostics.debug(\n `Transformed components → ${kind}`,\n context.diagnostics.now() - startedAt,\n );\n return irProperty(toPropertyName(kind), type);\n}\n\n/**\n * The `components` interface body (OpenAPI 3.1 §4.8.7), one member per component kind. With\n * `--exclude-deprecated`, `kept` holds the deprecated components that kept output references\n * (`keptDeprecatedComponents`); they stay, so no reference names a missing key.\n */\nexport function componentsType(\n components: ComponentsObject,\n context: TransformContext,\n kept: ReadonlySet<object> = new Set(),\n): ComponentsResult {\n // A plain object, as in the original: its key order (integer-like names first) is the\n // output order.\n const aliases: Record<string, IrTypeAliasDeclaration> = {};\n const displaced = context.options.fixes.has(OutputFix.ROOT_TYPE_NUMBERING) ? [] : null;\n const isKept = (item: unknown) => kept.has(item as object);\n const request = { components, isKept, aliases, displaced };\n const declaredKinds = DECLARED_COMPONENT_KINDS.filter((kind) => components[kind] !== undefined);\n const members = [...COMPONENT_KINDS, ...declaredKinds].map((kind) =>\n kindMember(kind, request, context),\n );\n const rootTypes = Object.values(aliases);\n return {\n type: irObject(members),\n rootTypes: [...rootTypes, ...(displaced ?? [])],\n };\n}\n"],"names":["alias"],"mappings":"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"}