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":"paths.cjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { isCoveredPathItemRejected } from \"./path-item-conflicts.js\";\nimport {\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\n\nconst PATH_PARAMETER_RE = /\\{[^}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\n/** `${type}`: the text of a template literal type placeholder. */\nfunction placeholderText(type: PathPlaceholder): string {\n return `\\${${type}}`;\n}\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type. Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const matches = url.match(PATH_PARAMETER_RE);\n if (!matches) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const placeholders = matches.map((match) => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER;\n });\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = placeholders[index];\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\ninterface PathMember {\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object.\n */\nfunction pathsObjectType(paths: readonly PathMember[]): IrType {\n const covering = coveringTemplateKeys(\n paths.map(({ key }) => key),\n (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n isCoveredPathItemRejected(coveredPath.type, coveringPath.type)\n );\n },\n );\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The `paths` interface body (OpenAPI 3.1 §4.8.8): one member per path, by URL. */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return pathsObjectType(members);\n}\n"],"names":["pathItemOperations","escapeTemplateText","pathItem","pathItemType","createRef","member","irProperty","toPropertyName","irRaw","coveringTemplateKeys","isCoveredPathItemRejected","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":"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"}
1
+ {"version":3,"file":"paths.cjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\nconst PATH_PARAMETER_RE = /\\{[^}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["pathItemOperations","OutputFix","replacedTemplateParts","escapeTemplateText","placeholderText","pathItem","pathItemType","createRef","member","irProperty","toPropertyName","irRaw","assignabilityProof","NO_DECLARED_TYPES","coveringTemplateKeys","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":"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"}
@@ -1,14 +1,17 @@
1
- import { irProperty, irRaw, irObject, irIntersection } from '../../../domain/ir/constructors.mjs';
1
+ import { irObject, irIntersection, irProperty, irRaw } from '../../../domain/ir/constructors.mjs';
2
2
  import { toPropertyName } from '../../../domain/ir/property-name.mjs';
3
3
  import { escapeTemplateText } from '../../../domain/ir/raw-text-escapes.mjs';
4
4
  import { createRef } from '../../../domain/openapi/json-pointer.mjs';
5
5
  import { pathItemOperations } from '../../../domain/openapi/path-item-object.mjs';
6
+ import { OutputFix } from '../../../domain/output-fixes.mjs';
6
7
  import { documentEntries } from '../document-entries.mjs';
7
8
  import { refType } from '../ref-type.mjs';
9
+ import { NO_DECLARED_TYPES } from './declared-types.mjs';
8
10
  import { documentMember } from './document-member.mjs';
9
11
  import { pathItemType } from './path-item.mjs';
10
- import { isCoveredPathItemRejected } from './path-item-conflicts.mjs';
11
12
  import { coveringTemplateKeys } from './path-key-overlaps.mjs';
13
+ import { replacedTemplateParts, placeholderText } from './path-template-replace.mjs';
14
+ import { assignabilityProof } from './type-assignability.mjs';
12
15
 
13
16
  const PATH_PARAMETER_RE = /\{[^}]+\}/g;
