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,24 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const binaryContent = require('../../../domain/openapi/binary-content.cjs');
4
+ const locatedNode = require('./located-node.cjs');
5
+ const propertyShape = require('./property-shape.cjs');
4
6
 
5
7
  const OPAQUE_KEYS = ["not", "enum", "const", "$ref"];
6
8
  const MAX_DEPTH = 8;
7
9
  const INDEX_RE = /^\d+$/;
8
10
  const MISSING = { kind: "missing" };
9
11
  const OPAQUE = { kind: "opaque" };
10
- function isJsonObject(value) {
11
- return typeof value === "object" && value !== null && !Array.isArray(value);
12
- }
13
- function followRefs(node, refs) {
14
- return isJsonObject(node) && typeof node.$ref === "string" ? refs.resolve(node.$ref) : node;
15
- }
16
- function isNullableSchema(node) {
17
- if (!isJsonObject(node)) {
18
- return false;
19
- }
20
- return node.nullable === true || Array.isArray(node.type) && node.type.includes("null");
21
- }
22
12
  function typeNames(node) {
23
13
  return Array.isArray(node.type) ? node.type : [node.type];
24
14
  }
@@ -35,7 +25,7 @@ function isArrayShape(node) {
35
25
  return typeNames(node).includes("array") || "items" in node;
36
26
  }
37
27
  function hasObjectKeywords(node) {
38
- const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;
28
+ const hasProperties = locatedNode.isJsonObject(node.properties) && Object.keys(node.properties).length > 0;
39
29
  return hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs);
40
30
  }
