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

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 (320) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/dist/adapters/node-file-system/node-file-system.cjs +7 -0
  3. package/dist/adapters/node-file-system/node-file-system.cjs.map +1 -1
  4. package/dist/adapters/node-file-system/node-file-system.mjs +7 -0
  5. package/dist/adapters/node-file-system/node-file-system.mjs.map +1 -1
  6. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs +19 -0
  7. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.cjs.map +1 -0
  8. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs +17 -0
  9. package/dist/adapters/pipe-safe-writer/pipe-safe-writer.mjs.map +1 -0
  10. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs +5 -32
  11. package/dist/adapters/redocly-loader/bundled-mapping-copies.cjs.map +1 -1
  12. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs +6 -33
  13. package/dist/adapters/redocly-loader/bundled-mapping-copies.mjs.map +1 -1
  14. package/dist/adapters/redocly-loader/component-schemas.cjs +17 -0
  15. package/dist/adapters/redocly-loader/component-schemas.cjs.map +1 -0
  16. package/dist/adapters/redocly-loader/component-schemas.mjs +14 -0
  17. package/dist/adapters/redocly-loader/component-schemas.mjs.map +1 -0
  18. package/dist/adapters/redocly-loader/mapping-schema-names.cjs +22 -0
  19. package/dist/adapters/redocly-loader/mapping-schema-names.cjs.map +1 -0
  20. package/dist/adapters/redocly-loader/mapping-schema-names.mjs +20 -0
  21. package/dist/adapters/redocly-loader/mapping-schema-names.mjs.map +1 -0
  22. package/dist/adapters/redocly-loader/query-named-components.cjs +137 -0
  23. package/dist/adapters/redocly-loader/query-named-components.cjs.map +1 -0
  24. package/dist/adapters/redocly-loader/query-named-components.mjs +134 -0
  25. package/dist/adapters/redocly-loader/query-named-components.mjs.map +1 -0
  26. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs +26 -14
  27. package/dist/adapters/redocly-loader/redocly-schema-loader.cjs.map +1 -1
  28. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs +26 -14
  29. package/dist/adapters/redocly-loader/redocly-schema-loader.mjs.map +1 -1
  30. package/dist/adapters/redocly-loader/ref-access.cjs +16 -3
  31. package/dist/adapters/redocly-loader/ref-access.cjs.map +1 -1
  32. package/dist/adapters/redocly-loader/ref-access.mjs +16 -3
  33. package/dist/adapters/redocly-loader/ref-access.mjs.map +1 -1
  34. package/dist/adapters/redocly-loader/ref-holders.cjs +52 -10
  35. package/dist/adapters/redocly-loader/ref-holders.cjs.map +1 -1
  36. package/dist/adapters/redocly-loader/ref-holders.mjs +52 -11
  37. package/dist/adapters/redocly-loader/ref-holders.mjs.map +1 -1
  38. package/dist/adapters/redocly-loader/remote-fetch.cjs +5 -3
  39. package/dist/adapters/redocly-loader/remote-fetch.cjs.map +1 -1
  40. package/dist/adapters/redocly-loader/remote-fetch.mjs +5 -3
  41. package/dist/adapters/redocly-loader/remote-fetch.mjs.map +1 -1
  42. package/dist/adapters/redocly-loader/remote-node-limit.cjs +17 -3
  43. package/dist/adapters/redocly-loader/remote-node-limit.cjs.map +1 -1
  44. package/dist/adapters/redocly-loader/remote-node-limit.mjs +17 -3
  45. package/dist/adapters/redocly-loader/remote-node-limit.mjs.map +1 -1
  46. package/dist/adapters/redocly-loader/schema-source.cjs +7 -2
  47. package/dist/adapters/redocly-loader/schema-source.cjs.map +1 -1
  48. package/dist/adapters/redocly-loader/schema-source.mjs +8 -3
  49. package/dist/adapters/redocly-loader/schema-source.mjs.map +1 -1
  50. package/dist/adapters/terminal-logger/terminal-logger.cjs +7 -3
  51. package/dist/adapters/terminal-logger/terminal-logger.cjs.map +1 -1
  52. package/dist/adapters/terminal-logger/terminal-logger.mjs +7 -3
  53. package/dist/adapters/terminal-logger/terminal-logger.mjs.map +1 -1
  54. package/dist/api/document-refs.cjs +16 -1
  55. package/dist/api/document-refs.cjs.map +1 -1
  56. package/dist/api/document-refs.mjs +16 -1
  57. package/dist/api/document-refs.mjs.map +1 -1
  58. package/dist/api/document-run.cjs +4 -10
  59. package/dist/api/document-run.cjs.map +1 -1
  60. package/dist/api/document-run.mjs +4 -10
  61. package/dist/api/document-run.mjs.map +1 -1
  62. package/dist/api/openapi-ts.cjs +1 -2
  63. package/dist/api/openapi-ts.cjs.map +1 -1
  64. package/dist/api/openapi-ts.mjs +2 -3
  65. package/dist/api/openapi-ts.mjs.map +1 -1
  66. package/dist/api/ref-limit-options.cjs +63 -0
  67. package/dist/api/ref-limit-options.cjs.map +1 -0
  68. package/dist/api/ref-limit-options.mjs +57 -0
  69. package/dist/api/ref-limit-options.mjs.map +1 -0
  70. package/dist/api/transform-schema.cjs +12 -5
  71. package/dist/api/transform-schema.cjs.map +1 -1
  72. package/dist/api/transform-schema.mjs +12 -5
  73. package/dist/api/transform-schema.mjs.map +1 -1
  74. package/dist/application/transform/declared-value-types.cjs +36 -0
  75. package/dist/application/transform/declared-value-types.cjs.map +1 -0
  76. package/dist/application/transform/declared-value-types.mjs +34 -0
  77. package/dist/application/transform/declared-value-types.mjs.map +1 -0
  78. package/dist/application/transform/document/document.cjs +3 -1
  79. package/dist/application/transform/document/document.cjs.map +1 -1
  80. package/dist/application/transform/document/document.mjs +3 -1
  81. package/dist/application/transform/document/document.mjs.map +1 -1
  82. package/dist/application/transform/document/exploded-query-values.cjs +63 -0
  83. package/dist/application/transform/document/exploded-query-values.cjs.map +1 -0
  84. package/dist/application/transform/document/exploded-query-values.mjs +59 -0
  85. package/dist/application/transform/document/exploded-query-values.mjs.map +1 -0
  86. package/dist/application/transform/document/header.cjs +11 -3
  87. package/dist/application/transform/document/header.cjs.map +1 -1
  88. package/dist/application/transform/document/header.mjs +10 -2
  89. package/dist/application/transform/document/header.mjs.map +1 -1
  90. package/dist/application/transform/document/parameter.cjs +1 -1
  91. package/dist/application/transform/document/parameter.cjs.map +1 -1
  92. package/dist/application/transform/document/parameter.mjs +1 -1
  93. package/dist/application/transform/document/parameter.mjs.map +1 -1
  94. package/dist/application/transform/document/parameters.cjs +23 -5
  95. package/dist/application/transform/document/parameters.cjs.map +1 -1
  96. package/dist/application/transform/document/parameters.mjs +23 -5
  97. package/dist/application/transform/document/parameters.mjs.map +1 -1
  98. package/dist/application/transform/document/path-item.cjs +4 -3
  99. package/dist/application/transform/document/path-item.cjs.map +1 -1
  100. package/dist/application/transform/document/path-item.mjs +4 -4
  101. package/dist/application/transform/document/path-item.mjs.map +1 -1
  102. package/dist/application/transform/document/path-template-key.cjs +84 -0
  103. package/dist/application/transform/document/path-template-key.cjs.map +1 -0
  104. package/dist/application/transform/document/path-template-key.mjs +79 -0
  105. package/dist/application/transform/document/path-template-key.mjs.map +1 -0
  106. package/dist/application/transform/document/path-template-refs.cjs +70 -0
  107. package/dist/application/transform/document/path-template-refs.cjs.map +1 -0
  108. package/dist/application/transform/document/path-template-refs.mjs +67 -0
  109. package/dist/application/transform/document/path-template-refs.mjs.map +1 -0
  110. package/dist/application/transform/document/paths-enum.cjs +7 -6
  111. package/dist/application/transform/document/paths-enum.cjs.map +1 -1
  112. package/dist/application/transform/document/paths-enum.mjs +7 -6
  113. package/dist/application/transform/document/paths-enum.mjs.map +1 -1
  114. package/dist/application/transform/document/paths.cjs +38 -66
  115. package/dist/application/transform/document/paths.cjs.map +1 -1
  116. package/dist/application/transform/document/paths.mjs +36 -66
  117. package/dist/application/transform/document/paths.mjs.map +1 -1
  118. package/dist/application/transform/document/webhooks.cjs +10 -3
  119. package/dist/application/transform/document/webhooks.cjs.map +1 -1
  120. package/dist/application/transform/document/webhooks.mjs +9 -2
  121. package/dist/application/transform/document/webhooks.mjs.map +1 -1
  122. package/dist/application/transform/footer/document-footer.cjs +6 -3
  123. package/dist/application/transform/footer/document-footer.cjs.map +1 -1
  124. package/dist/application/transform/footer/document-footer.mjs +6 -3
  125. package/dist/application/transform/footer/document-footer.mjs.map +1 -1
  126. package/dist/application/transform/helper-types.cjs +3 -3
  127. package/dist/application/transform/helper-types.cjs.map +1 -1
  128. package/dist/application/transform/helper-types.mjs +3 -3
  129. package/dist/application/transform/helper-types.mjs.map +1 -1
  130. package/dist/application/transform/ref-pointer/generated-location.cjs +4 -4
  131. package/dist/application/transform/ref-pointer/generated-location.cjs.map +1 -1
  132. package/dist/application/transform/ref-pointer/generated-location.mjs +1 -1
  133. package/dist/application/transform/ref-pointer/generated-location.mjs.map +1 -1
  134. package/dist/application/transform/ref-pointer/generated-shape.cjs +47 -66
  135. package/dist/application/transform/ref-pointer/generated-shape.cjs.map +1 -1
  136. package/dist/application/transform/ref-pointer/generated-shape.mjs +36 -50
  137. package/dist/application/transform/ref-pointer/generated-shape.mjs.map +1 -1
  138. package/dist/application/transform/ref-pointer/inline-cycles.cjs +2 -2
  139. package/dist/application/transform/ref-pointer/inline-cycles.cjs.map +1 -1
  140. package/dist/application/transform/ref-pointer/inline-cycles.mjs +1 -1
  141. package/dist/application/transform/ref-pointer/inline-cycles.mjs.map +1 -1
  142. package/dist/application/transform/ref-pointer/located-node.cjs +23 -0
  143. package/dist/application/transform/ref-pointer/located-node.cjs.map +1 -0
  144. package/dist/application/transform/ref-pointer/located-node.mjs +18 -0
  145. package/dist/application/transform/ref-pointer/located-node.mjs.map +1 -0
  146. package/dist/application/transform/ref-pointer/original-index.cjs +68 -13
  147. package/dist/application/transform/ref-pointer/original-index.cjs.map +1 -1
  148. package/dist/application/transform/ref-pointer/original-index.mjs +70 -15
  149. package/dist/application/transform/ref-pointer/original-index.mjs.map +1 -1
  150. package/dist/application/transform/ref-pointer/pointer-type.cjs +2 -2
  151. package/dist/application/transform/ref-pointer/pointer-type.cjs.map +1 -1
  152. package/dist/application/transform/ref-pointer/pointer-type.mjs +1 -1
  153. package/dist/application/transform/ref-pointer/pointer-type.mjs.map +1 -1
  154. package/dist/application/transform/ref-pointer/pointer-walk.cjs +54 -13
  155. package/dist/application/transform/ref-pointer/pointer-walk.cjs.map +1 -1
  156. package/dist/application/transform/ref-pointer/pointer-walk.mjs +46 -7
  157. package/dist/application/transform/ref-pointer/pointer-walk.mjs.map +1 -1
  158. package/dist/application/transform/ref-pointer/property-shape.cjs +52 -0
  159. package/dist/application/transform/ref-pointer/property-shape.cjs.map +1 -0
  160. package/dist/application/transform/ref-pointer/property-shape.mjs +45 -0
  161. package/dist/application/transform/ref-pointer/property-shape.mjs.map +1 -0
  162. package/dist/application/transform/ref-pointer/typed-walk.cjs +79 -21
  163. package/dist/application/transform/ref-pointer/typed-walk.cjs.map +1 -1
  164. package/dist/application/transform/ref-pointer/typed-walk.mjs +76 -18
  165. package/dist/application/transform/ref-pointer/typed-walk.mjs.map +1 -1
  166. package/dist/application/transform/schema/access-flags.cjs.map +1 -1
  167. package/dist/application/transform/schema/access-flags.mjs.map +1 -1
  168. package/dist/application/transform/schema/index-signature-type.cjs +21 -0
  169. package/dist/application/transform/schema/index-signature-type.cjs.map +1 -0
  170. package/dist/application/transform/schema/index-signature-type.mjs +19 -0
  171. package/dist/application/transform/schema/index-signature-type.mjs.map +1 -0
  172. package/dist/application/transform/schema/input-location.cjs +23 -0
  173. package/dist/application/transform/schema/input-location.cjs.map +1 -0
  174. package/dist/application/transform/schema/input-location.mjs +21 -0
  175. package/dist/application/transform/schema/input-location.mjs.map +1 -0
  176. package/dist/application/transform/schema/object-type.cjs +15 -5
  177. package/dist/application/transform/schema/object-type.cjs.map +1 -1
  178. package/dist/application/transform/schema/object-type.mjs +15 -5
  179. package/dist/application/transform/schema/object-type.mjs.map +1 -1
  180. package/dist/application/transform/schema/schema-transform.cjs +2 -1
  181. package/dist/application/transform/schema/schema-transform.cjs.map +1 -1
  182. package/dist/application/transform/schema/schema-transform.mjs +2 -1
  183. package/dist/application/transform/schema/schema-transform.mjs.map +1 -1
  184. package/dist/application/transform/schema/unevaluated-properties.cjs +2 -30
  185. package/dist/application/transform/schema/unevaluated-properties.cjs.map +1 -1
  186. package/dist/application/transform/schema/unevaluated-properties.mjs +3 -31
  187. package/dist/application/transform/schema/unevaluated-properties.mjs.map +1 -1
  188. package/dist/cli/api-logger.cjs +13 -0
  189. package/dist/cli/api-logger.cjs.map +1 -0
  190. package/dist/cli/api-logger.mjs +11 -0
  191. package/dist/cli/api-logger.mjs.map +1 -0
  192. package/dist/cli/api-settings.cjs +7 -15
  193. package/dist/cli/api-settings.cjs.map +1 -1
  194. package/dist/cli/api-settings.mjs +8 -16
  195. package/dist/cli/api-settings.mjs.map +1 -1
  196. package/dist/cli/cli-arguments.cjs +51 -11
  197. package/dist/cli/cli-arguments.cjs.map +1 -1
  198. package/dist/cli/cli-arguments.mjs +51 -11
  199. package/dist/cli/cli-arguments.mjs.map +1 -1
  200. package/dist/cli/cli-errors.cjs +17 -0
  201. package/dist/cli/cli-errors.cjs.map +1 -1
  202. package/dist/cli/cli-errors.mjs +17 -1
  203. package/dist/cli/cli-errors.mjs.map +1 -1
  204. package/dist/cli/cli-output.cjs +6 -4
  205. package/dist/cli/cli-output.cjs.map +1 -1
  206. package/dist/cli/cli-output.mjs +7 -5
  207. package/dist/cli/cli-output.mjs.map +1 -1
  208. package/dist/cli/main.cjs +10 -4
  209. package/dist/cli/main.cjs.map +1 -1
  210. package/dist/cli/main.mjs +10 -4
  211. package/dist/cli/main.mjs.map +1 -1
  212. package/dist/cli/redocly-apis.cjs +20 -9
  213. package/dist/cli/redocly-apis.cjs.map +1 -1
  214. package/dist/cli/redocly-apis.mjs +22 -11
  215. package/dist/cli/redocly-apis.mjs.map +1 -1
  216. package/dist/cli/ref-limits.cjs +15 -1
  217. package/dist/cli/ref-limits.cjs.map +1 -1
  218. package/dist/cli/ref-limits.mjs +15 -2
  219. package/dist/cli/ref-limits.mjs.map +1 -1
  220. package/dist/cli/run-cli.cjs +24 -7
  221. package/dist/cli/run-cli.cjs.map +1 -1
  222. package/dist/cli/run-cli.mjs +25 -8
  223. package/dist/cli/run-cli.mjs.map +1 -1
  224. package/dist/domain/cause-secrets.cjs +31 -16
  225. package/dist/domain/cause-secrets.cjs.map +1 -1
  226. package/dist/domain/cause-secrets.mjs +31 -16
  227. package/dist/domain/cause-secrets.mjs.map +1 -1
  228. package/dist/domain/errors.cjs +2 -0
  229. package/dist/domain/errors.cjs.map +1 -1
  230. package/dist/domain/errors.mjs +2 -0
  231. package/dist/domain/errors.mjs.map +1 -1
  232. package/dist/domain/location-text.cjs +9 -0
  233. package/dist/domain/location-text.cjs.map +1 -0
  234. package/dist/domain/location-text.mjs +7 -0
  235. package/dist/domain/location-text.mjs.map +1 -0
  236. package/dist/domain/openapi/document-places.cjs +55 -0
  237. package/dist/domain/openapi/document-places.cjs.map +1 -0
  238. package/dist/domain/openapi/document-places.mjs +53 -0
  239. package/dist/domain/openapi/document-places.mjs.map +1 -0
  240. package/dist/domain/output-fixes.cjs +8 -2
  241. package/dist/domain/output-fixes.cjs.map +1 -1
  242. package/dist/domain/output-fixes.mjs +8 -2
  243. package/dist/domain/output-fixes.mjs.map +1 -1
  244. package/dist/domain/terminal-text.cjs +31 -0
  245. package/dist/domain/terminal-text.cjs.map +1 -0
  246. package/dist/domain/terminal-text.mjs +29 -0
  247. package/dist/domain/terminal-text.mjs.map +1 -0
  248. package/dist/domain/warnings.cjs +1 -0
  249. package/dist/domain/warnings.cjs.map +1 -1
  250. package/dist/domain/warnings.mjs +1 -0
  251. package/dist/domain/warnings.mjs.map +1 -1
  252. package/dist/index.d.cts +26 -18
  253. package/dist/index.d.mts +26 -18
  254. package/dist/index.d.ts +26 -18
  255. package/package.json +1 -1
  256. package/src/adapters/node-file-system/node-file-system.ts +14 -1
  257. package/src/adapters/pipe-safe-writer/pipe-safe-writer.ts +29 -0
  258. package/src/adapters/redocly-loader/bundled-mapping-copies.ts +7 -42
  259. package/src/adapters/redocly-loader/component-schemas.ts +19 -0
  260. package/src/adapters/redocly-loader/mapping-schema-names.ts +25 -0
  261. package/src/adapters/redocly-loader/query-named-components.ts +201 -0
  262. package/src/adapters/redocly-loader/redocly-schema-loader.ts +46 -14
  263. package/src/adapters/redocly-loader/ref-access.ts +16 -3
  264. package/src/adapters/redocly-loader/ref-holders.ts +75 -14
  265. package/src/adapters/redocly-loader/remote-fetch.ts +11 -2
  266. package/src/adapters/redocly-loader/remote-node-limit.ts +44 -4
  267. package/src/adapters/redocly-loader/schema-source.ts +15 -3
  268. package/src/adapters/terminal-logger/terminal-logger.ts +10 -4
  269. package/src/api/document-refs.ts +29 -1
  270. package/src/api/document-run.ts +6 -16
  271. package/src/api/openapi-ts.ts +6 -3
  272. package/src/api/ref-limit-options.ts +76 -0
  273. package/src/api/transform-schema.ts +20 -5
  274. package/src/application/ports/file-system.ts +8 -0
  275. package/src/application/transform/declared-value-types.ts +42 -0
  276. package/src/application/transform/document/document.ts +4 -2
  277. package/src/application/transform/document/exploded-query-values.ts +88 -0
  278. package/src/application/transform/document/header.ts +25 -5
  279. package/src/application/transform/document/parameter.ts +4 -4
  280. package/src/application/transform/document/parameters.ts +45 -10
  281. package/src/application/transform/document/path-item.ts +3 -3
  282. package/src/application/transform/document/path-template-key.ts +152 -0
  283. package/src/application/transform/document/path-template-refs.ts +106 -0
  284. package/src/application/transform/document/paths-enum.ts +23 -9
  285. package/src/application/transform/document/paths.ts +53 -123
  286. package/src/application/transform/document/webhooks.ts +18 -5
  287. package/src/application/transform/footer/document-footer.ts +18 -8
  288. package/src/application/transform/helper-types.ts +4 -4
  289. package/src/application/transform/ref-pointer/generated-location.ts +1 -1
  290. package/src/application/transform/ref-pointer/generated-shape.ts +67 -78
  291. package/src/application/transform/ref-pointer/inline-cycles.ts +1 -1
  292. package/src/application/transform/ref-pointer/located-node.ts +38 -0
  293. package/src/application/transform/ref-pointer/original-index.ts +100 -17
  294. package/src/application/transform/ref-pointer/pointer-type.ts +1 -1
  295. package/src/application/transform/ref-pointer/pointer-walk.ts +82 -8
  296. package/src/application/transform/ref-pointer/property-shape.ts +97 -0
  297. package/src/application/transform/ref-pointer/typed-walk.ts +117 -25
  298. package/src/application/transform/schema/access-flags.ts +5 -2
  299. package/src/application/transform/schema/index-signature-type.ts +31 -0
  300. package/src/application/transform/schema/input-location.ts +35 -0
  301. package/src/application/transform/schema/object-type.ts +18 -8
  302. package/src/application/transform/schema/schema-transform.ts +2 -1
  303. package/src/application/transform/schema/unevaluated-properties.ts +4 -44
  304. package/src/cli/api-logger.ts +17 -0
  305. package/src/cli/api-settings.ts +12 -20
  306. package/src/cli/cli-arguments.ts +90 -14
  307. package/src/cli/cli-dependencies.ts +7 -2
  308. package/src/cli/cli-errors.ts +22 -0
  309. package/src/cli/cli-output.ts +11 -10
  310. package/src/cli/main.ts +10 -4
  311. package/src/cli/redocly-apis.ts +37 -17
  312. package/src/cli/ref-limits.ts +21 -2
  313. package/src/cli/run-cli.ts +39 -7
  314. package/src/domain/cause-secrets.ts +59 -25
  315. package/src/domain/errors.ts +2 -0
  316. package/src/domain/location-text.ts +12 -0
  317. package/src/domain/openapi/document-places.ts +78 -0
  318. package/src/domain/output-fixes.ts +9 -2
  319. package/src/domain/terminal-text.ts +44 -0
  320. package/src/domain/warnings.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"paths-enum.cjs","sources":["../../../../src/application/transform/document/paths-enum.ts"],"sourcesContent":["import type { IrEnumDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport {\n ADDITIONAL_OPERATIONS_KEY,\n HTTP_METHODS,\n type PathItemMethod,\n type PathsObject,\n QUERY_METHOD,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport { EnumNaming, enumDeclaration } from \"../footer/enum-naming.js\";\nimport { withNumberedRepeats } from \"../numbered-names.js\";\nimport type { EnumMemberMetadata } from \"../schema/schema-context.js\";\n\n/** A path segment that is one parameter: `{user_id}` or `:user_id`. */\nconst PARAMETER_SEGMENT_RE = /^(?:{(.+)}|:(.+))$/;\n/** Characters not allowed in an enum key, or a `{param}` / `:param` part (first match only). */\nconst INVALID_KEY_PART_RE = /{.*}|:.*|[^a-zA-Z\\d_]+/;\nexport const API_PATHS_NAME = \"ApiPaths\";\nconst METHODS: ReadonlySet<string> = new Set<PathItemMethod>([...HTTP_METHODS, QUERY_METHOD]);\n\n/** The members of the `ApiPaths` enum (`--make-paths-enum`). */\nexport interface ApiPathsEnum {\n readonly values: readonly string[];\n readonly metadata: readonly EnumMemberMetadata[];\n}\n\n/** `getUsersById` style key from the method and URL, when the operation has no ID. */\nfunction keyFromUrl(method: string, url: string): string {\n return `${method}${url}`\n .split(\"/\")\n .map((part) => {\n const capitalized = part.charAt(0).toUpperCase() + part.slice(1);\n return capitalized.replace(INVALID_KEY_PART_RE, \"\");\n })\n .join(\"\");\n}\n\n/** `user_id` and `order-id` as `UserId` and `OrderId`. */\nfunction parameterWord(name: string): string {\n return name\n .split(/[^a-zA-Z\\d]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\n/** The key with parameters named, `GetUserByUserId`, for keys that collide without them. */\nfunction keyWithParameters(method: string, url: string): string {\n const parts = url.split(\"/\").map((part) => {\n const parameter = PARAMETER_SEGMENT_RE.exec(part);\n const name = parameter?.[1] ?? parameter?.[2];\n return name === undefined ? part : `By${parameterWord(name)}`;\n });\n return keyFromUrl(method, parts.join(\"/\"));\n}\n\ninterface PathOperation {\n readonly url: string;\n readonly method: string;\n readonly operationId: string | undefined;\n}\n\n/**\n * The operations of one path item in document order; `additionalOperations` (OpenAPI 3.2) adds\n * its methods where the key stands.\n */\nfunction pathItemEntries(pathItem: object): [string, unknown][] {\n return Object.entries(pathItem).flatMap(([key, value]): [string, unknown][] => {\n if (key === ADDITIONAL_OPERATIONS_KEY) {\n return typeof value === \"object\" && value !== null ? Object.entries(value) : [];\n }\n return METHODS.has(key) ? [[key, value]] : [];\n });\n}\n\nfunction pathOperations(paths: PathsObject): PathOperation[] {\n return Object.entries(paths).flatMap(([url, pathItem]) =>\n pathItemEntries(pathItem).map(([method, operation]) => {\n const operationId = (operation as OperationObject).operationId || undefined;\n return { url, method, operationId };\n }),\n );\n}\n\nfunction countOf(names: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const name of names) {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n return counts;\n}\n\n/**\n * Names that are unique, so the enum compiles (upstream #2194). A URL key that collides names\n * its parameters; a name that still collides gets 2, 3… after its first use.\n */\nfunction uniqueNames(operations: readonly PathOperation[]): string[] {\n const keys = operations.map((op) => op.operationId ?? keyFromUrl(op.method, op.url));\n const counts = countOf(keys);\n const named = operations.map((op, index) => {\n const isCollidingUrlKey =\n op.operationId === undefined && (counts.get(keys[index] as string) ?? 0) > 1;\n return isCollidingUrlKey ? keyWithParameters(op.method, op.url) : (keys[index] as string);\n });\n return withNumberedRepeats(named, (name, count) => `${name}${count}`);\n}\n\n/**\n * One enum member per operation: the URL as the value, the operation ID (or a key built from the\n * method and URL) as the name. Paths are in document order; `--alphabetize` does not apply.\n */\nexport function apiPathsEnum(paths: PathsObject): ApiPathsEnum {\n const operations = pathOperations(paths);\n const names = uniqueNames(operations);\n return {\n values: operations.map((operation) => operation.url),\n metadata: names.map((name) => ({ name, description: undefined })),\n };\n}\n\n/**\n * The `ApiPaths` enum declaration. Its own naming state is equivalent to the run's: the name is a\n * valid identifier, and member names only reset the state, never read it.\n */\nexport function apiPathsEnumDeclaration(paths: PathsObject): IrEnumDeclaration {\n const naming = new EnumNaming();\n return enumDeclaration(naming.enumName(API_PATHS_NAME), apiPathsEnum(paths), naming);\n}\n"],"names":["HTTP_METHODS","QUERY_METHOD","ADDITIONAL_OPERATIONS_KEY","withNumberedRepeats","EnumNaming","enumDeclaration"],"mappings":";;;;;;AAcA,MAAM,oBAAA,GAAuB,oBAAA;AAE7B,MAAM,mBAAA,GAAsB,wBAAA;AACrB,MAAM,cAAA,GAAiB;AAC9B,MAAM,0BAA+B,IAAI,GAAA,CAAoB,CAAC,GAAGA,2BAAA,EAAcC,2BAAY,CAAC,CAAA;AAS5F,SAAS,UAAA,CAAW,QAAgB,GAAA,EAAqB;AACvD,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,EAAG,GAAG,CAAA,CAAA,CACnB,MAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS;AACb,IAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,CAAC,EAAE,WAAA,EAAY,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAC/D,IAAA,OAAO,WAAA,CAAY,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA;AAAA,EACpD,CAAC,CAAA,CACA,IAAA,CAAK,EAAE,CAAA;AACZ;AAGA,SAAS,cAAc,IAAA,EAAsB;AAC3C,EAAA,OAAO,KACJ,KAAA,CAAM,cAAc,EACpB,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,KAAgB,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA,CAC1D,KAAK,EAAE,CAAA;AACZ;AAGA,SAAS,iBAAA,CAAkB,QAAgB,GAAA,EAAqB;AAC9D,EAAA,MAAM,QAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS;AACzC,IAAA,MAAM,SAAA,GAAY,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAA;AAChD,IAAA,MAAM,IAAA,GAAO,SAAA,GAAY,CAAC,CAAA,IAAK,YAAY,CAAC,CAAA;AAC5C,IAAA,OAAO,SAAS,MAAA,GAAY,IAAA,GAAO,CAAA,EAAA,EAAK,aAAA,CAAc,IAAI,CAAC,CAAA,CAAA;AAAA,EAC7D,CAAC,CAAA;AACD,EAAA,OAAO,UAAA,CAAW,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA;AAC3C;AAYA,SAAS,gBAAgB,QAAA,EAAuC;AAC9D,EAAA,OAAO,MAAA,CAAO,QAAQ,QAAQ,CAAA,CAAE,QAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAA2B;AAC7E,IAAA,IAAI,QAAQC,wCAAA,EAA2B;AACrC,MAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,GAAI,EAAC;AAAA,IAChF;AACA,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,GAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAC,CAAA,GAAI,EAAC;AAAA,EAC9C,CAAC,CAAA;AACH;AAEA,SAAS,eAAe,KAAA,EAAqC;AAC3D,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA;AAAA,IAAQ,CAAC,CAAC,GAAA,EAAK,QAAQ,CAAA,KAClD,eAAA,CAAgB,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,MAAA,EAAQ,SAAS,CAAA,KAAM;AACrD,MAAA,MAAM,WAAA,GAAe,UAA8B,WAAA,IAAe,MAAA;AAClE,MAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,WAAA,EAAY;AAAA,IACpC,CAAC;AAAA,GACH;AACF;AAEA,SAAS,QAAQ,KAAA,EAA+C;AAC9D,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAA,CAAO,IAAI,IAAA,EAAA,CAAO,MAAA,CAAO,IAAI,IAAI,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,YAAY,UAAA,EAAgD;AACnE,EAAA,MAAM,IAAA,GAAO,UAAA,CAAW,GAAA,CAAI,CAAC,EAAA,KAAO,EAAA,CAAG,WAAA,IAAe,UAAA,CAAW,EAAA,CAAG,MAAA,EAAQ,EAAA,CAAG,GAAG,CAAC,CAAA;AACnF,EAAA,MAAM,MAAA,GAAS,QAAQ,IAAI,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,IAAI,KAAA,KAAU;AAC1C,IAAA,MAAM,iBAAA,GACJ,EAAA,CAAG,WAAA,KAAgB,MAAA,IAAA,CAAc,MAAA,CAAO,IAAI,IAAA,CAAK,KAAK,CAAW,CAAA,IAAK,CAAA,IAAK,CAAA;AAC7E,IAAA,OAAO,iBAAA,GAAoB,kBAAkB,EAAA,CAAG,MAAA,EAAQ,GAAG,GAAG,CAAA,GAAK,KAAK,KAAK,CAAA;AAAA,EAC/E,CAAC,CAAA;AACD,EAAA,OAAOC,iCAAA,CAAoB,OAAO,CAAC,IAAA,EAAM,UAAU,CAAA,EAAG,IAAI,CAAA,EAAG,KAAK,CAAA,CAAE,CAAA;AACtE;AAMO,SAAS,aAAa,KAAA,EAAkC;AAC7D,EAAA,MAAM,UAAA,GAAa,eAAe,KAAK,CAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,YAAY,UAAU,CAAA;AACpC,EAAA,OAAO;AAAA,IACL,QAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,SAAA,KAAc,UAAU,GAAG,CAAA;AAAA,IACnD,QAAA,EAAU,MAAM,GAAA,CAAI,CAAC,UAAU,EAAE,IAAA,EAAM,WAAA,EAAa,MAAA,EAAU,CAAE;AAAA,GAClE;AACF;AAMO,SAAS,wBAAwB,KAAA,EAAuC;AAC7E,EAAA,MAAM,MAAA,GAAS,IAAIC,qBAAA,EAAW;AAC9B,EAAA,OAAOC,0BAAA,CAAgB,OAAO,QAAA,CAAS,cAAc,GAAG,YAAA,CAAa,KAAK,GAAG,MAAM,CAAA;AACrF;;;;"}