14
17
  const PLACEHOLDERS = /* @__PURE__ */ new Map([
@@ -17,9 +20,6 @@ const PLACEHOLDERS = /* @__PURE__ */ new Map([
17
20
  ["boolean", "boolean"]
18
21
  ]);
19
22
  const STRING_PLACEHOLDER = "string";
20
- function placeholderText(type) {
21
- return `\${${type}}`;
22
- }
23
23
  function resolvedParameter(parameter, context) {
24
24
  return "$ref" in parameter && parameter.$ref ? context.refs.resolve(parameter.$ref) : parameter;
25
25
  }
@@ -40,21 +40,24 @@ function pathParameters(pathItem, context) {
40
40
  }
41
41
  return byName;
42
42
  }
43
+ function splitTemplateParts(url, matches) {
44
+ return url.split(PATH_PARAMETER_RE).flatMap((text, index) => {
45
+ const type = matches[index]?.type;
46
+ const textPart = { kind: "text", text };
47
+ return type === void 0 ? [textPart] : [textPart, { kind: "placeholder", type }];
48
+ });
49
+ }
43
50
  function pathTemplateParts(url, pathItem, context) {
44
- const matches = url.match(PATH_PARAMETER_RE);
45
- if (!matches) {
51
+ const found = url.match(PATH_PARAMETER_RE);
52
+ if (!found) {
46
53
  return null;
47
54
  }
48
55
  const parameters = pathParameters(pathItem, context);
49
- const placeholders = matches.map((match) => {
56
+ const matches = found.map((match) => {
50
57
  const schema = parameters.get(match.slice(1, -1))?.schema;
51
- return PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER;
52
- });
53
- return url.split(PATH_PARAMETER_RE).flatMap((text, index) => {
54
- const type = placeholders[index];
55
- const textPart = { kind: "text", text };
56
- return type === void 0 ? [textPart] : [textPart, { kind: "placeholder", type }];
58
+ return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
57
59
  });
60
+ return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : replacedTemplateParts(url, matches);
58
61
  }
59
62
  function templateText(parts) {
60
63
  const text = parts.map(
@@ -68,7 +71,7 @@ function pathItemMember(url, pathItem, context) {
68
71
  const parts = context.options.pathParamsAsTypes && url.includes("{") ? pathTemplateParts(url, pathItem, context) : null;
69
72
  if (parts === null) {
70
73
  const member2 = irProperty(toPropertyName(url), type, { isReadonly });
71
- return { member: member2, key: literalKey(url), type };
74
+ return { url, member: member2, key: literalKey(url), type };
72
75
  }
73
76
  const member = {
74
77
  kind: "indexSignature",
@@ -78,20 +81,38 @@ function pathItemMember(url, pathItem, context) {
78
81
  isReadonly,
79
82
  comments: []
80
83
  };
81
- return { member, key: { kind: "template", parts }, type };
84
+ return { url, member, key: { kind: "template", parts }, type };
82
85
  }
83
86
  function literalKey(url) {
84
87
  return { kind: "literal", url };
85
88
  }
86
- function pathsObjectType(paths) {
87
- const covering = coveringTemplateKeys(
88
- paths.map(({ key }) => key),
89
- (coveringIndex, coveredIndex) => {
90
- const coveringPath = paths[coveringIndex];
91
- const coveredPath = paths[coveredIndex];
92
- return coveringPath !== void 0 && coveredPath !== void 0 && isCoveredPathItemRejected(coveredPath.type, coveringPath.type);
93
- }
94
- );
89
+ const PATHS_TYPE_NAME = "paths";
90
+ function pathsIndexOf(type) {
91
+ if (type.kind !== "indexedAccess" || type.index.kind !== "stringLiteral") {
92
+ return null;
93
+ }
94
+ const { object } = type;
95
+ const isPaths = object.kind === "reference" && object.name === PATHS_TYPE_NAME && object.typeArguments.length === 0;
96
+ return isPaths ? type.index.value : null;
97
+ }
98
+ function withPathItems(paths, lookup) {
99
+ const byUrl = new Map(paths.map((path) => [path.url, path.type]));
100
+ return (type) => {
101
+ const url = pathsIndexOf(type);
102
+ return (url === null ? void 0 : byUrl.get(url)) ?? lookup(type);
103
+ };
104
+ }
105
+ function rejectionOf(paths, lookup) {
106
+ const relate = assignabilityProof(withPathItems(paths, lookup));
107
+ return (coveringIndex, coveredIndex) => {
108
+ const coveringPath = paths[coveringIndex];
109
+ const coveredPath = paths[coveredIndex];
110
+ return coveringPath !== void 0 && coveredPath !== void 0 && relate(coveredPath.type, coveringPath.type) === "rejected";
111
+ };
112
+ }
113
+ function pathsObjectType(paths, lookup = NO_DECLARED_TYPES) {
114
+ const keys = paths.map(({ key }) => key);
115
+ const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));
95
116
  if (covering.size === 0) {
96
117
  return irObject(paths.map(({ member }) => member));
97
118
  }
@@ -99,7 +120,7 @@ function pathsObjectType(paths) {
99
120
  const own = paths.filter((_, index) => covering.has(index)).map(({ member }) => irObject([member]));
100
121
  return irIntersection([irObject(rest), ...own]);
101
122
  }
102
- function pathsType(paths, context) {
123
+ function pathMembers(paths, context) {
103
124
  const members = [];
104
125
  for (const [url, pathItem] of documentEntries(paths, context.options)) {
105
126
  if (!pathItem || typeof pathItem !== "object") {
@@ -108,7 +129,7 @@ function pathsType(paths, context) {
108
129
  if ("$ref" in pathItem) {
109
130
  const options = { isReadonly: context.options.immutable };
110
131
  const member = documentMember(url, refType(pathItem.$ref), pathItem, options);
111
- members.push({ member, key: literalKey(url), type: member.type });
132
+ members.push({ url, member, key: literalKey(url), type: member.type });
112
133
  continue;
113
134
  }
114
135
  const startedAt = context.diagnostics.now();
@@ -118,8 +139,11 @@ function pathsType(paths, context) {
118
139
  context.diagnostics.debug(`Transformed path "${url}"`, context.diagnostics.now() - startedAt);
119
140
  }
120
141
  }
121
- return pathsObjectType(members);
142
+ return members;
143
+ }
144
+ function pathsType(paths, context) {
145
+ return pathsObjectType(pathMembers(paths, context));
122
146
  }
123
147
 
124
- export { pathsType };
148
+ export { pathMembers, pathsObjectType, pathsType };
125
149
  //# sourceMappingURL=paths.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.mjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport { isCoveredPathItemRejected } from \"./path-item-conflicts.js\";\nimport {\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\n\nconst PATH_PARAMETER_RE = /\\{[^}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\n/** `${type}`: the text of a template literal type placeholder. */\nfunction placeholderText(type: PathPlaceholder): string {\n return `\\${${type}}`;\n}\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type. Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const matches = url.match(PATH_PARAMETER_RE);\n if (!matches) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const placeholders = matches.map((match) => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER;\n });\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = placeholders[index];\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\ninterface PathMember {\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object.\n */\nfunction pathsObjectType(paths: readonly PathMember[]): IrType {\n const covering = coveringTemplateKeys(\n paths.map(({ key }) => key),\n (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n isCoveredPathItemRejected(coveredPath.type, coveringPath.type)\n );\n },\n );\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The `paths` interface body (OpenAPI 3.1 §4.8.8): one member per path, by URL. */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return pathsObjectType(members);\n}\n"],"names":["member"],"mappings":"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"}
1
+ {"version":3,"file":"paths.mjs","sources":["../../../../src/application/transform/document/paths.ts"],"sourcesContent":["import { irIntersection, irObject, irProperty, irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrMember, IrType } from \"../../../domain/ir/nodes.js\";\nimport { toPropertyName } from \"../../../domain/ir/property-name.js\";\nimport { escapeTemplateText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport { createRef } from \"../../../domain/openapi/json-pointer.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport type {\n ParameterObject,\n ParameterOrReference,\n} from \"../../../domain/openapi/parameter-object.js\";\nimport {\n type PathItemObject,\n type PathsObject,\n pathItemOperations,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport type { ReferenceSchema, SchemaObject } from \"../../../domain/openapi/schema-object.js\";\nimport { OutputFix } from \"../../../domain/output-fixes.js\";\nimport { documentEntries } from \"../document-entries.js\";\nimport { refType } from \"../ref-type.js\";\nimport type { TransformContext } from \"../transform-context.js\";\nimport { type DeclaredTypeLookup, NO_DECLARED_TYPES } from \"./declared-types.js\";\nimport { documentMember } from \"./document-member.js\";\nimport { pathItemType } from \"./path-item.js\";\nimport {\n type CoverRejection,\n coveringTemplateKeys,\n type PathKey,\n type PathKeyPart,\n type PathPlaceholder,\n} from \"./path-key-overlaps.js\";\nimport {\n type PathParameterMatch,\n placeholderText,\n replacedTemplateParts,\n} from \"./path-template-replace.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\n\nconst PATH_PARAMETER_RE = /\\{[^}]+\\}/g;\n\n/** Placeholders by parameter schema type; anything else is a string placeholder. */\nconst PLACEHOLDERS: ReadonlyMap<unknown, PathPlaceholder> = new Map([\n [\"number\", \"number\"],\n [\"integer\", \"number\"],\n [\"boolean\", \"boolean\"],\n]);\nconst STRING_PLACEHOLDER: PathPlaceholder = \"string\";\n\nfunction resolvedParameter(\n parameter: ParameterOrReference,\n context: TransformContext,\n): ParameterObject | undefined {\n return \"$ref\" in parameter && parameter.$ref\n ? (context.refs.resolve(parameter.$ref) as ParameterObject | undefined)\n : (parameter as ParameterObject);\n}\n\nfunction addPathParameters(\n parameters: readonly ParameterOrReference[],\n byName: Map<string, ParameterObject>,\n context: TransformContext,\n): void {\n for (const parameter of parameters) {\n const resolved = resolvedParameter(parameter, context);\n if (resolved && resolved.in === \"path\") {\n byName.set(resolved.name, resolved);\n }\n }\n}\n\n/** Path parameters of the path item and of its operations; later definitions win. */\nfunction pathParameters(\n pathItem: PathItemObject,\n context: TransformContext,\n): Map<string, ParameterObject> {\n const byName = new Map<string, ParameterObject>();\n addPathParameters(pathItem.parameters ?? [], byName, context);\n for (const { operation: entry } of pathItemOperations(pathItem)) {\n const operation = (entry as ReferenceSchema).$ref\n ? (context.refs.resolve((entry as ReferenceSchema).$ref) as OperationObject | undefined)\n : (entry as OperationObject);\n addPathParameters(operation?.parameters ?? [], byName, context);\n }\n return byName;\n}\n\n/** Each `{name}` of the URL and its own placeholder, from the URL split at the matches. */\nfunction splitTemplateParts(url: string, matches: readonly PathParameterMatch[]): PathKeyPart[] {\n return url.split(PATH_PARAMETER_RE).flatMap((text, index): PathKeyPart[] => {\n const type = matches[index]?.type;\n const textPart: PathKeyPart = { kind: \"text\", text };\n return type === undefined ? [textPart] : [textPart, { kind: \"placeholder\", type }];\n });\n}\n\n/**\n * `--path-params-as-types`: the URL as template parts, each `{name}` replaced by a placeholder for\n * its parameter's type, the way the original replaces them unless the `path-param-type-names` fix\n * is on (see `replacedTemplateParts`). Null when the URL has no complete `{…}` placeholder.\n */\nfunction pathTemplateParts(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathKeyPart[] | null {\n const found = url.match(PATH_PARAMETER_RE);\n if (!found) {\n return null;\n }\n const parameters = pathParameters(pathItem, context);\n const matches = found.map((match): PathParameterMatch => {\n const schema = parameters.get(match.slice(1, -1))?.schema as SchemaObject | undefined;\n return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };\n });\n return context.options.fixes.has(OutputFix.PATH_PARAM_TYPE_NAMES)\n ? splitTemplateParts(url, matches)\n : replacedTemplateParts(url, matches);\n}\n\n/**\n * The template literal type of the parts. The original escaped only backticks: a backslash or\n * `${` in the URL could end the literal or open a placeholder, and add code to the generated file\n * (intentional fix). So the text parts are escaped.\n */\nfunction templateText(parts: readonly PathKeyPart[]): string {\n const text = parts\n .map((part) =>\n part.kind === \"text\" ? escapeTemplateText(part.text) : placeholderText(part.type),\n )\n .join(\"\");\n return `\\`${text}\\``;\n}\n\n/** A path's member, its key and its path item type for the overlap check. */\nexport interface PathMember {\n readonly url: string;\n readonly member: IrMember;\n readonly key: PathKey;\n readonly type: IrType;\n}\n\nfunction pathItemMember(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember {\n const isReadonly = context.options.immutable;\n const type = pathItemType(pathItem, { path: createRef([\"paths\", url]) }, context);\n const parts =\n context.options.pathParamsAsTypes && url.includes(\"{\")\n ? pathTemplateParts(url, pathItem, context)\n : null;\n if (parts === null) {\n const member = irProperty(toPropertyName(url), type, { isReadonly });\n return { url, member, key: literalKey(url), type };\n }\n const member: IrMember = {\n kind: \"indexSignature\",\n parameterName: \"path\",\n parameterType: irRaw(templateText(parts)),\n type,\n isReadonly,\n comments: [],\n };\n return { url, member, key: { kind: \"template\", parts }, type };\n}\n\nfunction literalKey(url: string): PathKey {\n return { kind: \"literal\", url };\n}\n\nconst PATHS_TYPE_NAME = \"paths\";\n\n/** The URL of `paths[\"/apps/{id}\"]`, or null for any other type. */\nfunction pathsIndexOf(type: IrType): string | null {\n if (type.kind !== \"indexedAccess\" || type.index.kind !== \"stringLiteral\") {\n return null;\n }\n const { object } = type;\n const isPaths =\n object.kind === \"reference\" &&\n object.name === PATHS_TYPE_NAME &&\n object.typeArguments.length === 0;\n return isPaths ? type.index.value : null;\n}\n\n/**\n * The lookup, and `paths[\"/apps/{id}\"]` as that path's item. The declarations cannot read it: a\n * templated path is no property of `paths`, and TypeScript finds it through the signature.\n */\nfunction withPathItems(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup,\n): DeclaredTypeLookup {\n const byUrl = new Map(paths.map((path) => [path.url, path.type]));\n return (type) => {\n const url = pathsIndexOf(type);\n return (url === null ? undefined : byUrl.get(url)) ?? lookup(type);\n };\n}\n\n/**\n * The rejection of a covered path item: only one proven not assignable to the signature's type\n * counts (ADR-028). A pair the proof cannot decide keeps the original output, which may well\n * compile (`Record<string, never>` fits `{ [key: string]: unknown }`).\n */\nfunction rejectionOf(paths: readonly PathMember[], lookup: DeclaredTypeLookup): CoverRejection {\n const relate = assignabilityProof(withPathItems(paths, lookup));\n return (coveringIndex, coveredIndex) => {\n const coveringPath = paths[coveringIndex];\n const coveredPath = paths[coveredIndex];\n return (\n coveringPath !== undefined &&\n coveredPath !== undefined &&\n relate(coveredPath.type, coveringPath.type) === \"rejected\"\n );\n };\n}\n\n/**\n * The members as one object type. When an index signature covers another key, TypeScript checks\n * the covered key's type against it. Where that check surely fails (TS2411, TS2413), each such\n * signature gets an object of its own in an intersection: an intersection does not check its parts\n * against each other, and every key has the type it had in the one object. Output that compiles\n * keeps the one object. The lookup reads the types that path items reference; without it, a\n * reference decides nothing.\n */\nexport function pathsObjectType(\n paths: readonly PathMember[],\n lookup: DeclaredTypeLookup = NO_DECLARED_TYPES,\n): IrType {\n const keys = paths.map(({ key }) => key);\n const covering = coveringTemplateKeys(keys, rejectionOf(paths, lookup));\n if (covering.size === 0) {\n return irObject(paths.map(({ member }) => member));\n }\n const rest = paths.filter((_, index) => !covering.has(index)).map(({ member }) => member);\n const own = paths\n .filter((_, index) => covering.has(index))\n .map(({ member }) => irObject([member]));\n return irIntersection([irObject(rest), ...own]);\n}\n\n/** The members of the `paths` interface (OpenAPI 3.1 §4.8.8): one per path, by URL. */\nexport function pathMembers(paths: PathsObject, context: TransformContext): PathMember[] {\n const members: PathMember[] = [];\n for (const [url, pathItem] of documentEntries(paths, context.options)) {\n if (!pathItem || typeof pathItem !== \"object\") {\n continue;\n }\n if (\"$ref\" in pathItem) {\n const options = { isReadonly: context.options.immutable };\n const member = documentMember(url, refType(pathItem.$ref), pathItem, options);\n members.push({ url, member, key: literalKey(url), type: member.type });\n continue;\n }\n const startedAt = context.diagnostics.now();\n const path = pathItemMember(url, pathItem, context);\n members.push(path);\n // The original reports only paths written as properties.\n if (path.member.kind === \"property\") {\n context.diagnostics.debug(`Transformed path \"${url}\"`, context.diagnostics.now() - startedAt);\n }\n }\n return members;\n}\n\n/**\n * The `paths` interface body, with only the path items' own types for the overlap check. The\n * document transform checks the overlaps again once the referenced types are declared.\n */\nexport function pathsType(paths: PathsObject, context: TransformContext): IrType {\n return pathsObjectType(pathMembers(paths, context));\n}\n"],"names":["member"],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
 
3
3
  const constructors = require('../../../domain/ir/constructors.cjs');
4
4
  const rawTextEscapes = require('../../../domain/ir/raw-text-escapes.cjs');
5
+ const globalTypeReferences = require('./global-type-references.cjs');
5
6
 
6
7
  const REFERENCE_PREFIX = "components['";
7
8
  function rootTypeAlias(name, kind, item) {
@@ -42,19 +43,20 @@ function freeName(name, taken) {
42
43
  }
43
44
  return candidate;
44
45
  }
45
- function numberDisplacedAliases(displaced, kept) {
46
- const taken = new Set(kept.map((alias) => alias.name));
47
- return displaced.map((alias) => {
48
- const name = freeName(alias.name, taken);
49
- taken.add(name);
50
- return { ...alias, name };
51
- });
52
- }
53
- function renameAliasesTakenByFooter(body, footer) {
54
- const footerNames = footerTypeNames(footer);
55
- const taken = declaredNames([...body, ...footer]);
46
+ function renameTakenAliases(body, footer, closing = []) {
47
+ const reserved = footerTypeNames(footer);
48
+ for (const name of globalTypeReferences.globalTypeReferences([...body, ...footer, ...closing])) {
49
+ reserved.add(name);
50
+ }
51
+ const taken = declaredNames([...body, ...footer, ...closing]);
52
+ const aliasNames = /* @__PURE__ */ new Set();
56
53
  return body.map((declaration) => {
57
- if (!isRootTypeAlias(declaration) || !footerNames.has(declaration.name)) {
54
+ if (!isRootTypeAlias(declaration)) {
55
+ return declaration;
56
+ }
57
+ const isRepeated = aliasNames.has(declaration.name);
58
+ aliasNames.add(declaration.name);
59
+ if (!isRepeated && !reserved.has(declaration.name)) {
58
60
  return declaration;
59
61
  }
60
62
  const name = freeName(declaration.name, taken);
@@ -63,7 +65,6 @@ function renameAliasesTakenByFooter(body, footer) {
63
65
  });
64
66
  }
65
67
 
66
- exports.numberDisplacedAliases = numberDisplacedAliases;
67
- exports.renameAliasesTakenByFooter = renameAliasesTakenByFooter;
68
+ exports.renameTakenAliases = renameTakenAliases;
68
69
  exports.rootTypeAlias = rootTypeAlias;
69
70
  //# sourceMappingURL=root-type-aliases.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-type-aliases.cjs","sources":["../../../../src/application/transform/document/root-type-aliases.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration, IrTypeAliasDeclaration } from \"../../../domain/ir/nodes.js\";\nimport { escapeSingleQuotedText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport type { ComponentKind } from \"../../../domain/openapi/components-object.js\";\n\n/** The `--root-types` aliases: `export type Pet = components['schemas']['Pet'];`. */\n\nconst REFERENCE_PREFIX = \"components['\";\n\n/** The alias of one component. */\nexport function rootTypeAlias(\n name: string,\n kind: ComponentKind,\n item: string,\n): IrTypeAliasDeclaration {\n return {\n kind: \"typeAlias\",\n name,\n isExported: true,\n // The original writes the reference as text, with single quotes, and did not escape the\n // name: a quote in it could add code to the generated file (intentional fix).\n type: irRaw(`${REFERENCE_PREFIX}${kind}']['${escapeSingleQuotedText(item)}']`),\n comments: [],\n };\n}\n\nfunction isRootTypeAlias(declaration: IrDeclaration): declaration is IrTypeAliasDeclaration {\n return (\n declaration.kind === \"typeAlias\" &&\n declaration.type.kind === \"raw\" &&\n declaration.type.text.startsWith(REFERENCE_PREFIX)\n );\n}\n\n/**\n * The type names the footer declares that an alias must not take: enums, and helper types such as\n * `WithRequired`. Value declarations (`--enum-values` arrays) live in another namespace.\n */\nfunction footerTypeNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) => {\n if (declaration.kind === \"enum\") {\n return [declaration.name];\n }\n return declaration.kind === \"rawDeclaration\" && declaration.name !== undefined\n ? [declaration.name]\n : [];\n }),\n );\n}\n\nfunction declaredNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) =>\n \"name\" in declaration && declaration.name !== undefined ? [declaration.name] : [],\n ),\n );\n}\n\nfunction freeName(name: string, taken: ReadonlySet<string>): string {\n let candidate = `${name}_2`;\n for (let counter = 3; taken.has(candidate); counter++) {\n candidate = `${name}_${counter}`;\n }\n return candidate;\n}\n\n/**\n * With the `root-type-numbering` fix (ADR-021, roadmap R13, backlog 30): the aliases that a later\n * schema of one exported name took the name from, numbered `Name_2`, `Name_3`, … in document order\n * with the next free number. The later schema keeps the name, so the fix only adds exports.\n */\nexport function numberDisplacedAliases(\n displaced: readonly IrTypeAliasDeclaration[],\n kept: readonly IrTypeAliasDeclaration[],\n): IrTypeAliasDeclaration[] {\n const taken = new Set(kept.map((alias) => alias.name));\n return displaced.map((alias) => {\n const name = freeName(alias.name, taken);\n taken.add(name);\n return { ...alias, name };\n });\n}\n\n/**\n * Rename each root alias whose name an enum or a helper type of the footer also declares, to the\n * next free `Name_2`, `Name_3`, … (the suffix `--root-types` uses for its own conflicts). The\n * footer keeps its names, because the generated types refer to them. Before, both were declared\n * under one name, which does not compile (enums: upstream #2099, #2341, #2206; helpers: a schema\n * named `WithRequired`, roadmap R11). Other declarations are returned unchanged.\n */\nexport function renameAliasesTakenByFooter(\n body: readonly IrDeclaration[],\n footer: readonly IrDeclaration[],\n): IrDeclaration[] {\n const footerNames = footerTypeNames(footer);\n const taken = declaredNames([...body, ...footer]);\n return body.map((declaration) => {\n if (!isRootTypeAlias(declaration) || !footerNames.has(declaration.name)) {\n return declaration;\n }\n const name = freeName(declaration.name, taken);\n taken.add(name);\n return { ...declaration, name };\n });\n}\n"],"names":["irRaw","escapeSingleQuotedText"],"mappings":"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"}
1
+ {"version":3,"file":"root-type-aliases.cjs","sources":["../../../../src/application/transform/document/root-type-aliases.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration, IrTypeAliasDeclaration } from \"../../../domain/ir/nodes.js\";\nimport { escapeSingleQuotedText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport type { ComponentKind } from \"../../../domain/openapi/components-object.js\";\nimport { globalTypeReferences } from \"./global-type-references.js\";\n\n/** The `--root-types` aliases: `export type Pet = components['schemas']['Pet'];`. */\n\nconst REFERENCE_PREFIX = \"components['\";\n\n/** The alias of one component. */\nexport function rootTypeAlias(\n name: string,\n kind: ComponentKind,\n item: string,\n): IrTypeAliasDeclaration {\n return {\n kind: \"typeAlias\",\n name,\n isExported: true,\n // The original writes the reference as text, with single quotes, and did not escape the\n // name: a quote in it could add code to the generated file (intentional fix).\n type: irRaw(`${REFERENCE_PREFIX}${kind}']['${escapeSingleQuotedText(item)}']`),\n comments: [],\n };\n}\n\nfunction isRootTypeAlias(declaration: IrDeclaration): declaration is IrTypeAliasDeclaration {\n return (\n declaration.kind === \"typeAlias\" &&\n declaration.type.kind === \"raw\" &&\n declaration.type.text.startsWith(REFERENCE_PREFIX)\n );\n}\n\n/**\n * The type names the footer declares that an alias must not take: enums, and helper types such as\n * `WithRequired`. Value declarations (`--enum-values` arrays) live in another namespace.\n */\nfunction footerTypeNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) => {\n if (declaration.kind === \"enum\") {\n return [declaration.name];\n }\n return declaration.kind === \"rawDeclaration\" && declaration.name !== undefined\n ? [declaration.name]\n : [];\n }),\n );\n}\n\nfunction declaredNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) =>\n \"name\" in declaration && declaration.name !== undefined ? [declaration.name] : [],\n ),\n );\n}\n\nfunction freeName(name: string, taken: ReadonlySet<string>): string {\n let candidate = `${name}_2`;\n for (let counter = 3; taken.has(candidate); counter++) {\n candidate = `${name}_${counter}`;\n }\n return candidate;\n}\n\n/**\n * Rename each root alias whose name an enum or a helper type of the footer also declares, or that\n * shadows a TypeScript global type the output refers to (`Record` in `Record<string, never>`), to\n * the next free `Name_2`, `Name_3`, … (the suffix `--root-types` uses for its own conflicts). The\n * footer and the globals keep their names, because the generated types refer to them. Before, the\n * output did not compile (enums: upstream #2099, #2341, #2206; helpers: a schema named\n * `WithRequired`, roadmap R11; globals: TS2315). Other declarations are returned unchanged.\n *\n * With the `root-type-numbering` fix (ADR-021, roadmap R13, backlog 30) the body also holds the\n * aliases a later schema of one exported name took the name from, after the other aliases and\n * under that same name. Each gets the next free number in body order, after the alias that kept\n * the name got its own: so the fix only adds exports, and every other alias keeps the name it has\n * without the fix.\n */\nexport function renameTakenAliases<T extends IrDeclaration>(\n body: readonly T[],\n footer: readonly IrDeclaration[],\n closing: readonly IrDeclaration[] = [],\n): T[] {\n const reserved = footerTypeNames(footer);\n for (const name of globalTypeReferences([...body, ...footer, ...closing])) {\n reserved.add(name);\n }\n const taken = declaredNames([...body, ...footer, ...closing]);\n const aliasNames = new Set<string>();\n return body.map((declaration) => {\n if (!isRootTypeAlias(declaration)) {\n return declaration;\n }\n const isRepeated = aliasNames.has(declaration.name);\n aliasNames.add(declaration.name);\n if (!isRepeated && !reserved.has(declaration.name)) {\n return declaration;\n }\n const name = freeName(declaration.name, taken);\n taken.add(name);\n return { ...declaration, name };\n });\n}\n"],"names":["irRaw","escapeSingleQuotedText","globalTypeReferences"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { irRaw } from '../../../domain/ir/constructors.mjs';
2
2
  import { escapeSingleQuotedText } from '../../../domain/ir/raw-text-escapes.mjs';
3
+ import { globalTypeReferences } from './global-type-references.mjs';
3
4
 
4
5
  const REFERENCE_PREFIX = "components['";
5
6
  function rootTypeAlias(name, kind, item) {
@@ -40,19 +41,20 @@ function freeName(name, taken) {
40
41
  }
41
42
  return candidate;
42
43
  }
43
- function numberDisplacedAliases(displaced, kept) {
44
- const taken = new Set(kept.map((alias) => alias.name));
45
- return displaced.map((alias) => {
46
- const name = freeName(alias.name, taken);
47
- taken.add(name);
48
- return { ...alias, name };
49
- });
50
- }
51
- function renameAliasesTakenByFooter(body, footer) {
52
- const footerNames = footerTypeNames(footer);
53
- const taken = declaredNames([...body, ...footer]);
44
+ function renameTakenAliases(body, footer, closing = []) {
45
+ const reserved = footerTypeNames(footer);
46
+ for (const name of globalTypeReferences([...body, ...footer, ...closing])) {
47
+ reserved.add(name);
48
+ }
49
+ const taken = declaredNames([...body, ...footer, ...closing]);
50
+ const aliasNames = /* @__PURE__ */ new Set();
54
51
  return body.map((declaration) => {
55
- if (!isRootTypeAlias(declaration) || !footerNames.has(declaration.name)) {
52
+ if (!isRootTypeAlias(declaration)) {
53
+ return declaration;
54
+ }
55
+ const isRepeated = aliasNames.has(declaration.name);
56
+ aliasNames.add(declaration.name);
57
+ if (!isRepeated && !reserved.has(declaration.name)) {
56
58
  return declaration;
57
59
  }
58
60
  const name = freeName(declaration.name, taken);
@@ -61,5 +63,5 @@ function renameAliasesTakenByFooter(body, footer) {
61
63
  });
62
64
  }
63
65
 
64
- export { numberDisplacedAliases, renameAliasesTakenByFooter, rootTypeAlias };
66
+ export { renameTakenAliases, rootTypeAlias };
65
67
  //# sourceMappingURL=root-type-aliases.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"root-type-aliases.mjs","sources":["../../../../src/application/transform/document/root-type-aliases.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration, IrTypeAliasDeclaration } from \"../../../domain/ir/nodes.js\";\nimport { escapeSingleQuotedText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport type { ComponentKind } from \"../../../domain/openapi/components-object.js\";\n\n/** The `--root-types` aliases: `export type Pet = components['schemas']['Pet'];`. */\n\nconst REFERENCE_PREFIX = \"components['\";\n\n/** The alias of one component. */\nexport function rootTypeAlias(\n name: string,\n kind: ComponentKind,\n item: string,\n): IrTypeAliasDeclaration {\n return {\n kind: \"typeAlias\",\n name,\n isExported: true,\n // The original writes the reference as text, with single quotes, and did not escape the\n // name: a quote in it could add code to the generated file (intentional fix).\n type: irRaw(`${REFERENCE_PREFIX}${kind}']['${escapeSingleQuotedText(item)}']`),\n comments: [],\n };\n}\n\nfunction isRootTypeAlias(declaration: IrDeclaration): declaration is IrTypeAliasDeclaration {\n return (\n declaration.kind === \"typeAlias\" &&\n declaration.type.kind === \"raw\" &&\n declaration.type.text.startsWith(REFERENCE_PREFIX)\n );\n}\n\n/**\n * The type names the footer declares that an alias must not take: enums, and helper types such as\n * `WithRequired`. Value declarations (`--enum-values` arrays) live in another namespace.\n */\nfunction footerTypeNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) => {\n if (declaration.kind === \"enum\") {\n return [declaration.name];\n }\n return declaration.kind === \"rawDeclaration\" && declaration.name !== undefined\n ? [declaration.name]\n : [];\n }),\n );\n}\n\nfunction declaredNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) =>\n \"name\" in declaration && declaration.name !== undefined ? [declaration.name] : [],\n ),\n );\n}\n\nfunction freeName(name: string, taken: ReadonlySet<string>): string {\n let candidate = `${name}_2`;\n for (let counter = 3; taken.has(candidate); counter++) {\n candidate = `${name}_${counter}`;\n }\n return candidate;\n}\n\n/**\n * With the `root-type-numbering` fix (ADR-021, roadmap R13, backlog 30): the aliases that a later\n * schema of one exported name took the name from, numbered `Name_2`, `Name_3`, … in document order\n * with the next free number. The later schema keeps the name, so the fix only adds exports.\n */\nexport function numberDisplacedAliases(\n displaced: readonly IrTypeAliasDeclaration[],\n kept: readonly IrTypeAliasDeclaration[],\n): IrTypeAliasDeclaration[] {\n const taken = new Set(kept.map((alias) => alias.name));\n return displaced.map((alias) => {\n const name = freeName(alias.name, taken);\n taken.add(name);\n return { ...alias, name };\n });\n}\n\n/**\n * Rename each root alias whose name an enum or a helper type of the footer also declares, to the\n * next free `Name_2`, `Name_3`, … (the suffix `--root-types` uses for its own conflicts). The\n * footer keeps its names, because the generated types refer to them. Before, both were declared\n * under one name, which does not compile (enums: upstream #2099, #2341, #2206; helpers: a schema\n * named `WithRequired`, roadmap R11). Other declarations are returned unchanged.\n */\nexport function renameAliasesTakenByFooter(\n body: readonly IrDeclaration[],\n footer: readonly IrDeclaration[],\n): IrDeclaration[] {\n const footerNames = footerTypeNames(footer);\n const taken = declaredNames([...body, ...footer]);\n return body.map((declaration) => {\n if (!isRootTypeAlias(declaration) || !footerNames.has(declaration.name)) {\n return declaration;\n }\n const name = freeName(declaration.name, taken);\n taken.add(name);\n return { ...declaration, name };\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root-type-aliases.mjs","sources":["../../../../src/application/transform/document/root-type-aliases.ts"],"sourcesContent":["import { irRaw } from \"../../../domain/ir/constructors.js\";\nimport type { IrDeclaration, IrTypeAliasDeclaration } from \"../../../domain/ir/nodes.js\";\nimport { escapeSingleQuotedText } from \"../../../domain/ir/raw-text-escapes.js\";\nimport type { ComponentKind } from \"../../../domain/openapi/components-object.js\";\nimport { globalTypeReferences } from \"./global-type-references.js\";\n\n/** The `--root-types` aliases: `export type Pet = components['schemas']['Pet'];`. */\n\nconst REFERENCE_PREFIX = \"components['\";\n\n/** The alias of one component. */\nexport function rootTypeAlias(\n name: string,\n kind: ComponentKind,\n item: string,\n): IrTypeAliasDeclaration {\n return {\n kind: \"typeAlias\",\n name,\n isExported: true,\n // The original writes the reference as text, with single quotes, and did not escape the\n // name: a quote in it could add code to the generated file (intentional fix).\n type: irRaw(`${REFERENCE_PREFIX}${kind}']['${escapeSingleQuotedText(item)}']`),\n comments: [],\n };\n}\n\nfunction isRootTypeAlias(declaration: IrDeclaration): declaration is IrTypeAliasDeclaration {\n return (\n declaration.kind === \"typeAlias\" &&\n declaration.type.kind === \"raw\" &&\n declaration.type.text.startsWith(REFERENCE_PREFIX)\n );\n}\n\n/**\n * The type names the footer declares that an alias must not take: enums, and helper types such as\n * `WithRequired`. Value declarations (`--enum-values` arrays) live in another namespace.\n */\nfunction footerTypeNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) => {\n if (declaration.kind === \"enum\") {\n return [declaration.name];\n }\n return declaration.kind === \"rawDeclaration\" && declaration.name !== undefined\n ? [declaration.name]\n : [];\n }),\n );\n}\n\nfunction declaredNames(declarations: readonly IrDeclaration[]): Set<string> {\n return new Set(\n declarations.flatMap((declaration) =>\n \"name\" in declaration && declaration.name !== undefined ? [declaration.name] : [],\n ),\n );\n}\n\nfunction freeName(name: string, taken: ReadonlySet<string>): string {\n let candidate = `${name}_2`;\n for (let counter = 3; taken.has(candidate); counter++) {\n candidate = `${name}_${counter}`;\n }\n return candidate;\n}\n\n/**\n * Rename each root alias whose name an enum or a helper type of the footer also declares, or that\n * shadows a TypeScript global type the output refers to (`Record` in `Record<string, never>`), to\n * the next free `Name_2`, `Name_3`, … (the suffix `--root-types` uses for its own conflicts). The\n * footer and the globals keep their names, because the generated types refer to them. Before, the\n * output did not compile (enums: upstream #2099, #2341, #2206; helpers: a schema named\n * `WithRequired`, roadmap R11; globals: TS2315). Other declarations are returned unchanged.\n *\n * With the `root-type-numbering` fix (ADR-021, roadmap R13, backlog 30) the body also holds the\n * aliases a later schema of one exported name took the name from, after the other aliases and\n * under that same name. Each gets the next free number in body order, after the alias that kept\n * the name got its own: so the fix only adds exports, and every other alias keeps the name it has\n * without the fix.\n */\nexport function renameTakenAliases<T extends IrDeclaration>(\n body: readonly T[],\n footer: readonly IrDeclaration[],\n closing: readonly IrDeclaration[] = [],\n): T[] {\n const reserved = footerTypeNames(footer);\n for (const name of globalTypeReferences([...body, ...footer, ...closing])) {\n reserved.add(name);\n }\n const taken = declaredNames([...body, ...footer, ...closing]);\n const aliasNames = new Set<string>();\n return body.map((declaration) => {\n if (!isRootTypeAlias(declaration)) {\n return declaration;\n }\n const isRepeated = aliasNames.has(declaration.name);\n aliasNames.add(declaration.name);\n if (!isRepeated && !reserved.has(declaration.name)) {\n return declaration;\n }\n const name = freeName(declaration.name, taken);\n taken.add(name);\n return { ...declaration, name };\n });\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ 'use strict';
2
+
3
+ function textAt(shape, index) {
4
+ return shape.texts[index];
5
+ }
6
+ function isNumberText(text) {
7
+ return text !== "" && Number.isFinite(Number(text));
8
+ }
9
+ function isValidMatch(match, placeholder) {
10
+ if (placeholder === "string") {
11
+ return true;
12
+ }
13
+ if (match.kind === "text") {
14
+ return isNumberText(match.text);
15
+ }
16
+ const { texts, types } = match.shape;
17
+ return texts.length === 2 && texts[0] === "" && texts[1] === "" && types[0] === "number";
18
+ }
19
+ class LiteralPartsScan {
20
+ matches = [];
21
+ cursor;
22
+ source;
23
+ lastSourceIndex;
24
+ remainingEndText;
25
+ constructor(source, startPosition, endTextLength) {
26
+ this.source = source;
27
+ this.lastSourceIndex = source.texts.length - 1;
28
+ const endText = textAt(source, this.lastSourceIndex);
29
+ this.remainingEndText = endText.slice(0, endText.length - endTextLength);
30
+ this.cursor = { segment: 0, position: startPosition };
31
+ }
32
+ /** The matches for the target's texts between its first and last; null when one is missing. */
33
+ run(delimiters) {
34
+ for (const delimiter of delimiters) {
35
+ if (!this.matchDelimiter(delimiter)) {
36
+ return null;
37
+ }
38
+ }
39
+ this.addMatch(this.lastSourceIndex, this.sourceText(this.lastSourceIndex).length);
40
+ return this.matches;
41
+ }
42
+ matchDelimiter(delimiter) {
43
+ const { segment, position } = this.cursor;
44
+ if (delimiter.length > 0) {
45
+ const found = this.find(delimiter);
46
+ if (found === null) {
47
+ return false;
48
+ }
49
+ this.addMatch(found.segment, found.position);
50
+ this.cursor = { ...this.cursor, position: this.cursor.position + delimiter.length };
51
+ return true;
52
+ }
53
+ if (position < this.sourceText(segment).length) {
54
+ this.addMatch(segment, position + 1);
55
+ return true;
56
+ }
57
+ if (segment < this.lastSourceIndex) {
58
+ this.addMatch(segment + 1, 0);
59
+ return true;
60
+ }
61
+ return false;
62
+ }
63
+ /** The first occurrence of the delimiter at or after the cursor, in this or a later text. */
64
+ find(delimiter) {
65
+ let { segment, position } = this.cursor;
66
+ while (segment < this.source.texts.length) {
67
+ const index = this.sourceText(segment).indexOf(delimiter, position);
68
+ if (index >= 0) {
69
+ return { segment, position: index };
70
+ }
71
+ segment += 1;
72
+ position = 0;
73
+ }
74
+ return null;
75
+ }
76
+ sourceText(index) {
77
+ return index < this.lastSourceIndex ? textAt(this.source, index) : this.remainingEndText;
78
+ }
79
+ addMatch(segment, position) {
80
+ const start = this.cursor;
81
+ if (segment === start.segment) {
82
+ const text = this.sourceText(segment).slice(start.position, position);
83
+ this.matches.push({ kind: "text", text });
84
+ } else {
85
+ const texts = [
86
+ textAt(this.source, start.segment).slice(start.position),
87
+ ...this.source.texts.slice(start.segment + 1, segment),
88
+ this.sourceText(segment).slice(0, position)
89
+ ];
90
+ const types = this.source.types.slice(start.segment, segment);
91
+ this.matches.push({ kind: "template", shape: { texts, types } });
92
+ }
93
+ this.cursor = { segment, position };
94
+ }
95
+ }
96
+ function inferMatches(source, target) {
97
+ const sourceStart = textAt(source, 0);
98
+ const sourceEnd = textAt(source, source.texts.length - 1);
99
+ const targetStart = textAt(target, 0);
100
+ const targetEnd = textAt(target, target.texts.length - 1);
101
+ const isTooShort = source.texts.length === 1 && sourceStart.length < targetStart.length + targetEnd.length;
102
+ if (isTooShort || !sourceStart.startsWith(targetStart) || !sourceEnd.endsWith(targetEnd)) {
103
+ return null;
104
+ }
105
+ const scan = new LiteralPartsScan(source, targetStart.length, targetEnd.length);
106
+ return scan.run(target.texts.slice(1, -1));
107
+ }
108
+ function haveSameTexts(source, target) {
109
+ return source.texts.length === target.texts.length && source.texts.every((text, index) => text === target.texts[index]);
110
+ }
111
+ function isAssignableToTemplate(source, target) {
112
+ if (source.types.length > 0 && haveSameTexts(source, target)) {
113
+ return source.types.every((type, index) => {
114
+ const placeholder = target.types[index];
115
+ return placeholder === "string" || type === placeholder;
116
+ });
117
+ }
118
+ const matches = inferMatches(source, target);
119
+ const isEveryMatchValid = matches?.every((match, index) => {
120
+ const placeholder = target.types[index];
121
+ return placeholder !== void 0 && isValidMatch(match, placeholder);
122
+ });
123
+ return isEveryMatchValid === true;
124
+ }
125
+
126
+ exports.isAssignableToTemplate = isAssignableToTemplate;
127
+ exports.isNumberText = isNumberText;
128
+ //# sourceMappingURL=template-key-match.cjs.map