41
31
  function emptyObjectMember(node, options) {
@@ -44,61 +34,57 @@ function emptyObjectMember(node, options) {
44
34
  function isBuiltInMember(key, prototype) {
45
35
  return key in prototype;
46
36
  }
47
- function indexMember(node, options) {
48
- const { additionalProperties: values, patternProperties: patterns } = node;
49
- if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {
37
+ function indexMember(owner, options) {
38
+ const { additionalProperties: values, patternProperties: patterns } = owner.node;
39
+ if (locatedNode.isJsonObject(patterns) && Object.keys(patterns).length > 0) {
50
40
  return OPAQUE;
51
41
  }
52
- if (isJsonObject(values) && Object.keys(values).length > 0) {
53
- return { kind: "index", node: values };
54
- }
55
- const isImplicit = values === true || isJsonObject(values) && Object.keys(values).length === 0;
56
- return isImplicit || !values && options.additionalProperties ? { kind: "index", node: void 0 } : null;
57
- }
58
- function isOptionalProperty(node, key, options) {
59
- const required = Array.isArray(node.required) ? node.required : void 0;
60
- const property = node.properties[key];
61
- const hasDefault = isJsonObject(property) && property.default !== void 0;
62
- const isRequired = required?.includes(key) === true || required === void 0 && options.propertiesRequiredByDefault || hasDefault && options.defaultNonNullable;
63
- return !isRequired;
64
- }
65
- function objectMember(node, key, options) {
66
- const properties = isJsonObject(node.properties) ? node.properties : {};
67
- if (Object.hasOwn(properties, key)) {
68
- const property = properties[key];
69
- const isExcluded = options.excludeDeprecated && isJsonObject(property) && property.deprecated;
70
- return isExcluded || isJsonObject(node.discriminator) ? OPAQUE : { kind: "property", node: property, isOptional: isOptionalProperty(node, key, options) };
71
- }
72
- const isUnknownShape = isJsonObject(node.discriminator) || node.unevaluatedProperties !== void 0;
42
+ if (locatedNode.isJsonObject(values) && Object.keys(values).length > 0) {
43
+ const location = locatedNode.childLocation(owner.location, "additionalProperties");
44
+ return { kind: "index", node: values, location };
45
+ }
46
+ const isImplicit = values === true || locatedNode.isJsonObject(values) && Object.keys(values).length === 0;
47
+ return isImplicit || !values && options.additionalProperties ? { kind: "index", node: void 0, location: void 0 } : null;
48
+ }
49
+ function objectMember(owner, key, input) {
50
+ const { options } = input;
51
+ const { node } = owner;
52
+ const properties = locatedNode.isJsonObject(node.properties) ? node.properties : {};
53
+ if (Object.hasOwn(properties, key) && !propertyShape.isExcludedProperty(properties[key], options, input.refs)) {
54
+ if (locatedNode.isJsonObject(node.discriminator)) {
55
+ return OPAQUE;
56
+ }
57
+ const location = locatedNode.childLocation(owner.location, "properties", key);
58
+ const isOptional = propertyShape.isOptionalProperty(owner, key, options);
59
+ const isMarked = propertyShape.isMarkedProperty(properties[key], options, input.refs);
60
+ return { kind: "property", node: properties[key], location, isOptional, isMarked };
61
+ }
62
+ const isUnknownShape = locatedNode.isJsonObject(node.discriminator) || node.unevaluatedProperties !== void 0;
73
63
  if (isBuiltInMember(key, {}) || key === "$defs" || isUnknownShape) {
74
64
  return OPAQUE;
75
65
  }
76
- return hasObjectKeywords(node) ? indexMember(node, options) ?? MISSING : emptyObjectMember(node, options);
77
- }
78
- function schemaPresence(schema, refs) {
79
- return isNullableSchema(followRefs(schema, refs)) ? "absent" : "present";
80
- }
81
- function propertyPresence(schema, key, options, refs) {
82
- const node = followRefs(schema, refs);
83
- const properties = isJsonObject(node) && isJsonObject(node.properties) ? node.properties : {};
84
- if (!isJsonObject(node) || !Object.hasOwn(properties, key)) {
85
- return "unknown";
86
- }
87
- return isOptionalProperty(node, key, options) ? "absent" : schemaPresence(properties[key], refs);
66
+ return hasObjectKeywords(node) ? indexMember(owner, options) ?? MISSING : emptyObjectMember(node, options);
88
67
  }
89
68
  function membersOf(node, keyword) {
90
69
  const members = node[keyword];
91
70
  return Array.isArray(members) ? members : [];
92
71
  }
72
+ function locatedMembers(owner, keyword) {
73
+ return membersOf(owner.node, keyword).map((node, index) => ({
74
+ node,
75
+ location: locatedNode.childLocation(owner.location, keyword, String(index))
76
+ }));
77
+ }
93
78
  function withoutComposition(node) {
94
79
  const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;
95
80
  return own;
96
81
  }
97
82
  function hasOwnObjectType(own) {
98
- return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));
83
+ return isObjectShape(own) && (hasObjectKeywords(own) || locatedNode.isJsonObject(own.discriminator));
99
84
  }
100
- function composedMember(node, key, input) {
101
- const variants = [...membersOf(node, "anyOf"), ...membersOf(node, "oneOf")];
85
+ function composedMember(owner, key, input) {
86
+ const { node } = owner;
87
+ const variants = [...locatedMembers(owner, "anyOf"), ...locatedMembers(owner, "oneOf")];
102
88
  const own = withoutComposition(node);
103
89
  const hasOwn = hasOwnObjectType(own);
104
90
  if (variants.length > 0) {
@@ -106,7 +92,8 @@ function composedMember(node, key, input) {
106
92
  const members = variants.map((variant) => memberAt(variant, key, input));
107
93
  return isAlone && members.some((member) => member.kind === "missing") ? MISSING : OPAQUE;
108
94
  }
109
- const parts = [...membersOf(node, "allOf"), ...hasOwn ? [own] : []];
95
+ const ownPart = { node: own, location: owner.location };
96
+ const parts = [...locatedMembers(owner, "allOf"), ...hasOwn ? [ownPart] : []];
110
97
  return intersectionMember(parts.map((part) => memberAt(part, key, input)));
111
98
  }
112
99
  function isUnknownIndex(member) {
@@ -122,21 +109,20 @@ function intersectionMember(members) {
122
109
  return typed.length === 1 && only.kind !== "opaque" ? only : OPAQUE;
123
110
  }
124
111
  function memberAt(schema, key, input) {
125
- const node = followRefs(schema, input.refs);
126
- if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {
112
+ const followed = locatedNode.followLocated(schema, input.refs);
113
+ const { node } = followed;
114
+ if (!locatedNode.isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {
127
115
  return OPAQUE;
128
116
  }
129
- if (isNullableSchema(node)) {
117
+ const owner = { ...followed, node };
118
+ if (propertyShape.isNullableSchema(node)) {
130
119
  return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;
131
120
  }
132
- if (input.options.readWriteMarkers) {
133
- return OPAQUE;
134
- }
135
121
  if ("allOf" in node || "anyOf" in node || "oneOf" in node) {
136
- return composedMember(node, key, { ...input, depth: input.depth + 1 });
122
+ return composedMember(owner, key, { ...input, depth: input.depth + 1 });
137
123
  }
138
124
  if (isObjectShape(node)) {
139
- return objectMember(node, key, input.options);
125
+ return objectMember(owner, key, input);
140
126
  }
141
127
  if (isArrayShape(node)) {
142
128
  return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;
@@ -160,12 +146,7 @@ function generatedMember(schema, key, options, refs) {
160
146
  return memberAt(schema, key, { options, refs, depth: 0 });
161
147
  }
162
148
 
163
- exports.followRefs = followRefs;
164
149
  exports.generatedMember = generatedMember;
165
150
  exports.isArrayShape = isArrayShape;
166
- exports.isJsonObject = isJsonObject;
167
- exports.isNullableSchema = isNullableSchema;
168
151
  exports.isObjectShape = isObjectShape;
169
- exports.propertyPresence = propertyPresence;
170
- exports.schemaPresence = schemaPresence;
171
152
  //# sourceMappingURL=generated-shape.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generated-shape.cjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | { readonly kind: \"property\"; readonly node: unknown; readonly isOptional: boolean }\n /** An index signature; `node` is undefined when its value type is `unknown`. */\n | { readonly kind: \"index\"; readonly node: unknown }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\ntype JsonObject = Readonly<Record<string, unknown>>;\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The schema a node stands for: a `$ref` is followed to its target. */\nexport function followRefs(node: unknown, refs: RefResolver): unknown {\n return isJsonObject(node) && typeof node.$ref === \"string\" ? refs.resolve(node.$ref) : node;\n}\n\n/** `nullable: true` or a `type` list with `null`: the generated type includes `null`. */\nexport function isNullableSchema(node: unknown): boolean {\n if (!isJsonObject(node)) {\n return false;\n }\n return node.nullable === true || (Array.isArray(node.type) && node.type.includes(\"null\"));\n}\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\nfunction indexMember(node: JsonObject, options: SchemaOptions): GeneratedMember | null {\n const { additionalProperties: values, patternProperties: patterns } = node;\n if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {\n return OPAQUE;\n }\n if (isJsonObject(values) && Object.keys(values).length > 0) {\n return { kind: \"index\", node: values };\n }\n const isImplicit = values === true || (isJsonObject(values) && Object.keys(values).length === 0);\n return isImplicit || (!values && options.additionalProperties)\n ? { kind: \"index\", node: undefined }\n : null;\n}\n\nfunction isOptionalProperty(node: JsonObject, key: string, options: SchemaOptions): boolean {\n const required = Array.isArray(node.required) ? node.required : undefined;\n const property = (node.properties as JsonObject)[key];\n const hasDefault = isJsonObject(property) && property.default !== undefined;\n const isRequired =\n required?.includes(key) === true ||\n (required === undefined && options.propertiesRequiredByDefault) ||\n (hasDefault && options.defaultNonNullable);\n return !isRequired;\n}\n\nfunction objectMember(node: JsonObject, key: string, options: SchemaOptions): GeneratedMember {\n const properties = isJsonObject(node.properties) ? node.properties : {};\n if (Object.hasOwn(properties, key)) {\n const property = properties[key];\n const isExcluded = options.excludeDeprecated && isJsonObject(property) && property.deprecated;\n return isExcluded || isJsonObject(node.discriminator)\n ? OPAQUE\n : { kind: \"property\", node: property, isOptional: isOptionalProperty(node, key, options) };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(node, options) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\n/** Whether a value is there: `present`, `absent` (may be `undefined` or `null`) or `unknown`. */\nexport type Presence = \"present\" | \"absent\" | \"unknown\";\n\n/** The presence of a value of `schema` itself: `absent` when its type includes `null`. */\nexport function schemaPresence(schema: unknown, refs: RefResolver): Presence {\n return isNullableSchema(followRefs(schema, refs)) ? \"absent\" : \"present\";\n}\n\n/** The presence of property `key` of `schema`: optional or nullable is `absent`. */\nexport function propertyPresence(\n schema: unknown,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): Presence {\n const node = followRefs(schema, refs);\n const properties = isJsonObject(node) && isJsonObject(node.properties) ? node.properties : {};\n if (!isJsonObject(node) || !Object.hasOwn(properties, key)) {\n return \"unknown\";\n }\n return isOptionalProperty(node, key, options) ? \"absent\" : schemaPresence(properties[key], refs);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(node: JsonObject, key: string, input: MemberInput): GeneratedMember {\n const variants = [...membersOf(node, \"anyOf\"), ...membersOf(node, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const parts = [...membersOf(node, \"allOf\"), ...(hasOwn ? [own] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: unknown, key: string, input: MemberInput): GeneratedMember {\n const node = followRefs(schema, input.refs);\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (input.options.readWriteMarkers) {\n return OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(node, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(node, key, input.options);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: unknown,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":["isRawBinarySchema"],"mappings":"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"}
1
+ {"version":3,"file":"generated-shape.cjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport {\n childLocation,\n followLocated,\n isJsonObject,\n type JsonObject,\n type LocatedNode,\n} from \"./located-node.js\";\nimport {\n isExcludedProperty,\n isMarkedProperty,\n isNullableSchema,\n isOptionalProperty,\n} from \"./property-shape.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | {\n readonly kind: \"property\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOptional: boolean;\n /** `$Read<T>` or `$Write<T>` (`isMarkedProperty`): no member but the marker's own. */\n readonly isMarked: boolean;\n }\n /** An index signature; `node` is undefined when its value type is `unknown`. */\n | { readonly kind: \"index\"; readonly node: unknown; readonly location: string | undefined }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\nfunction indexMember(owner: LocatedNode & { node: JsonObject }, options: SchemaOptions) {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {\n return OPAQUE;\n }\n if (isJsonObject(values) && Object.keys(values).length > 0) {\n const location = childLocation(owner.location, \"additionalProperties\");\n return { kind: \"index\", node: values, location } satisfies GeneratedMember;\n }\n const isImplicit = values === true || (isJsonObject(values) && Object.keys(values).length === 0);\n return isImplicit || (!values && options.additionalProperties)\n ? ({ kind: \"index\", node: undefined, location: undefined } satisfies GeneratedMember)\n : null;\n}\n\nfunction objectMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { options } = input;\n const { node } = owner;\n const properties = isJsonObject(node.properties) ? node.properties : {};\n if (Object.hasOwn(properties, key) && !isExcludedProperty(properties[key], options, input.refs)) {\n if (isJsonObject(node.discriminator)) {\n return OPAQUE;\n }\n const location = childLocation(owner.location, \"properties\", key);\n const isOptional = isOptionalProperty(owner, key, options);\n const isMarked = isMarkedProperty(properties[key], options, input.refs);\n return { kind: \"property\", node: properties[key], location, isOptional, isMarked };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(owner, options) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\n/** The members of a composition keyword with their locations. */\nfunction locatedMembers(owner: LocatedNode & { node: JsonObject }, keyword: string): LocatedNode[] {\n return membersOf(owner.node, keyword).map((node, index) => ({\n node,\n location: childLocation(owner.location, keyword, String(index)),\n }));\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { node } = owner;\n const variants = [...locatedMembers(owner, \"anyOf\"), ...locatedMembers(owner, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const ownPart = { node: own, location: owner.location };\n const parts = [...locatedMembers(owner, \"allOf\"), ...(hasOwn ? [ownPart] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: LocatedNode, key: string, input: MemberInput): GeneratedMember {\n const followed = followLocated(schema, input.refs);\n const { node } = followed;\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n const owner = { ...followed, node };\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(owner, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(owner, key, input);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: LocatedNode,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":["isJsonObject","childLocation","isExcludedProperty","isOptionalProperty","isMarkedProperty","followLocated","isNullableSchema","isRawBinarySchema"],"mappings":"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"}
@@ -1,22 +1,12 @@
1
1
  import { isRawBinarySchema } from '../../../domain/openapi/binary-content.mjs';
2
+ import { followLocated, isJsonObject, childLocation } from './located-node.mjs';
3
+ import { isNullableSchema, isExcludedProperty, isOptionalProperty, isMarkedProperty } from './property-shape.mjs';
2
4
 
3
5
  const OPAQUE_KEYS = ["not", "enum", "const", "$ref"];
4
6
  const MAX_DEPTH = 8;
5
7
  const INDEX_RE = /^\d+$/;
6
8
  const MISSING = { kind: "missing" };
7
9
  const OPAQUE = { kind: "opaque" };
8
- function isJsonObject(value) {
9
- return typeof value === "object" && value !== null && !Array.isArray(value);
10
- }
11
- function followRefs(node, refs) {
12
- return isJsonObject(node) && typeof node.$ref === "string" ? refs.resolve(node.$ref) : node;
13
- }
14
- function isNullableSchema(node) {
15
- if (!isJsonObject(node)) {
16
- return false;
17
- }
18
- return node.nullable === true || Array.isArray(node.type) && node.type.includes("null");
19
- }
20
10
  function typeNames(node) {
21
11
  return Array.isArray(node.type) ? node.type : [node.type];
22
12
  }
@@ -42,52 +32,47 @@ function emptyObjectMember(node, options) {
42
32
  function isBuiltInMember(key, prototype) {
43
33
  return key in prototype;
44
34
  }
45
- function indexMember(node, options) {
46
- const { additionalProperties: values, patternProperties: patterns } = node;
35
+ function indexMember(owner, options) {
36
+ const { additionalProperties: values, patternProperties: patterns } = owner.node;
47
37
  if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {
48
38
  return OPAQUE;
49
39
  }
50
40
  if (isJsonObject(values) && Object.keys(values).length > 0) {
51
- return { kind: "index", node: values };
41
+ const location = childLocation(owner.location, "additionalProperties");
42
+ return { kind: "index", node: values, location };
52
43
  }
53
44
  const isImplicit = values === true || isJsonObject(values) && Object.keys(values).length === 0;
54
- return isImplicit || !values && options.additionalProperties ? { kind: "index", node: void 0 } : null;
55
- }
56
- function isOptionalProperty(node, key, options) {
57
- const required = Array.isArray(node.required) ? node.required : void 0;
58
- const property = node.properties[key];
59
- const hasDefault = isJsonObject(property) && property.default !== void 0;
60
- const isRequired = required?.includes(key) === true || required === void 0 && options.propertiesRequiredByDefault || hasDefault && options.defaultNonNullable;
61
- return !isRequired;
45
+ return isImplicit || !values && options.additionalProperties ? { kind: "index", node: void 0, location: void 0 } : null;
62
46
  }
63
- function objectMember(node, key, options) {
47
+ function objectMember(owner, key, input) {
48
+ const { options } = input;
49
+ const { node } = owner;
64
50
  const properties = isJsonObject(node.properties) ? node.properties : {};
65
- if (Object.hasOwn(properties, key)) {
66
- const property = properties[key];
67
- const isExcluded = options.excludeDeprecated && isJsonObject(property) && property.deprecated;
68
- return isExcluded || isJsonObject(node.discriminator) ? OPAQUE : { kind: "property", node: property, isOptional: isOptionalProperty(node, key, options) };
51
+ if (Object.hasOwn(properties, key) && !isExcludedProperty(properties[key], options, input.refs)) {
52
+ if (isJsonObject(node.discriminator)) {
53
+ return OPAQUE;
54
+ }
55
+ const location = childLocation(owner.location, "properties", key);
56
+ const isOptional = isOptionalProperty(owner, key, options);
57
+ const isMarked = isMarkedProperty(properties[key], options, input.refs);
58
+ return { kind: "property", node: properties[key], location, isOptional, isMarked };
69
59
  }
70
60
  const isUnknownShape = isJsonObject(node.discriminator) || node.unevaluatedProperties !== void 0;
71
61
  if (isBuiltInMember(key, {}) || key === "$defs" || isUnknownShape) {
72
62
  return OPAQUE;
73
63
  }
74
- return hasObjectKeywords(node) ? indexMember(node, options) ?? MISSING : emptyObjectMember(node, options);
75
- }
76
- function schemaPresence(schema, refs) {
77
- return isNullableSchema(followRefs(schema, refs)) ? "absent" : "present";
78
- }
79
- function propertyPresence(schema, key, options, refs) {
80
- const node = followRefs(schema, refs);
81
- const properties = isJsonObject(node) && isJsonObject(node.properties) ? node.properties : {};
82
- if (!isJsonObject(node) || !Object.hasOwn(properties, key)) {
83
- return "unknown";
84
- }
85
- return isOptionalProperty(node, key, options) ? "absent" : schemaPresence(properties[key], refs);
64
+ return hasObjectKeywords(node) ? indexMember(owner, options) ?? MISSING : emptyObjectMember(node, options);
86
65
  }
87
66
  function membersOf(node, keyword) {
88
67
  const members = node[keyword];
89
68
  return Array.isArray(members) ? members : [];
90
69
  }
70
+ function locatedMembers(owner, keyword) {
71
+ return membersOf(owner.node, keyword).map((node, index) => ({
72
+ node,
73
+ location: childLocation(owner.location, keyword, String(index))
74
+ }));
75
+ }
91
76
  function withoutComposition(node) {
92
77
  const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;
93
78
  return own;
@@ -95,8 +80,9 @@ function withoutComposition(node) {
95
80
  function hasOwnObjectType(own) {
96
81
  return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));
97
82
  }
98
- function composedMember(node, key, input) {
99
- const variants = [...membersOf(node, "anyOf"), ...membersOf(node, "oneOf")];
83
+ function composedMember(owner, key, input) {
84
+ const { node } = owner;
85
+ const variants = [...locatedMembers(owner, "anyOf"), ...locatedMembers(owner, "oneOf")];
100
86
  const own = withoutComposition(node);
101
87
  const hasOwn = hasOwnObjectType(own);
102
88
  if (variants.length > 0) {
@@ -104,7 +90,8 @@ function composedMember(node, key, input) {
104
90
  const members = variants.map((variant) => memberAt(variant, key, input));
105
91
  return isAlone && members.some((member) => member.kind === "missing") ? MISSING : OPAQUE;
106
92
  }
107
- const parts = [...membersOf(node, "allOf"), ...hasOwn ? [own] : []];
93
+ const ownPart = { node: own, location: owner.location };
94
+ const parts = [...locatedMembers(owner, "allOf"), ...hasOwn ? [ownPart] : []];
108
95
  return intersectionMember(parts.map((part) => memberAt(part, key, input)));
109
96
  }
110
97
  function isUnknownIndex(member) {
@@ -120,21 +107,20 @@ function intersectionMember(members) {
120
107
  return typed.length === 1 && only.kind !== "opaque" ? only : OPAQUE;
121
108
  }
122
109
  function memberAt(schema, key, input) {
123
- const node = followRefs(schema, input.refs);
110
+ const followed = followLocated(schema, input.refs);
111
+ const { node } = followed;
124
112
  if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {
125
113
  return OPAQUE;
126
114
  }
115
+ const owner = { ...followed, node };
127
116
  if (isNullableSchema(node)) {
128
117
  return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;
129
118
  }
130
- if (input.options.readWriteMarkers) {
131
- return OPAQUE;
132
- }
133
119
  if ("allOf" in node || "anyOf" in node || "oneOf" in node) {
134
- return composedMember(node, key, { ...input, depth: input.depth + 1 });
120
+ return composedMember(owner, key, { ...input, depth: input.depth + 1 });
135
121
  }
136
122
  if (isObjectShape(node)) {
137
- return objectMember(node, key, input.options);
123
+ return objectMember(owner, key, input);
138
124
  }
139
125
  if (isArrayShape(node)) {
140
126
  return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;
@@ -158,5 +144,5 @@ function generatedMember(schema, key, options, refs) {
158
144
  return memberAt(schema, key, { options, refs, depth: 0 });
159
145
  }
160
146
 
161
- export { followRefs, generatedMember, isArrayShape, isJsonObject, isNullableSchema, isObjectShape, propertyPresence, schemaPresence };
147
+ export { generatedMember, isArrayShape, isObjectShape };
162
148
  //# sourceMappingURL=generated-shape.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generated-shape.mjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | { readonly kind: \"property\"; readonly node: unknown; readonly isOptional: boolean }\n /** An index signature; `node` is undefined when its value type is `unknown`. */\n | { readonly kind: \"index\"; readonly node: unknown }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\ntype JsonObject = Readonly<Record<string, unknown>>;\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The schema a node stands for: a `$ref` is followed to its target. */\nexport function followRefs(node: unknown, refs: RefResolver): unknown {\n return isJsonObject(node) && typeof node.$ref === \"string\" ? refs.resolve(node.$ref) : node;\n}\n\n/** `nullable: true` or a `type` list with `null`: the generated type includes `null`. */\nexport function isNullableSchema(node: unknown): boolean {\n if (!isJsonObject(node)) {\n return false;\n }\n return node.nullable === true || (Array.isArray(node.type) && node.type.includes(\"null\"));\n}\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\nfunction indexMember(node: JsonObject, options: SchemaOptions): GeneratedMember | null {\n const { additionalProperties: values, patternProperties: patterns } = node;\n if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {\n return OPAQUE;\n }\n if (isJsonObject(values) && Object.keys(values).length > 0) {\n return { kind: \"index\", node: values };\n }\n const isImplicit = values === true || (isJsonObject(values) && Object.keys(values).length === 0);\n return isImplicit || (!values && options.additionalProperties)\n ? { kind: \"index\", node: undefined }\n : null;\n}\n\nfunction isOptionalProperty(node: JsonObject, key: string, options: SchemaOptions): boolean {\n const required = Array.isArray(node.required) ? node.required : undefined;\n const property = (node.properties as JsonObject)[key];\n const hasDefault = isJsonObject(property) && property.default !== undefined;\n const isRequired =\n required?.includes(key) === true ||\n (required === undefined && options.propertiesRequiredByDefault) ||\n (hasDefault && options.defaultNonNullable);\n return !isRequired;\n}\n\nfunction objectMember(node: JsonObject, key: string, options: SchemaOptions): GeneratedMember {\n const properties = isJsonObject(node.properties) ? node.properties : {};\n if (Object.hasOwn(properties, key)) {\n const property = properties[key];\n const isExcluded = options.excludeDeprecated && isJsonObject(property) && property.deprecated;\n return isExcluded || isJsonObject(node.discriminator)\n ? OPAQUE\n : { kind: \"property\", node: property, isOptional: isOptionalProperty(node, key, options) };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(node, options) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\n/** Whether a value is there: `present`, `absent` (may be `undefined` or `null`) or `unknown`. */\nexport type Presence = \"present\" | \"absent\" | \"unknown\";\n\n/** The presence of a value of `schema` itself: `absent` when its type includes `null`. */\nexport function schemaPresence(schema: unknown, refs: RefResolver): Presence {\n return isNullableSchema(followRefs(schema, refs)) ? \"absent\" : \"present\";\n}\n\n/** The presence of property `key` of `schema`: optional or nullable is `absent`. */\nexport function propertyPresence(\n schema: unknown,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): Presence {\n const node = followRefs(schema, refs);\n const properties = isJsonObject(node) && isJsonObject(node.properties) ? node.properties : {};\n if (!isJsonObject(node) || !Object.hasOwn(properties, key)) {\n return \"unknown\";\n }\n return isOptionalProperty(node, key, options) ? \"absent\" : schemaPresence(properties[key], refs);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(node: JsonObject, key: string, input: MemberInput): GeneratedMember {\n const variants = [...membersOf(node, \"anyOf\"), ...membersOf(node, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const parts = [...membersOf(node, \"allOf\"), ...(hasOwn ? [own] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: unknown, key: string, input: MemberInput): GeneratedMember {\n const node = followRefs(schema, input.refs);\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (input.options.readWriteMarkers) {\n return OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(node, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(node, key, input.options);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: unknown,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generated-shape.mjs","sources":["../../../../src/application/transform/ref-pointer/generated-shape.ts"],"sourcesContent":["import { isRawBinarySchema } from \"../../../domain/openapi/binary-content.js\";\nimport type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport {\n childLocation,\n followLocated,\n isJsonObject,\n type JsonObject,\n type LocatedNode,\n} from \"./located-node.js\";\nimport {\n isExcludedProperty,\n isMarkedProperty,\n isNullableSchema,\n isOptionalProperty,\n} from \"./property-shape.js\";\n\n/**\n * What the generated type of a schema has under a key, read from the schema itself. It answers the\n * question TypeScript answers when it checks `T[\"key\"]`, for the schema shapes where the answer is\n * sure; for every other shape it says `opaque`, so a caller never assumes an error that is not.\n */\n\nexport type GeneratedMember =\n | {\n readonly kind: \"property\";\n readonly node: unknown;\n readonly location: string | undefined;\n readonly isOptional: boolean;\n /** `$Read<T>` or `$Write<T>` (`isMarkedProperty`): no member but the marker's own. */\n readonly isMarked: boolean;\n }\n /** An index signature; `node` is undefined when its value type is `unknown`. */\n | { readonly kind: \"index\"; readonly node: unknown; readonly location: string | undefined }\n | { readonly kind: \"missing\" }\n | { readonly kind: \"opaque\" };\n\nconst OPAQUE_KEYS = [\"not\", \"enum\", \"const\", \"$ref\"] as const;\n/** How deep `allOf`/`anyOf`/`oneOf` members are read; deeper shapes count as opaque. */\nconst MAX_DEPTH = 8;\nconst INDEX_RE = /^\\d+$/;\nconst MISSING: GeneratedMember = { kind: \"missing\" };\nconst OPAQUE: GeneratedMember = { kind: \"opaque\" };\n\nfunction typeNames(node: JsonObject): readonly unknown[] {\n return Array.isArray(node.type) ? node.type : [node.type];\n}\n\n/**\n * Whether the generated type is an object. One `type` name decides alone: `type: string` with\n * `properties` or `items` is `string`, as `coreType` matches the `type` before the keywords.\n */\nexport function isObjectShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"object\";\n }\n return (\n typeNames(node).includes(\"object\") ||\n \"properties\" in node ||\n \"additionalProperties\" in node ||\n \"patternProperties\" in node\n );\n}\n\n/** Whether the generated type is an array; one `type` name decides alone (`isObjectShape`). */\nexport function isArrayShape(node: JsonObject): boolean {\n if (typeof node.type === \"string\") {\n return node.type === \"array\";\n }\n return typeNames(node).includes(\"array\") || \"items\" in node;\n}\n\n/** Whether `objectType` writes a type for the schema; the same test as there. */\nfunction hasObjectKeywords(node: JsonObject): boolean {\n const hasProperties = isJsonObject(node.properties) && Object.keys(node.properties).length > 0;\n return (\n hasProperties || Boolean(node.additionalProperties || node.patternProperties || node.$defs)\n );\n}\n\n/**\n * A key of an object schema without object keywords. With a `type` it is `Record<string, never>`:\n * every key is `never`, and so is every key after it (or `unknown` with `--empty-objects-unknown`,\n * which has no key). Without a `type` it is `unknown`.\n */\nfunction emptyObjectMember(node: JsonObject, options: SchemaOptions): GeneratedMember {\n return node.type !== undefined && !options.emptyObjectsUnknown ? OPAQUE : MISSING;\n}\n\n/** Whether a key the object has no property for is still a member: `toString`, `length`, `0`. */\nfunction isBuiltInMember(key: string, prototype: object): boolean {\n return key in prototype;\n}\n\nfunction indexMember(owner: LocatedNode & { node: JsonObject }, options: SchemaOptions) {\n const { additionalProperties: values, patternProperties: patterns } = owner.node;\n if (isJsonObject(patterns) && Object.keys(patterns).length > 0) {\n return OPAQUE;\n }\n if (isJsonObject(values) && Object.keys(values).length > 0) {\n const location = childLocation(owner.location, \"additionalProperties\");\n return { kind: \"index\", node: values, location } satisfies GeneratedMember;\n }\n const isImplicit = values === true || (isJsonObject(values) && Object.keys(values).length === 0);\n return isImplicit || (!values && options.additionalProperties)\n ? ({ kind: \"index\", node: undefined, location: undefined } satisfies GeneratedMember)\n : null;\n}\n\nfunction objectMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { options } = input;\n const { node } = owner;\n const properties = isJsonObject(node.properties) ? node.properties : {};\n if (Object.hasOwn(properties, key) && !isExcludedProperty(properties[key], options, input.refs)) {\n if (isJsonObject(node.discriminator)) {\n return OPAQUE;\n }\n const location = childLocation(owner.location, \"properties\", key);\n const isOptional = isOptionalProperty(owner, key, options);\n const isMarked = isMarkedProperty(properties[key], options, input.refs);\n return { kind: \"property\", node: properties[key], location, isOptional, isMarked };\n }\n // `unevaluatedProperties` adds an index signature with its fix, so it counts as opaque too.\n const isUnknownShape =\n isJsonObject(node.discriminator) || node.unevaluatedProperties !== undefined;\n if (isBuiltInMember(key, {}) || key === \"$defs\" || isUnknownShape) {\n return OPAQUE;\n }\n return hasObjectKeywords(node)\n ? (indexMember(owner, options) ?? MISSING)\n : emptyObjectMember(node, options);\n}\n\nfunction membersOf(node: JsonObject, keyword: string): readonly unknown[] {\n const members = node[keyword];\n return Array.isArray(members) ? members : [];\n}\n\n/** The members of a composition keyword with their locations. */\nfunction locatedMembers(owner: LocatedNode & { node: JsonObject }, keyword: string): LocatedNode[] {\n return membersOf(owner.node, keyword).map((node, index) => ({\n node,\n location: childLocation(owner.location, keyword, String(index)),\n }));\n}\n\nfunction withoutComposition(node: JsonObject): JsonObject {\n const { allOf: _allOf, anyOf: _anyOf, oneOf: _oneOf, ...own } = node;\n return own;\n}\n\n/** Own keywords without an object type of their own (`properties: {}`) add no part. */\nfunction hasOwnObjectType(own: JsonObject): boolean {\n return isObjectShape(own) && (hasObjectKeywords(own) || isJsonObject(own.discriminator));\n}\n\n/**\n * `allOf` with own keywords is an intersection (`intersectionMember`).\n * `anyOf` or `oneOf` alone is a union: a key is missing if one member misses it. A mix of both\n * is written in more than one way (`anyof-properties`), so it counts as opaque.\n */\nfunction composedMember(\n owner: LocatedNode & { node: JsonObject },\n key: string,\n input: MemberInput,\n): GeneratedMember {\n const { node } = owner;\n const variants = [...locatedMembers(owner, \"anyOf\"), ...locatedMembers(owner, \"oneOf\")];\n const own = withoutComposition(node);\n const hasOwn = hasOwnObjectType(own);\n if (variants.length > 0) {\n const isAlone = membersOf(node, \"allOf\").length === 0 && !hasOwn;\n const members = variants.map((variant) => memberAt(variant, key, input));\n return isAlone && members.some((member) => member.kind === \"missing\") ? MISSING : OPAQUE;\n }\n const ownPart = { node: own, location: owner.location };\n const parts = [...locatedMembers(owner, \"allOf\"), ...(hasOwn ? [ownPart] : [])];\n return intersectionMember(parts.map((part) => memberAt(part, key, input)));\n}\n\nfunction isUnknownIndex(member: GeneratedMember): boolean {\n return member.kind === \"index\" && member.node === undefined;\n}\n\n/**\n * A key of an intersection: missing if every part misses it; the part's member if only one part\n * has it (`A & B` where `B` has no such key and no index signature); else opaque. A part's\n * `[key: string]: unknown` adds nothing (`unknown & T` is `T`), and only such parts give `unknown`.\n */\nfunction intersectionMember(members: readonly GeneratedMember[]): GeneratedMember {\n const found = members.filter((member) => member.kind !== \"missing\");\n const typed = found.filter((member) => !isUnknownIndex(member));\n const [only] = typed;\n if (only === undefined) {\n return found[0] ?? MISSING;\n }\n return typed.length === 1 && only.kind !== \"opaque\" ? only : OPAQUE;\n}\n\ninterface MemberInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n readonly depth: number;\n}\n\nfunction memberAt(schema: LocatedNode, key: string, input: MemberInput): GeneratedMember {\n const followed = followLocated(schema, input.refs);\n const { node } = followed;\n if (!isJsonObject(node) || OPAQUE_KEYS.some((name) => name in node) || input.depth > MAX_DEPTH) {\n return OPAQUE;\n }\n const owner = { ...followed, node };\n if (isNullableSchema(node)) {\n // Every key of `T | null` is an error, unless `T` is unknown (then the type is `unknown`).\n return isObjectShape(node) || isArrayShape(node) ? MISSING : OPAQUE;\n }\n if (\"allOf\" in node || \"anyOf\" in node || \"oneOf\" in node) {\n return composedMember(owner, key, { ...input, depth: input.depth + 1 });\n }\n if (isObjectShape(node)) {\n return objectMember(owner, key, input);\n }\n if (isArrayShape(node)) {\n return INDEX_RE.test(key) || isBuiltInMember(key, []) ? OPAQUE : MISSING;\n }\n // `--binary-as-blob` types raw binary strings as `Blob`, which has members of its own.\n return input.options.binaryAsBlob && isRawBinarySchema(node as never)\n ? OPAQUE\n : primitiveMember(node, key);\n}\n\n/** The JavaScript value whose members a primitive `type` has: `\"\".length`, `(0).toFixed`. */\nconst PRIMITIVE_PROTOTYPES: Readonly<Record<string, object>> = {\n string: String.prototype,\n number: Number.prototype,\n integer: Number.prototype,\n boolean: Boolean.prototype,\n};\n\n/**\n * A key of a schema with one primitive `type`: missing unless the primitive has it. Object and\n * array keywords next to that `type` do not change the type (`isObjectShape`). Without a `type`\n * and object keywords the schema is `unknown` (`objectType` writes nothing), which has no keys.\n */\nfunction primitiveMember(node: JsonObject, key: string): GeneratedMember {\n if (node.type === undefined) {\n return hasObjectKeywords(node) ? OPAQUE : MISSING;\n }\n const prototype = typeof node.type === \"string\" ? PRIMITIVE_PROTOTYPES[node.type] : undefined;\n return prototype !== undefined && !isBuiltInMember(key, prototype) ? MISSING : OPAQUE;\n}\n\n/** The member `key` of the type generated for `schema` (a `$ref` is followed first). */\nexport function generatedMember(\n schema: LocatedNode,\n key: string,\n options: SchemaOptions,\n refs: RefResolver,\n): GeneratedMember {\n return memberAt(schema, key, { options, refs, depth: 0 });\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const generatedShape = require('./generated-shape.cjs');
3
+ const locatedNode = require('./located-node.cjs');
4
4
  const pointerWalk = require('./pointer-walk.cjs');
5
5
  const typedWalk = require('./typed-walk.cjs');
6
6
 
@@ -9,7 +9,7 @@ function refsIn(node, found = []) {
9
9
  for (const item of node) {
10
10
  refsIn(item, found);
11
11
  }
12
- } else if (generatedShape.isJsonObject(node)) {
12
+ } else if (locatedNode.isJsonObject(node)) {
13
13
  if (typeof node.$ref === "string") {
14
14
  found.push(node.$ref);
15
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inline-cycles.cjs","sources":["../../../../src/application/transform/ref-pointer/inline-cycles.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { pointerNode, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * A `$ref` whose pointer crosses a segment with no type (`definitions/A`) is typed by writing its\n * target inline. If the target, directly or through other such `$ref`s, points back at itself,\n * writing it inline never ends; such a `$ref` keeps the original type.\n */\n\ninterface CycleInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction refsIn(node: unknown, found: string[] = []): string[] {\n if (Array.isArray(node)) {\n for (const item of node) {\n refsIn(item, found);\n }\n } else if (isJsonObject(node)) {\n if (typeof node.$ref === \"string\") {\n found.push(node.$ref);\n }\n for (const value of Object.values(node)) {\n refsIn(value, found);\n }\n }\n return found;\n}\n\nfunction isWrittenInline(ref: string, input: CycleInput): boolean {\n const pointer = refPointerOf(ref);\n return pointer !== null && typedWalk({ pointer, ...input }).kind === \"untyped\";\n}\n\n/** Depth-first search with the usual colors: a `$ref` met again while it is open is a cycle. */\nfunction reachesOpenRef(ref: string, open: Map<string, boolean>, input: CycleInput): boolean {\n if (open.has(ref)) {\n return open.get(ref) === true;\n }\n open.set(ref, true);\n const pointer = refPointerOf(ref);\n const target = pointer === null ? undefined : pointerNode(pointer, input.refs);\n const isCycle = refsIn(target).some(\n (inner) => isWrittenInline(inner, input) && reachesOpenRef(inner, open, input),\n );\n open.set(ref, false);\n return isCycle;\n}\n\n/** Whether writing the target of `ref` inline would write it again inside itself. */\nexport function hasInlineCycle(ref: string, options: SchemaOptions, refs: RefResolver): boolean {\n return reachesOpenRef(ref, new Map(), { options, refs });\n}\n"],"names":["isJsonObject","refPointerOf","typedWalk","pointerNode"],"mappings":";;;;;;AAgBA,SAAS,MAAA,CAAO,IAAA,EAAe,KAAA,GAAkB,EAAC,EAAa;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,MAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,MAAA,IAAWA,2BAAA,CAAa,IAAI,CAAA,EAAG;AAC7B,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,MAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,IACtB;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAAG;AACvC,MAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAA,CAAgB,KAAa,KAAA,EAA4B;AAChE,EAAA,MAAM,OAAA,GAAUC,yBAAa,GAAG,CAAA;AAChC,EAAA,OAAO,OAAA,KAAY,QAAQC,mBAAA,CAAU,EAAE,SAAS,GAAG,KAAA,EAAO,CAAA,CAAE,IAAA,KAAS,SAAA;AACvE;AAGA,SAAS,cAAA,CAAe,GAAA,EAAa,IAAA,EAA4B,KAAA,EAA4B;AAC3F,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACjB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,KAAM,IAAA;AAAA,EAC3B;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,CAAA;AAClB,EAAA,MAAM,OAAA,GAAUD,yBAAa,GAAG,CAAA;AAChC,EAAA,MAAM,SAAS,OAAA,KAAY,IAAA,GAAO,SAAYE,uBAAA,CAAY,OAAA,EAAS,MAAM,IAAI,CAAA;AAC7E,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA;AAAA,IAC7B,CAAC,UAAU,eAAA,CAAgB,KAAA,EAAO,KAAK,CAAA,IAAK,cAAA,CAAe,KAAA,EAAO,IAAA,EAAM,KAAK;AAAA,GAC/E;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,cAAA,CAAe,GAAA,EAAa,OAAA,EAAwB,IAAA,EAA4B;AAC9F,EAAA,OAAO,cAAA,CAAe,qBAAK,IAAI,GAAA,IAAO,EAAE,OAAA,EAAS,MAAM,CAAA;AACzD;;"}
1
+ {"version":3,"file":"inline-cycles.cjs","sources":["../../../../src/application/transform/ref-pointer/inline-cycles.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { isJsonObject } from \"./located-node.js\";\nimport { pointerNode, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * A `$ref` whose pointer crosses a segment with no type (`definitions/A`) is typed by writing its\n * target inline. If the target, directly or through other such `$ref`s, points back at itself,\n * writing it inline never ends; such a `$ref` keeps the original type.\n */\n\ninterface CycleInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction refsIn(node: unknown, found: string[] = []): string[] {\n if (Array.isArray(node)) {\n for (const item of node) {\n refsIn(item, found);\n }\n } else if (isJsonObject(node)) {\n if (typeof node.$ref === \"string\") {\n found.push(node.$ref);\n }\n for (const value of Object.values(node)) {\n refsIn(value, found);\n }\n }\n return found;\n}\n\nfunction isWrittenInline(ref: string, input: CycleInput): boolean {\n const pointer = refPointerOf(ref);\n return pointer !== null && typedWalk({ pointer, ...input }).kind === \"untyped\";\n}\n\n/** Depth-first search with the usual colors: a `$ref` met again while it is open is a cycle. */\nfunction reachesOpenRef(ref: string, open: Map<string, boolean>, input: CycleInput): boolean {\n if (open.has(ref)) {\n return open.get(ref) === true;\n }\n open.set(ref, true);\n const pointer = refPointerOf(ref);\n const target = pointer === null ? undefined : pointerNode(pointer, input.refs);\n const isCycle = refsIn(target).some(\n (inner) => isWrittenInline(inner, input) && reachesOpenRef(inner, open, input),\n );\n open.set(ref, false);\n return isCycle;\n}\n\n/** Whether writing the target of `ref` inline would write it again inside itself. */\nexport function hasInlineCycle(ref: string, options: SchemaOptions, refs: RefResolver): boolean {\n return reachesOpenRef(ref, new Map(), { options, refs });\n}\n"],"names":["isJsonObject","refPointerOf","typedWalk","pointerNode"],"mappings":";;;;;;AAgBA,SAAS,MAAA,CAAO,IAAA,EAAe,KAAA,GAAkB,EAAC,EAAa;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,MAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,MAAA,IAAWA,wBAAA,CAAa,IAAI,CAAA,EAAG;AAC7B,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,MAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,IACtB;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAAG;AACvC,MAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAA,CAAgB,KAAa,KAAA,EAA4B;AAChE,EAAA,MAAM,OAAA,GAAUC,yBAAa,GAAG,CAAA;AAChC,EAAA,OAAO,OAAA,KAAY,QAAQC,mBAAA,CAAU,EAAE,SAAS,GAAG,KAAA,EAAO,CAAA,CAAE,IAAA,KAAS,SAAA;AACvE;AAGA,SAAS,cAAA,CAAe,GAAA,EAAa,IAAA,EAA4B,KAAA,EAA4B;AAC3F,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACjB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,KAAM,IAAA;AAAA,EAC3B;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,CAAA;AAClB,EAAA,MAAM,OAAA,GAAUD,yBAAa,GAAG,CAAA;AAChC,EAAA,MAAM,SAAS,OAAA,KAAY,IAAA,GAAO,SAAYE,uBAAA,CAAY,OAAA,EAAS,MAAM,IAAI,CAAA;AAC7E,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA;AAAA,IAC7B,CAAC,UAAU,eAAA,CAAgB,KAAA,EAAO,KAAK,CAAA,IAAK,cAAA,CAAe,KAAA,EAAO,IAAA,EAAM,KAAK;AAAA,GAC/E;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,cAAA,CAAe,GAAA,EAAa,OAAA,EAAwB,IAAA,EAA4B;AAC9F,EAAA,OAAO,cAAA,CAAe,qBAAK,IAAI,GAAA,IAAO,EAAE,OAAA,EAAS,MAAM,CAAA;AACzD;;"}
@@ -1,4 +1,4 @@
1
- import { isJsonObject } from './generated-shape.mjs';
1
+ import { isJsonObject } from './located-node.mjs';
2
2
  import { refPointerOf, pointerNode } from './pointer-walk.mjs';
3
3
  import { typedWalk } from './typed-walk.mjs';
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"inline-cycles.mjs","sources":["../../../../src/application/transform/ref-pointer/inline-cycles.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { isJsonObject } from \"./generated-shape.js\";\nimport { pointerNode, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * A `$ref` whose pointer crosses a segment with no type (`definitions/A`) is typed by writing its\n * target inline. If the target, directly or through other such `$ref`s, points back at itself,\n * writing it inline never ends; such a `$ref` keeps the original type.\n */\n\ninterface CycleInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction refsIn(node: unknown, found: string[] = []): string[] {\n if (Array.isArray(node)) {\n for (const item of node) {\n refsIn(item, found);\n }\n } else if (isJsonObject(node)) {\n if (typeof node.$ref === \"string\") {\n found.push(node.$ref);\n }\n for (const value of Object.values(node)) {\n refsIn(value, found);\n }\n }\n return found;\n}\n\nfunction isWrittenInline(ref: string, input: CycleInput): boolean {\n const pointer = refPointerOf(ref);\n return pointer !== null && typedWalk({ pointer, ...input }).kind === \"untyped\";\n}\n\n/** Depth-first search with the usual colors: a `$ref` met again while it is open is a cycle. */\nfunction reachesOpenRef(ref: string, open: Map<string, boolean>, input: CycleInput): boolean {\n if (open.has(ref)) {\n return open.get(ref) === true;\n }\n open.set(ref, true);\n const pointer = refPointerOf(ref);\n const target = pointer === null ? undefined : pointerNode(pointer, input.refs);\n const isCycle = refsIn(target).some(\n (inner) => isWrittenInline(inner, input) && reachesOpenRef(inner, open, input),\n );\n open.set(ref, false);\n return isCycle;\n}\n\n/** Whether writing the target of `ref` inline would write it again inside itself. */\nexport function hasInlineCycle(ref: string, options: SchemaOptions, refs: RefResolver): boolean {\n return reachesOpenRef(ref, new Map(), { options, refs });\n}\n"],"names":[],"mappings":";;;;AAgBA,SAAS,MAAA,CAAO,IAAA,EAAe,KAAA,GAAkB,EAAC,EAAa;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,MAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,MAAA,IAAW,YAAA,CAAa,IAAI,CAAA,EAAG;AAC7B,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,MAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,IACtB;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAAG;AACvC,MAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAA,CAAgB,KAAa,KAAA,EAA4B;AAChE,EAAA,MAAM,OAAA,GAAU,aAAa,GAAG,CAAA;AAChC,EAAA,OAAO,OAAA,KAAY,QAAQ,SAAA,CAAU,EAAE,SAAS,GAAG,KAAA,EAAO,CAAA,CAAE,IAAA,KAAS,SAAA;AACvE;AAGA,SAAS,cAAA,CAAe,GAAA,EAAa,IAAA,EAA4B,KAAA,EAA4B;AAC3F,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACjB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,KAAM,IAAA;AAAA,EAC3B;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,CAAA;AAClB,EAAA,MAAM,OAAA,GAAU,aAAa,GAAG,CAAA;AAChC,EAAA,MAAM,SAAS,OAAA,KAAY,IAAA,GAAO,SAAY,WAAA,CAAY,OAAA,EAAS,MAAM,IAAI,CAAA;AAC7E,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA;AAAA,IAC7B,CAAC,UAAU,eAAA,CAAgB,KAAA,EAAO,KAAK,CAAA,IAAK,cAAA,CAAe,KAAA,EAAO,IAAA,EAAM,KAAK;AAAA,GAC/E;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,cAAA,CAAe,GAAA,EAAa,OAAA,EAAwB,IAAA,EAA4B;AAC9F,EAAA,OAAO,cAAA,CAAe,qBAAK,IAAI,GAAA,IAAO,EAAE,OAAA,EAAS,MAAM,CAAA;AACzD;;"}
1
+ {"version":3,"file":"inline-cycles.mjs","sources":["../../../../src/application/transform/ref-pointer/inline-cycles.ts"],"sourcesContent":["import type { RefResolver, SchemaOptions } from \"../schema/schema-context.js\";\nimport { isJsonObject } from \"./located-node.js\";\nimport { pointerNode, refPointerOf } from \"./pointer-walk.js\";\nimport { typedWalk } from \"./typed-walk.js\";\n\n/**\n * A `$ref` whose pointer crosses a segment with no type (`definitions/A`) is typed by writing its\n * target inline. If the target, directly or through other such `$ref`s, points back at itself,\n * writing it inline never ends; such a `$ref` keeps the original type.\n */\n\ninterface CycleInput {\n readonly options: SchemaOptions;\n readonly refs: RefResolver;\n}\n\nfunction refsIn(node: unknown, found: string[] = []): string[] {\n if (Array.isArray(node)) {\n for (const item of node) {\n refsIn(item, found);\n }\n } else if (isJsonObject(node)) {\n if (typeof node.$ref === \"string\") {\n found.push(node.$ref);\n }\n for (const value of Object.values(node)) {\n refsIn(value, found);\n }\n }\n return found;\n}\n\nfunction isWrittenInline(ref: string, input: CycleInput): boolean {\n const pointer = refPointerOf(ref);\n return pointer !== null && typedWalk({ pointer, ...input }).kind === \"untyped\";\n}\n\n/** Depth-first search with the usual colors: a `$ref` met again while it is open is a cycle. */\nfunction reachesOpenRef(ref: string, open: Map<string, boolean>, input: CycleInput): boolean {\n if (open.has(ref)) {\n return open.get(ref) === true;\n }\n open.set(ref, true);\n const pointer = refPointerOf(ref);\n const target = pointer === null ? undefined : pointerNode(pointer, input.refs);\n const isCycle = refsIn(target).some(\n (inner) => isWrittenInline(inner, input) && reachesOpenRef(inner, open, input),\n );\n open.set(ref, false);\n return isCycle;\n}\n\n/** Whether writing the target of `ref` inline would write it again inside itself. */\nexport function hasInlineCycle(ref: string, options: SchemaOptions, refs: RefResolver): boolean {\n return reachesOpenRef(ref, new Map(), { options, refs });\n}\n"],"names":[],"mappings":";;;;AAgBA,SAAS,MAAA,CAAO,IAAA,EAAe,KAAA,GAAkB,EAAC,EAAa;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,IAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,MAAA,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,MAAA,IAAW,YAAA,CAAa,IAAI,CAAA,EAAG;AAC7B,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,MAAA,KAAA,CAAM,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,IACtB;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,EAAG;AACvC,MAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAA,CAAgB,KAAa,KAAA,EAA4B;AAChE,EAAA,MAAM,OAAA,GAAU,aAAa,GAAG,CAAA;AAChC,EAAA,OAAO,OAAA,KAAY,QAAQ,SAAA,CAAU,EAAE,SAAS,GAAG,KAAA,EAAO,CAAA,CAAE,IAAA,KAAS,SAAA;AACvE;AAGA,SAAS,cAAA,CAAe,GAAA,EAAa,IAAA,EAA4B,KAAA,EAA4B;AAC3F,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACjB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,KAAM,IAAA;AAAA,EAC3B;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,IAAI,CAAA;AAClB,EAAA,MAAM,OAAA,GAAU,aAAa,GAAG,CAAA;AAChC,EAAA,MAAM,SAAS,OAAA,KAAY,IAAA,GAAO,SAAY,WAAA,CAAY,OAAA,EAAS,MAAM,IAAI,CAAA;AAC7E,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA;AAAA,IAC7B,CAAC,UAAU,eAAA,CAAgB,KAAA,EAAO,KAAK,CAAA,IAAK,cAAA,CAAe,KAAA,EAAO,IAAA,EAAM,KAAK;AAAA,GAC/E;AACA,EAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,cAAA,CAAe,GAAA,EAAa,OAAA,EAAwB,IAAA,EAA4B;AAC9F,EAAA,OAAO,cAAA,CAAe,qBAAK,IAAI,GAAA,IAAO,EAAE,OAAA,EAAS,MAAM,CAAA;AACzD;;"}
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ const jsonPointer = require('../../../domain/openapi/json-pointer.cjs');
4
+
5
+ function isJsonObject(value) {
6
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7
+ }
8
+ function followRefs(node, refs) {
9
+ return isJsonObject(node) && typeof node.$ref === "string" ? refs.resolve(node.$ref) : node;
10
+ }
11
+ function followLocated(located, refs) {
12
+ const { node } = located;
13
+ return isJsonObject(node) && typeof node.$ref === "string" ? { node: refs.resolve(node.$ref), location: node.$ref } : located;
14
+ }
15
+ function childLocation(location, ...segments) {
16
+ return location === void 0 ? void 0 : jsonPointer.appendPointer(location, segments);
17
+ }
18
+
19
+ exports.childLocation = childLocation;
20
+ exports.followLocated = followLocated;
21
+ exports.followRefs = followRefs;
22
+ exports.isJsonObject = isJsonObject;
23
+ //# sourceMappingURL=located-node.cjs.map