1
+ {"version":3,"file":"paths-enum.cjs","sources":["../../../../src/application/transform/document/paths-enum.ts"],"sourcesContent":["import type { IrEnumDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport {\n ADDITIONAL_OPERATIONS_KEY,\n HTTP_METHODS,\n type OperationEntry,\n type PathItemMethod,\n type PathsObject,\n QUERY_METHOD,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport { EnumNaming, enumDeclaration } from \"../footer/enum-naming.js\";\nimport { withNumberedRepeats } from \"../numbered-names.js\";\nimport type { EnumMemberMetadata } from \"../schema/schema-context.js\";\n\n/** A path segment that is one parameter: `{user_id}` or `:user_id`. */\nconst PARAMETER_SEGMENT_RE = /^(?:{(.+)}|:(.+))$/;\n/** Characters not allowed in an enum key, or a `{param}` / `:param` part (first match only). */\nconst INVALID_KEY_PART_RE = /{.*}|:.*|[^a-zA-Z\\d_]+/;\nexport const API_PATHS_NAME = \"ApiPaths\";\nconst METHODS: ReadonlySet<string> = new Set<PathItemMethod>([...HTTP_METHODS, QUERY_METHOD]);\n\n/** The members of the `ApiPaths` enum (`--make-paths-enum`). */\nexport interface ApiPathsEnum {\n readonly values: readonly string[];\n readonly metadata: readonly EnumMemberMetadata[];\n}\n\n/** `getUsersById` style key from the method and URL, when the operation has no ID. */\nfunction keyFromUrl(method: string, url: string): string {\n return `${method}${url}`\n .split(\"/\")\n .map((part) => {\n const capitalized = part.charAt(0).toUpperCase() + part.slice(1);\n return capitalized.replace(INVALID_KEY_PART_RE, \"\");\n })\n .join(\"\");\n}\n\n/** `user_id` and `order-id` as `UserId` and `OrderId`. */\nfunction parameterWord(name: string): string {\n return name\n .split(/[^a-zA-Z\\d]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\n/** The key with parameters named, `GetUserByUserId`, for keys that collide without them. */\nfunction keyWithParameters(method: string, url: string): string {\n const parts = url.split(\"/\").map((part) => {\n const parameter = PARAMETER_SEGMENT_RE.exec(part);\n const name = parameter?.[1] ?? parameter?.[2];\n return name === undefined ? part : `By${parameterWord(name)}`;\n });\n return keyFromUrl(method, parts.join(\"/\"));\n}\n\ninterface PathOperation {\n readonly url: string;\n readonly method: string;\n readonly operationId: string | undefined;\n}\n\n/**\n * The operations of one path item in document order; `additionalOperations` (OpenAPI 3.2) adds\n * its methods where the key stands.\n */\nfunction pathItemEntries(pathItem: object): [string, unknown][] {\n return Object.entries(pathItem).flatMap(([key, value]): [string, unknown][] => {\n if (key === ADDITIONAL_OPERATIONS_KEY) {\n return typeof value === \"object\" && value !== null ? Object.entries(value) : [];\n }\n return METHODS.has(key) ? [[key, value]] : [];\n });\n}\n\n/** Which operations get a member; the generator leaves out those `--exclude-deprecated` drops. */\nexport type OperationFilter = (operation: OperationEntry) => boolean;\n\nconst INCLUDES_EVERY_OPERATION: OperationFilter = () => true;\n\nfunction pathOperations(paths: PathsObject, isIncluded: OperationFilter): PathOperation[] {\n return Object.entries(paths).flatMap(([url, pathItem]) =>\n pathItemEntries(pathItem)\n .filter(([, operation]) => isIncluded(operation as OperationEntry))\n .map(([method, operation]) => {\n const operationId = (operation as OperationObject).operationId || undefined;\n return { url, method, operationId };\n }),\n );\n}\n\nfunction countOf(names: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const name of names) {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n return counts;\n}\n\n/**\n * Names that are unique, so the enum compiles (upstream #2194). A URL key that collides names\n * its parameters; a name that still collides gets 2, 3… after its first use.\n */\nfunction uniqueNames(operations: readonly PathOperation[]): string[] {\n const keys = operations.map((op) => op.operationId ?? keyFromUrl(op.method, op.url));\n const counts = countOf(keys);\n const named = operations.map((op, index) => {\n const isCollidingUrlKey =\n op.operationId === undefined && (counts.get(keys[index] as string) ?? 0) > 1;\n return isCollidingUrlKey ? keyWithParameters(op.method, op.url) : (keys[index] as string);\n });\n return withNumberedRepeats(named, (name, count) => `${name}${count}`);\n}\n\n/**\n * One enum member per operation: the URL as the value, the operation ID (or a key built from the\n * method and URL) as the name. Paths are in document order; `--alphabetize` does not apply.\n */\nexport function apiPathsEnum(\n paths: PathsObject,\n isIncluded: OperationFilter = INCLUDES_EVERY_OPERATION,\n): ApiPathsEnum {\n const operations = pathOperations(paths, isIncluded);\n const names = uniqueNames(operations);\n return {\n values: operations.map((operation) => operation.url),\n metadata: names.map((name) => ({ name, description: undefined })),\n };\n}\n\n/**\n * The `ApiPaths` enum declaration. Its own naming state is equivalent to the run's: the name is a\n * valid identifier, and member names only reset the state, never read it.\n */\nexport function apiPathsEnumDeclaration(\n paths: PathsObject,\n isIncluded: OperationFilter = INCLUDES_EVERY_OPERATION,\n): IrEnumDeclaration {\n const naming = new EnumNaming();\n return enumDeclaration(naming.enumName(API_PATHS_NAME), apiPathsEnum(paths, isIncluded), naming);\n}\n"],"names":["HTTP_METHODS","QUERY_METHOD","ADDITIONAL_OPERATIONS_KEY","withNumberedRepeats","EnumNaming","enumDeclaration"],"mappings":"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"}
@@ -31,9 +31,10 @@ function pathItemEntries(pathItem) {
31
31
  return METHODS.has(key) ? [[key, value]] : [];
32
32
  });
