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

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 (513) hide show
  1. package/README.md +12 -5
  2. package/dist/adapters/redocly-loader/configured-headers.cjs +32 -0
  3. package/dist/adapters/redocly-loader/configured-headers.cjs.map +1 -0
  4. package/dist/adapters/redocly-loader/configured-headers.mjs +30 -0
  5. package/dist/adapters/redocly-loader/configured-headers.mjs.map +1 -0
  6. package/dist/adapters/redocly-loader/redocly-config-source.cjs +21 -2
  7. package/dist/adapters/redocly-loader/redocly-config-source.cjs.map +1 -1
  8. package/dist/adapters/redocly-loader/redocly-config-source.mjs +22 -3
  9. package/dist/adapters/redocly-loader/redocly-config-source.mjs.map +1 -1
  10. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +34 -11
  11. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  12. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +33 -10
  13. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/ref-access.cjs +37 -4
  15. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  16. package/dist/adapters/redocly-loader/ref-access.mjs +37 -4
  17. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  18. package/dist/adapters/redocly-loader/ref-resolution-check.cjs +191 -0
  19. package/dist/adapters/redocly-loader/ref-resolution-check.cjs.map +1 -0
  20. package/dist/adapters/redocly-loader/ref-resolution-check.mjs +189 -0
  21. package/dist/adapters/redocly-loader/ref-resolution-check.mjs.map +1 -0
  22. package/dist/adapters/redocly-loader/ref-resolution-steps.cjs +73 -0
  23. package/dist/adapters/redocly-loader/ref-resolution-steps.cjs.map +1 -0
  24. package/dist/adapters/redocly-loader/ref-resolution-steps.mjs +60 -0
  25. package/dist/adapters/redocly-loader/ref-resolution-steps.mjs.map +1 -0
  26. package/dist/adapters/redocly-loader/remote-fetch.cjs +41 -14
  27. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  28. package/dist/adapters/redocly-loader/remote-fetch.mjs +40 -14
  29. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  30. package/dist/adapters/redocly-loader/schema-load-errors.cjs +23 -5
  31. package/dist/adapters/redocly-loader/schema-load-errors.cjs.map +1 -1
  32. package/dist/adapters/redocly-loader/schema-load-errors.mjs +23 -5
  33. package/dist/adapters/redocly-loader/schema-load-errors.mjs.map +1 -1
  34. package/dist/adapters/redocly-loader/unsupported-keys.cjs +9 -1
  35. package/dist/adapters/redocly-loader/unsupported-keys.cjs.map +1 -1
  36. package/dist/adapters/redocly-loader/unsupported-keys.mjs +9 -1
  37. package/dist/adapters/redocly-loader/unsupported-keys.mjs.map +1 -1
  38. package/dist/adapters/terminal-logger/terminal-logger.cjs +6 -4
  39. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  40. package/dist/adapters/terminal-logger/terminal-logger.mjs +6 -4
  41. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  42. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs +5 -1
  43. package/dist/adapters/type-ast-bridge/ir-to-typescript.cjs.map +1 -1
  44. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs +5 -1
  45. package/dist/adapters/type-ast-bridge/ir-to-typescript.mjs.map +1 -1
  46. package/dist/adapters/type-ast-bridge/print-typescript.cjs.map +1 -1
  47. package/dist/adapters/type-ast-bridge/print-typescript.mjs.map +1 -1
  48. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs +15 -9
  49. package/dist/adapters/type-ast-bridge/typescript-to-ir.cjs.map +1 -1
  50. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs +15 -9
  51. package/dist/adapters/type-ast-bridge/typescript-to-ir.mjs.map +1 -1
  52. package/dist/api/default-ports.cjs +9 -0
  53. package/dist/api/default-ports.cjs.map +1 -1
  54. package/dist/api/default-ports.mjs +8 -1
  55. package/dist/api/default-ports.mjs.map +1 -1
  56. package/dist/api/discriminator-conflict-warnings.cjs +25 -0
  57. package/dist/api/discriminator-conflict-warnings.cjs.map +1 -0
  58. package/dist/api/discriminator-conflict-warnings.mjs +23 -0
  59. package/dist/api/discriminator-conflict-warnings.mjs.map +1 -0
  60. package/dist/api/discriminator-enum-names.cjs +19 -0
  61. package/dist/api/discriminator-enum-names.cjs.map +1 -0
  62. package/dist/api/discriminator-enum-names.mjs +17 -0
  63. package/dist/api/discriminator-enum-names.mjs.map +1 -0
  64. package/dist/api/discriminator-enum-parent.cjs +59 -0
  65. package/dist/api/discriminator-enum-parent.cjs.map +1 -0
  66. package/dist/api/discriminator-enum-parent.mjs +57 -0
  67. package/dist/api/discriminator-enum-parent.mjs.map +1 -0
  68. package/dist/api/discriminator-enum.cjs +25 -0
  69. package/dist/api/discriminator-enum.cjs.map +1 -1
  70. package/dist/api/discriminator-enum.mjs +25 -1
  71. package/dist/api/discriminator-enum.mjs.map +1 -1
  72. package/dist/api/discriminator-other-owners.cjs +67 -0
  73. package/dist/api/discriminator-other-owners.cjs.map +1 -0
  74. package/dist/api/discriminator-other-owners.mjs +64 -0
  75. package/dist/api/discriminator-other-owners.mjs.map +1 -0
  76. package/dist/api/discriminator-patch.cjs +92 -0
  77. package/dist/api/discriminator-patch.cjs.map +1 -0
  78. package/dist/api/discriminator-patch.mjs +86 -0
  79. package/dist/api/discriminator-patch.mjs.map +1 -0
  80. package/dist/api/discriminator-scan.cjs +50 -65
  81. package/dist/api/discriminator-scan.cjs.map +1 -1
  82. package/dist/api/discriminator-scan.mjs +44 -59
  83. package/dist/api/discriminator-scan.mjs.map +1 -1
  84. package/dist/api/document-refs.cjs +15 -12
  85. package/dist/api/document-refs.cjs.map +1 -1
  86. package/dist/api/document-refs.mjs +15 -12
  87. package/dist/api/document-refs.mjs.map +1 -1
  88. package/dist/api/document-run.cjs +21 -4
  89. package/dist/api/document-run.cjs.map +1 -1
  90. package/dist/api/document-run.mjs +22 -5
  91. package/dist/api/document-run.mjs.map +1 -1
  92. package/dist/api/enum-values-warnings.cjs +16 -0
  93. package/dist/api/enum-values-warnings.cjs.map +1 -0
  94. package/dist/api/enum-values-warnings.mjs +14 -0
  95. package/dist/api/enum-values-warnings.mjs.map +1 -0
  96. package/dist/api/footer-sink.cjs +25 -2
  97. package/dist/api/footer-sink.cjs.map +1 -1
  98. package/dist/api/footer-sink.mjs +25 -2
  99. package/dist/api/footer-sink.mjs.map +1 -1
  100. package/dist/api/legacy-callback-warning.cjs +4 -1
  101. package/dist/api/legacy-callback-warning.cjs.map +1 -1
  102. package/dist/api/legacy-callback-warning.mjs +4 -1
  103. package/dist/api/legacy-callback-warning.mjs.map +1 -1
  104. package/dist/api/legacy-ts-helpers.cjs.map +1 -1
  105. package/dist/api/legacy-ts-helpers.mjs.map +1 -1
  106. package/dist/api/legacy-utils.cjs.map +1 -1
  107. package/dist/api/legacy-utils.mjs.map +1 -1
  108. package/dist/api/openapi-ts.cjs +2 -1
  109. package/dist/api/openapi-ts.cjs.map +1 -1
  110. package/dist/api/openapi-ts.mjs +3 -2
  111. package/dist/api/openapi-ts.mjs.map +1 -1
  112. package/dist/api/path-template-warnings.cjs +21 -0
  113. package/dist/api/path-template-warnings.cjs.map +1 -0
  114. package/dist/api/path-template-warnings.mjs +19 -0
  115. package/dist/api/path-template-warnings.mjs.map +1 -0
  116. package/dist/api/transform-context.cjs +4 -2
  117. package/dist/api/transform-context.cjs.map +1 -1
  118. package/dist/api/transform-context.mjs +4 -2
  119. package/dist/api/transform-context.mjs.map +1 -1
  120. package/dist/api/transform-schema.cjs +52 -3
  121. package/dist/api/transform-schema.cjs.map +1 -1
  122. package/dist/api/transform-schema.mjs +53 -4
  123. package/dist/api/transform-schema.mjs.map +1 -1
  124. package/dist/api/unsupported-feature-warnings.cjs +6 -1
  125. package/dist/api/unsupported-feature-warnings.cjs.map +1 -1
  126. package/dist/api/unsupported-feature-warnings.mjs +6 -1
  127. package/dist/api/unsupported-feature-warnings.mjs.map +1 -1
  128. package/dist/application/print/type-printer.cjs +7 -1
  129. package/dist/application/print/type-printer.cjs.map +1 -1
  130. package/dist/application/print/type-printer.mjs +7 -1
  131. package/dist/application/print/type-printer.mjs.map +1 -1
  132. package/dist/application/transform/document/assignability.cjs +144 -0
  133. package/dist/application/transform/document/assignability.cjs.map +1 -0
  134. package/dist/application/transform/document/assignability.mjs +138 -0
  135. package/dist/application/transform/document/assignability.mjs.map +1 -0
  136. package/dist/application/transform/document/components.cjs +2 -2
  137. package/dist/application/transform/document/components.cjs.map +1 -1
  138. package/dist/application/transform/document/components.mjs +4 -4
  139. package/dist/application/transform/document/components.mjs.map +1 -1
  140. package/dist/application/transform/document/declared-types.cjs +66 -0
  141. package/dist/application/transform/document/declared-types.cjs.map +1 -0
  142. package/dist/application/transform/document/declared-types.mjs +63 -0
  143. package/dist/application/transform/document/declared-types.mjs.map +1 -0
  144. package/dist/application/transform/document/document.cjs +32 -9
  145. package/dist/application/transform/document/document.cjs.map +1 -1
  146. package/dist/application/transform/document/document.mjs +34 -11
  147. package/dist/application/transform/document/document.mjs.map +1 -1
  148. package/dist/application/transform/document/exploded-query.cjs +46 -0
  149. package/dist/application/transform/document/exploded-query.cjs.map +1 -0
  150. package/dist/application/transform/document/exploded-query.mjs +43 -0
  151. package/dist/application/transform/document/exploded-query.mjs.map +1 -0
  152. package/dist/application/transform/document/global-type-references.cjs +63 -0
  153. package/dist/application/transform/document/global-type-references.cjs.map +1 -0
  154. package/dist/application/transform/document/global-type-references.mjs +61 -0
  155. package/dist/application/transform/document/global-type-references.mjs.map +1 -0
  156. package/dist/application/transform/document/list-assignability.cjs +54 -0
  157. package/dist/application/transform/document/list-assignability.cjs.map +1 -0
  158. package/dist/application/transform/document/list-assignability.mjs +52 -0
  159. package/dist/application/transform/document/list-assignability.mjs.map +1 -0
  160. package/dist/application/transform/document/parameters.cjs +41 -9
  161. package/dist/application/transform/document/parameters.cjs.map +1 -1
  162. package/dist/application/transform/document/parameters.mjs +42 -10
  163. package/dist/application/transform/document/parameters.mjs.map +1 -1
  164. package/dist/application/transform/document/path-key-overlaps.cjs +83 -33
  165. package/dist/application/transform/document/path-key-overlaps.cjs.map +1 -1
  166. package/dist/application/transform/document/path-key-overlaps.mjs +83 -33
  167. package/dist/application/transform/document/path-key-overlaps.mjs.map +1 -1
  168. package/dist/application/transform/document/path-template-replace.cjs +48 -0
  169. package/dist/application/transform/document/path-template-replace.cjs.map +1 -0
  170. package/dist/application/transform/document/path-template-replace.mjs +45 -0
  171. package/dist/application/transform/document/path-template-replace.mjs.map +1 -0
  172. package/dist/application/transform/document/paths.cjs +55 -29
  173. package/dist/application/transform/document/paths.cjs.map +1 -1
  174. package/dist/application/transform/document/paths.mjs +54 -30
  175. package/dist/application/transform/document/paths.mjs.map +1 -1
  176. package/dist/application/transform/document/root-type-aliases.cjs +15 -14
  177. package/dist/application/transform/document/root-type-aliases.cjs.map +1 -1
  178. package/dist/application/transform/document/root-type-aliases.mjs +15 -13
  179. package/dist/application/transform/document/root-type-aliases.mjs.map +1 -1
  180. package/dist/application/transform/document/template-key-match.cjs +128 -0
  181. package/dist/application/transform/document/template-key-match.cjs.map +1 -0
  182. package/dist/application/transform/document/template-key-match.mjs +125 -0
  183. package/dist/application/transform/document/template-key-match.mjs.map +1 -0
  184. package/dist/application/transform/document/type-assignability.cjs +192 -0
  185. package/dist/application/transform/document/type-assignability.cjs.map +1 -0
  186. package/dist/application/transform/document/type-assignability.mjs +190 -0
  187. package/dist/application/transform/document/type-assignability.mjs.map +1 -0
  188. package/dist/application/transform/document/type-key.cjs +70 -0
  189. package/dist/application/transform/document/type-key.cjs.map +1 -0
  190. package/dist/application/transform/document/type-key.mjs +68 -0
  191. package/dist/application/transform/document/type-key.mjs.map +1 -0
  192. package/dist/application/transform/document/type-resolution.cjs +131 -0
  193. package/dist/application/transform/document/type-resolution.cjs.map +1 -0
  194. package/dist/application/transform/document/type-resolution.mjs +125 -0
  195. package/dist/application/transform/document/type-resolution.mjs.map +1 -0
  196. package/dist/application/transform/footer/document-footer.cjs +66 -4
  197. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  198. package/dist/application/transform/footer/document-footer.mjs +67 -5
  199. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  200. package/dist/application/transform/footer/enum-naming.cjs +17 -0
  201. package/dist/application/transform/footer/enum-naming.cjs.map +1 -1
  202. package/dist/application/transform/footer/enum-naming.mjs +17 -1
  203. package/dist/application/transform/footer/enum-naming.mjs.map +1 -1
  204. package/dist/application/transform/footer/enum-values-check.cjs +129 -0
  205. package/dist/application/transform/footer/enum-values-check.cjs.map +1 -0
  206. package/dist/application/transform/footer/enum-values-check.mjs +127 -0
  207. package/dist/application/transform/footer/enum-values-check.mjs.map +1 -0
  208. package/dist/application/transform/footer/evaluation.cjs +42 -0
  209. package/dist/application/transform/footer/evaluation.cjs.map +1 -0
  210. package/dist/application/transform/footer/evaluation.mjs +33 -0
  211. package/dist/application/transform/footer/evaluation.mjs.map +1 -0
  212. package/dist/application/transform/footer/shared-enum-names.cjs +60 -0
  213. package/dist/application/transform/footer/shared-enum-names.cjs.map +1 -0
  214. package/dist/application/transform/footer/shared-enum-names.mjs +57 -0
  215. package/dist/application/transform/footer/shared-enum-names.mjs.map +1 -0
  216. package/dist/application/transform/footer/type-evaluation.cjs +138 -0
  217. package/dist/application/transform/footer/type-evaluation.cjs.map +1 -0
  218. package/dist/application/transform/footer/type-evaluation.mjs +136 -0
  219. package/dist/application/transform/footer/type-evaluation.mjs.map +1 -0
  220. package/dist/application/transform/footer/type-indexing.cjs +107 -0
  221. package/dist/application/transform/footer/type-indexing.cjs.map +1 -0
  222. package/dist/application/transform/footer/type-indexing.mjs +105 -0
  223. package/dist/application/transform/footer/type-indexing.mjs.map +1 -0
  224. package/dist/application/transform/footer/type-rules.cjs +172 -0
  225. package/dist/application/transform/footer/type-rules.cjs.map +1 -0
  226. package/dist/application/transform/footer/type-rules.mjs +166 -0
  227. package/dist/application/transform/footer/type-rules.mjs.map +1 -0
  228. package/dist/application/transform/ref-pointer/generated-location.cjs +138 -0
  229. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -0
  230. package/dist/application/transform/ref-pointer/generated-location.mjs +136 -0
  231. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -0
  232. package/dist/application/transform/ref-pointer/generated-shape.cjs +171 -0
  233. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -0
  234. package/dist/application/transform/ref-pointer/generated-shape.mjs +162 -0
  235. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -0
  236. package/dist/application/transform/ref-pointer/inline-cycles.cjs +44 -0
  237. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -0
  238. package/dist/application/transform/ref-pointer/inline-cycles.mjs +42 -0
  239. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -0
  240. package/dist/application/transform/ref-pointer/original-index.cjs +62 -0
  241. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -0
  242. package/dist/application/transform/ref-pointer/original-index.mjs +60 -0
  243. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -0
  244. package/dist/application/transform/ref-pointer/pointer-type.cjs +60 -0
  245. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -0
  246. package/dist/application/transform/ref-pointer/pointer-type.mjs +57 -0
  247. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -0
  248. package/dist/application/transform/ref-pointer/pointer-walk.cjs +66 -0
  249. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -0
  250. package/dist/application/transform/ref-pointer/pointer-walk.mjs +56 -0
  251. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -0
  252. package/dist/application/transform/ref-pointer/typed-walk.cjs +124 -0
  253. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -0
  254. package/dist/application/transform/ref-pointer/typed-walk.mjs +122 -0
  255. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -0
  256. package/dist/application/transform/ref-type.cjs +7 -2
  257. package/dist/application/transform/ref-type.cjs.map +1 -1
  258. package/dist/application/transform/ref-type.mjs +3 -2
  259. package/dist/application/transform/ref-type.mjs.map +1 -1
  260. package/dist/application/transform/schema/access-flags.cjs +38 -0
  261. package/dist/application/transform/schema/access-flags.cjs.map +1 -0
  262. package/dist/application/transform/schema/access-flags.mjs +36 -0
  263. package/dist/application/transform/schema/access-flags.mjs.map +1 -0
  264. package/dist/application/transform/schema/array-type.cjs +32 -1
  265. package/dist/application/transform/schema/array-type.cjs.map +1 -1
  266. package/dist/application/transform/schema/array-type.mjs +33 -2
  267. package/dist/application/transform/schema/array-type.mjs.map +1 -1
  268. package/dist/application/transform/schema/composition-type.cjs +50 -15
  269. package/dist/application/transform/schema/composition-type.cjs.map +1 -1
  270. package/dist/application/transform/schema/composition-type.mjs +50 -15
  271. package/dist/application/transform/schema/composition-type.mjs.map +1 -1
  272. package/dist/application/transform/schema/core-type.cjs +3 -1
  273. package/dist/application/transform/schema/core-type.cjs.map +1 -1
  274. package/dist/application/transform/schema/core-type.mjs +3 -1
  275. package/dist/application/transform/schema/core-type.mjs.map +1 -1
  276. package/dist/application/transform/schema/discriminated-union.cjs +30 -0
  277. package/dist/application/transform/schema/discriminated-union.cjs.map +1 -0
  278. package/dist/application/transform/schema/discriminated-union.mjs +27 -0
  279. package/dist/application/transform/schema/discriminated-union.mjs.map +1 -0
  280. package/dist/application/transform/schema/discriminator-property.cjs +3 -2
  281. package/dist/application/transform/schema/discriminator-property.cjs.map +1 -1
  282. package/dist/application/transform/schema/discriminator-property.mjs +3 -2
  283. package/dist/application/transform/schema/discriminator-property.mjs.map +1 -1
  284. package/dist/application/transform/schema/enum-rule.cjs +66 -10
  285. package/dist/application/transform/schema/enum-rule.cjs.map +1 -1
  286. package/dist/application/transform/schema/enum-rule.mjs +67 -12
  287. package/dist/application/transform/schema/enum-rule.mjs.map +1 -1
  288. package/dist/application/transform/schema/inherited-discriminator.cjs +29 -0
  289. package/dist/application/transform/schema/inherited-discriminator.cjs.map +1 -0
  290. package/dist/application/transform/schema/inherited-discriminator.mjs +26 -0
  291. package/dist/application/transform/schema/inherited-discriminator.mjs.map +1 -0
  292. package/dist/application/transform/schema/object-type.cjs +38 -25
  293. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  294. package/dist/application/transform/schema/object-type.mjs +39 -27
  295. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  296. package/dist/application/transform/schema/required-variants.cjs +45 -0
  297. package/dist/application/transform/schema/required-variants.cjs.map +1 -0
  298. package/dist/application/transform/schema/required-variants.mjs +42 -0
  299. package/dist/application/transform/schema/required-variants.mjs.map +1 -0
  300. package/dist/application/transform/schema/schema-transform.cjs +2 -2
  301. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  302. package/dist/application/transform/schema/schema-transform.mjs +2 -2
  303. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  304. package/dist/application/transform/schema-comment.cjs +51 -5
  305. package/dist/application/transform/schema-comment.cjs.map +1 -1
  306. package/dist/application/transform/schema-comment.mjs +50 -6
  307. package/dist/application/transform/schema-comment.mjs.map +1 -1
  308. package/dist/application/transform/type-combinators.mjs +1 -1
  309. package/dist/cli/api-settings.cjs +78 -0
  310. package/dist/cli/api-settings.cjs.map +1 -0
  311. package/dist/cli/api-settings.mjs +73 -0
  312. package/dist/cli/api-settings.mjs.map +1 -0
  313. package/dist/cli/cli-arguments.cjs +12 -3
  314. package/dist/cli/cli-arguments.cjs.map +1 -1
  315. package/dist/cli/cli-arguments.mjs +12 -4
  316. package/dist/cli/cli-arguments.mjs.map +1 -1
  317. package/dist/cli/cli-errors.cjs +3 -2
  318. package/dist/cli/cli-errors.cjs.map +1 -1
  319. package/dist/cli/cli-errors.mjs +3 -2
  320. package/dist/cli/cli-errors.mjs.map +1 -1
  321. package/dist/cli/cli-output.cjs +8 -3
  322. package/dist/cli/cli-output.cjs.map +1 -1
  323. package/dist/cli/cli-output.mjs +9 -4
  324. package/dist/cli/cli-output.mjs.map +1 -1
  325. package/dist/cli/help-text.cjs +3 -3
  326. package/dist/cli/help-text.cjs.map +1 -1
  327. package/dist/cli/help-text.mjs +3 -3
  328. package/dist/cli/help-text.mjs.map +1 -1
  329. package/dist/cli/main.cjs +5 -0
  330. package/dist/cli/main.cjs.map +1 -1
  331. package/dist/cli/main.mjs +5 -0
  332. package/dist/cli/main.mjs.map +1 -1
  333. package/dist/cli/redocly-apis.cjs +15 -7
  334. package/dist/cli/redocly-apis.cjs.map +1 -1
  335. package/dist/cli/redocly-apis.mjs +15 -7
  336. package/dist/cli/redocly-apis.mjs.map +1 -1
  337. package/dist/cli/ref-limits.cjs +1 -1
  338. package/dist/cli/ref-limits.cjs.map +1 -1
  339. package/dist/cli/ref-limits.mjs +2 -2
  340. package/dist/cli/ref-limits.mjs.map +1 -1
  341. package/dist/cli/run-cli.cjs +20 -3
  342. package/dist/cli/run-cli.cjs.map +1 -1
  343. package/dist/cli/run-cli.mjs +21 -4
  344. package/dist/cli/run-cli.mjs.map +1 -1
  345. package/dist/domain/errors.cjs +6 -1
  346. package/dist/domain/errors.cjs.map +1 -1
  347. package/dist/domain/errors.mjs +6 -1
  348. package/dist/domain/errors.mjs.map +1 -1
  349. package/dist/domain/ir/constructors.cjs +7 -1
  350. package/dist/domain/ir/constructors.cjs.map +1 -1
  351. package/dist/domain/ir/constructors.mjs +6 -2
  352. package/dist/domain/ir/constructors.mjs.map +1 -1
  353. package/dist/domain/openapi/admitted-values.cjs +75 -0
  354. package/dist/domain/openapi/admitted-values.cjs.map +1 -0
  355. package/dist/domain/openapi/admitted-values.mjs +72 -0
  356. package/dist/domain/openapi/admitted-values.mjs.map +1 -0
  357. package/dist/domain/openapi/discriminated-union.cjs +68 -0
  358. package/dist/domain/openapi/discriminated-union.cjs.map +1 -0
  359. package/dist/domain/openapi/discriminated-union.mjs +62 -0
  360. package/dist/domain/openapi/discriminated-union.mjs.map +1 -0
  361. package/dist/domain/openapi/discriminator-conflicts.cjs +143 -0
  362. package/dist/domain/openapi/discriminator-conflicts.cjs.map +1 -0
  363. package/dist/domain/openapi/discriminator-conflicts.mjs +141 -0
  364. package/dist/domain/openapi/discriminator-conflicts.mjs.map +1 -0
  365. package/dist/domain/openapi/parameter-object.cjs.map +1 -1
  366. package/dist/domain/openapi/parameter-object.mjs.map +1 -1
  367. package/dist/domain/openapi/path-templates.cjs +23 -0
  368. package/dist/domain/openapi/path-templates.cjs.map +1 -0
  369. package/dist/domain/openapi/path-templates.mjs +21 -0
  370. package/dist/domain/openapi/path-templates.mjs.map +1 -0
  371. package/dist/domain/output-fixes.cjs +36 -1
  372. package/dist/domain/output-fixes.cjs.map +1 -1
  373. package/dist/domain/output-fixes.mjs +36 -1
  374. package/dist/domain/output-fixes.mjs.map +1 -1
  375. package/dist/domain/url-credentials.cjs +10 -0
  376. package/dist/domain/url-credentials.cjs.map +1 -0
  377. package/dist/domain/url-credentials.mjs +8 -0
  378. package/dist/domain/url-credentials.mjs.map +1 -0
  379. package/dist/domain/warnings.cjs +23 -0
  380. package/dist/domain/warnings.cjs.map +1 -0
  381. package/dist/domain/warnings.mjs +20 -0
  382. package/dist/domain/warnings.mjs.map +1 -0
  383. package/dist/index.cjs +2 -0
  384. package/dist/index.cjs.map +1 -1
  385. package/dist/index.d.cts +1182 -46
  386. package/dist/index.d.mts +1182 -46
  387. package/dist/index.d.ts +1182 -46
  388. package/dist/index.mjs +1 -0
  389. package/dist/index.mjs.map +1 -1
  390. package/dist/transform/components-object.cjs +2 -1
  391. package/dist/transform/components-object.cjs.map +1 -1
  392. package/dist/transform/components-object.mjs +2 -1
  393. package/dist/transform/components-object.mjs.map +1 -1
  394. package/dist/transform/path-item-object.cjs.map +1 -1
  395. package/dist/transform/path-item-object.mjs.map +1 -1
  396. package/package.json +6 -5
  397. package/src/adapters/redocly-loader/configured-headers.ts +65 -0
  398. package/src/adapters/redocly-loader/redocly-config-source.ts +41 -6
  399. package/src/adapters/redocly-loader/redocly-schema-loader.ts +44 -13
  400. package/src/adapters/redocly-loader/ref-access.ts +60 -5
  401. package/src/adapters/redocly-loader/ref-resolution-check.ts +257 -0
  402. package/src/adapters/redocly-loader/ref-resolution-steps.ts +113 -0
  403. package/src/adapters/redocly-loader/remote-fetch.ts +77 -21
  404. package/src/adapters/redocly-loader/schema-load-errors.ts +33 -11
  405. package/src/adapters/redocly-loader/unsupported-keys.ts +17 -2
  406. package/src/adapters/terminal-logger/terminal-logger.ts +9 -5
  407. package/src/adapters/type-ast-bridge/ir-to-typescript.ts +5 -1
  408. package/src/adapters/type-ast-bridge/print-typescript.ts +3 -1
  409. package/src/adapters/type-ast-bridge/typescript-to-ir.ts +26 -12
  410. package/src/adapters/type-ast-bridge/typescript-types.ts +57 -5
  411. package/src/api/default-ports.ts +16 -0
  412. package/src/api/discriminator-conflict-warnings.ts +43 -0
  413. package/src/api/discriminator-enum-names.ts +26 -0
  414. package/src/api/discriminator-enum-parent.ts +129 -0
  415. package/src/api/discriminator-enum.ts +39 -0
  416. package/src/api/discriminator-other-owners.ts +97 -0
  417. package/src/api/discriminator-patch.ts +152 -0
  418. package/src/api/discriminator-scan.ts +78 -90
  419. package/src/api/document-refs.ts +19 -15
  420. package/src/api/document-run.ts +32 -11
  421. package/src/api/enum-values-warnings.ts +21 -0
  422. package/src/api/footer-sink.ts +34 -2
  423. package/src/api/legacy-callback-warning.ts +7 -3
  424. package/src/api/legacy-ts-helpers.ts +7 -5
  425. package/src/api/legacy-utils.ts +1 -1
  426. package/src/api/openapi-ts.ts +2 -0
  427. package/src/api/path-template-warnings.ts +27 -0
  428. package/src/api/run-context.ts +34 -0
  429. package/src/api/transform-context.ts +17 -9
  430. package/src/api/transform-schema.ts +90 -5
  431. package/src/api/unsupported-feature-warnings.ts +8 -1
  432. package/src/application/ports/redocly-config-source.ts +5 -1
  433. package/src/application/print/type-printer.ts +8 -1
  434. package/src/application/transform/document/assignability.ts +203 -0
  435. package/src/application/transform/document/components.ts +6 -6
  436. package/src/application/transform/document/declared-types.ts +93 -0
  437. package/src/application/transform/document/document.ts +71 -13
  438. package/src/application/transform/document/exploded-query.ts +91 -0
  439. package/src/application/transform/document/global-type-references.ts +78 -0
  440. package/src/application/transform/document/list-assignability.ts +87 -0
  441. package/src/application/transform/document/parameters.ts +78 -12
  442. package/src/application/transform/document/path-key-overlaps.ts +148 -59
  443. package/src/application/transform/document/path-template-replace.ts +90 -0
  444. package/src/application/transform/document/paths.ts +101 -38
  445. package/src/application/transform/document/root-type-aliases.ts +29 -28
  446. package/src/application/transform/document/template-key-match.ts +183 -0
  447. package/src/application/transform/document/type-assignability.ts +268 -0
  448. package/src/application/transform/document/type-key.ts +80 -0
  449. package/src/application/transform/document/type-resolution.ts +163 -0
  450. package/src/application/transform/footer/document-footer.ts +91 -6
  451. package/src/application/transform/footer/enum-naming.ts +29 -0
  452. package/src/application/transform/footer/enum-values-check.ts +171 -0
  453. package/src/application/transform/footer/evaluation.ts +57 -0
  454. package/src/application/transform/footer/shared-enum-names.ts +86 -0
  455. package/src/application/transform/footer/type-evaluation.ts +167 -0
  456. package/src/application/transform/footer/type-indexing.ts +152 -0
  457. package/src/application/transform/footer/type-rules.ts +269 -0
  458. package/src/application/transform/ref-pointer/generated-location.ts +211 -0
  459. package/src/application/transform/ref-pointer/generated-shape.ts +275 -0
  460. package/src/application/transform/ref-pointer/inline-cycles.ts +56 -0
  461. package/src/application/transform/ref-pointer/original-index.ts +95 -0
  462. package/src/application/transform/ref-pointer/pointer-type.ts +92 -0
  463. package/src/application/transform/ref-pointer/pointer-walk.ts +96 -0
  464. package/src/application/transform/ref-pointer/typed-walk.ts +192 -0
  465. package/src/application/transform/ref-type.ts +11 -6
  466. package/src/application/transform/schema/access-flags.ts +63 -0
  467. package/src/application/transform/schema/array-type.ts +66 -5
  468. package/src/application/transform/schema/composition-type.ts +96 -24
  469. package/src/application/transform/schema/core-type.ts +8 -4
  470. package/src/application/transform/schema/discriminated-union.ts +58 -0
  471. package/src/application/transform/schema/discriminator-property.ts +8 -3
  472. package/src/application/transform/schema/enum-rule.ts +136 -13
  473. package/src/application/transform/schema/inherited-discriminator.ts +54 -0
  474. package/src/application/transform/schema/object-type.ts +51 -33
  475. package/src/application/transform/schema/required-variants.ts +88 -0
  476. package/src/application/transform/schema/schema-context.ts +26 -0
  477. package/src/application/transform/schema/schema-transform.ts +2 -2
  478. package/src/application/transform/schema-comment.ts +84 -4
  479. package/src/cli/api-settings.ts +109 -0
  480. package/src/cli/cli-arguments.ts +18 -5
  481. package/src/cli/cli-dependencies.ts +5 -0
  482. package/src/cli/cli-errors.ts +4 -2
  483. package/src/cli/cli-output.ts +18 -4
  484. package/src/cli/help-text.ts +4 -4
  485. package/src/cli/main.ts +6 -0
  486. package/src/cli/redocly-apis.ts +21 -11
  487. package/src/cli/ref-limits.ts +2 -2
  488. package/src/cli/run-cli.ts +25 -4
  489. package/src/domain/errors.ts +10 -2
  490. package/src/domain/ir/constructors.ts +9 -1
  491. package/src/domain/ir/nodes.ts +11 -7
  492. package/src/domain/openapi/admitted-values.ts +113 -0
  493. package/src/domain/openapi/discriminated-union.ts +109 -0
  494. package/src/domain/openapi/discriminator-conflicts.ts +251 -0
  495. package/src/domain/openapi/parameter-object.ts +4 -0
  496. package/src/domain/openapi/path-templates.ts +32 -0
  497. package/src/domain/openapi/schema-object.ts +2 -0
  498. package/src/domain/output-fixes.ts +43 -2
  499. package/src/domain/url-credentials.ts +18 -0
  500. package/src/domain/warnings.ts +28 -0
  501. package/src/index.ts +1 -0
  502. package/src/transform/components-object.ts +3 -1
  503. package/src/transform/path-item-object.ts +6 -2
  504. package/src/types/generator-options.ts +12 -21
  505. package/src/types/openapi-common.ts +1 -0
  506. package/src/types/openapi-request.ts +3 -0
  507. package/src/types/openapi-schema.ts +2 -0
  508. package/src/types/openapi-security.ts +1 -0
  509. package/dist/application/transform/document/path-item-conflicts.cjs +0 -51
  510. package/dist/application/transform/document/path-item-conflicts.cjs.map +0 -1
  511. package/dist/application/transform/document/path-item-conflicts.mjs +0 -49
  512. package/dist/application/transform/document/path-item-conflicts.mjs.map +0 -1
  513. package/src/application/transform/document/path-item-conflicts.ts +0 -79
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-values-check.mjs","sources":["../../../../src/application/transform/footer/enum-values-check.ts"],"sourcesContent":["import { irArray, irReadonly, irReference } from \"../../../domain/ir/constructors.js\";\nimport type { IrConstArrayDeclaration, IrDeclaration, IrType } from \"../../../domain/ir/nodes.js\";\nimport { HELPER_TYPES } from \"../helper-types.js\";\nimport { literalType } from \"../literal-type.js\";\nimport { unionOf } from \"../type-combinators.js\";\nimport { type Evaluated, type Evaluation, NEVER } from \"./evaluation.js\";\nimport { TypeEvaluator } from \"./type-evaluation.js\";\n\n/**\n * `--enum-values` arrays are typed by the location of their schema in the generated types\n * (`FlattenedDeepRequired<components>[\"schemas\"][\"A\"][\"status\"]`). Where that type surely does not\n * hold the values (ADR-027), the array is typed by its own values instead, so it compiles:\n * - the location indexes a key the generated type does not have (`definitions`, `allOf`, a\n * property of `unknown`), or\n * - the type there does not admit a listed value (an `allOf` of different enums, a discriminator\n * value the property enum does not list, an array next to other `anyOf` members).\n * Everything else stays as it was.\n */\n\n/** Why an array got its own values as its type. */\nexport type EnumValuesRetype =\n /** The location's type admits only other values, or none: the document contradicts itself. */\n | { readonly kind: \"excluded\"; readonly name: string; readonly excluded: readonly unknown[] }\n /** The location could not be typed; nothing to report, the array is right now. */\n | { readonly kind: \"untyped\"; readonly name: string };\n\ntype Admission = \"yes\" | \"no\" | \"opaque\";\n\nfunction literalAdmission(type: IrType, value: string | number): Admission {\n switch (type.kind) {\n case \"stringLiteral\":\n case \"numberLiteral\":\n return type.value === value ? \"yes\" : \"no\";\n case \"booleanLiteral\":\n return \"no\";\n case \"keyword\":\n if (type.keyword === \"unknown\") {\n return \"yes\";\n }\n return type.keyword === typeof value ? \"yes\" : \"no\";\n case \"object\":\n // `{}` (as in `string & {}`) admits every value but `null` and `undefined`.\n return type.members.length === 0 ? \"yes\" : \"no\";\n case \"array\":\n return \"no\";\n default:\n return \"opaque\";\n }\n}\n\nfunction admission(evaluator: TypeEvaluator, value: Evaluated, item: string | number): Admission {\n const { type } = value;\n if (type.kind === \"union\" || type.kind === \"intersection\") {\n const parts = type.types.map((part) => {\n const expanded = evaluator.expand({ ...value, type: part });\n return expanded.kind === \"type\" ? admission(evaluator, expanded, item) : \"opaque\";\n });\n // A union admits a value one member admits; an intersection excludes one a part excludes.\n const decisive: Admission = type.kind === \"union\" ? \"yes\" : \"no\";\n if (parts.includes(decisive)) {\n return decisive;\n }\n return parts.includes(\"opaque\") ? \"opaque\" : decisive === \"yes\" ? \"no\" : \"yes\";\n }\n return literalAdmission(type, item);\n}\n\n/** `ReadonlyArray<T>`: an array type `T` is the array itself, so its elements are checked. */\nfunction elementOf(evaluator: TypeEvaluator, value: Evaluated): Evaluation {\n const members = evaluator.membersOf(value);\n const elements = members.map((member) =>\n member.kind === \"type\" && member.type.kind === \"array\" ? member.type.element : null,\n );\n if (members.length === 0 || elements.some((element) => element === null)) {\n return value;\n }\n return evaluator.expand({ ...value, type: unionOf(elements as IrType[]) });\n}\n\nconst LITERAL_KINDS: ReadonlySet<string> = new Set([\n \"stringLiteral\",\n \"numberLiteral\",\n \"booleanLiteral\",\n]);\n\n/** Whether a type is made of literals only (or `never`): a finite set of values. */\nfunction isFiniteType(evaluator: TypeEvaluator, value: Evaluated): boolean {\n const { type } = value;\n if (type.kind === \"union\" || type.kind === \"intersection\") {\n return type.types.every((part) => {\n const expanded = evaluator.expand({ ...value, type: part });\n return expanded.kind === \"type\" && isFiniteType(evaluator, expanded);\n });\n }\n return LITERAL_KINDS.has(type.kind) || (type.kind === \"keyword\" && type.keyword === \"never\");\n}\n\nfunction locationType(declaration: IrConstArrayDeclaration): IrType | null {\n const { type } = declaration;\n const isTyped = type.kind === \"reference\" && type.name === HELPER_TYPES.readonlyArray.name;\n return isTyped ? (type.typeArguments[0] ?? null) : null;\n}\n\nfunction retypeOf(\n evaluator: TypeEvaluator,\n declaration: IrConstArrayDeclaration,\n): EnumValuesRetype | null {\n const location = locationType(declaration);\n const evaluated = location === null ? null : evaluator.evaluate(location);\n if (evaluated === null || evaluated.kind === \"opaque\") {\n return null;\n }\n if (evaluated.kind === \"missing\") {\n return { kind: \"untyped\", name: declaration.name };\n }\n const element = elementOf(evaluator, evaluated);\n if (element.kind !== \"type\") {\n return element.kind === \"missing\" ? { kind: \"untyped\", name: declaration.name } : null;\n }\n if (declaration.values.length === 0 && isNever(element.type)) {\n // The `ReadonlyArray` helper of `never` is `never` (`never` extends an array): not even `[]`.\n return { kind: \"untyped\", name: declaration.name };\n }\n const results = declaration.values.map((value) => admission(evaluator, element, value));\n if (!results.includes(\"no\")) {\n return null;\n }\n if (!isFiniteType(evaluator, element)) {\n return { kind: \"untyped\", name: declaration.name };\n }\n const excluded = declaration.values.filter((_, index) => results[index] === \"no\");\n return { kind: \"excluded\", name: declaration.name, excluded };\n}\n\nfunction isNever(type: IrType): boolean {\n return type.kind === \"keyword\" && type.keyword === \"never\";\n}\n\n/** The values' own type; with no values `readonly never[]` (`ReadonlyArray<never>` is never). */\nfunction ownValuesType(declaration: IrConstArrayDeclaration): IrType {\n if (declaration.values.length === 0) {\n return irReadonly(irArray(NEVER));\n }\n const values = unionOf(declaration.values.map((value) => literalType(value)));\n return irReference(HELPER_TYPES.readonlyArray.name, [values]);\n}\n\n/**\n * The footer with each `--enum-values` array whose location type does not hold its values typed\n * by its own values, and why each one changed. `declarations` are the document's types.\n */\nexport function checkedEnumValues<T>(\n footer: readonly (T | IrDeclaration)[],\n declarations: readonly IrDeclaration[],\n isDeclaration: (entry: T | IrDeclaration) => entry is IrDeclaration,\n): { footer: (T | IrDeclaration)[]; retyped: EnumValuesRetype[] } {\n const evaluator = new TypeEvaluator([...declarations, ...footer.filter(isDeclaration)]);\n const retyped: EnumValuesRetype[] = [];\n const checked = footer.map((entry) => {\n if (!isDeclaration(entry) || entry.kind !== \"constArray\") {\n return entry;\n }\n const retype = retypeOf(evaluator, entry);\n if (retype === null) {\n return entry;\n }\n retyped.push(retype);\n return { ...entry, type: ownValuesType(entry) };\n });\n return { footer: checked, retyped };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const MISSING = { kind: "missing" };
4
+ const OPAQUE = { kind: "opaque" };
5
+ const NEVER = { kind: "keyword", keyword: "never" };
6
+ function unionType(types) {
7
+ if (types.length === 1) {
8
+ return types[0];
9
+ }
10
+ return types.length === 0 ? NEVER : { kind: "union", types };
11
+ }
12
+ function intersectionType(types) {
13
+ return types.length === 1 ? types[0] : { kind: "intersection", types };
14
+ }
15
+ const NULLISH = /* @__PURE__ */ new Set(["null", "undefined"]);
16
+ function isNullish(type) {
17
+ return type.kind === "keyword" && NULLISH.has(type.keyword);
18
+ }
19
+ function propertyKey(name) {
20
+ return name.kind === "string" ? name.value : name.text;
21
+ }
22
+ function isKeyword(member, keyword) {
23
+ return member.kind === "type" && member.type.kind === "keyword" && member.type.keyword === keyword;
24
+ }
25
+ function absorbed(members) {
26
+ const any = members.find((member) => isKeyword(member, "any"));
27
+ const unknown = members.find((member) => isKeyword(member, "unknown"));
28
+ if (any !== void 0 || unknown === void 0) {
29
+ return any === void 0 ? members : [any];
30
+ }
31
+ return members.some((member) => member.kind !== "type") ? [OPAQUE] : [unknown];
32
+ }
33
+
34
+ exports.MISSING = MISSING;
35
+ exports.NEVER = NEVER;
36
+ exports.OPAQUE = OPAQUE;
37
+ exports.absorbed = absorbed;
38
+ exports.intersectionType = intersectionType;
39
+ exports.isNullish = isNullish;
40
+ exports.propertyKey = propertyKey;
41
+ exports.unionType = unionType;
42
+ //# sourceMappingURL=evaluation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluation.cjs","sources":["../../../../src/application/transform/footer/evaluation.ts"],"sourcesContent":["import type { IrPropertyName, IrType } from \"../../../domain/ir/nodes.js\";\n\n/** The values the evaluator of the `--enum-values` check works with (ADR-027). */\n\n/** A type as evaluated: `deep` is set inside `FlattenedDeepRequired`. */\nexport interface Evaluated {\n readonly kind: \"type\";\n readonly type: IrType;\n readonly deep: boolean;\n}\n\nexport type Evaluation = Evaluated | { readonly kind: \"missing\" } | { readonly kind: \"opaque\" };\n\nexport const MISSING: Evaluation = { kind: \"missing\" };\nexport const OPAQUE: Evaluation = { kind: \"opaque\" };\n\nexport const NEVER: IrType = { kind: \"keyword\", keyword: \"never\" };\n\nexport function unionType(types: readonly IrType[]): IrType {\n if (types.length === 1) {\n return types[0] as IrType;\n }\n return types.length === 0 ? NEVER : { kind: \"union\", types };\n}\n\nexport function intersectionType(types: readonly IrType[]): IrType {\n return types.length === 1 ? (types[0] as IrType) : { kind: \"intersection\", types };\n}\n\nconst NULLISH: ReadonlySet<string> = new Set([\"null\", \"undefined\"]);\n\nexport function isNullish(type: IrType): boolean {\n return type.kind === \"keyword\" && NULLISH.has(type.keyword);\n}\n\nexport function propertyKey(name: IrPropertyName): string {\n return name.kind === \"string\" ? name.value : name.text;\n}\n\nfunction isKeyword(member: Evaluation, keyword: string): boolean {\n return (\n member.kind === \"type\" && member.type.kind === \"keyword\" && member.type.keyword === keyword\n );\n}\n\n/**\n * Union members as TypeScript reduces them: `any` absorbs every member, `unknown` every member\n * but `any`, so `{ a: X } | unknown` is `unknown`. An opaque member may be `any`.\n */\nexport function absorbed(members: readonly Evaluation[]): readonly Evaluation[] {\n const any = members.find((member) => isKeyword(member, \"any\"));\n const unknown = members.find((member) => isKeyword(member, \"unknown\"));\n if (any !== undefined || unknown === undefined) {\n return any === undefined ? members : [any];\n }\n return members.some((member) => member.kind !== \"type\") ? [OPAQUE] : [unknown];\n}\n"],"names":[],"mappings":";;AAaO,MAAM,OAAA,GAAsB,EAAE,IAAA,EAAM,SAAA;AACpC,MAAM,MAAA,GAAqB,EAAE,IAAA,EAAM,QAAA;AAEnC,MAAM,KAAA,GAAgB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,OAAA;AAElD,SAAS,UAAU,KAAA,EAAkC;AAC1D,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,MAAM,CAAC,CAAA;AAAA,EAChB;AACA,EAAA,OAAO,MAAM,MAAA,KAAW,CAAA,GAAI,QAAQ,EAAE,IAAA,EAAM,SAAS,KAAA,EAAM;AAC7D;AAEO,SAAS,iBAAiB,KAAA,EAAkC;AACjE,EAAA,OAAO,KAAA,CAAM,WAAW,CAAA,GAAK,KAAA,CAAM,CAAC,CAAA,GAAe,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAM;AACnF;AAEA,MAAM,0BAA+B,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,WAAW,CAAC,CAAA;AAE3D,SAAS,UAAU,IAAA,EAAuB;AAC/C,EAAA,OAAO,KAAK,IAAA,KAAS,SAAA,IAAa,OAAA,CAAQ,GAAA,CAAI,KAAK,OAAO,CAAA;AAC5D;AAEO,SAAS,YAAY,IAAA,EAA8B;AACxD,EAAA,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,IAAA,CAAK,QAAQ,IAAA,CAAK,IAAA;AACpD;AAEA,SAAS,SAAA,CAAU,QAAoB,OAAA,EAA0B;AAC/D,EAAA,OACE,MAAA,CAAO,SAAS,MAAA,IAAU,MAAA,CAAO,KAAK,IAAA,KAAS,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,OAAA,KAAY,OAAA;AAExF;AAMO,SAAS,SAAS,OAAA,EAAuD;AAC9E,EAAA,MAAM,GAAA,GAAM,QAAQ,IAAA,CAAK,CAAC,WAAW,SAAA,CAAU,MAAA,EAAQ,KAAK,CAAC,CAAA;AAC7D,EAAA,MAAM,OAAA,GAAU,QAAQ,IAAA,CAAK,CAAC,WAAW,SAAA,CAAU,MAAA,EAAQ,SAAS,CAAC,CAAA;AACrE,EAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,OAAA,KAAY,MAAA,EAAW;AAC9C,IAAA,OAAO,GAAA,KAAQ,MAAA,GAAY,OAAA,GAAU,CAAC,GAAG,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,KAAW,MAAA,CAAO,IAAA,KAAS,MAAM,CAAA,GAAI,CAAC,MAAM,CAAA,GAAI,CAAC,OAAO,CAAA;AAC/E;;;;;;;;;"}
@@ -0,0 +1,33 @@
1
+ const MISSING = { kind: "missing" };
2
+ const OPAQUE = { kind: "opaque" };
3
+ const NEVER = { kind: "keyword", keyword: "never" };
4
+ function unionType(types) {
5
+ if (types.length === 1) {
6
+ return types[0];
7
+ }
8
+ return types.length === 0 ? NEVER : { kind: "union", types };
9
+ }
10
+ function intersectionType(types) {
11
+ return types.length === 1 ? types[0] : { kind: "intersection", types };
12
+ }
13
+ const NULLISH = /* @__PURE__ */ new Set(["null", "undefined"]);
14
+ function isNullish(type) {
15
+ return type.kind === "keyword" && NULLISH.has(type.keyword);
16
+ }
17
+ function propertyKey(name) {
18
+ return name.kind === "string" ? name.value : name.text;
19
+ }
20
+ function isKeyword(member, keyword) {
21
+ return member.kind === "type" && member.type.kind === "keyword" && member.type.keyword === keyword;
22
+ }
23
+ function absorbed(members) {
24
+ const any = members.find((member) => isKeyword(member, "any"));
25
+ const unknown = members.find((member) => isKeyword(member, "unknown"));
26
+ if (any !== void 0 || unknown === void 0) {
27
+ return any === void 0 ? members : [any];
28
+ }
29
+ return members.some((member) => member.kind !== "type") ? [OPAQUE] : [unknown];
30
+ }
31
+
32
+ export { MISSING, NEVER, OPAQUE, absorbed, intersectionType, isNullish, propertyKey, unionType };
33
+ //# sourceMappingURL=evaluation.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluation.mjs","sources":["../../../../src/application/transform/footer/evaluation.ts"],"sourcesContent":["import type { IrPropertyName, IrType } from \"../../../domain/ir/nodes.js\";\n\n/** The values the evaluator of the `--enum-values` check works with (ADR-027). */\n\n/** A type as evaluated: `deep` is set inside `FlattenedDeepRequired`. */\nexport interface Evaluated {\n readonly kind: \"type\";\n readonly type: IrType;\n readonly deep: boolean;\n}\n\nexport type Evaluation = Evaluated | { readonly kind: \"missing\" } | { readonly kind: \"opaque\" };\n\nexport const MISSING: Evaluation = { kind: \"missing\" };\nexport const OPAQUE: Evaluation = { kind: \"opaque\" };\n\nexport const NEVER: IrType = { kind: \"keyword\", keyword: \"never\" };\n\nexport function unionType(types: readonly IrType[]): IrType {\n if (types.length === 1) {\n return types[0] as IrType;\n }\n return types.length === 0 ? NEVER : { kind: \"union\", types };\n}\n\nexport function intersectionType(types: readonly IrType[]): IrType {\n return types.length === 1 ? (types[0] as IrType) : { kind: \"intersection\", types };\n}\n\nconst NULLISH: ReadonlySet<string> = new Set([\"null\", \"undefined\"]);\n\nexport function isNullish(type: IrType): boolean {\n return type.kind === \"keyword\" && NULLISH.has(type.keyword);\n}\n\nexport function propertyKey(name: IrPropertyName): string {\n return name.kind === \"string\" ? name.value : name.text;\n}\n\nfunction isKeyword(member: Evaluation, keyword: string): boolean {\n return (\n member.kind === \"type\" && member.type.kind === \"keyword\" && member.type.keyword === keyword\n );\n}\n\n/**\n * Union members as TypeScript reduces them: `any` absorbs every member, `unknown` every member\n * but `any`, so `{ a: X } | unknown` is `unknown`. An opaque member may be `any`.\n */\nexport function absorbed(members: readonly Evaluation[]): readonly Evaluation[] {\n const any = members.find((member) => isKeyword(member, \"any\"));\n const unknown = members.find((member) => isKeyword(member, \"unknown\"));\n if (any !== undefined || unknown === undefined) {\n return any === undefined ? members : [any];\n }\n return members.some((member) => member.kind !== \"type\") ? [OPAQUE] : [unknown];\n}\n"],"names":[],"mappings":"AAaO,MAAM,OAAA,GAAsB,EAAE,IAAA,EAAM,SAAA;AACpC,MAAM,MAAA,GAAqB,EAAE,IAAA,EAAM,QAAA;AAEnC,MAAM,KAAA,GAAgB,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,OAAA;AAElD,SAAS,UAAU,KAAA,EAAkC;AAC1D,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,IAAA,OAAO,MAAM,CAAC,CAAA;AAAA,EAChB;AACA,EAAA,OAAO,MAAM,MAAA,KAAW,CAAA,GAAI,QAAQ,EAAE,IAAA,EAAM,SAAS,KAAA,EAAM;AAC7D;AAEO,SAAS,iBAAiB,KAAA,EAAkC;AACjE,EAAA,OAAO,KAAA,CAAM,WAAW,CAAA,GAAK,KAAA,CAAM,CAAC,CAAA,GAAe,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAM;AACnF;AAEA,MAAM,0BAA+B,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,WAAW,CAAC,CAAA;AAE3D,SAAS,UAAU,IAAA,EAAuB;AAC/C,EAAA,OAAO,KAAK,IAAA,KAAS,SAAA,IAAa,OAAA,CAAQ,GAAA,CAAI,KAAK,OAAO,CAAA;AAC5D;AAEO,SAAS,YAAY,IAAA,EAA8B;AACxD,EAAA,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,IAAA,CAAK,QAAQ,IAAA,CAAK,IAAA;AACpD;AAEA,SAAS,SAAA,CAAU,QAAoB,OAAA,EAA0B;AAC/D,EAAA,OACE,MAAA,CAAO,SAAS,MAAA,IAAU,MAAA,CAAO,KAAK,IAAA,KAAS,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,OAAA,KAAY,OAAA;AAExF;AAMO,SAAS,SAAS,OAAA,EAAuD;AAC9E,EAAA,MAAM,GAAA,GAAM,QAAQ,IAAA,CAAK,CAAC,WAAW,SAAA,CAAU,MAAA,EAAQ,KAAK,CAAC,CAAA;AAC7D,EAAA,MAAM,OAAA,GAAU,QAAQ,IAAA,CAAK,CAAC,WAAW,SAAA,CAAU,MAAA,EAAQ,SAAS,CAAC,CAAA;AACrE,EAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,OAAA,KAAY,MAAA,EAAW;AAC9C,IAAA,OAAO,GAAA,KAAQ,MAAA,GAAY,OAAA,GAAU,CAAC,GAAG,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,KAAW,MAAA,CAAO,IAAA,KAAS,MAAM,CAAA,GAAI,CAAC,MAAM,CAAA,GAAI,CAAC,OAAO,CAAA;AAC/E;;"}
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ const enumNaming = require('./enum-naming.cjs');
4
+
5
+ const FIRST_SCHEMA_NAMES = { nameOf: (_key, name) => name };
6
+ function isBetterName(candidate, other) {
7
+ if (candidate.isComponentSchema !== other.isComponentSchema) {
8
+ return candidate.isComponentSchema;
9
+ }
10
+ if (candidate.name.length !== other.name.length) {
11
+ return candidate.name.length < other.name.length;
12
+ }
13
+ return candidate.name < other.name;
14
+ }
15
+ function ranked(candidates) {
16
+ return [...candidates].sort((left, right) => {
17
+ if (left.name === right.name && left.isComponentSchema === right.isComponentSchema) {
18
+ return 0;
19
+ }
20
+ return isBetterName(left, right) ? -1 : 1;
21
+ });
22
+ }
23
+ class SharedEnumNameRecorder {
24
+ candidatesByKey = /* @__PURE__ */ new Map();
25
+ nameOf(key, name, request) {
26
+ const candidate = {
27
+ name: new enumNaming.EnumNaming().enumName(request.name),
28
+ isComponentSchema: request.isComponentSchema
29
+ };
30
+ const candidates = this.candidatesByKey.get(key);
31
+ if (candidates === void 0) {
32
+ this.candidatesByKey.set(key, [candidate]);
33
+ } else {
34
+ candidates.push(candidate);
35
+ }
36
+ return name;
37
+ }
38
+ /**
39
+ * The best name of each enum. Two enums whose best names are the same (two schemas that give
40
+ * one name) are resolved in key order: the later one takes its next name that is free.
41
+ */
42
+ chosenNames() {
43
+ const chosen = /* @__PURE__ */ new Map();
44
+ const taken = /* @__PURE__ */ new Set();
45
+ const keys = [...this.candidatesByKey.keys()].sort();
46
+ for (const key of keys) {
47
+ const names = ranked(this.candidatesByKey.get(key) ?? []).map(({ name: name2 }) => name2);
48
+ const name = names.find((candidate) => !taken.has(candidate)) ?? names[0];
49
+ if (name !== void 0) {
50
+ chosen.set(key, name);
51
+ taken.add(name);
52
+ }
53
+ }
54
+ return { nameOf: (key, name) => chosen.get(key) ?? name };
55
+ }
56
+ }
57
+
58
+ exports.FIRST_SCHEMA_NAMES = FIRST_SCHEMA_NAMES;
59
+ exports.SharedEnumNameRecorder = SharedEnumNameRecorder;
60
+ //# sourceMappingURL=shared-enum-names.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-enum-names.cjs","sources":["../../../../src/application/transform/footer/shared-enum-names.ts"],"sourcesContent":["import type { EnumDeclarationRequest } from \"../schema/schema-context.js\";\nimport { EnumNaming } from \"./enum-naming.js\";\n\n/**\n * How `--dedupe-enums` names the one enum that schemas with the same members share. `key` is the\n * dedupe key of the members; `name` is the name the schema gives with the run's naming state.\n */\nexport interface SharedEnumNames {\n /** Called for every schema of the enum, in document order; returns the name to declare. */\n nameOf(key: string, name: string, request: EnumDeclarationRequest): string;\n}\n\n/** The original: the enum takes the name of the first schema in the document. */\nexport const FIRST_SCHEMA_NAMES: SharedEnumNames = { nameOf: (_key, name) => name };\n\ninterface NameCandidate {\n readonly name: string;\n readonly isComponentSchema: boolean;\n}\n\n/**\n * Whether `candidate` names the enum better than `other`: a component schema that is the enum\n * itself, then the shorter name, then the earlier one in code-unit order. No part depends on the\n * document order, so adding or moving a schema changes the name only when the new one ranks first.\n */\nfunction isBetterName(candidate: NameCandidate, other: NameCandidate): boolean {\n if (candidate.isComponentSchema !== other.isComponentSchema) {\n return candidate.isComponentSchema;\n }\n if (candidate.name.length !== other.name.length) {\n return candidate.name.length < other.name.length;\n }\n return candidate.name < other.name;\n}\n\n/** The candidates from best to worst. */\nfunction ranked(candidates: readonly NameCandidate[]): NameCandidate[] {\n return [...candidates].sort((left, right) => {\n if (left.name === right.name && left.isComponentSchema === right.isComponentSchema) {\n return 0;\n }\n return isBetterName(left, right) ? -1 : 1;\n });\n}\n\n/**\n * The `dedupe-enum-names` fix (ADR-021, upstream #1683), first pass: records every schema of each\n * shared enum and keeps the run's own names. `chosenNames` gives the names for the second pass.\n */\nexport class SharedEnumNameRecorder implements SharedEnumNames {\n private readonly candidatesByKey = new Map<string, NameCandidate[]>();\n\n nameOf(key: string, name: string, request: EnumDeclarationRequest): string {\n // A fresh naming state: the run's state depends on the names built before (EnumNaming).\n const candidate = {\n name: new EnumNaming().enumName(request.name),\n isComponentSchema: request.isComponentSchema,\n };\n const candidates = this.candidatesByKey.get(key);\n if (candidates === undefined) {\n this.candidatesByKey.set(key, [candidate]);\n } else {\n candidates.push(candidate);\n }\n return name;\n }\n\n /**\n * The best name of each enum. Two enums whose best names are the same (two schemas that give\n * one name) are resolved in key order: the later one takes its next name that is free.\n */\n chosenNames(): SharedEnumNames {\n const chosen = new Map<string, string>();\n const taken = new Set<string>();\n const keys = [...this.candidatesByKey.keys()].sort();\n for (const key of keys) {\n const names = ranked(this.candidatesByKey.get(key) ?? []).map(({ name }) => name);\n const name = names.find((candidate) => !taken.has(candidate)) ?? names[0];\n if (name !== undefined) {\n chosen.set(key, name);\n taken.add(name);\n }\n }\n return { nameOf: (key, name) => chosen.get(key) ?? name };\n }\n}\n"],"names":["EnumNaming","name"],"mappings":";;;;AAaO,MAAM,qBAAsC,EAAE,MAAA,EAAQ,CAAC,IAAA,EAAM,SAAS,IAAA;AAY7E,SAAS,YAAA,CAAa,WAA0B,KAAA,EAA+B;AAC7E,EAAA,IAAI,SAAA,CAAU,iBAAA,KAAsB,KAAA,CAAM,iBAAA,EAAmB;AAC3D,IAAA,OAAO,SAAA,CAAU,iBAAA;AAAA,EACnB;AACA,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,MAAA,KAAW,KAAA,CAAM,KAAK,MAAA,EAAQ;AAC/C,IAAA,OAAO,SAAA,CAAU,IAAA,CAAK,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,MAAA;AAAA,EAC5C;AACA,EAAA,OAAO,SAAA,CAAU,OAAO,KAAA,CAAM,IAAA;AAChC;AAGA,SAAS,OAAO,UAAA,EAAuD;AACrE,EAAA,OAAO,CAAC,GAAG,UAAU,EAAE,IAAA,CAAK,CAAC,MAAM,KAAA,KAAU;AAC3C,IAAA,IAAI,KAAK,IAAA,KAAS,KAAA,CAAM,QAAQ,IAAA,CAAK,iBAAA,KAAsB,MAAM,iBAAA,EAAmB;AAClF,MAAA,OAAO,CAAA;AAAA,IACT;AACA,IAAA,OAAO,YAAA,CAAa,IAAA,EAAM,KAAK,CAAA,GAAI,EAAA,GAAK,CAAA;AAAA,EAC1C,CAAC,CAAA;AACH;AAMO,MAAM,sBAAA,CAAkD;AAAA,EAC5C,eAAA,uBAAsB,GAAA,EAA6B;AAAA,EAEpE,MAAA,CAAO,GAAA,EAAa,IAAA,EAAc,OAAA,EAAyC;AAEzE,IAAA,MAAM,SAAA,GAAY;AAAA,MAChB,MAAM,IAAIA,qBAAA,EAAW,CAAE,QAAA,CAAS,QAAQ,IAAI,CAAA;AAAA,MAC5C,mBAAmB,OAAA,CAAQ;AAAA,KAC7B;AACA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA;AAC/C,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAA,EAAK,CAAC,SAAS,CAAC,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,KAAK,SAAS,CAAA;AAAA,IAC3B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAA,GAA+B;AAC7B,IAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,IAAA,MAAM,IAAA,GAAO,CAAC,GAAG,IAAA,CAAK,gBAAgB,IAAA,EAAM,EAAE,IAAA,EAAK;AACnD,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA,IAAK,EAAE,CAAA,CAAE,IAAI,CAAC,EAAE,IAAA,EAAAC,KAAAA,OAAWA,KAAI,CAAA;AAChF,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,CAAC,SAAA,KAAc,CAAC,KAAA,CAAM,GAAA,CAAI,SAAS,CAAC,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA;AACxE,MAAA,IAAI,SAAS,MAAA,EAAW;AACtB,QAAA,MAAA,CAAO,GAAA,CAAI,KAAK,IAAI,CAAA;AACpB,QAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AAAA,MAChB;AAAA,IACF;AACA,IAAA,OAAO,EAAE,QAAQ,CAAC,GAAA,EAAK,SAAS,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,IAAK,IAAA,EAAK;AAAA,EAC1D;AACF;;;"}
@@ -0,0 +1,57 @@
1
+ import { EnumNaming } from './enum-naming.mjs';
2
+
3
+ const FIRST_SCHEMA_NAMES = { nameOf: (_key, name) => name };
4
+ function isBetterName(candidate, other) {
5
+ if (candidate.isComponentSchema !== other.isComponentSchema) {
6
+ return candidate.isComponentSchema;
7
+ }
8
+ if (candidate.name.length !== other.name.length) {
9
+ return candidate.name.length < other.name.length;
10
+ }
11
+ return candidate.name < other.name;
12
+ }
13
+ function ranked(candidates) {
14
+ return [...candidates].sort((left, right) => {
15
+ if (left.name === right.name && left.isComponentSchema === right.isComponentSchema) {
16
+ return 0;
17
+ }
18
+ return isBetterName(left, right) ? -1 : 1;
19
+ });
20
+ }
21
+ class SharedEnumNameRecorder {
22
+ candidatesByKey = /* @__PURE__ */ new Map();
23
+ nameOf(key, name, request) {
24
+ const candidate = {
25
+ name: new EnumNaming().enumName(request.name),
26
+ isComponentSchema: request.isComponentSchema
27
+ };
28
+ const candidates = this.candidatesByKey.get(key);
29
+ if (candidates === void 0) {
30
+ this.candidatesByKey.set(key, [candidate]);
31
+ } else {
32
+ candidates.push(candidate);
33
+ }
34
+ return name;
35
+ }
36
+ /**
37
+ * The best name of each enum. Two enums whose best names are the same (two schemas that give
38
+ * one name) are resolved in key order: the later one takes its next name that is free.
39
+ */
40
+ chosenNames() {
41
+ const chosen = /* @__PURE__ */ new Map();
42
+ const taken = /* @__PURE__ */ new Set();
43
+ const keys = [...this.candidatesByKey.keys()].sort();
44
+ for (const key of keys) {
45
+ const names = ranked(this.candidatesByKey.get(key) ?? []).map(({ name: name2 }) => name2);
46
+ const name = names.find((candidate) => !taken.has(candidate)) ?? names[0];
47
+ if (name !== void 0) {
48
+ chosen.set(key, name);
49
+ taken.add(name);
50
+ }
51
+ }
52
+ return { nameOf: (key, name) => chosen.get(key) ?? name };
53
+ }
54
+ }
55
+
56
+ export { FIRST_SCHEMA_NAMES, SharedEnumNameRecorder };
57
+ //# sourceMappingURL=shared-enum-names.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-enum-names.mjs","sources":["../../../../src/application/transform/footer/shared-enum-names.ts"],"sourcesContent":["import type { EnumDeclarationRequest } from \"../schema/schema-context.js\";\nimport { EnumNaming } from \"./enum-naming.js\";\n\n/**\n * How `--dedupe-enums` names the one enum that schemas with the same members share. `key` is the\n * dedupe key of the members; `name` is the name the schema gives with the run's naming state.\n */\nexport interface SharedEnumNames {\n /** Called for every schema of the enum, in document order; returns the name to declare. */\n nameOf(key: string, name: string, request: EnumDeclarationRequest): string;\n}\n\n/** The original: the enum takes the name of the first schema in the document. */\nexport const FIRST_SCHEMA_NAMES: SharedEnumNames = { nameOf: (_key, name) => name };\n\ninterface NameCandidate {\n readonly name: string;\n readonly isComponentSchema: boolean;\n}\n\n/**\n * Whether `candidate` names the enum better than `other`: a component schema that is the enum\n * itself, then the shorter name, then the earlier one in code-unit order. No part depends on the\n * document order, so adding or moving a schema changes the name only when the new one ranks first.\n */\nfunction isBetterName(candidate: NameCandidate, other: NameCandidate): boolean {\n if (candidate.isComponentSchema !== other.isComponentSchema) {\n return candidate.isComponentSchema;\n }\n if (candidate.name.length !== other.name.length) {\n return candidate.name.length < other.name.length;\n }\n return candidate.name < other.name;\n}\n\n/** The candidates from best to worst. */\nfunction ranked(candidates: readonly NameCandidate[]): NameCandidate[] {\n return [...candidates].sort((left, right) => {\n if (left.name === right.name && left.isComponentSchema === right.isComponentSchema) {\n return 0;\n }\n return isBetterName(left, right) ? -1 : 1;\n });\n}\n\n/**\n * The `dedupe-enum-names` fix (ADR-021, upstream #1683), first pass: records every schema of each\n * shared enum and keeps the run's own names. `chosenNames` gives the names for the second pass.\n */\nexport class SharedEnumNameRecorder implements SharedEnumNames {\n private readonly candidatesByKey = new Map<string, NameCandidate[]>();\n\n nameOf(key: string, name: string, request: EnumDeclarationRequest): string {\n // A fresh naming state: the run's state depends on the names built before (EnumNaming).\n const candidate = {\n name: new EnumNaming().enumName(request.name),\n isComponentSchema: request.isComponentSchema,\n };\n const candidates = this.candidatesByKey.get(key);\n if (candidates === undefined) {\n this.candidatesByKey.set(key, [candidate]);\n } else {\n candidates.push(candidate);\n }\n return name;\n }\n\n /**\n * The best name of each enum. Two enums whose best names are the same (two schemas that give\n * one name) are resolved in key order: the later one takes its next name that is free.\n */\n chosenNames(): SharedEnumNames {\n const chosen = new Map<string, string>();\n const taken = new Set<string>();\n const keys = [...this.candidatesByKey.keys()].sort();\n for (const key of keys) {\n const names = ranked(this.candidatesByKey.get(key) ?? []).map(({ name }) => name);\n const name = names.find((candidate) => !taken.has(candidate)) ?? names[0];\n if (name !== undefined) {\n chosen.set(key, name);\n taken.add(name);\n }\n }\n return { nameOf: (key, name) => chosen.get(key) ?? name };\n }\n}\n"],"names":["name"],"mappings":";;AAaO,MAAM,qBAAsC,EAAE,MAAA,EAAQ,CAAC,IAAA,EAAM,SAAS,IAAA;AAY7E,SAAS,YAAA,CAAa,WAA0B,KAAA,EAA+B;AAC7E,EAAA,IAAI,SAAA,CAAU,iBAAA,KAAsB,KAAA,CAAM,iBAAA,EAAmB;AAC3D,IAAA,OAAO,SAAA,CAAU,iBAAA;AAAA,EACnB;AACA,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,MAAA,KAAW,KAAA,CAAM,KAAK,MAAA,EAAQ;AAC/C,IAAA,OAAO,SAAA,CAAU,IAAA,CAAK,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,MAAA;AAAA,EAC5C;AACA,EAAA,OAAO,SAAA,CAAU,OAAO,KAAA,CAAM,IAAA;AAChC;AAGA,SAAS,OAAO,UAAA,EAAuD;AACrE,EAAA,OAAO,CAAC,GAAG,UAAU,EAAE,IAAA,CAAK,CAAC,MAAM,KAAA,KAAU;AAC3C,IAAA,IAAI,KAAK,IAAA,KAAS,KAAA,CAAM,QAAQ,IAAA,CAAK,iBAAA,KAAsB,MAAM,iBAAA,EAAmB;AAClF,MAAA,OAAO,CAAA;AAAA,IACT;AACA,IAAA,OAAO,YAAA,CAAa,IAAA,EAAM,KAAK,CAAA,GAAI,EAAA,GAAK,CAAA;AAAA,EAC1C,CAAC,CAAA;AACH;AAMO,MAAM,sBAAA,CAAkD;AAAA,EAC5C,eAAA,uBAAsB,GAAA,EAA6B;AAAA,EAEpE,MAAA,CAAO,GAAA,EAAa,IAAA,EAAc,OAAA,EAAyC;AAEzE,IAAA,MAAM,SAAA,GAAY;AAAA,MAChB,MAAM,IAAI,UAAA,EAAW,CAAE,QAAA,CAAS,QAAQ,IAAI,CAAA;AAAA,MAC5C,mBAAmB,OAAA,CAAQ;AAAA,KAC7B;AACA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA;AAC/C,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAA,EAAK,CAAC,SAAS,CAAC,CAAA;AAAA,IAC3C,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,KAAK,SAAS,CAAA;AAAA,IAC3B;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAA,GAA+B;AAC7B,IAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,IAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,IAAA,MAAM,IAAA,GAAO,CAAC,GAAG,IAAA,CAAK,gBAAgB,IAAA,EAAM,EAAE,IAAA,EAAK;AACnD,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA,IAAK,EAAE,CAAA,CAAE,IAAI,CAAC,EAAE,IAAA,EAAAA,KAAAA,OAAWA,KAAI,CAAA;AAChF,MAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,CAAC,SAAA,KAAc,CAAC,KAAA,CAAM,GAAA,CAAI,SAAS,CAAC,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA;AACxE,MAAA,IAAI,SAAS,MAAA,EAAW;AACtB,QAAA,MAAA,CAAO,GAAA,CAAI,KAAK,IAAI,CAAA;AACpB,QAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AAAA,MAChB;AAAA,IACF;AACA,IAAA,OAAO,EAAE,QAAQ,CAAC,GAAA,EAAK,SAAS,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,IAAK,IAAA,EAAK;AAAA,EAC1D;AACF;;"}
@@ -0,0 +1,138 @@
1
+ 'use strict';
2
+
3
+ const evaluation = require('./evaluation.cjs');
4
+ const typeIndexing = require('./type-indexing.cjs');
5
+ const typeRules = require('./type-rules.cjs');
6
+
7
+ const MAX_EXPANSIONS = 200;
8
+ const DEEP_PREFIX = "FlattenedDeepRequired<";
9
+ const MAX_DISTRIBUTED = 64;
10
+ class TypeEvaluator {
11
+ declared = /* @__PURE__ */ new Map();
12
+ expansions = 0;
13
+ constructor(declarations) {
14
+ for (const declaration of declarations) {
15
+ if (declaration.kind === "interface") {
16
+ this.declared.set(declaration.name, { kind: "object", members: declaration.members });
17
+ } else if (declaration.kind === "typeAlias") {
18
+ this.declared.set(declaration.name, declaration.type);
19
+ }
20
+ }
21
+ }
22
+ /** Evaluate a type written in the footer; the expansion budget starts again. */
23
+ evaluate(type) {
24
+ this.expansions = 0;
25
+ return this.expand({ kind: "type", type, deep: false });
26
+ }
27
+ /** The type with references, `readonly` and indexed access resolved at the top. */
28
+ expand(value) {
29
+ const { type } = value;
30
+ switch (type.kind) {
31
+ case "readonly":
32
+ return this.expand({ ...value, type: type.type });
33
+ case "indexedAccess":
34
+ return this.indexedAccess(value, type.object, type.index);
35
+ case "reference":
36
+ return this.reference(value, type.name, type.typeArguments);
37
+ case "raw":
38
+ case "tuple":
39
+ return evaluation.OPAQUE;
40
+ default:
41
+ return value;
42
+ }
43
+ }
44
+ indexedAccess(value, object, index) {
45
+ const owner = this.expand({ ...value, type: object });
46
+ return owner.kind === "type" ? this.index(owner, index) : owner;
47
+ }
48
+ reference(value, name, args) {
49
+ if (this.expansions++ > MAX_EXPANSIONS) {
50
+ return evaluation.OPAQUE;
51
+ }
52
+ if (name.startsWith(DEEP_PREFIX) && name.endsWith(">")) {
53
+ const root = this.declared.get(name.slice(DEEP_PREFIX.length, -1));
54
+ return root === void 0 ? evaluation.OPAQUE : this.expand({ kind: "type", type: root, deep: true });
55
+ }
56
+ const declared = args.length === 0 ? this.declared.get(name) : void 0;
57
+ if (declared !== void 0) {
58
+ return this.expand({ ...value, type: declared });
59
+ }
60
+ const [first, second] = args;
61
+ if (first === void 0) {
62
+ return evaluation.OPAQUE;
63
+ }
64
+ const argument = this.expand({ ...value, type: first });
65
+ if (argument.kind !== "type") {
66
+ return argument;
67
+ }
68
+ return this.helper(name, argument, second);
69
+ }
70
+ helper(name, argument, second) {
71
+ switch (name) {
72
+ case "NonNullable":
73
+ return this.withoutNullish(argument);
74
+ case "WithRequired":
75
+ case "Readonly":
76
+ return argument;
77
+ case "Extract":
78
+ return second === void 0 ? evaluation.OPAQUE : this.extract(argument, second);
79
+ case "Omit":
80
+ return second === void 0 ? evaluation.OPAQUE : typeRules.omitted(this, argument, second);
81
+ default:
82
+ return typeRules.markerObject(name, argument) ?? evaluation.OPAQUE;
83
+ }
84
+ }
85
+ /**
86
+ * The members of a union, each expanded; an intersection with unions in it is distributed over
87
+ * them (`A & (B | C)` is `(A & B) | (A & C)`), as TypeScript normalizes it. A type that is not a
88
+ * union is its only member. A union with an `any` or `unknown` member is that keyword alone.
89
+ */
90
+ membersOf(value) {
91
+ const expanded = this.expand(value);
92
+ if (expanded.kind !== "type") {
93
+ return [expanded];
94
+ }
95
+ const { type } = expanded;
96
+ if (type.kind === "union") {
97
+ return evaluation.absorbed(
98
+ type.types.flatMap((member) => this.membersOf({ ...expanded, type: member }))
99
+ );
100
+ }
101
+ return type.kind === "intersection" ? this.distributed(expanded, type.types) : [expanded];
102
+ }
103
+ distributed(value, parts) {
104
+ const memberLists = parts.map((part) => this.membersOf({ ...value, type: part }));
105
+ const size = memberLists.reduce((product, list) => product * list.length, 1);
106
+ if (size > MAX_DISTRIBUTED || memberLists.some((list) => list.some((m) => m.kind !== "type"))) {
107
+ return [evaluation.OPAQUE];
108
+ }
109
+ let combinations = [[]];
110
+ for (const list of memberLists) {
111
+ combinations = combinations.flatMap((done) => list.map((member) => [...done, member.type]));
112
+ }
113
+ return combinations.map((types) => ({ ...value, type: evaluation.intersectionType(types) }));
114
+ }
115
+ withoutNullish(value) {
116
+ const members = this.membersOf(value);
117
+ if (members.some((member) => member.kind !== "type")) {
118
+ return evaluation.OPAQUE;
119
+ }
120
+ const kept = members.filter((member) => !evaluation.isNullish(member.type));
121
+ return { ...value, type: evaluation.unionType(kept.map((member) => member.type)) };
122
+ }
123
+ /** `Extract<T, { key: unknown }>` keeps the members that have `key`; other probes are opaque. */
124
+ extract(value, probe) {
125
+ const [member] = probe.kind === "object" ? probe.members : [];
126
+ if (probe.kind !== "object" || probe.members.length !== 1 || member?.kind !== "property") {
127
+ return evaluation.OPAQUE;
128
+ }
129
+ return typeRules.extracted(this, value, evaluation.propertyKey(member.name));
130
+ }
131
+ /** `value[index]` for a string literal, `string` or `number` index. */
132
+ index(value, index) {
133
+ return typeIndexing.indexType(this, value, index);
134
+ }
135
+ }
136
+
137
+ exports.TypeEvaluator = TypeEvaluator;
138
+ //# sourceMappingURL=type-evaluation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-evaluation.cjs","sources":["../../../../src/application/transform/footer/type-evaluation.ts"],"sourcesContent":["import type { IrDeclaration, IrType } from \"../../../domain/ir/nodes.js\";\nimport {\n absorbed,\n type Evaluated,\n type Evaluation,\n intersectionType,\n isNullish,\n OPAQUE,\n propertyKey,\n unionType,\n} from \"./evaluation.js\";\nimport { indexType } from \"./type-indexing.js\";\nimport { extracted, markerObject, omitted } from \"./type-rules.js\";\n\n/**\n * A small evaluator of the generated types, as TypeScript reads them, for the `--enum-values`\n * check (ADR-027). It follows the declarations of the document and the helper types the generator\n * writes (`NonNullable`, `Extract`, `WithRequired`, `Omit`, `Record`, `FlattenedDeepRequired`). Its\n * answers are sure: a key is `missing` only where TypeScript reports it, and every type it does\n * not model is `opaque`, which never counts as an error.\n */\n\n/** How many references one evaluation expands; a deeper one is opaque. */\nconst MAX_EXPANSIONS = 200;\nconst DEEP_PREFIX = \"FlattenedDeepRequired<\";\n/** How many members distributing an intersection may give; more is opaque. */\nconst MAX_DISTRIBUTED = 64;\n\nexport class TypeEvaluator {\n private readonly declared = new Map<string, IrType>();\n private expansions = 0;\n\n constructor(declarations: readonly IrDeclaration[]) {\n for (const declaration of declarations) {\n if (declaration.kind === \"interface\") {\n this.declared.set(declaration.name, { kind: \"object\", members: declaration.members });\n } else if (declaration.kind === \"typeAlias\") {\n this.declared.set(declaration.name, declaration.type);\n }\n }\n }\n\n /** Evaluate a type written in the footer; the expansion budget starts again. */\n evaluate(type: IrType): Evaluation {\n this.expansions = 0;\n return this.expand({ kind: \"type\", type, deep: false });\n }\n\n /** The type with references, `readonly` and indexed access resolved at the top. */\n expand(value: Evaluated): Evaluation {\n const { type } = value;\n switch (type.kind) {\n case \"readonly\":\n return this.expand({ ...value, type: type.type });\n case \"indexedAccess\":\n return this.indexedAccess(value, type.object, type.index);\n case \"reference\":\n return this.reference(value, type.name, type.typeArguments);\n case \"raw\":\n case \"tuple\":\n return OPAQUE;\n default:\n return value;\n }\n }\n\n private indexedAccess(value: Evaluated, object: IrType, index: IrType): Evaluation {\n const owner = this.expand({ ...value, type: object });\n return owner.kind === \"type\" ? this.index(owner, index) : owner;\n }\n\n private reference(value: Evaluated, name: string, args: readonly IrType[]): Evaluation {\n // Only references cost budget: re-expanding an already expanded value (as the checks after\n // `evaluate` do) is free, so a large evaluation does not leave its checks opaque.\n if (this.expansions++ > MAX_EXPANSIONS) {\n return OPAQUE;\n }\n if (name.startsWith(DEEP_PREFIX) && name.endsWith(\">\")) {\n const root = this.declared.get(name.slice(DEEP_PREFIX.length, -1));\n return root === undefined ? OPAQUE : this.expand({ kind: \"type\", type: root, deep: true });\n }\n const declared = args.length === 0 ? this.declared.get(name) : undefined;\n if (declared !== undefined) {\n return this.expand({ ...value, type: declared });\n }\n const [first, second] = args;\n if (first === undefined) {\n return OPAQUE;\n }\n const argument = this.expand({ ...value, type: first });\n if (argument.kind !== \"type\") {\n return argument;\n }\n return this.helper(name, argument, second);\n }\n\n private helper(name: string, argument: Evaluated, second: IrType | undefined): Evaluation {\n switch (name) {\n case \"NonNullable\":\n return this.withoutNullish(argument);\n case \"WithRequired\":\n case \"Readonly\":\n return argument;\n case \"Extract\":\n return second === undefined ? OPAQUE : this.extract(argument, second);\n case \"Omit\":\n return second === undefined ? OPAQUE : omitted(this, argument, second);\n default:\n return markerObject(name, argument) ?? OPAQUE;\n }\n }\n\n /**\n * The members of a union, each expanded; an intersection with unions in it is distributed over\n * them (`A & (B | C)` is `(A & B) | (A & C)`), as TypeScript normalizes it. A type that is not a\n * union is its only member. A union with an `any` or `unknown` member is that keyword alone.\n */\n membersOf(value: Evaluated): readonly Evaluation[] {\n const expanded = this.expand(value);\n if (expanded.kind !== \"type\") {\n return [expanded];\n }\n const { type } = expanded;\n if (type.kind === \"union\") {\n return absorbed(\n type.types.flatMap((member) => this.membersOf({ ...expanded, type: member })),\n );\n }\n return type.kind === \"intersection\" ? this.distributed(expanded, type.types) : [expanded];\n }\n\n private distributed(value: Evaluated, parts: readonly IrType[]): readonly Evaluation[] {\n const memberLists = parts.map((part) => this.membersOf({ ...value, type: part }));\n const size = memberLists.reduce((product, list) => product * list.length, 1);\n if (size > MAX_DISTRIBUTED || memberLists.some((list) => list.some((m) => m.kind !== \"type\"))) {\n return [OPAQUE];\n }\n let combinations: IrType[][] = [[]];\n for (const list of memberLists as Evaluated[][]) {\n combinations = combinations.flatMap((done) => list.map((member) => [...done, member.type]));\n }\n return combinations.map((types) => ({ ...value, type: intersectionType(types) }));\n }\n\n private withoutNullish(value: Evaluated): Evaluation {\n const members = this.membersOf(value);\n if (members.some((member) => member.kind !== \"type\")) {\n return OPAQUE;\n }\n const kept = (members as Evaluated[]).filter((member) => !isNullish(member.type));\n return { ...value, type: unionType(kept.map((member) => member.type)) };\n }\n\n /** `Extract<T, { key: unknown }>` keeps the members that have `key`; other probes are opaque. */\n private extract(value: Evaluated, probe: IrType): Evaluation {\n const [member] = probe.kind === \"object\" ? probe.members : [];\n if (probe.kind !== \"object\" || probe.members.length !== 1 || member?.kind !== \"property\") {\n return OPAQUE;\n }\n return extracted(this, value, propertyKey(member.name));\n }\n\n /** `value[index]` for a string literal, `string` or `number` index. */\n index(value: Evaluated, index: IrType): Evaluation {\n return indexType(this, value, index);\n }\n}\n"],"names":["OPAQUE","omitted","markerObject","absorbed","intersectionType","isNullish","unionType","extracted","propertyKey","indexType"],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import { OPAQUE, absorbed, intersectionType, isNullish, unionType, propertyKey } from './evaluation.mjs';
2
+ import { indexType } from './type-indexing.mjs';
3
+ import { markerObject, omitted, extracted } from './type-rules.mjs';
4
+
5
+ const MAX_EXPANSIONS = 200;
6
+ const DEEP_PREFIX = "FlattenedDeepRequired<";
7
+ const MAX_DISTRIBUTED = 64;
8
+ class TypeEvaluator {
9
+ declared = /* @__PURE__ */ new Map();
10
+ expansions = 0;
11
+ constructor(declarations) {
12
+ for (const declaration of declarations) {
13
+ if (declaration.kind === "interface") {
14
+ this.declared.set(declaration.name, { kind: "object", members: declaration.members });
15
+ } else if (declaration.kind === "typeAlias") {
16
+ this.declared.set(declaration.name, declaration.type);
17
+ }
18
+ }
19
+ }
20
+ /** Evaluate a type written in the footer; the expansion budget starts again. */
21
+ evaluate(type) {
22
+ this.expansions = 0;
23
+ return this.expand({ kind: "type", type, deep: false });
24
+ }
25
+ /** The type with references, `readonly` and indexed access resolved at the top. */
26
+ expand(value) {
27
+ const { type } = value;
28
+ switch (type.kind) {
29
+ case "readonly":
30
+ return this.expand({ ...value, type: type.type });
31
+ case "indexedAccess":
32
+ return this.indexedAccess(value, type.object, type.index);
33
+ case "reference":
34
+ return this.reference(value, type.name, type.typeArguments);
35
+ case "raw":
36
+ case "tuple":
37
+ return OPAQUE;
38
+ default:
39
+ return value;
40
+ }
41
+ }
42
+ indexedAccess(value, object, index) {
43
+ const owner = this.expand({ ...value, type: object });
44
+ return owner.kind === "type" ? this.index(owner, index) : owner;
45
+ }
46
+ reference(value, name, args) {
47
+ if (this.expansions++ > MAX_EXPANSIONS) {
48
+ return OPAQUE;
49
+ }
50
+ if (name.startsWith(DEEP_PREFIX) && name.endsWith(">")) {
51
+ const root = this.declared.get(name.slice(DEEP_PREFIX.length, -1));
52
+ return root === void 0 ? OPAQUE : this.expand({ kind: "type", type: root, deep: true });
53
+ }
54
+ const declared = args.length === 0 ? this.declared.get(name) : void 0;
55
+ if (declared !== void 0) {
56
+ return this.expand({ ...value, type: declared });
57
+ }
58
+ const [first, second] = args;
59
+ if (first === void 0) {
60
+ return OPAQUE;
61
+ }
62
+ const argument = this.expand({ ...value, type: first });
63
+ if (argument.kind !== "type") {
64
+ return argument;
65
+ }
66
+ return this.helper(name, argument, second);
67
+ }
68
+ helper(name, argument, second) {
69
+ switch (name) {
70
+ case "NonNullable":
71
+ return this.withoutNullish(argument);
72
+ case "WithRequired":
73
+ case "Readonly":
74
+ return argument;
75
+ case "Extract":
76
+ return second === void 0 ? OPAQUE : this.extract(argument, second);
77
+ case "Omit":
78
+ return second === void 0 ? OPAQUE : omitted(this, argument, second);
79
+ default:
80
+ return markerObject(name, argument) ?? OPAQUE;
81
+ }
82
+ }
83
+ /**
84
+ * The members of a union, each expanded; an intersection with unions in it is distributed over
85
+ * them (`A & (B | C)` is `(A & B) | (A & C)`), as TypeScript normalizes it. A type that is not a
86
+ * union is its only member. A union with an `any` or `unknown` member is that keyword alone.
87
+ */
88
+ membersOf(value) {
89
+ const expanded = this.expand(value);
90
+ if (expanded.kind !== "type") {
91
+ return [expanded];
92
+ }
93
+ const { type } = expanded;
94
+ if (type.kind === "union") {
95
+ return absorbed(
96
+ type.types.flatMap((member) => this.membersOf({ ...expanded, type: member }))
97
+ );
98
+ }
99
+ return type.kind === "intersection" ? this.distributed(expanded, type.types) : [expanded];
100
+ }
101
+ distributed(value, parts) {
102
+ const memberLists = parts.map((part) => this.membersOf({ ...value, type: part }));
103
+ const size = memberLists.reduce((product, list) => product * list.length, 1);
104
+ if (size > MAX_DISTRIBUTED || memberLists.some((list) => list.some((m) => m.kind !== "type"))) {
105
+ return [OPAQUE];
106
+ }
107
+ let combinations = [[]];
108
+ for (const list of memberLists) {
109
+ combinations = combinations.flatMap((done) => list.map((member) => [...done, member.type]));
110
+ }
111
+ return combinations.map((types) => ({ ...value, type: intersectionType(types) }));
112
+ }
113
+ withoutNullish(value) {
114
+ const members = this.membersOf(value);
115
+ if (members.some((member) => member.kind !== "type")) {
116
+ return OPAQUE;
117
+ }
118
+ const kept = members.filter((member) => !isNullish(member.type));
119
+ return { ...value, type: unionType(kept.map((member) => member.type)) };
120
+ }
121
+ /** `Extract<T, { key: unknown }>` keeps the members that have `key`; other probes are opaque. */
122
+ extract(value, probe) {
123
+ const [member] = probe.kind === "object" ? probe.members : [];
124
+ if (probe.kind !== "object" || probe.members.length !== 1 || member?.kind !== "property") {
125
+ return OPAQUE;
126
+ }
127
+ return extracted(this, value, propertyKey(member.name));
128
+ }
129
+ /** `value[index]` for a string literal, `string` or `number` index. */
130
+ index(value, index) {
131
+ return indexType(this, value, index);
132
+ }
133
+ }
134
+
135
+ export { TypeEvaluator };
136
+ //# sourceMappingURL=type-evaluation.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-evaluation.mjs","sources":["../../../../src/application/transform/footer/type-evaluation.ts"],"sourcesContent":["import type { IrDeclaration, IrType } from \"../../../domain/ir/nodes.js\";\nimport {\n absorbed,\n type Evaluated,\n type Evaluation,\n intersectionType,\n isNullish,\n OPAQUE,\n propertyKey,\n unionType,\n} from \"./evaluation.js\";\nimport { indexType } from \"./type-indexing.js\";\nimport { extracted, markerObject, omitted } from \"./type-rules.js\";\n\n/**\n * A small evaluator of the generated types, as TypeScript reads them, for the `--enum-values`\n * check (ADR-027). It follows the declarations of the document and the helper types the generator\n * writes (`NonNullable`, `Extract`, `WithRequired`, `Omit`, `Record`, `FlattenedDeepRequired`). Its\n * answers are sure: a key is `missing` only where TypeScript reports it, and every type it does\n * not model is `opaque`, which never counts as an error.\n */\n\n/** How many references one evaluation expands; a deeper one is opaque. */\nconst MAX_EXPANSIONS = 200;\nconst DEEP_PREFIX = \"FlattenedDeepRequired<\";\n/** How many members distributing an intersection may give; more is opaque. */\nconst MAX_DISTRIBUTED = 64;\n\nexport class TypeEvaluator {\n private readonly declared = new Map<string, IrType>();\n private expansions = 0;\n\n constructor(declarations: readonly IrDeclaration[]) {\n for (const declaration of declarations) {\n if (declaration.kind === \"interface\") {\n this.declared.set(declaration.name, { kind: \"object\", members: declaration.members });\n } else if (declaration.kind === \"typeAlias\") {\n this.declared.set(declaration.name, declaration.type);\n }\n }\n }\n\n /** Evaluate a type written in the footer; the expansion budget starts again. */\n evaluate(type: IrType): Evaluation {\n this.expansions = 0;\n return this.expand({ kind: \"type\", type, deep: false });\n }\n\n /** The type with references, `readonly` and indexed access resolved at the top. */\n expand(value: Evaluated): Evaluation {\n const { type } = value;\n switch (type.kind) {\n case \"readonly\":\n return this.expand({ ...value, type: type.type });\n case \"indexedAccess\":\n return this.indexedAccess(value, type.object, type.index);\n case \"reference\":\n return this.reference(value, type.name, type.typeArguments);\n case \"raw\":\n case \"tuple\":\n return OPAQUE;\n default:\n return value;\n }\n }\n\n private indexedAccess(value: Evaluated, object: IrType, index: IrType): Evaluation {\n const owner = this.expand({ ...value, type: object });\n return owner.kind === \"type\" ? this.index(owner, index) : owner;\n }\n\n private reference(value: Evaluated, name: string, args: readonly IrType[]): Evaluation {\n // Only references cost budget: re-expanding an already expanded value (as the checks after\n // `evaluate` do) is free, so a large evaluation does not leave its checks opaque.\n if (this.expansions++ > MAX_EXPANSIONS) {\n return OPAQUE;\n }\n if (name.startsWith(DEEP_PREFIX) && name.endsWith(\">\")) {\n const root = this.declared.get(name.slice(DEEP_PREFIX.length, -1));\n return root === undefined ? OPAQUE : this.expand({ kind: \"type\", type: root, deep: true });\n }\n const declared = args.length === 0 ? this.declared.get(name) : undefined;\n if (declared !== undefined) {\n return this.expand({ ...value, type: declared });\n }\n const [first, second] = args;\n if (first === undefined) {\n return OPAQUE;\n }\n const argument = this.expand({ ...value, type: first });\n if (argument.kind !== \"type\") {\n return argument;\n }\n return this.helper(name, argument, second);\n }\n\n private helper(name: string, argument: Evaluated, second: IrType | undefined): Evaluation {\n switch (name) {\n case \"NonNullable\":\n return this.withoutNullish(argument);\n case \"WithRequired\":\n case \"Readonly\":\n return argument;\n case \"Extract\":\n return second === undefined ? OPAQUE : this.extract(argument, second);\n case \"Omit\":\n return second === undefined ? OPAQUE : omitted(this, argument, second);\n default:\n return markerObject(name, argument) ?? OPAQUE;\n }\n }\n\n /**\n * The members of a union, each expanded; an intersection with unions in it is distributed over\n * them (`A & (B | C)` is `(A & B) | (A & C)`), as TypeScript normalizes it. A type that is not a\n * union is its only member. A union with an `any` or `unknown` member is that keyword alone.\n */\n membersOf(value: Evaluated): readonly Evaluation[] {\n const expanded = this.expand(value);\n if (expanded.kind !== \"type\") {\n return [expanded];\n }\n const { type } = expanded;\n if (type.kind === \"union\") {\n return absorbed(\n type.types.flatMap((member) => this.membersOf({ ...expanded, type: member })),\n );\n }\n return type.kind === \"intersection\" ? this.distributed(expanded, type.types) : [expanded];\n }\n\n private distributed(value: Evaluated, parts: readonly IrType[]): readonly Evaluation[] {\n const memberLists = parts.map((part) => this.membersOf({ ...value, type: part }));\n const size = memberLists.reduce((product, list) => product * list.length, 1);\n if (size > MAX_DISTRIBUTED || memberLists.some((list) => list.some((m) => m.kind !== \"type\"))) {\n return [OPAQUE];\n }\n let combinations: IrType[][] = [[]];\n for (const list of memberLists as Evaluated[][]) {\n combinations = combinations.flatMap((done) => list.map((member) => [...done, member.type]));\n }\n return combinations.map((types) => ({ ...value, type: intersectionType(types) }));\n }\n\n private withoutNullish(value: Evaluated): Evaluation {\n const members = this.membersOf(value);\n if (members.some((member) => member.kind !== \"type\")) {\n return OPAQUE;\n }\n const kept = (members as Evaluated[]).filter((member) => !isNullish(member.type));\n return { ...value, type: unionType(kept.map((member) => member.type)) };\n }\n\n /** `Extract<T, { key: unknown }>` keeps the members that have `key`; other probes are opaque. */\n private extract(value: Evaluated, probe: IrType): Evaluation {\n const [member] = probe.kind === \"object\" ? probe.members : [];\n if (probe.kind !== \"object\" || probe.members.length !== 1 || member?.kind !== \"property\") {\n return OPAQUE;\n }\n return extracted(this, value, propertyKey(member.name));\n }\n\n /** `value[index]` for a string literal, `string` or `number` index. */\n index(value: Evaluated, index: IrType): Evaluation {\n return indexType(this, value, index);\n }\n}\n"],"names":[],"mappings":"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"}