33
33
  }
34
- function pathOperations(paths) {
34
+ const INCLUDES_EVERY_OPERATION = () => true;
35
+ function pathOperations(paths, isIncluded) {
35
36
  return Object.entries(paths).flatMap(
36
- ([url, pathItem]) => pathItemEntries(pathItem).map(([method, operation]) => {
37
+ ([url, pathItem]) => pathItemEntries(pathItem).filter(([, operation]) => isIncluded(operation)).map(([method, operation]) => {
37
38
  const operationId = operation.operationId || void 0;
38
39
  return { url, method, operationId };
39
40
  })
@@ -55,17 +56,17 @@ function uniqueNames(operations) {
55
56
  });
56
57
  return withNumberedRepeats(named, (name, count) => `${name}${count}`);
57
58
  }
58
- function apiPathsEnum(paths) {
59
- const operations = pathOperations(paths);
59
+ function apiPathsEnum(paths, isIncluded = INCLUDES_EVERY_OPERATION) {
60
+ const operations = pathOperations(paths, isIncluded);
60
61
  const names = uniqueNames(operations);
61
62
  return {
62
63
  values: operations.map((operation) => operation.url),
63
64
  metadata: names.map((name) => ({ name, description: void 0 }))
64
65
  };
65
66
  }
66
- function apiPathsEnumDeclaration(paths) {
67
+ function apiPathsEnumDeclaration(paths, isIncluded = INCLUDES_EVERY_OPERATION) {
67
68
  const naming = new EnumNaming();
68
- return enumDeclaration(naming.enumName(API_PATHS_NAME), apiPathsEnum(paths), naming);
69
+ return enumDeclaration(naming.enumName(API_PATHS_NAME), apiPathsEnum(paths, isIncluded), naming);
69
70
  }
70
71
 
71
72
  export { API_PATHS_NAME, apiPathsEnum, apiPathsEnumDeclaration };
@@ -1 +1 @@
1
- {"version":3,"file":"paths-enum.mjs","sources":["../../../../src/application/transform/document/paths-enum.ts"],"sourcesContent":["import type { IrEnumDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport {\n ADDITIONAL_OPERATIONS_KEY,\n HTTP_METHODS,\n type PathItemMethod,\n type PathsObject,\n QUERY_METHOD,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport { EnumNaming, enumDeclaration } from \"../footer/enum-naming.js\";\nimport { withNumberedRepeats } from \"../numbered-names.js\";\nimport type { EnumMemberMetadata } from \"../schema/schema-context.js\";\n\n/** A path segment that is one parameter: `{user_id}` or `:user_id`. */\nconst PARAMETER_SEGMENT_RE = /^(?:{(.+)}|:(.+))$/;\n/** Characters not allowed in an enum key, or a `{param}` / `:param` part (first match only). */\nconst INVALID_KEY_PART_RE = /{.*}|:.*|[^a-zA-Z\\d_]+/;\nexport const API_PATHS_NAME = \"ApiPaths\";\nconst METHODS: ReadonlySet<string> = new Set<PathItemMethod>([...HTTP_METHODS, QUERY_METHOD]);\n\n/** The members of the `ApiPaths` enum (`--make-paths-enum`). */\nexport interface ApiPathsEnum {\n readonly values: readonly string[];\n readonly metadata: readonly EnumMemberMetadata[];\n}\n\n/** `getUsersById` style key from the method and URL, when the operation has no ID. */\nfunction keyFromUrl(method: string, url: string): string {\n return `${method}${url}`\n .split(\"/\")\n .map((part) => {\n const capitalized = part.charAt(0).toUpperCase() + part.slice(1);\n return capitalized.replace(INVALID_KEY_PART_RE, \"\");\n })\n .join(\"\");\n}\n\n/** `user_id` and `order-id` as `UserId` and `OrderId`. */\nfunction parameterWord(name: string): string {\n return name\n .split(/[^a-zA-Z\\d]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\n/** The key with parameters named, `GetUserByUserId`, for keys that collide without them. */\nfunction keyWithParameters(method: string, url: string): string {\n const parts = url.split(\"/\").map((part) => {\n const parameter = PARAMETER_SEGMENT_RE.exec(part);\n const name = parameter?.[1] ?? parameter?.[2];\n return name === undefined ? part : `By${parameterWord(name)}`;\n });\n return keyFromUrl(method, parts.join(\"/\"));\n}\n\ninterface PathOperation {\n readonly url: string;\n readonly method: string;\n readonly operationId: string | undefined;\n}\n\n/**\n * The operations of one path item in document order; `additionalOperations` (OpenAPI 3.2) adds\n * its methods where the key stands.\n */\nfunction pathItemEntries(pathItem: object): [string, unknown][] {\n return Object.entries(pathItem).flatMap(([key, value]): [string, unknown][] => {\n if (key === ADDITIONAL_OPERATIONS_KEY) {\n return typeof value === \"object\" && value !== null ? Object.entries(value) : [];\n }\n return METHODS.has(key) ? [[key, value]] : [];\n });\n}\n\nfunction pathOperations(paths: PathsObject): PathOperation[] {\n return Object.entries(paths).flatMap(([url, pathItem]) =>\n pathItemEntries(pathItem).map(([method, operation]) => {\n const operationId = (operation as OperationObject).operationId || undefined;\n return { url, method, operationId };\n }),\n );\n}\n\nfunction countOf(names: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const name of names) {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n return counts;\n}\n\n/**\n * Names that are unique, so the enum compiles (upstream #2194). A URL key that collides names\n * its parameters; a name that still collides gets 2, 3… after its first use.\n */\nfunction uniqueNames(operations: readonly PathOperation[]): string[] {\n const keys = operations.map((op) => op.operationId ?? keyFromUrl(op.method, op.url));\n const counts = countOf(keys);\n const named = operations.map((op, index) => {\n const isCollidingUrlKey =\n op.operationId === undefined && (counts.get(keys[index] as string) ?? 0) > 1;\n return isCollidingUrlKey ? keyWithParameters(op.method, op.url) : (keys[index] as string);\n });\n return withNumberedRepeats(named, (name, count) => `${name}${count}`);\n}\n\n/**\n * One enum member per operation: the URL as the value, the operation ID (or a key built from the\n * method and URL) as the name. Paths are in document order; `--alphabetize` does not apply.\n */\nexport function apiPathsEnum(paths: PathsObject): ApiPathsEnum {\n const operations = pathOperations(paths);\n const names = uniqueNames(operations);\n return {\n values: operations.map((operation) => operation.url),\n metadata: names.map((name) => ({ name, description: undefined })),\n };\n}\n\n/**\n * The `ApiPaths` enum declaration. Its own naming state is equivalent to the run's: the name is a\n * valid identifier, and member names only reset the state, never read it.\n */\nexport function apiPathsEnumDeclaration(paths: PathsObject): IrEnumDeclaration {\n const naming = new EnumNaming();\n return enumDeclaration(naming.enumName(API_PATHS_NAME), apiPathsEnum(paths), naming);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths-enum.mjs","sources":["../../../../src/application/transform/document/paths-enum.ts"],"sourcesContent":["import type { IrEnumDeclaration } from \"../../../domain/ir/nodes.js\";\nimport type { OperationObject } from \"../../../domain/openapi/operation-object.js\";\nimport {\n ADDITIONAL_OPERATIONS_KEY,\n HTTP_METHODS,\n type OperationEntry,\n type PathItemMethod,\n type PathsObject,\n QUERY_METHOD,\n} from \"../../../domain/openapi/path-item-object.js\";\nimport { EnumNaming, enumDeclaration } from \"../footer/enum-naming.js\";\nimport { withNumberedRepeats } from \"../numbered-names.js\";\nimport type { EnumMemberMetadata } from \"../schema/schema-context.js\";\n\n/** A path segment that is one parameter: `{user_id}` or `:user_id`. */\nconst PARAMETER_SEGMENT_RE = /^(?:{(.+)}|:(.+))$/;\n/** Characters not allowed in an enum key, or a `{param}` / `:param` part (first match only). */\nconst INVALID_KEY_PART_RE = /{.*}|:.*|[^a-zA-Z\\d_]+/;\nexport const API_PATHS_NAME = \"ApiPaths\";\nconst METHODS: ReadonlySet<string> = new Set<PathItemMethod>([...HTTP_METHODS, QUERY_METHOD]);\n\n/** The members of the `ApiPaths` enum (`--make-paths-enum`). */\nexport interface ApiPathsEnum {\n readonly values: readonly string[];\n readonly metadata: readonly EnumMemberMetadata[];\n}\n\n/** `getUsersById` style key from the method and URL, when the operation has no ID. */\nfunction keyFromUrl(method: string, url: string): string {\n return `${method}${url}`\n .split(\"/\")\n .map((part) => {\n const capitalized = part.charAt(0).toUpperCase() + part.slice(1);\n return capitalized.replace(INVALID_KEY_PART_RE, \"\");\n })\n .join(\"\");\n}\n\n/** `user_id` and `order-id` as `UserId` and `OrderId`. */\nfunction parameterWord(name: string): string {\n return name\n .split(/[^a-zA-Z\\d]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\"\");\n}\n\n/** The key with parameters named, `GetUserByUserId`, for keys that collide without them. */\nfunction keyWithParameters(method: string, url: string): string {\n const parts = url.split(\"/\").map((part) => {\n const parameter = PARAMETER_SEGMENT_RE.exec(part);\n const name = parameter?.[1] ?? parameter?.[2];\n return name === undefined ? part : `By${parameterWord(name)}`;\n });\n return keyFromUrl(method, parts.join(\"/\"));\n}\n\ninterface PathOperation {\n readonly url: string;\n readonly method: string;\n readonly operationId: string | undefined;\n}\n\n/**\n * The operations of one path item in document order; `additionalOperations` (OpenAPI 3.2) adds\n * its methods where the key stands.\n */\nfunction pathItemEntries(pathItem: object): [string, unknown][] {\n return Object.entries(pathItem).flatMap(([key, value]): [string, unknown][] => {\n if (key === ADDITIONAL_OPERATIONS_KEY) {\n return typeof value === \"object\" && value !== null ? Object.entries(value) : [];\n }\n return METHODS.has(key) ? [[key, value]] : [];\n });\n}\n\n/** Which operations get a member; the generator leaves out those `--exclude-deprecated` drops. */\nexport type OperationFilter = (operation: OperationEntry) => boolean;\n\nconst INCLUDES_EVERY_OPERATION: OperationFilter = () => true;\n\nfunction pathOperations(paths: PathsObject, isIncluded: OperationFilter): PathOperation[] {\n return Object.entries(paths).flatMap(([url, pathItem]) =>\n pathItemEntries(pathItem)\n .filter(([, operation]) => isIncluded(operation as OperationEntry))\n .map(([method, operation]) => {\n const operationId = (operation as OperationObject).operationId || undefined;\n return { url, method, operationId };\n }),\n );\n}\n\nfunction countOf(names: readonly string[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const name of names) {\n counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n return counts;\n}\n\n/**\n * Names that are unique, so the enum compiles (upstream #2194). A URL key that collides names\n * its parameters; a name that still collides gets 2, 3… after its first use.\n */\nfunction uniqueNames(operations: readonly PathOperation[]): string[] {\n const keys = operations.map((op) => op.operationId ?? keyFromUrl(op.method, op.url));\n const counts = countOf(keys);\n const named = operations.map((op, index) => {\n const isCollidingUrlKey =\n op.operationId === undefined && (counts.get(keys[index] as string) ?? 0) > 1;\n return isCollidingUrlKey ? keyWithParameters(op.method, op.url) : (keys[index] as string);\n });\n return withNumberedRepeats(named, (name, count) => `${name}${count}`);\n}\n\n/**\n * One enum member per operation: the URL as the value, the operation ID (or a key built from the\n * method and URL) as the name. Paths are in document order; `--alphabetize` does not apply.\n */\nexport function apiPathsEnum(\n paths: PathsObject,\n isIncluded: OperationFilter = INCLUDES_EVERY_OPERATION,\n): ApiPathsEnum {\n const operations = pathOperations(paths, isIncluded);\n const names = uniqueNames(operations);\n return {\n values: operations.map((operation) => operation.url),\n metadata: names.map((name) => ({ name, description: undefined })),\n };\n}\n\n/**\n * The `ApiPaths` enum declaration. Its own naming state is equivalent to the run's: the name is a\n * valid identifier, and member names only reset the state, never read it.\n */\nexport function apiPathsEnumDeclaration(\n paths: PathsObject,\n isIncluded: OperationFilter = INCLUDES_EVERY_OPERATION,\n): IrEnumDeclaration {\n const naming = new EnumNaming();\n return enumDeclaration(naming.enumName(API_PATHS_NAME), apiPathsEnum(paths, isIncluded), naming);\n}\n"],"names":[],"mappings":";;;;AAeA,MAAM,oBAAA,GAAuB,oBAAA;AAE7B,MAAM,mBAAA,GAAsB,wBAAA;AACrB,MAAM,cAAA,GAAiB;AAC9B,MAAM,0BAA+B,IAAI,GAAA,CAAoB,CAAC,GAAG,YAAA,EAAc,YAAY,CAAC,CAAA;AAS5F,SAAS,UAAA,CAAW,QAAgB,GAAA,EAAqB;AACvD,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,EAAG,GAAG,CAAA,CAAA,CACnB,MAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS;AACb,IAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,CAAC,EAAE,WAAA,EAAY,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AAC/D,IAAA,OAAO,WAAA,CAAY,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA;AAAA,EACpD,CAAC,CAAA,CACA,IAAA,CAAK,EAAE,CAAA;AACZ;AAGA,SAAS,cAAc,IAAA,EAAsB;AAC3C,EAAA,OAAO,KACJ,KAAA,CAAM,cAAc,EACpB,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,KAAgB,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA,CAC1D,KAAK,EAAE,CAAA;AACZ;AAGA,SAAS,iBAAA,CAAkB,QAAgB,GAAA,EAAqB;AAC9D,EAAA,MAAM,QAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS;AACzC,IAAA,MAAM,SAAA,GAAY,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAA;AAChD,IAAA,MAAM,IAAA,GAAO,SAAA,GAAY,CAAC,CAAA,IAAK,YAAY,CAAC,CAAA;AAC5C,IAAA,OAAO,SAAS,MAAA,GAAY,IAAA,GAAO,CAAA,EAAA,EAAK,aAAA,CAAc,IAAI,CAAC,CAAA,CAAA;AAAA,EAC7D,CAAC,CAAA;AACD,EAAA,OAAO,UAAA,CAAW,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA;AAC3C;AAYA,SAAS,gBAAgB,QAAA,EAAuC;AAC9D,EAAA,OAAO,MAAA,CAAO,QAAQ,QAAQ,CAAA,CAAE,QAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAA2B;AAC7E,IAAA,IAAI,QAAQ,yBAAA,EAA2B;AACrC,MAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,GAAI,EAAC;AAAA,IAChF;AACA,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,GAAI,CAAC,CAAC,GAAA,EAAK,KAAK,CAAC,CAAA,GAAI,EAAC;AAAA,EAC9C,CAAC,CAAA;AACH;AAKA,MAAM,2BAA4C,MAAM,IAAA;AAExD,SAAS,cAAA,CAAe,OAAoB,UAAA,EAA8C;AACxF,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA;AAAA,IAAQ,CAAC,CAAC,GAAA,EAAK,QAAQ,MAClD,eAAA,CAAgB,QAAQ,CAAA,CACrB,MAAA,CAAO,CAAC,GAAG,SAAS,CAAA,KAAM,UAAA,CAAW,SAA2B,CAAC,CAAA,CACjE,IAAI,CAAC,CAAC,MAAA,EAAQ,SAAS,CAAA,KAAM;AAC5B,MAAA,MAAM,WAAA,GAAe,UAA8B,WAAA,IAAe,MAAA;AAClE,MAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,WAAA,EAAY;AAAA,IACpC,CAAC;AAAA,GACL;AACF;AAEA,SAAS,QAAQ,KAAA,EAA+C;AAC9D,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAA,CAAO,IAAI,IAAA,EAAA,CAAO,MAAA,CAAO,IAAI,IAAI,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,YAAY,UAAA,EAAgD;AACnE,EAAA,MAAM,IAAA,GAAO,UAAA,CAAW,GAAA,CAAI,CAAC,EAAA,KAAO,EAAA,CAAG,WAAA,IAAe,UAAA,CAAW,EAAA,CAAG,MAAA,EAAQ,EAAA,CAAG,GAAG,CAAC,CAAA;AACnF,EAAA,MAAM,MAAA,GAAS,QAAQ,IAAI,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,IAAI,KAAA,KAAU;AAC1C,IAAA,MAAM,iBAAA,GACJ,EAAA,CAAG,WAAA,KAAgB,MAAA,IAAA,CAAc,MAAA,CAAO,IAAI,IAAA,CAAK,KAAK,CAAW,CAAA,IAAK,CAAA,IAAK,CAAA;AAC7E,IAAA,OAAO,iBAAA,GAAoB,kBAAkB,EAAA,CAAG,MAAA,EAAQ,GAAG,GAAG,CAAA,GAAK,KAAK,KAAK,CAAA;AAAA,EAC/E,CAAC,CAAA;AACD,EAAA,OAAO,mBAAA,CAAoB,OAAO,CAAC,IAAA,EAAM,UAAU,CAAA,EAAG,IAAI,CAAA,EAAG,KAAK,CAAA,CAAE,CAAA;AACtE;AAMO,SAAS,YAAA,CACd,KAAA,EACA,UAAA,GAA8B,wBAAA,EAChB;AACd,EAAA,MAAM,UAAA,GAAa,cAAA,CAAe,KAAA,EAAO,UAAU,CAAA;AACnD,EAAA,MAAM,KAAA,GAAQ,YAAY,UAAU,CAAA;AACpC,EAAA,OAAO;AAAA,IACL,QAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,SAAA,KAAc,UAAU,GAAG,CAAA;AAAA,IACnD,QAAA,EAAU,MAAM,GAAA,CAAI,CAAC,UAAU,EAAE,IAAA,EAAM,WAAA,EAAa,MAAA,EAAU,CAAE;AAAA,GAClE;AACF;AAMO,SAAS,uBAAA,CACd,KAAA,EACA,UAAA,GAA8B,wBAAA,EACX;AACnB,EAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAC9B,EAAA,OAAO,eAAA,CAAgB,OAAO,QAAA,CAAS,cAAc,GAAG,YAAA,CAAa,KAAA,EAAO,UAAU,CAAA,EAAG,MAAM,CAAA;AACjG;;"}
@@ -2,92 +2,61 @@
2
2
 
3
3
  const constructors = require('../../../domain/ir/constructors.cjs');
4
4
  const propertyName = require('../../../domain/ir/property-name.cjs');
5
- const rawTextEscapes = require('../../../domain/ir/raw-text-escapes.cjs');
6
5
  const jsonPointer = require('../../../domain/openapi/json-pointer.cjs');
7
- const pathItemObject = require('../../../domain/openapi/path-item-object.cjs');
8
- const outputFixes = require('../../../domain/output-fixes.cjs');
9
6
  const documentEntries = require('../document-entries.cjs');
10
7
  const refType = require('../ref-type.cjs');
11
8
  const declaredTypes = require('./declared-types.cjs');
12
9
  const documentMember = require('./document-member.cjs');
13
10
  const pathItem = require('./path-item.cjs');
14
11
  const pathKeyOverlaps = require('./path-key-overlaps.cjs');
15
- const pathTemplateReplace = require('./path-template-replace.cjs');
12
+ const pathTemplateKey = require('./path-template-key.cjs');
16
13
  const typeAssignability = require('./type-assignability.cjs');
17
14
 
18
- const PATH_PARAMETER_RE = /\{[^{}]+\}/g;
19
- const PLACEHOLDERS = /* @__PURE__ */ new Map([
20
- ["number", "number"],
21
- ["integer", "number"],
22
- ["boolean", "boolean"]
23
- ]);
24
- const STRING_PLACEHOLDER = "string";
25
- function resolvedParameter(parameter, context) {
26
- return "$ref" in parameter && parameter.$ref ? context.refs.resolve(parameter.$ref) : parameter;
15
+ function pathKeyOf(parts) {
16
+ const plainUrl = pathTemplateKey.plainUrlOf(parts);
17
+ return plainUrl === null ? { kind: "template", parts } : literalKey(plainUrl);
27
18
  }
28
- function addPathParameters(parameters, byName, context) {
29
- for (const parameter of parameters) {
30
- const resolved = resolvedParameter(parameter, context);
31
- if (resolved && resolved.in === "path") {
32
- byName.set(resolved.name, resolved);
33
- }
34
- }
35
- }
36
- function pathParameters(pathItem, context) {
37
- const byName = /* @__PURE__ */ new Map();
38
- addPathParameters(pathItem.parameters ?? [], byName, context);
39
- for (const { operation: entry } of pathItemObject.pathItemOperations(pathItem)) {
40
- const operation = entry.$ref ? context.refs.resolve(entry.$ref) : entry;
41
- addPathParameters(operation?.parameters ?? [], byName, context);
19
+ function keyMember(url, parts, type, isReadonly) {
20
+ const key = pathKeyOf(parts);
21
+ if (key.kind === "literal") {
22
+ const member2 = constructors.irProperty(propertyName.toPropertyName(key.url), type, { isReadonly });
23
+ return { url, member: member2, key, type };
42
24
  }
43
- return byName;
44
- }
45
- function splitTemplateParts(url, matches) {
46
- return url.split(PATH_PARAMETER_RE).flatMap((text, index) => {
47
- const type = matches[index]?.type;
48
- const textPart = { kind: "text", text };
49
- return type === void 0 ? [textPart] : [textPart, { kind: "placeholder", type }];
50
- });
25
+ const member = {
26
+ kind: "indexSignature",
27
+ parameterName: "path",
28
+ parameterType: constructors.irRaw(pathTemplateKey.templateText(parts)),
29
+ type,
30
+ isReadonly,
31
+ comments: []
32
+ };
33
+ return { url, member, key, type };
51
34
  }
52
- function pathTemplateParts(url, pathItem, context) {
53
- const found = url.match(PATH_PARAMETER_RE);
54
- if (!found) {
55
- return null;
35
+ function isUntakenKey(url, key, takenUrls) {
36
+ const isExpandedUrl = key.kind === "literal" && key.url !== url;
37
+ if (!isExpandedUrl) {
38
+ return true;
56
39
  }
57
- const parameters = pathParameters(pathItem, context);
58
- const matches = found.map((match) => {
59
- const schema = parameters.get(match.slice(1, -1))?.schema;
60
- return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
61
- });
62
- return context.options.fixes.has(outputFixes.FIX.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : pathTemplateReplace.replacedTemplateParts(url, matches);
40
+ const isTaken = takenUrls.has(key.url);
41
+ takenUrls.add(key.url);
42
+ return !isTaken;
63
43
  }
64
- function templateText(parts) {
65
- const text = parts.map(
66
- (part) => part.kind === "text" ? rawTextEscapes.escapeTemplateText(part.text) : pathTemplateReplace.placeholderText(part.type)
67
- ).join("");
68
- return `\`${text}\``;
44
+ function withoutTakenUrls(url, members, takenUrls) {
45
+ return members.filter(({ key }) => isUntakenKey(url, key, takenUrls));
69
46
  }
70
- function pathItemMember(url, pathItem$1, context) {
47
+ function pathItemMembers(url, pathItem$1, context) {
71
48
  const isReadonly = context.options.immutable;
72
49
  const type = pathItem.pathItemType(
73
50
  pathItem$1,
74
51
  { path: jsonPointer.appendPointer(jsonPointer.ROOT_POINTER, ["paths", url]) },
75
52
  context
76
53
  );
77
- const parts = context.options.pathParamsAsTypes && url.includes("{") ? pathTemplateParts(url, pathItem$1, context) : null;
54
+ const parts = context.options.pathParamsAsTypes && url.includes("{") ? pathTemplateKey.pathTemplateParts(url, pathItem$1, context) : null;
78
55
  if (parts === null) {
79
- const member2 = constructors.irProperty(propertyName.toPropertyName(url), type, { isReadonly });
80
- return { url, member: member2, key: literalKey(url), type };
56
+ const member = constructors.irProperty(propertyName.toPropertyName(url), type, { isReadonly });
57
+ return [{ url, member, key: literalKey(url), type }];
81
58
  }
82
- const member = {
83
- kind: "indexSignature",
84
- parameterName: "path",
85
- parameterType: constructors.irRaw(templateText(parts)),
86
- type,
87
- isReadonly,
88
- comments: []
89
- };
90
- return { url, member, key: { kind: "template", parts }, type };
59
+ return pathTemplateKey.booleanExpandedKeys(parts).map((key) => keyMember(url, key, type, isReadonly));
91
60
  }
92
61
  function literalKey(url) {
93
62
  return { kind: "literal", url };
@@ -128,6 +97,7 @@ function pathsObjectType(paths, lookup = declaredTypes.NO_DECLARED_TYPES) {
128
97
  }
129
98
  function pathMembers(paths, context) {
130
99
  const members = [];
100
+ const takenUrls = new Set(Object.keys(paths));
131
101
  for (const [url, pathItem] of documentEntries.documentEntries(paths, context.options)) {
132
102
  if (!pathItem || typeof pathItem !== "object") {
133
103
  continue;
@@ -139,9 +109,9 @@ function pathMembers(paths, context) {
139
109
  continue;
140
110
  }
141
111
  const startedAt = context.diagnostics.now();
142
- const path = pathItemMember(url, pathItem, context);
143
- members.push(path);
144
- if (path.member.kind === "property") {
112
+ const pathMembersOfUrl = pathItemMembers(url, pathItem, context);
113
+ members.push(...withoutTakenUrls(url, pathMembersOfUrl, takenUrls));
114
+ if (pathMembersOfUrl[0]?.key.kind === "literal" && pathMembersOfUrl[0].key.url === url) {
145
115
  context.diagnostics.debug(`Transformed path "${url}"`, context.diagnostics.now() - startedAt);
146
116
  }
147
117
  }
@@ -151,6 +121,8 @@ function pathsType(paths, context) {
151
121
  return pathsObjectType(pathMembers(paths, context));
152
122
  }
153
123
 
124
+ exports.isUntakenKey = isUntakenKey;
125
+ exports.pathKeyOf = pathKeyOf;
154
126
  exports.pathMembers = pathMembers;
155
127
  exports.pathsObjectType = pathsObjectType;
156
128
  exports.pathsType = pathsType;
@@ -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 { appendPointer, ROOT_POINTER } 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 { FIX } 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\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\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(FIX.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(\n pathItem,\n { path: appendPointer(ROOT_POINTER, [\"paths\", url]) },\n context,\n );\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","FIX","replacedTemplateParts","escapeTemplateText","placeholderText","pathItem","pathItemType","appendPointer","ROOT_POINTER","member","irProperty","toPropertyName","irRaw","assignabilityProof","NO_DECLARED_TYPES","coveringTemplateKeys","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 { appendPointer, ROOT_POINTER } from \"../../../domain/openapi/json-pointer.js\";\nimport type { PathItemObject, PathsObject } from \"../../../domain/openapi/path-item-object.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} from \"./path-key-overlaps.js\";\nimport {\n booleanExpandedKeys,\n pathTemplateParts,\n plainUrlOf,\n templateText,\n} from \"./path-template-key.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\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\n/** The key of the parts: a plain URL, or a template with placeholders left. */\nexport function pathKeyOf(parts: readonly PathKeyPart[]): PathKey {\n const plainUrl = plainUrlOf(parts);\n return plainUrl === null ? { kind: \"template\", parts } : literalKey(plainUrl);\n}\n\n/** The member of one key of a path: a property for a plain URL, else an index signature. */\nfunction keyMember(url: string, parts: readonly PathKeyPart[], type: IrType, isReadonly: boolean) {\n const key = pathKeyOf(parts);\n if (key.kind === \"literal\") {\n const member = irProperty(toPropertyName(key.url), type, { isReadonly });\n return { url, member, key, 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, type };\n}\n\n/**\n * Whether a key of the path at `url` is written. A URL that `${boolean}` keys give is not when it\n * is taken already: by a path of the document, which OpenAPI matches before a template (Paths\n * Object), or by the keys of an earlier path. A property written twice does not compile (TS2300).\n * `takenUrls` starts with the document's URLs and gets each expanded URL, in document order.\n */\nexport function isUntakenKey(url: string, key: PathKey, takenUrls: Set<string>): boolean {\n const isExpandedUrl = key.kind === \"literal\" && key.url !== url;\n if (!isExpandedUrl) {\n return true;\n }\n const isTaken = takenUrls.has(key.url);\n takenUrls.add(key.url);\n return !isTaken;\n}\n\nfunction withoutTakenUrls(url: string, members: readonly PathMember[], takenUrls: Set<string>) {\n return members.filter(({ key }) => isUntakenKey(url, key, takenUrls));\n}\n\n/** The members of a path: one, or one per key of its `${boolean}` placeholders. */\nfunction pathItemMembers(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember[] {\n const isReadonly = context.options.immutable;\n const type = pathItemType(\n pathItem,\n { path: appendPointer(ROOT_POINTER, [\"paths\", url]) },\n context,\n );\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 return booleanExpandedKeys(parts).map((key) => keyMember(url, key, type, isReadonly));\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 const takenUrls = new Set(Object.keys(paths));\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 pathMembersOfUrl = pathItemMembers(url, pathItem, context);\n members.push(...withoutTakenUrls(url, pathMembersOfUrl, takenUrls));\n // The original reports only paths written as properties.\n if (pathMembersOfUrl[0]?.key.kind === \"literal\" && pathMembersOfUrl[0].key.url === url) {\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":["plainUrlOf","member","irProperty","toPropertyName","irRaw","templateText","pathItem","pathItemType","appendPointer","ROOT_POINTER","pathTemplateParts","booleanExpandedKeys","assignabilityProof","NO_DECLARED_TYPES","coveringTemplateKeys","irObject","irIntersection","documentEntries","documentMember","refType"],"mappings":"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"}
@@ -1,71 +1,48 @@
1
1
  import { irObject, irIntersection, irProperty, irRaw } from '../../../domain/ir/constructors.mjs';
2
2
  import { toPropertyName } from '../../../domain/ir/property-name.mjs';
3
- import { escapeTemplateText } from '../../../domain/ir/raw-text-escapes.mjs';
4
3
  import { appendPointer, ROOT_POINTER } from '../../../domain/openapi/json-pointer.mjs';
5
- import { pathItemOperations } from '../../../domain/openapi/path-item-object.mjs';
6
- import { FIX } from '../../../domain/output-fixes.mjs';
7
4
  import { documentEntries } from '../document-entries.mjs';
8
5
  import { refType } from '../ref-type.mjs';
9
6
  import { NO_DECLARED_TYPES } from './declared-types.mjs';
10
7
  import { documentMember } from './document-member.mjs';
11
8
  import { pathItemType } from './path-item.mjs';
12
9
  import { coveringTemplateKeys } from './path-key-overlaps.mjs';
13
- import { replacedTemplateParts, placeholderText } from './path-template-replace.mjs';
10
+ import { plainUrlOf, pathTemplateParts, booleanExpandedKeys, templateText } from './path-template-key.mjs';
14
11
  import { assignabilityProof } from './type-assignability.mjs';
15
12
 
16
- const PATH_PARAMETER_RE = /\{[^{}]+\}/g;
17
- const PLACEHOLDERS = /* @__PURE__ */ new Map([
18
- ["number", "number"],
19
- ["integer", "number"],
20
- ["boolean", "boolean"]
21
- ]);
22
- const STRING_PLACEHOLDER = "string";
23
- function resolvedParameter(parameter, context) {
24
- return "$ref" in parameter && parameter.$ref ? context.refs.resolve(parameter.$ref) : parameter;
13
+ function pathKeyOf(parts) {
14
+ const plainUrl = plainUrlOf(parts);
15
+ return plainUrl === null ? { kind: "template", parts } : literalKey(plainUrl);
25
16
  }
26
- function addPathParameters(parameters, byName, context) {
27
- for (const parameter of parameters) {
28
- const resolved = resolvedParameter(parameter, context);
29
- if (resolved && resolved.in === "path") {
30
- byName.set(resolved.name, resolved);
31
- }
32
- }
33
- }
34
- function pathParameters(pathItem, context) {
35
- const byName = /* @__PURE__ */ new Map();
36
- addPathParameters(pathItem.parameters ?? [], byName, context);
37
- for (const { operation: entry } of pathItemOperations(pathItem)) {
38
- const operation = entry.$ref ? context.refs.resolve(entry.$ref) : entry;
39
- addPathParameters(operation?.parameters ?? [], byName, context);
17
+ function keyMember(url, parts, type, isReadonly) {
18
+ const key = pathKeyOf(parts);
19
+ if (key.kind === "literal") {
20
+ const member2 = irProperty(toPropertyName(key.url), type, { isReadonly });
21
+ return { url, member: member2, key, type };
40
22
  }
41
- return byName;
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
- });
23
+ const member = {
24
+ kind: "indexSignature",
25
+ parameterName: "path",
26
+ parameterType: irRaw(templateText(parts)),
27
+ type,
28
+ isReadonly,
29
+ comments: []
30
+ };
31
+ return { url, member, key, type };
49
32
  }
50
- function pathTemplateParts(url, pathItem, context) {
51
- const found = url.match(PATH_PARAMETER_RE);
52
- if (!found) {
53
- return null;
33
+ function isUntakenKey(url, key, takenUrls) {
34
+ const isExpandedUrl = key.kind === "literal" && key.url !== url;
35
+ if (!isExpandedUrl) {
36
+ return true;
54
37
  }
55
- const parameters = pathParameters(pathItem, context);
56
- const matches = found.map((match) => {
57
- const schema = parameters.get(match.slice(1, -1))?.schema;
58
- return { match, type: PLACEHOLDERS.get(schema?.type) ?? STRING_PLACEHOLDER };
59
- });
60
- return context.options.fixes.has(FIX.PATH_PARAM_TYPE_NAMES) ? splitTemplateParts(url, matches) : replacedTemplateParts(url, matches);
38
+ const isTaken = takenUrls.has(key.url);
39
+ takenUrls.add(key.url);
40
+ return !isTaken;
61
41
  }
62
- function templateText(parts) {
63
- const text = parts.map(
64
- (part) => part.kind === "text" ? escapeTemplateText(part.text) : placeholderText(part.type)
65
- ).join("");
66
- return `\`${text}\``;
42
+ function withoutTakenUrls(url, members, takenUrls) {
43
+ return members.filter(({ key }) => isUntakenKey(url, key, takenUrls));
67
44
  }
68
- function pathItemMember(url, pathItem, context) {
45
+ function pathItemMembers(url, pathItem, context) {
69
46
  const isReadonly = context.options.immutable;
70
47
  const type = pathItemType(
71
48
  pathItem,
@@ -74,18 +51,10 @@ function pathItemMember(url, pathItem, context) {
74
51
  );
75
52
  const parts = context.options.pathParamsAsTypes && url.includes("{") ? pathTemplateParts(url, pathItem, context) : null;
76
53
  if (parts === null) {
77
- const member2 = irProperty(toPropertyName(url), type, { isReadonly });
78
- return { url, member: member2, key: literalKey(url), type };
54
+ const member = irProperty(toPropertyName(url), type, { isReadonly });
55
+ return [{ url, member, key: literalKey(url), type }];
79
56
  }
80
- const member = {
81
- kind: "indexSignature",
82
- parameterName: "path",
83
- parameterType: irRaw(templateText(parts)),
84
- type,
85
- isReadonly,
86
- comments: []
87
- };
88
- return { url, member, key: { kind: "template", parts }, type };
57
+ return booleanExpandedKeys(parts).map((key) => keyMember(url, key, type, isReadonly));
89
58
  }
90
59
  function literalKey(url) {
91
60
  return { kind: "literal", url };
@@ -126,6 +95,7 @@ function pathsObjectType(paths, lookup = NO_DECLARED_TYPES) {
126
95
  }
127
96
  function pathMembers(paths, context) {
128
97
  const members = [];
98
+ const takenUrls = new Set(Object.keys(paths));
129
99
  for (const [url, pathItem] of documentEntries(paths, context.options)) {
130
100
  if (!pathItem || typeof pathItem !== "object") {
131
101
  continue;
@@ -137,9 +107,9 @@ function pathMembers(paths, context) {
137
107
  continue;
138
108
  }
139
109
  const startedAt = context.diagnostics.now();
140
- const path = pathItemMember(url, pathItem, context);
141
- members.push(path);
142
- if (path.member.kind === "property") {
110
+ const pathMembersOfUrl = pathItemMembers(url, pathItem, context);
111
+ members.push(...withoutTakenUrls(url, pathMembersOfUrl, takenUrls));
112
+ if (pathMembersOfUrl[0]?.key.kind === "literal" && pathMembersOfUrl[0].key.url === url) {
143
113
  context.diagnostics.debug(`Transformed path "${url}"`, context.diagnostics.now() - startedAt);
144
114
  }
145
115
  }
@@ -149,5 +119,5 @@ function pathsType(paths, context) {
149
119
  return pathsObjectType(pathMembers(paths, context));
150
120
  }
151
121
 
152
- export { pathMembers, pathsObjectType, pathsType };
122
+ export { isUntakenKey, pathKeyOf, pathMembers, pathsObjectType, pathsType };
153
123
  //# 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 { appendPointer, ROOT_POINTER } 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 { FIX } 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\n/** `[^{}]` keeps the scan linear: `[^}]` retried from every `{` of a long run of them. */\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(FIX.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(\n pathItem,\n { path: appendPointer(ROOT_POINTER, [\"paths\", url]) },\n context,\n );\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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"}
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 { appendPointer, ROOT_POINTER } from \"../../../domain/openapi/json-pointer.js\";\nimport type { PathItemObject, PathsObject } from \"../../../domain/openapi/path-item-object.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} from \"./path-key-overlaps.js\";\nimport {\n booleanExpandedKeys,\n pathTemplateParts,\n plainUrlOf,\n templateText,\n} from \"./path-template-key.js\";\nimport { assignabilityProof } from \"./type-assignability.js\";\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\n/** The key of the parts: a plain URL, or a template with placeholders left. */\nexport function pathKeyOf(parts: readonly PathKeyPart[]): PathKey {\n const plainUrl = plainUrlOf(parts);\n return plainUrl === null ? { kind: \"template\", parts } : literalKey(plainUrl);\n}\n\n/** The member of one key of a path: a property for a plain URL, else an index signature. */\nfunction keyMember(url: string, parts: readonly PathKeyPart[], type: IrType, isReadonly: boolean) {\n const key = pathKeyOf(parts);\n if (key.kind === \"literal\") {\n const member = irProperty(toPropertyName(key.url), type, { isReadonly });\n return { url, member, key, 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, type };\n}\n\n/**\n * Whether a key of the path at `url` is written. A URL that `${boolean}` keys give is not when it\n * is taken already: by a path of the document, which OpenAPI matches before a template (Paths\n * Object), or by the keys of an earlier path. A property written twice does not compile (TS2300).\n * `takenUrls` starts with the document's URLs and gets each expanded URL, in document order.\n */\nexport function isUntakenKey(url: string, key: PathKey, takenUrls: Set<string>): boolean {\n const isExpandedUrl = key.kind === \"literal\" && key.url !== url;\n if (!isExpandedUrl) {\n return true;\n }\n const isTaken = takenUrls.has(key.url);\n takenUrls.add(key.url);\n return !isTaken;\n}\n\nfunction withoutTakenUrls(url: string, members: readonly PathMember[], takenUrls: Set<string>) {\n return members.filter(({ key }) => isUntakenKey(url, key, takenUrls));\n}\n\n/** The members of a path: one, or one per key of its `${boolean}` placeholders. */\nfunction pathItemMembers(\n url: string,\n pathItem: PathItemObject,\n context: TransformContext,\n): PathMember[] {\n const isReadonly = context.options.immutable;\n const type = pathItemType(\n pathItem,\n { path: appendPointer(ROOT_POINTER, [\"paths\", url]) },\n context,\n );\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 return booleanExpandedKeys(parts).map((key) => keyMember(url, key, type, isReadonly));\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 const takenUrls = new Set(Object.keys(paths));\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 pathMembersOfUrl = pathItemMembers(url, pathItem, context);\n members.push(...withoutTakenUrls(url, pathMembersOfUrl, takenUrls));\n // The original reports only paths written as properties.\n if (pathMembersOfUrl[0]?.key.kind === \"literal\" && pathMembersOfUrl[0].key.url === url) {\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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"}
@@ -4,16 +4,23 @@ const constructors = require('../../../domain/ir/constructors.cjs');
4
4
  const propertyName = require('../../../domain/ir/property-name.cjs');
5
5
  const jsonPointer = require('../../../domain/openapi/json-pointer.cjs');
6
6
  const documentEntries = require('../document-entries.cjs');
7
+ const refType = require('../ref-type.cjs');
7
8
  const pathItem = require('./path-item.cjs');
8
9
 
9
10
  function webhooksType(webhooks, context) {
10
- const members = documentEntries.documentEntries(webhooks, context.options).map(([name, pathItem$1]) => {
11
- const location = { path: jsonPointer.appendPointer(jsonPointer.ROOT_POINTER, ["webhooks", name]) };
12
- const type = pathItem.pathItemType(pathItem$1, location, context);
11
+ const members = documentEntries.documentEntries(webhooks, context.options).map(([name, pathItem]) => {
12
+ const type = webhookType(name, pathItem, context);
13
13
  return constructors.irProperty(propertyName.toPropertyName(name), type, { isReadonly: context.options.immutable });
14
14
  });
15
15
  return constructors.irObject(members);
16
16
  }
17
+ function webhookType(name, pathItem$1, context) {
18
+ if (typeof pathItem$1 === "object" && pathItem$1 !== null && "$ref" in pathItem$1) {
19
+ return refType.refType(pathItem$1.$ref);
20
+ }
21
+ const location = { path: jsonPointer.appendPointer(jsonPointer.ROOT_POINTER, ["webhooks", name]) };
22
+ return pathItem.pathItemType(pathItem$1, location, context);
23
+ }
17
24
 
18
25
  exports.webhooksType = webhooksType;
19
26
  //# sourceMappingURL=webhooks.cjs.map