@maycombhq/atticus 2.0.0-beta.2 → 2.0.0-beta.21

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 (273) hide show
  1. package/dist/bin.js +8 -4
  2. package/dist/chunk-265LWMOA.js +91 -0
  3. package/dist/chunk-26WBY34Y.js +37 -0
  4. package/dist/{chunk-UBBC2XSG.js → chunk-26Z7OGQW.js} +518 -93
  5. package/dist/chunk-2D7PWSOK.js +172 -0
  6. package/dist/{chunk-JCZIKA4C.js → chunk-2HH3UCZM.js} +4 -4
  7. package/dist/{chunk-GDLULHTC.js → chunk-2HTEMYTB.js} +12 -26
  8. package/dist/chunk-2UCRFXFZ.js +130 -0
  9. package/dist/{chunk-MVZVGYXH.js → chunk-2V2ZPQQU.js} +81 -13
  10. package/dist/{chunk-BOHJZTEQ.js → chunk-36RY7ZXM.js} +130 -71
  11. package/dist/{chunk-I3E7CX4H.js → chunk-37WE3LS2.js} +3 -3
  12. package/dist/{chunk-IPKHE5D6.js → chunk-3AQ2R5NL.js} +1520 -871
  13. package/dist/chunk-3G6S7LAA.js +43 -0
  14. package/dist/chunk-3J5I7ZOU.js +58 -0
  15. package/dist/{chunk-65NYPGRC.js → chunk-3LZ6P5EP.js} +1 -1
  16. package/dist/chunk-3SSTNB4E.js +191 -0
  17. package/dist/chunk-3TD6S4TC.js +49 -0
  18. package/dist/{chunk-3C7EYRFZ.js → chunk-3UTYPHN3.js} +1 -1
  19. package/dist/{chunk-G2B4ZQGH.js → chunk-3WON4G3M.js} +2 -2
  20. package/dist/{chunk-S3QNRWYR.js → chunk-42EPP7OB.js} +12 -12
  21. package/dist/chunk-455SYIIE.js +113 -0
  22. package/dist/{chunk-YISXLPHN.js → chunk-4B6BT75O.js} +166 -23
  23. package/dist/{chunk-C6EKFH7J.js → chunk-4CLK2RJO.js} +7 -7
  24. package/dist/chunk-4CYTJ5TZ.js +38 -0
  25. package/dist/{chunk-EYWIDJFU.js → chunk-4D62IZII.js} +5 -5
  26. package/dist/chunk-4FOAYLI4.js +328 -0
  27. package/dist/{chunk-7JUKDRSZ.js → chunk-4KNOJC6J.js} +294 -215
  28. package/dist/{chunk-YMZ3TNYB.js → chunk-4PYC2UGC.js} +2 -2
  29. package/dist/{chunk-27NKUS3X.js → chunk-4SLBCEPD.js} +2104 -726
  30. package/dist/chunk-4TKVU2I2.js +122 -0
  31. package/dist/{chunk-RUVFXE2L.js → chunk-4WXRPQDE.js} +448 -47
  32. package/dist/{chunk-7ZUIMTOU.js → chunk-5CMPVC3N.js} +24 -24
  33. package/dist/chunk-5G7ILBUG.js +66 -0
  34. package/dist/{chunk-HFQCFSJR.js → chunk-5PV7S2ZP.js} +3 -3
  35. package/dist/{chunk-FITWGOJ2.js → chunk-5QUOPNLN.js} +4 -4
  36. package/dist/{chunk-Z6LF7HQN.js → chunk-5TDRBOAV.js} +5 -5
  37. package/dist/{chunk-T6AIP7H5.js → chunk-5WERBKLE.js} +199 -63
  38. package/dist/{chunk-XPCM366L.js → chunk-62DLJSLV.js} +8 -8
  39. package/dist/{chunk-L24C55VN.js → chunk-64AADMTW.js} +99 -25
  40. package/dist/{chunk-K65BJIMT.js → chunk-67BP7HXL.js} +17 -17
  41. package/dist/chunk-6DQYZU2W.js +379 -0
  42. package/dist/{chunk-EDS2L2LD.js → chunk-6EXDI5GI.js} +52 -26
  43. package/dist/chunk-6FNAKCET.js +38 -0
  44. package/dist/{chunk-6IU67AEK.js → chunk-75ASLHBT.js} +21 -15
  45. package/dist/{chunk-A3GY6SOA.js → chunk-75ZOZFGH.js} +18 -18
  46. package/dist/{chunk-MGYZM27B.js → chunk-77O633L5.js} +49 -23
  47. package/dist/{chunk-GQ4N4WKF.js → chunk-7AB6OWTV.js} +3 -3
  48. package/dist/{chunk-M766ZJ6W.js → chunk-7CZHUZBL.js} +25 -25
  49. package/dist/{chunk-A7UPUQFY.js → chunk-7FHNFCHK.js} +643 -124
  50. package/dist/chunk-7FUIVIBG.js +415 -0
  51. package/dist/{chunk-6QSERWXH.js → chunk-7QPCGTPS.js} +21 -21
  52. package/dist/{chunk-LR3R6Z2A.js → chunk-A2G72UI4.js} +7 -7
  53. package/dist/{chunk-I4JRCD6M.js → chunk-AE4P57KK.js} +23 -17
  54. package/dist/{chunk-AVJDSJ2F.js → chunk-AHW3RY3X.js} +7 -7
  55. package/dist/chunk-AM6FP6JW.js +43 -0
  56. package/dist/{chunk-CSZ4C5N6.js → chunk-AOCWFA7T.js} +93 -10
  57. package/dist/{chunk-EPTBZ3GP.js → chunk-API5TOUB.js} +1 -1
  58. package/dist/{chunk-652QWTLZ.js → chunk-AZDITBCT.js} +3 -3
  59. package/dist/{chunk-DPUYDDQG.js → chunk-BA2HUMDN.js} +25 -3
  60. package/dist/chunk-BA3U7ALS.js +99 -0
  61. package/dist/{chunk-HVUPKCGJ.js → chunk-BC6KKZ67.js} +5 -5
  62. package/dist/{chunk-CKSITVS4.js → chunk-BEPCKDCP.js} +2554 -722
  63. package/dist/{chunk-3ALD2W2A.js → chunk-BPPU3PW7.js} +4 -4
  64. package/dist/{chunk-QRAOANID.js → chunk-BVWWPBKD.js} +21 -21
  65. package/dist/{chunk-ZDPAS56H.js → chunk-BXBCMGIQ.js} +7 -1
  66. package/dist/chunk-BXZ4PKIT.js +233 -0
  67. package/dist/chunk-C7CEK3KW.js +247 -0
  68. package/dist/chunk-CFH3QH26.js +29 -0
  69. package/dist/chunk-CG6CULP6.js +170 -0
  70. package/dist/chunk-CLD4RVTA.js +45 -0
  71. package/dist/{chunk-DKJA76CJ.js → chunk-CNPY4NTZ.js} +13 -13
  72. package/dist/chunk-CNU5Q2D5.js +575 -0
  73. package/dist/{chunk-T2UYZSCQ.js → chunk-COYN3UAN.js} +126 -23
  74. package/dist/{chunk-23W7VWKR.js → chunk-CPK7QSBG.js} +1360 -113
  75. package/dist/{chunk-4AK7IBVP.js → chunk-D2WSW4GU.js} +1 -1
  76. package/dist/{chunk-ABWHYWNI.js → chunk-D57MFJPP.js} +3 -3
  77. package/dist/chunk-D5KV5PSK.js +45 -0
  78. package/dist/chunk-D5MASS4I.js +48 -0
  79. package/dist/{chunk-7EOBHUMC.js → chunk-DCWN3HFV.js} +2 -2
  80. package/dist/{chunk-QSXK2RGH.js → chunk-DDJPM5YX.js} +2 -2
  81. package/dist/chunk-DN4A2Q2O.js +57 -0
  82. package/dist/{chunk-IHMLFRVV.js → chunk-DUPZPDCJ.js} +58 -16
  83. package/dist/{chunk-PRPPGYZG.js → chunk-E2VXBSIR.js} +4 -4
  84. package/dist/chunk-E57AOFYN.js +32 -0
  85. package/dist/{chunk-UGLN7QHV.js → chunk-ECLXZWAG.js} +12 -12
  86. package/dist/{chunk-5WG5YP4T.js → chunk-EDZ45WIR.js} +14 -14
  87. package/dist/chunk-EFCQSMXB.js +37 -0
  88. package/dist/{chunk-2ANOROX3.js → chunk-EZIN5E5B.js} +8 -8
  89. package/dist/{chunk-BWZ77RQT.js → chunk-F6H2RJ3N.js} +1 -1
  90. package/dist/{chunk-OLQJTJJU.js → chunk-FAJDKNSD.js} +7 -3
  91. package/dist/chunk-FGAGWYZB.js +47 -0
  92. package/dist/{chunk-4WBVUHXN.js → chunk-FLVZFTLQ.js} +18 -18
  93. package/dist/chunk-FQ6WH6PB.js +140 -0
  94. package/dist/{chunk-T6XQL73F.js → chunk-FRHD22WM.js} +61 -23
  95. package/dist/{chunk-XAKWMCXI.js → chunk-FVMPFCDS.js} +4 -4
  96. package/dist/{chunk-B2WLAWNJ.js → chunk-FY3QIRTL.js} +3 -3
  97. package/dist/{chunk-CPA6HPVR.js → chunk-FYBF5MB2.js} +15 -11
  98. package/dist/{chunk-V2YTAIQO.js → chunk-G5YJBNDZ.js} +21 -6
  99. package/dist/chunk-G6IQYM25.js +339 -0
  100. package/dist/chunk-G6X4YL4D.js +161 -0
  101. package/dist/{chunk-SJRGMG6A.js → chunk-GC2VK3JT.js} +25 -25
  102. package/dist/{chunk-SP2I63OO.js → chunk-GCS3FZOB.js} +77 -3
  103. package/dist/{chunk-6TACQN3N.js → chunk-GDZB57IU.js} +5 -5
  104. package/dist/chunk-GIFMBCTW.js +221 -0
  105. package/dist/{chunk-YY6ZQQBP.js → chunk-GK4PYVEC.js} +18 -8
  106. package/dist/{chunk-TDD55CJH.js → chunk-GNWAOVFQ.js} +6 -5
  107. package/dist/chunk-GS76RXQE.js +226 -0
  108. package/dist/{chunk-YYQN46FY.js → chunk-GSGIZ2OO.js} +23 -23
  109. package/dist/chunk-GUYL7RMK.js +60 -0
  110. package/dist/chunk-GX74YWR7.js +321 -0
  111. package/dist/chunk-HE3HRDNZ.js +122 -0
  112. package/dist/{chunk-AIOQPLA5.js → chunk-HGHRSF3E.js} +30 -12
  113. package/dist/{chunk-2RMYG36Q.js → chunk-HK3VOHIE.js} +198 -336
  114. package/dist/{chunk-QZSX3F7C.js → chunk-HS4BGB4G.js} +24 -22
  115. package/dist/{chunk-XY3P7JW7.js → chunk-HSZMPH5T.js} +834 -149
  116. package/dist/{chunk-L6SGQIR3.js → chunk-HWD4JPU7.js} +4 -2
  117. package/dist/{chunk-PCVDV3UZ.js → chunk-HXXP2NTE.js} +6 -6
  118. package/dist/{chunk-AA6YULYB.js → chunk-I2A3Z5AK.js} +7 -7
  119. package/dist/{chunk-N7IXEHK3.js → chunk-ICHDSWEY.js} +7 -7
  120. package/dist/chunk-IFFRGC3N.js +31 -0
  121. package/dist/{chunk-4BN53TG3.js → chunk-IFHDV6KQ.js} +31 -23
  122. package/dist/chunk-J2O4LFVI.js +80 -0
  123. package/dist/chunk-J5AAZ6OJ.js +161 -0
  124. package/dist/{chunk-ZMFPW66A.js → chunk-JAABT3DA.js} +3 -3
  125. package/dist/chunk-JITJP64K.js +34 -0
  126. package/dist/chunk-JKIGL3XQ.js +162 -0
  127. package/dist/chunk-JRVNXLZP.js +615 -0
  128. package/dist/chunk-JRXHON4E.js +41 -0
  129. package/dist/{chunk-DHPACDG7.js → chunk-JS6WMC3J.js} +8 -8
  130. package/dist/chunk-JU4QNJSR.js +62 -0
  131. package/dist/{chunk-PAMPPUR6.js → chunk-JYMIB5XY.js} +1697 -172
  132. package/dist/{chunk-RRTKKSLQ.js → chunk-JYTIHTIK.js} +8 -6
  133. package/dist/{chunk-3HI6Z55Y.js → chunk-K332XW7K.js} +324 -39
  134. package/dist/{chunk-GLUX4EEP.js → chunk-K6JB6XTX.js} +9 -9
  135. package/dist/chunk-KDAHXQIE.js +294 -0
  136. package/dist/chunk-KYZMRSPS.js +93 -0
  137. package/dist/chunk-L4CESDPB.js +22 -0
  138. package/dist/{chunk-NXFPS2LR.js → chunk-LEBR5NHW.js} +14 -14
  139. package/dist/chunk-LIJJCBQI.js +223 -0
  140. package/dist/{chunk-DE76JROX.js → chunk-LIRVU3HW.js} +16 -16
  141. package/dist/{chunk-JMSCMUCA.js → chunk-LN77DXBM.js} +145 -21
  142. package/dist/{chunk-JIITQXFB.js → chunk-LNWEWYCM.js} +2969 -788
  143. package/dist/{chunk-TANFV3MZ.js → chunk-LO3BLMVG.js} +3 -3
  144. package/dist/chunk-LPV6T362.js +250 -0
  145. package/dist/{chunk-2VHF7OXM.js → chunk-LQH4P45K.js} +1 -1
  146. package/dist/chunk-LU4MQVAL.js +41 -0
  147. package/dist/chunk-LWDNKE4X.js +273 -0
  148. package/dist/chunk-M4H2UG4R.js +218 -0
  149. package/dist/{chunk-6BVONWJ7.js → chunk-M6D2U3YM.js} +3 -3
  150. package/dist/chunk-MD7KUEJ3.js +514 -0
  151. package/dist/{chunk-66YVAGGM.js → chunk-MMZUN7ZO.js} +20 -20
  152. package/dist/chunk-MZGRDONP.js +916 -0
  153. package/dist/chunk-N3RUGTGV.js +39 -0
  154. package/dist/{chunk-JGZCG5VM.js → chunk-NCB6656Z.js} +7 -7
  155. package/dist/{chunk-4NDAAFQT.js → chunk-NRQ65LTQ.js} +7 -5
  156. package/dist/{chunk-UNM6ZOKP.js → chunk-NTAVOWYD.js} +145 -18
  157. package/dist/{chunk-3USYZGRF.js → chunk-NYOABJNK.js} +36 -27
  158. package/dist/{chunk-WVPJSRRJ.js → chunk-O4IKAIZ2.js} +24 -20
  159. package/dist/{chunk-D3PO4DOZ.js → chunk-ODMBPDDV.js} +51 -14
  160. package/dist/chunk-OKUB6RJA.js +533 -0
  161. package/dist/chunk-OMPENNWY.js +39 -0
  162. package/dist/chunk-OPQZISG3.js +25 -0
  163. package/dist/{chunk-5GGOLAKC.js → chunk-OV57AHCG.js} +26 -26
  164. package/dist/chunk-OZJ3JLYI.js +58 -0
  165. package/dist/{chunk-KEM4SDDP.js → chunk-P2VBXX7N.js} +11 -10
  166. package/dist/{chunk-S2A7YC3Q.js → chunk-PAINMSID.js} +10150 -1720
  167. package/dist/chunk-PKJAV25S.js +43 -0
  168. package/dist/{chunk-EBEW3XXQ.js → chunk-PNQLCRSS.js} +4 -4
  169. package/dist/{chunk-WY6PP6AA.js → chunk-PQH56YF6.js} +37 -5
  170. package/dist/chunk-PRTBPXYA.js +50 -0
  171. package/dist/{chunk-YEDDOYSC.js → chunk-PRW3HXM3.js} +2 -2
  172. package/dist/chunk-PRZ7KMWL.js +42 -0
  173. package/dist/{chunk-6M5NK3K3.js → chunk-PTQ3ZALZ.js} +42 -4
  174. package/dist/{chunk-5GDRCDQB.js → chunk-PUEWDYGP.js} +2 -2
  175. package/dist/chunk-Q26LDIUV.js +236 -0
  176. package/dist/{chunk-CR3MTH32.js → chunk-Q46QDDMF.js} +77 -7
  177. package/dist/chunk-QBNWF5ZU.js +19 -0
  178. package/dist/chunk-QE527XRY.js +342 -0
  179. package/dist/{chunk-CNUKCS2T.js → chunk-QHJJMZLX.js} +1518 -54
  180. package/dist/chunk-QJCJOMW3.js +425 -0
  181. package/dist/{chunk-VYDBJ73M.js → chunk-QKMRFNMA.js} +15 -15
  182. package/dist/chunk-QOOEYDNJ.js +317 -0
  183. package/dist/chunk-QSIDVFB7.js +45 -0
  184. package/dist/{chunk-R77KLRB3.js → chunk-RA33EYS4.js} +19 -18
  185. package/dist/{chunk-DFBCSHVT.js → chunk-RALY3E5U.js} +4 -4
  186. package/dist/{chunk-ZCJDOK2S.js → chunk-S2RY3BOD.js} +35 -21
  187. package/dist/chunk-S5LSDXV4.js +40 -0
  188. package/dist/chunk-SB5GRUFM.js +54 -0
  189. package/dist/chunk-SH27FYPF.js +150 -0
  190. package/dist/chunk-T74WQQGS.js +40 -0
  191. package/dist/{chunk-O3WI5KWW.js → chunk-TGVVUKTG.js} +2 -2
  192. package/dist/chunk-THN26IEF.js +48 -0
  193. package/dist/chunk-TJH2EUAZ.js +47 -0
  194. package/dist/{chunk-ZNCEKR4J.js → chunk-TQ4TG57V.js} +12 -8
  195. package/dist/{chunk-7FBGJFEE.js → chunk-TQTRWENN.js} +12 -12
  196. package/dist/{chunk-TYAID7B7.js → chunk-TSM6T6GQ.js} +23 -23
  197. package/dist/{chunk-DPZHZQKE.js → chunk-TW3KOSQK.js} +43 -10
  198. package/dist/{chunk-MC3H7736.js → chunk-TWQRPM76.js} +37 -4
  199. package/dist/chunk-TYD6I4CZ.js +109 -0
  200. package/dist/chunk-U3NBK4EU.js +420 -0
  201. package/dist/{chunk-6JCPI55B.js → chunk-UDXWIPCB.js} +47 -7
  202. package/dist/{chunk-MMOSZPWJ.js → chunk-UEVZZZU2.js} +4 -4
  203. package/dist/{chunk-JBTK5OP2.js → chunk-UF4UHCIG.js} +2 -2
  204. package/dist/{chunk-6JUBZBMW.js → chunk-UFE36WJH.js} +4 -4
  205. package/dist/{chunk-ONLS5QA5.js → chunk-URIKUID7.js} +12 -12
  206. package/dist/chunk-UYLBRRFK.js +1106 -0
  207. package/dist/chunk-UZACEG2C.js +515 -0
  208. package/dist/{chunk-7SW2QWLU.js → chunk-VAMHOHUU.js} +12 -12
  209. package/dist/{chunk-RZPYKDWS.js → chunk-VUVGX5L2.js} +1 -1
  210. package/dist/{chunk-Q4D5X7QB.js → chunk-VYOCPTUB.js} +44 -24
  211. package/dist/{chunk-CAQZUNOH.js → chunk-WAZEXEJH.js} +567 -3
  212. package/dist/chunk-WCEF7H6L.js +221 -0
  213. package/dist/{chunk-2DIQQJCB.js → chunk-WEOMJHPV.js} +12 -12
  214. package/dist/{chunk-FHH4I4ZV.js → chunk-WFU77T3A.js} +12 -6
  215. package/dist/chunk-WIWTJMMR.js +292 -0
  216. package/dist/{chunk-2BFCZ3RK.js → chunk-WNTIOBOG.js} +18 -18
  217. package/dist/{chunk-7WD63HU2.js → chunk-X2CUXTWU.js} +6 -6
  218. package/dist/chunk-X7EMBM5X.js +34 -0
  219. package/dist/chunk-XEQCQO66.js +33 -0
  220. package/dist/{chunk-F7HYOUFF.js → chunk-XG4WJHLQ.js} +20 -4
  221. package/dist/{chunk-EFHQ3TWP.js → chunk-XOL3GFW2.js} +171 -31
  222. package/dist/{chunk-NE2W3OO7.js → chunk-XQ3YZ4QW.js} +22 -22
  223. package/dist/{chunk-CEXSU4S6.js → chunk-Y6K3CJBU.js} +723 -85
  224. package/dist/{chunk-4RS5KZQD.js → chunk-YAH5IQAL.js} +5 -5
  225. package/dist/{chunk-64EQYWCA.js → chunk-YBOVNMHC.js} +51 -14
  226. package/dist/chunk-YF5DZCPN.js +1212 -0
  227. package/dist/chunk-YIGBJNH4.js +37 -0
  228. package/dist/{chunk-BKVWTZ6A.js → chunk-YJ3TBOTK.js} +25 -25
  229. package/dist/{chunk-Q5AMFEWD.js → chunk-YKTE2RU3.js} +2 -2
  230. package/dist/{chunk-7EKXJZ2Y.js → chunk-YO2PKTXT.js} +296 -37
  231. package/dist/{chunk-6J5OKA4Y.js → chunk-YTTNTQOX.js} +15 -15
  232. package/dist/{chunk-OT2O76OS.js → chunk-YWAKDNMH.js} +183 -33
  233. package/dist/{chunk-R6XF6UR3.js → chunk-YZDZOEV4.js} +4 -4
  234. package/dist/chunk-Z3QFH7YG.js +17 -0
  235. package/dist/{chunk-W5BVQF44.js → chunk-Z6VLC5X4.js} +17 -17
  236. package/dist/{chunk-HLJAXMM4.js → chunk-ZFQMMU5Y.js} +2 -2
  237. package/dist/{chunk-W3BQAZ3Q.js → chunk-ZKYRDV7A.js} +12 -12
  238. package/dist/{chunk-ZMAINWBW.js → chunk-ZLS6PU2O.js} +3 -3
  239. package/dist/{chunk-ZVM6AKKM.js → chunk-ZOSD4FXV.js} +3 -3
  240. package/dist/chunk-ZPDDEVQX.js +47 -0
  241. package/dist/{chunk-TXLH6WHQ.js → chunk-ZQLRCA2V.js} +11 -11
  242. package/dist/{chunk-HITVBIJS.js → chunk-ZX7235KR.js} +128 -54
  243. package/dist/{chunk-GT4I4ZWM.js → chunk-ZZFHLRQW.js} +18 -16
  244. package/dist/files.json +636 -364
  245. package/dist/packages/naysayer/constitution/constitution.yaml +19 -0
  246. package/dist/packages/sdk/npm/index.js +5614 -2343
  247. package/dist/packages/ui/dist/assets/{elk-api-tma0MCuh.js → elk-api-CowTnhEJ.js} +2 -2
  248. package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +1 -0
  249. package/dist/packages/ui/dist/assets/index-z2wv0d5d.js +47 -0
  250. package/dist/packages/ui/dist/index.html +2 -2
  251. package/package.json +4 -4
  252. package/dist/chunk-2BF2EYJV.js +0 -174
  253. package/dist/chunk-42EVSKME.js +0 -37
  254. package/dist/chunk-4BKGMUIK.js +0 -53
  255. package/dist/chunk-5KLGBXG5.js +0 -48
  256. package/dist/chunk-6BNC6EQ4.js +0 -41
  257. package/dist/chunk-6D2CQ5II.js +0 -41
  258. package/dist/chunk-7AVHLZGD.js +0 -45
  259. package/dist/chunk-D46WUV3T.js +0 -33
  260. package/dist/chunk-E36QOJMD.js +0 -47
  261. package/dist/chunk-FQXYPF7E.js +0 -147
  262. package/dist/chunk-GBRFVT63.js +0 -45
  263. package/dist/chunk-ICY36XCH.js +0 -34
  264. package/dist/chunk-J4K3KVLD.js +0 -131
  265. package/dist/chunk-JZU3H6UQ.js +0 -54
  266. package/dist/chunk-NN2ZQEB4.js +0 -38
  267. package/dist/chunk-PCOCACY3.js +0 -385
  268. package/dist/chunk-RTEYOSJY.js +0 -29
  269. package/dist/chunk-RVH5SUW5.js +0 -69
  270. package/dist/chunk-VN3DP4LQ.js +0 -43
  271. package/dist/chunk-XPTOBS2D.js +0 -48
  272. package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +0 -29
  273. package/dist/packages/ui/dist/assets/index-DD_hufQz.css +0 -1
@@ -7,27 +7,30 @@ import {
7
7
  documentFormat,
8
8
  drawioIngestor,
9
9
  officeFormat,
10
+ parseCsv,
10
11
  readDocument,
11
12
  readDrawio,
12
13
  readMermaid,
13
14
  resolveNames
14
- } from "./chunk-7EKXJZ2Y.js";
15
+ } from "./chunk-YO2PKTXT.js";
15
16
  import {
16
17
  openapiExtractor,
17
18
  readOpenApiDocument
18
- } from "./chunk-MC3H7736.js";
19
+ } from "./chunk-TWQRPM76.js";
19
20
  import {
20
21
  combine,
21
22
  formatOf,
22
23
  screenDiagramXml,
23
24
  screenOfficeXml,
24
25
  screenText
25
- } from "./chunk-CNUKCS2T.js";
26
+ } from "./chunk-QHJJMZLX.js";
26
27
  import {
28
+ TrafficFile,
27
29
  endpointId,
28
30
  entryEndpointId,
29
31
  factIdPart,
30
32
  fieldNameKey,
33
+ interfaceId,
31
34
  joinFacts,
32
35
  joinVendorOperations,
33
36
  loadOrgPack,
@@ -36,11 +39,13 @@ import {
36
39
  parseRecord,
37
40
  readZip,
38
41
  require_dist,
39
- toCanonicalYaml
40
- } from "./chunk-S2A7YC3Q.js";
42
+ routeScore,
43
+ toCanonicalYaml,
44
+ trafficFileText
45
+ } from "./chunk-PAINMSID.js";
41
46
  import {
42
47
  writeFileAtomic
43
- } from "./chunk-D3PO4DOZ.js";
48
+ } from "./chunk-ODMBPDDV.js";
44
49
  import {
45
50
  __toESM
46
51
  } from "./chunk-TV45EUGM.js";
@@ -122,6 +127,151 @@ function fromData(data) {
122
127
  }
123
128
  return void 0;
124
129
  }
130
+ var STRICT_ALIASES = 100;
131
+ var LENIENT_ALIASES = 1e4;
132
+ var LENIENT = { uniqueKeys: false, maxAliasCount: LENIENT_ALIASES };
133
+ var reasonOf = (e) => e.message.split("\n")[0].replace(/\s+at line \d+, column \d+:?\s*$/, "").trim();
134
+ var unreadableOf = (e) => ({
135
+ reason: reasonOf(e),
136
+ ...e.linePos?.[0] ? { line: e.linePos[0].line, column: e.linePos[0].col } : {}
137
+ });
138
+ function duplicateKeys(text3) {
139
+ const lines = text3.split(/\r?\n/);
140
+ return (0, import_yaml.parseDocument)(text3).errors.filter((e) => e.code === "DUPLICATE_KEY" && e.linePos?.[0]).map((e) => {
141
+ const { line, col } = e.linePos[0];
142
+ const key3 = /^\s*["']?([^"':]+)["']?\s*:/.exec((lines[line - 1] ?? "").slice(col - 1))?.[1];
143
+ return `duplicate key ${key3 ? `"${key3.trim()}" ` : ""}at ${line}:${col}: the last one is kept`;
144
+ });
145
+ }
146
+ function braceBalance(line) {
147
+ let n = 0;
148
+ let quote;
149
+ for (let i = 0; i < line.length; i++) {
150
+ const c = line[i];
151
+ if (quote) {
152
+ if (c === "\\" && quote === '"')
153
+ i++;
154
+ else if (c === quote)
155
+ quote = void 0;
156
+ } else if (c === '"' || c === "'")
157
+ quote = c;
158
+ else if (c === "#" && (i === 0 || /\s/.test(line[i - 1])))
159
+ return NaN;
160
+ else if (c === "{")
161
+ n++;
162
+ else if (c === "}")
163
+ n--;
164
+ }
165
+ return quote ? NaN : n;
166
+ }
167
+ var indentOf = (l) => /^\s*/.exec(l)[0].length;
168
+ var blank = (l) => !l.trim() || /^\s*#/.test(l);
169
+ function joinServerVariables(text3) {
170
+ const lines = text3.split(/\r?\n/);
171
+ const at = [];
172
+ let servers;
173
+ let vars;
174
+ for (let i = 0; i < lines.length; i++) {
175
+ const l = lines[i];
176
+ if (blank(l))
177
+ continue;
178
+ const ind = indentOf(l);
179
+ if (vars !== void 0 && ind <= vars)
180
+ vars = void 0;
181
+ if (servers !== void 0 && ind <= servers && !/^\s*-(\s|$)/.test(l))
182
+ servers = void 0;
183
+ if (servers !== void 0 && ind < servers)
184
+ servers = void 0;
185
+ if (/^\s*["']?servers["']?\s*:\s*$/.test(l)) {
186
+ servers = ind;
187
+ vars = void 0;
188
+ continue;
189
+ }
190
+ if (servers === void 0)
191
+ continue;
192
+ const v = /^(\s*)(-\s+)?["']?variables["']?\s*:\s*$/.exec(l);
193
+ if (v) {
194
+ vars = v[1].length + (v[2]?.length ?? 0);
195
+ continue;
196
+ }
197
+ if (vars === void 0)
198
+ continue;
199
+ const m = /^(\s*)(["']?[\w.-]+["']?)\s*:\s*(\{.*)$/.exec(l);
200
+ if (!m)
201
+ continue;
202
+ let balance = braceBalance(m[3]);
203
+ if (Number.isNaN(balance))
204
+ return void 0;
205
+ const parts = [m[3].trim()];
206
+ let j = i;
207
+ while (balance > 0) {
208
+ j++;
209
+ if (j >= lines.length || j - i > 200)
210
+ return void 0;
211
+ const b = braceBalance(lines[j]);
212
+ if (Number.isNaN(b))
213
+ return void 0;
214
+ balance += b;
215
+ parts.push(lines[j].trim());
216
+ }
217
+ if (balance < 0)
218
+ return void 0;
219
+ const joined = `${m[1]}${m[2]}: ${parts.filter(Boolean).join(" ")}`;
220
+ if (joined === l && j === i)
221
+ continue;
222
+ lines[i] = joined;
223
+ for (let k = i + 1; k <= j; k++)
224
+ lines[k] = "";
225
+ at.push(i + 1);
226
+ i = j;
227
+ }
228
+ return at.length ? { text: lines.join("\n"), at } : void 0;
229
+ }
230
+ var SPEC_KINDS = ["openapi", "swagger", "asyncapi"];
231
+ function readYaml(text3) {
232
+ let first;
233
+ try {
234
+ return { data: (0, import_yaml.parse)(text3) };
235
+ } catch (e) {
236
+ first = e;
237
+ }
238
+ const notes = [];
239
+ const dup = first.code === "DUPLICATE_KEY";
240
+ const aliases = /alias count/i.test(first.message);
241
+ const lenient = (t) => {
242
+ try {
243
+ return { data: (0, import_yaml.parse)(t, LENIENT) };
244
+ } catch (e) {
245
+ return { error: e };
246
+ }
247
+ };
248
+ const notesOf = (t) => {
249
+ const out = duplicateKeys(t);
250
+ try {
251
+ (0, import_yaml.parse)(t, { uniqueKeys: false });
252
+ } catch (e) {
253
+ if (/alias count/i.test(e.message))
254
+ out.push(`more aliases than the strict parser allows (${STRICT_ALIASES}): read with a higher limit (${LENIENT_ALIASES})`);
255
+ }
256
+ return out;
257
+ };
258
+ if (dup || aliases) {
259
+ const r = lenient(text3);
260
+ if ("data" in r)
261
+ return { data: r.data, notes: notesOf(text3) };
262
+ }
263
+ const fixed = joinServerVariables(text3);
264
+ if (fixed) {
265
+ const r = lenient(fixed.text);
266
+ if ("data" in r && SPEC_KINDS.includes(fromData(r.data)?.classification ?? "unknown")) {
267
+ notes.push(...notesOf(fixed.text));
268
+ const lines = fixed.at.length === 1 ? `line ${fixed.at[0]} is a flow mapping` : `lines ${fixed.at.slice(0, -1).join(", ")} and ${fixed.at.at(-1)} are flow mappings`;
269
+ notes.push(`servers[].variables at ${lines} written over several lines, not indented past ${fixed.at.length === 1 ? "its key: read as if it were" : "their key: read as if each were"} on one line`);
270
+ return { data: r.data, notes, text: fixed.text };
271
+ }
272
+ }
273
+ return { error: first };
274
+ }
125
275
  function classify(fileName, bytes) {
126
276
  const name = fileName.toLowerCase();
127
277
  const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1) : "";
@@ -163,19 +313,26 @@ function classify(fileName, bytes) {
163
313
  return { classification: "diagram" };
164
314
  if (/^<(!doctype html|html)\b/i.test(head))
165
315
  return { classification: "document" };
316
+ if (ext === "proto" || /^(syntax\s*=\s*["']proto[23]["']|package\s+[\w.]+\s*;)/m.test(head))
317
+ return { classification: "protobuf" };
318
+ if (ext === "avsc" || /^\{/.test(head) && /"type"\s*:\s*"record"/.test(head) && /"fields"\s*:/.test(head))
319
+ return { classification: "avro" };
166
320
  if (["json", "yaml", "yml"].includes(ext) || /^[[{]/.test(head)) {
167
- let data;
168
- try {
169
- data = (0, import_yaml.parse)(text3);
170
- } catch {
171
- data = void 0;
172
- }
321
+ const r = readYaml(text3);
322
+ const named = ["json", "yaml", "yml"].includes(ext);
323
+ if ("error" in r && named)
324
+ return { classification: "unknown", unreadable: unreadableOf(r.error) };
325
+ const data = "data" in r ? r.data : void 0;
326
+ const lenient = {
327
+ ..."notes" in r && r.notes?.length ? { notes: r.notes } : {},
328
+ ..."text" in r && r.text !== void 0 ? { text: r.text } : {}
329
+ };
173
330
  const known = fromData(data);
174
331
  if (known)
175
- return known;
332
+ return { ...known, ...lenient };
176
333
  if (ext === "json" || /^[[{]/.test(head)) {
177
334
  if (isObj(data) || Array.isArray(data))
178
- return { classification: "payload", data };
335
+ return { classification: "payload", data, ...lenient };
179
336
  }
180
337
  if (ext === "yaml" || ext === "yml")
181
338
  return { classification: "unknown" };
@@ -195,7 +352,10 @@ import { createHash } from "node:crypto";
195
352
  var READERS = {
196
353
  openapi: `${openapiExtractor.id}@${openapiExtractor.version}`,
197
354
  asyncapi: "asyncapi@0.1.0",
198
- payload: "payload@0.1.0"
355
+ payload: "payload@0.1.0",
356
+ // ADR 0164: a topic's message spec.
357
+ protobuf: "protobuf@0.1.0",
358
+ avro: "avro@0.1.0"
199
359
  };
200
360
  var short = (s) => createHash("sha256").update(s).digest("hex").slice(0, 6);
201
361
  function oneFile(path, text3) {
@@ -365,8 +525,8 @@ var KIND_ORDER = [
365
525
  "needs-reading"
366
526
  ];
367
527
  var slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
368
- function boundedId(prefix, key2) {
369
- const id = `${prefix}${key2}`;
528
+ function boundedId(prefix, key3) {
529
+ const id = `${prefix}${key3}`;
370
530
  if (id.length <= 120)
371
531
  return id;
372
532
  return `${id.slice(0, 110)}-${createHash2("sha256").update(id).digest("hex").slice(0, 8)}`;
@@ -411,9 +571,9 @@ var opt = {
411
571
  };
412
572
 
413
573
  // packages/intake/dist/scan-inputs.js
414
- import { createHash as createHash4 } from "node:crypto";
415
- import { readdir, readFile, stat } from "node:fs/promises";
416
- import { join, relative, resolve, sep } from "node:path";
574
+ import { createHash as createHash5 } from "node:crypto";
575
+ import { readdir as readdir2, readFile as readFile2, stat as stat2 } from "node:fs/promises";
576
+ import { join as join2, relative, resolve, sep } from "node:path";
417
577
 
418
578
  // packages/intake/dist/screen-file.js
419
579
  var PK = (b) => b[0] === 80 && b[1] === 75;
@@ -455,10 +615,314 @@ function screenFile(path, bytes) {
455
615
  }
456
616
  }
457
617
 
618
+ // packages/intake/dist/contract-specs.js
619
+ var import_yaml4 = __toESM(require_dist(), 1);
620
+ import { readdir, readFile, stat } from "node:fs/promises";
621
+ import { join } from "node:path";
622
+
623
+ // packages/intake/dist/traffic.js
624
+ import { createHash as createHash3 } from "node:crypto";
625
+ var cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
626
+ var key = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
627
+ var sha = (s) => createHash3("sha256").update(s, "utf8").digest("hex");
628
+ var IPV4 = /\b\d{1,3}(?:\.\d{1,3}){3}\b/;
629
+ var IPV6 = /[0-9a-f]{0,4}::[0-9a-f]{0,4}|\b[0-9a-f]{1,4}(?::[0-9a-f]{1,4}){2,7}\b/i;
630
+ var EMAIL = /[^\s@/]+@[^\s@/]+/;
631
+ var JWT = /\beyJ[A-Za-z0-9_-]{6,}/;
632
+ var OPAQUE = /\b(?=[A-Za-z0-9+_-]*\d)(?=[A-Za-z0-9+_-]*[A-Za-z])[A-Za-z0-9+_-]{24,}={0,2}/;
633
+ var UUID = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i;
634
+ var HEX = /\b[0-9a-f]{16,}\b/i;
635
+ function looksSensitive(v) {
636
+ return [IPV4, IPV6, EMAIL, JWT, OPAQUE, UUID, HEX].some((re) => re.test(v));
637
+ }
638
+ function rowsOf(text3) {
639
+ const t = text3.replace(/^\uFEFF/, "").trim();
640
+ if (!t)
641
+ return void 0;
642
+ if (t.startsWith("[") || t.startsWith("{")) {
643
+ let v;
644
+ try {
645
+ v = JSON.parse(t);
646
+ } catch {
647
+ return void 0;
648
+ }
649
+ const list2 = Array.isArray(v) ? v : v && typeof v === "object" ? ["rows", "data", "records", "items"].map((k) => v[k]).find((x) => Array.isArray(x)) : void 0;
650
+ if (!Array.isArray(list2) || !list2.length)
651
+ return void 0;
652
+ const out = [];
653
+ for (const r of list2) {
654
+ if (!r || typeof r !== "object" || Array.isArray(r))
655
+ return void 0;
656
+ const row = {};
657
+ for (const [k, x] of Object.entries(r))
658
+ if (typeof x === "string" || typeof x === "number")
659
+ row[k] = String(x);
660
+ out.push(row);
661
+ }
662
+ return out;
663
+ }
664
+ const recs = parseCsv(t);
665
+ if (recs.length < 2)
666
+ return void 0;
667
+ const head = recs[0].cells.map((c) => c.trim());
668
+ if (head.length < 2)
669
+ return void 0;
670
+ return recs.slice(1).map((r) => {
671
+ const row = {};
672
+ head.forEach((h, i) => row[h] = (r.cells[i] ?? "").trim());
673
+ return row;
674
+ });
675
+ }
676
+ function dayOf(v) {
677
+ const m = /^(\d{4}-\d{2}-\d{2})/.exec(v.trim());
678
+ if (m)
679
+ return m[1];
680
+ if (/^\d{12,13}$/.test(v.trim()))
681
+ return new Date(Number(v)).toISOString().slice(0, 10);
682
+ return void 0;
683
+ }
684
+ var VERSION = /^v\d+(?:\.\d+)*$/i;
685
+ var PARAM = /^(?:\{[A-Za-z_][A-Za-z0-9_.-]{0,40}\}|:[A-Za-z_][A-Za-z0-9_]{0,40}|<[A-Za-z_][A-Za-z0-9_:]{0,40}>)$/;
686
+ var segmentOf = (s) => VERSION.test(s) || PARAM.test(s) || /^[a-z][a-z._-]*$/.test(s) && s.length <= 20 && /[aeiou]/.test(s) && !looksSensitive(s) ? s : "{id}";
687
+ function barePath(path) {
688
+ let p = path.trim().split(/[?#]/, 1)[0] ?? "";
689
+ p = p.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]*/i, "");
690
+ return p.replace(/;[^/]*/g, "");
691
+ }
692
+ function safePathOf(path) {
693
+ const p = barePath(path);
694
+ if (!p.startsWith("/"))
695
+ return void 0;
696
+ return `/${p.split("/").filter(Boolean).map(segmentOf).join("/")}`;
697
+ }
698
+ var MATCH = 100;
699
+ function pathTemplateOf(path, templates) {
700
+ const p = barePath(path);
701
+ if (!p.startsWith("/"))
702
+ return void 0;
703
+ const sorted2 = [...templates].sort();
704
+ let best;
705
+ let score = 0;
706
+ for (const t of sorted2) {
707
+ const s = routeScore(p, t);
708
+ if (s > MATCH && s > score) {
709
+ score = s;
710
+ best = t;
711
+ }
712
+ }
713
+ if (best)
714
+ return best;
715
+ const segs = p.split("/").filter(Boolean);
716
+ let prefix;
717
+ let len = 0;
718
+ score = 0;
719
+ for (const t of sorted2) {
720
+ const n = t.split("/").filter(Boolean).length;
721
+ if (n === 0 || n >= segs.length || n < len)
722
+ continue;
723
+ const s = routeScore(`/${segs.slice(0, n).join("/")}`, t);
724
+ if (s <= MATCH)
725
+ continue;
726
+ if (n > len || s > score) {
727
+ len = n;
728
+ score = s;
729
+ prefix = t;
730
+ }
731
+ }
732
+ return prefix ? `${prefix.replace(/\/+$/, "")}/**` : void 0;
733
+ }
734
+ var appLabelOf = (name) => `app-${sha(name).slice(0, 8)}`;
735
+ function denyListHits(text3, hashes) {
736
+ const hits = [];
737
+ text3.toLowerCase().split("\n").forEach((line, i) => {
738
+ const w = line.match(/[a-z0-9]+/g) ?? [];
739
+ for (let k = 0; k < w.length; k++)
740
+ if (hashes.has(sha(w[k])) || k + 1 < w.length && hashes.has(sha(`${w[k]} ${w[k + 1]}`))) {
741
+ hits.push(i + 1);
742
+ break;
743
+ }
744
+ });
745
+ return hits;
746
+ }
747
+ function aggregateTraffic(input) {
748
+ const text3 = Buffer.from(input.bytes).toString("utf8");
749
+ const rows = rowsOf(text3);
750
+ const shape = `a CSV with a header row, or a JSON list of rows, with an app, a method and a path column (${input.source}: app ${input.columns.app.join("/")}; method ${input.columns.method.join("/")}; path ${[...input.columns.path, ...input.columns.basepath].join("/")})`;
751
+ if (!rows)
752
+ return { ok: false, message: `The file doesn't read as a traffic export: give ${shape}.` };
753
+ const names = [...new Set(rows.flatMap((r) => Object.keys(r)))];
754
+ const col = (aliases) => {
755
+ for (const a of aliases) {
756
+ const hit = names.find((n) => key(n) === key(a));
757
+ if (hit)
758
+ return hit;
759
+ }
760
+ return void 0;
761
+ };
762
+ const c = {
763
+ app: col(input.columns.app),
764
+ method: col(input.columns.method),
765
+ basepath: col(input.columns.basepath),
766
+ suffix: col(input.columns.suffix),
767
+ proxy: col(input.columns.proxy),
768
+ count: col(input.columns.count),
769
+ time: col(input.columns.time),
770
+ path: void 0
771
+ };
772
+ if (!c.basepath || !c.suffix)
773
+ c.path = col(input.columns.path);
774
+ const missing = [
775
+ !c.app ? "app" : "",
776
+ !c.method ? "method" : "",
777
+ !c.path && !(c.basepath && c.suffix) ? "path" : ""
778
+ ].filter(Boolean);
779
+ if (missing.length)
780
+ return {
781
+ ok: false,
782
+ message: `The file has no ${missing.join(", ")} column, so it can't be kept as aggregates: give ${shape}.`
783
+ };
784
+ const range = (v) => v && /^\d{4}-\d{2}-\d{2}$/.test(v) ? v : void 0;
785
+ if (input.from && !range(input.from) || input.to && !range(input.to))
786
+ return { ok: false, message: "--from and --to are days: YYYY-MM-DD." };
787
+ if ((!input.from || !input.to) && !c.time)
788
+ return {
789
+ ok: false,
790
+ message: "The export has no date column: give --from and --to (YYYY-MM-DD) for the range it covers."
791
+ };
792
+ const kept = new Set(Object.values(c).filter((x) => !!x));
793
+ const dropped = names.filter((n) => !kept.has(n)).sort();
794
+ const secrets = /* @__PURE__ */ new Set();
795
+ const keptValues = /* @__PURE__ */ new Set();
796
+ const agg = /* @__PURE__ */ new Map();
797
+ let outOfRange = 0;
798
+ let skipped2 = 0;
799
+ let unmatched = 0;
800
+ const known = /* @__PURE__ */ new Map();
801
+ for (const a of input.apps ?? [])
802
+ if (a.trim() && !known.has(key(a)))
803
+ known.set(key(a), a.trim());
804
+ const days = [];
805
+ for (const r of rows) {
806
+ for (const n of dropped) {
807
+ const v = (r[n] ?? "").trim();
808
+ const q = /^(?:[a-z][a-z0-9+.-]*:\/\/|\/)/i.test(v) ? v.split(/[?#]/)[1] ?? "" : v;
809
+ if (q.length >= 6)
810
+ secrets.add(q);
811
+ }
812
+ for (const n of [c.path, c.suffix, c.basepath]) {
813
+ const v = n ? r[n] ?? "" : "";
814
+ const q = v.split(/[?#]/)[1] ?? "";
815
+ if (q.length >= 4)
816
+ secrets.add(q);
817
+ for (const m of (v.split(/[?#]/, 1)[0] ?? "").match(/;[^/]*/g) ?? [])
818
+ if (m.length >= 5)
819
+ secrets.add(m.slice(1));
820
+ }
821
+ if (c.time) {
822
+ const d = dayOf(r[c.time] ?? "");
823
+ if (d) {
824
+ if (input.from && d < input.from || input.to && d > input.to) {
825
+ outOfRange++;
826
+ continue;
827
+ }
828
+ days.push(d);
829
+ } else if (!input.from || !input.to) {
830
+ skipped2++;
831
+ continue;
832
+ }
833
+ }
834
+ const method = (r[c.method] ?? "").trim().toUpperCase();
835
+ const rawPath = c.path ? r[c.path] ?? "" : `${(r[c.basepath] ?? "").replace(/\/+$/, "")}/${(r[c.suffix] ?? "").replace(/^\/+/, "")}`;
836
+ const countText = c.count ? (r[c.count] ?? "").trim() : "1";
837
+ const count = Number(countText);
838
+ if (!/^[A-Z]{3,10}$/.test(method) || !barePath(rawPath).startsWith("/") || !Number.isInteger(count) || count < 0) {
839
+ skipped2++;
840
+ continue;
841
+ }
842
+ const path = pathTemplateOf(rawPath, input.templates);
843
+ if (!path) {
844
+ unmatched++;
845
+ continue;
846
+ }
847
+ if (count === 0)
848
+ continue;
849
+ const appRaw = (r[c.app] ?? "").trim();
850
+ const app = !appRaw ? "(none)" : known.get(key(appRaw)) ?? appLabelOf(appRaw);
851
+ const proxyRaw = c.proxy ? (r[c.proxy] ?? "").trim() : "";
852
+ const proxy = proxyRaw && !looksSensitive(proxyRaw) ? proxyRaw : void 0;
853
+ const baseRaw = c.basepath ? (r[c.basepath] ?? "").trim() : "";
854
+ const basepath = baseRaw ? safePathOf(baseRaw) : void 0;
855
+ for (const v of [app, proxy, basepath, path])
856
+ if (v)
857
+ keptValues.add(v);
858
+ const k = [app, method, path, proxy ?? "", basepath ?? ""].join("\0");
859
+ const row = agg.get(k) ?? {
860
+ app,
861
+ method,
862
+ path,
863
+ ...proxy ? { proxy } : {},
864
+ ...basepath ? { basepath } : {},
865
+ count: 0
866
+ };
867
+ row.count += count;
868
+ agg.set(k, row);
869
+ }
870
+ if (!agg.size)
871
+ return {
872
+ ok: false,
873
+ message: `No row of the file is a request in the range to a route of the estate (${rows.length} read, ${outOfRange} outside it, ${skipped2} without a method, path or count, ${unmatched} matching no route template of the estate): nothing to keep.`
874
+ };
875
+ days.sort();
876
+ const from = input.from ?? days[0];
877
+ const to = input.to ?? days[days.length - 1];
878
+ if (!from || !to)
879
+ return { ok: false, message: "The rows carry no dates: give --from and --to (YYYY-MM-DD)." };
880
+ const parsed = TrafficFile.safeParse({
881
+ schemaVersion: 1,
882
+ source: input.source,
883
+ from,
884
+ to,
885
+ inputSha256: createHash3("sha256").update(input.bytes).digest("hex"),
886
+ rows: [...agg.values()].sort((a, b) => cmp(a.app, b.app) || cmp(a.proxy ?? "", b.proxy ?? "") || cmp(a.path, b.path) || cmp(a.method, b.method))
887
+ });
888
+ if (!parsed.success)
889
+ return { ok: false, message: `The aggregate isn't valid: ${parsed.error.issues[0]?.message}.` };
890
+ const out = trafficFileText(parsed.data);
891
+ const lower = out.toLowerCase();
892
+ const leaked = [...secrets].filter((s) => !keptValues.has(s) && lower.includes(s.toLowerCase()));
893
+ if (leaked.length)
894
+ return {
895
+ ok: false,
896
+ message: `Refused: ${leaked.length} value${leaked.length === 1 ? "" : "s"} of the export's dropped columns would be written. Nothing was written.`
897
+ };
898
+ const body = out.replace(/^inputSha256: .*$/m, "");
899
+ if ([IPV4, IPV6, EMAIL, JWT, OPAQUE, UUID, HEX].some((re) => re.test(body)))
900
+ return {
901
+ ok: false,
902
+ message: "Refused: the aggregate would hold an IP, an email or a token-looking value. Nothing was written."
903
+ };
904
+ const hits = input.denyHashes?.size ? denyListHits(out, input.denyHashes) : [];
905
+ if (hits.length)
906
+ return {
907
+ ok: false,
908
+ message: `Refused: the deny-list names a word on line${hits.length === 1 ? "" : "s"} ${hits.join(", ")} of the aggregate. Nothing was written.`
909
+ };
910
+ return {
911
+ ok: true,
912
+ file: parsed.data,
913
+ text: out,
914
+ read: rows.length,
915
+ outOfRange,
916
+ skipped: skipped2,
917
+ unmatched,
918
+ dropped
919
+ };
920
+ }
921
+
458
922
  // packages/intake/dist/vendor-ops.js
459
923
  var import_yaml3 = __toESM(require_dist(), 1);
460
- import { createHash as createHash3 } from "node:crypto";
461
- var short2 = (s) => createHash3("sha256").update(s).digest("hex").slice(0, 6);
924
+ import { createHash as createHash4 } from "node:crypto";
925
+ var short2 = (s) => createHash4("sha256").update(s).digest("hex").slice(0, 6);
462
926
  function specEndpointIds(component, ops) {
463
927
  const ids = ops.map((o) => endpointId(component, o.method, o.normalizedPath));
464
928
  const count = /* @__PURE__ */ new Map();
@@ -507,7 +971,8 @@ function readVendorSpec(path, text3, system) {
507
971
  scopes: op.scopes,
508
972
  cite: `${path}:${op.methodLine ?? op.line ?? 1}`,
509
973
  request: requestFields(ctx, op, swagger2),
510
- response: responseFields(ctx, op, swagger2)
974
+ response: responseFields(ctx, op, swagger2),
975
+ ...errorsOf(ctx, op, swagger2)
511
976
  };
512
977
  });
513
978
  const ids = specEndpointIds(system, ops);
@@ -522,6 +987,56 @@ function readVendorSpec(path, text3, system) {
522
987
  operations: ops.map((o, i) => ({ id: ids[i], ...o }))
523
988
  };
524
989
  }
990
+ function errorsOf(ctx, op, swagger2) {
991
+ const responses = (0, import_yaml3.isMap)(op.node) ? op.node.get("responses") : void 0;
992
+ if (!(0, import_yaml3.isMap)(responses))
993
+ return {};
994
+ const errors = responses.items.flatMap((p) => {
995
+ const status = (0, import_yaml3.isScalar)(p.key) ? String(p.key.value) : "";
996
+ if (!/^[45]\d\d$/.test(status))
997
+ return [];
998
+ const cite = ctx.at((0, import_yaml3.isScalar)(p.key) ? p.key.range?.[0] : void 0);
999
+ if (!cite)
1000
+ return [];
1001
+ const fields = [];
1002
+ schemaFields(ctx, bodySchema(ctx, p.value, swagger2), "body", "", 0, /* @__PURE__ */ new Set(), fields);
1003
+ return [{ status, cite, ...fields.length ? { fields } : {} }];
1004
+ });
1005
+ return errors.length ? { errors } : {};
1006
+ }
1007
+ function bodySchema(ctx, response, swagger2) {
1008
+ if (!swagger2)
1009
+ return contentSchema(ctx, response);
1010
+ const r = deref(ctx, response);
1011
+ return (0, import_yaml3.isMap)(r) ? r.get("schema", true) : void 0;
1012
+ }
1013
+ function responseHeaders(ctx, response, swagger2) {
1014
+ const r = deref(ctx, response);
1015
+ const headers = (0, import_yaml3.isMap)(r) ? r.get("headers") : void 0;
1016
+ if (!(0, import_yaml3.isMap)(headers))
1017
+ return [];
1018
+ const out = [];
1019
+ for (const pair of headers.items) {
1020
+ if (!(0, import_yaml3.isScalar)(pair.key))
1021
+ continue;
1022
+ const h = deref(ctx, pair.value);
1023
+ if (!(0, import_yaml3.isMap)(h))
1024
+ continue;
1025
+ const schema = swagger2 ? h : deref(ctx, h.get("schema", true));
1026
+ const sm = (0, import_yaml3.isMap)(schema) ? schema : void 0;
1027
+ const type = sm ? typeOf2(sm) : void 0;
1028
+ const values = sm ? strings(sm.get("enum")) : void 0;
1029
+ out.push({
1030
+ name: String(pair.key.value),
1031
+ in: "header",
1032
+ ...type ? { type } : {},
1033
+ ...swagger2 ? {} : { required: h.get("required") === true },
1034
+ ...values ? { enum: values } : {},
1035
+ cite: ctx.at(pair.key.range?.[0]) ?? `${ctx.path}:1`
1036
+ });
1037
+ }
1038
+ return out;
1039
+ }
525
1040
  function deref(ctx, node, seen = /* @__PURE__ */ new Set()) {
526
1041
  let n = node;
527
1042
  for (let i = 0; i < 8 && (0, import_yaml3.isMap)(n); i++) {
@@ -536,8 +1051,8 @@ function deref(ctx, node, seen = /* @__PURE__ */ new Set()) {
536
1051
  }
537
1052
  return n;
538
1053
  }
539
- var offsetOfKey = (map, key2) => {
540
- const pair = map.items.find((p) => (0, import_yaml3.isScalar)(p.key) && String(p.key.value) === key2);
1054
+ var offsetOfKey = (map, key3) => {
1055
+ const pair = map.items.find((p) => (0, import_yaml3.isScalar)(p.key) && String(p.key.value) === key3);
541
1056
  return pair && (0, import_yaml3.isScalar)(pair.key) ? pair.key.range?.[0] : void 0;
542
1057
  };
543
1058
  var strings = (n) => (0, import_yaml3.isSeq)(n) ? n.items.filter(import_yaml3.isScalar).map((s) => String(s.value)) : void 0;
@@ -587,13 +1102,13 @@ function schemaFields(ctx, node, where, prefix, depth, seen, out) {
587
1102
  for (const pair of props.items) {
588
1103
  if (!(0, import_yaml3.isScalar)(pair.key))
589
1104
  continue;
590
- const key2 = String(pair.key.value);
591
- const name = prefix ? `${prefix}.${key2}` : key2;
1105
+ const key3 = String(pair.key.value);
1106
+ const name = prefix ? `${prefix}.${key3}` : key3;
592
1107
  const prop = deref(ctx, pair.value, new Set(refs));
593
1108
  const p = (0, import_yaml3.isMap)(prop) ? prop : void 0;
594
1109
  const type = p ? typeOf2(p) : void 0;
595
1110
  const values = p ? strings(p.get("enum")) : void 0;
596
- const req = required.has(key2);
1111
+ const req = required.has(key3);
597
1112
  out.push({
598
1113
  name,
599
1114
  in: where,
@@ -601,7 +1116,7 @@ function schemaFields(ctx, node, where, prefix, depth, seen, out) {
601
1116
  ...objectLike ? { required: req } : {},
602
1117
  ...values ? { enum: values } : {},
603
1118
  cite: ctx.at(pair.key.range?.[0]) ?? `${ctx.path}:1`,
604
- ...req && required.get(key2) !== void 0 ? { requiredCite: ctx.at(required.get(key2)) } : {}
1119
+ ...req && required.get(key3) !== void 0 ? { requiredCite: ctx.at(required.get(key3)) } : {}
605
1120
  });
606
1121
  if (p && (type === "object" || type === "array"))
607
1122
  schemaFields(ctx, pair.value, where, name, depth + 1, refs, out);
@@ -683,11 +1198,8 @@ function responseFields(ctx, op, swagger2) {
683
1198
  if (!ok)
684
1199
  return [];
685
1200
  const out = [];
686
- const schema = swagger2 ? (() => {
687
- const r = deref(ctx, ok.value);
688
- return (0, import_yaml3.isMap)(r) ? r.get("schema", true) : void 0;
689
- })() : contentSchema(ctx, ok.value);
690
- schemaFields(ctx, schema, "body", "", 0, /* @__PURE__ */ new Set(), out);
1201
+ schemaFields(ctx, bodySchema(ctx, ok.value, swagger2), "body", "", 0, /* @__PURE__ */ new Set(), out);
1202
+ out.push(...responseHeaders(ctx, ok.value, swagger2));
691
1203
  return out;
692
1204
  }
693
1205
  var pointer = (s) => s.replace(/~/g, "~0").replace(/\//g, "~1");
@@ -722,12 +1234,442 @@ function operationSchemas(spec) {
722
1234
  });
723
1235
  }
724
1236
 
1237
+ // packages/intake/dist/contract-specs.js
1238
+ var MAX_BYTES = 1024 * 1024;
1239
+ var SKIP = /* @__PURE__ */ new Set([
1240
+ ".git",
1241
+ "node_modules",
1242
+ "vendor",
1243
+ "target",
1244
+ "build",
1245
+ "dist",
1246
+ "out",
1247
+ "bin",
1248
+ "obj",
1249
+ ".gradle",
1250
+ ".idea",
1251
+ ".venv",
1252
+ "__pycache__"
1253
+ ]);
1254
+ var cmp2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
1255
+ function readProtoSpecs(path, text3) {
1256
+ const proto3 = /^\s*syntax\s*=\s*["']proto3["']/m.test(text3);
1257
+ let pkg = "";
1258
+ const out = [];
1259
+ const stack = [];
1260
+ let inComment = false;
1261
+ text3.split(/\r?\n/).forEach((raw, i) => {
1262
+ let line = raw;
1263
+ if (inComment) {
1264
+ const end = line.indexOf("*/");
1265
+ if (end < 0)
1266
+ return;
1267
+ line = line.slice(end + 2);
1268
+ inComment = false;
1269
+ }
1270
+ line = line.replace(/\/\*.*?\*\//g, "").replace(/\/\/.*$/, "");
1271
+ const open = line.indexOf("/*");
1272
+ if (open >= 0) {
1273
+ inComment = true;
1274
+ line = line.slice(0, open);
1275
+ }
1276
+ const n = i + 1;
1277
+ const p = /^\s*package\s+([\w.]+)\s*;/.exec(line);
1278
+ if (p)
1279
+ pkg = p[1];
1280
+ const message = /^\s*message\s+(\w+)\s*\{/.exec(line);
1281
+ const oneof = /^\s*oneof\s+(\w+)\s*\{/.exec(line);
1282
+ const other = /^\s*(enum|service|extend|extensions)\b[^{]*\{/.exec(line);
1283
+ let rest = line;
1284
+ if (message) {
1285
+ const outer = stack.filter((f) => f.kind === "message").map((f) => f.name);
1286
+ const name = [...outer, message[1]].join(".");
1287
+ const spec = {
1288
+ kind: "message",
1289
+ format: "protobuf",
1290
+ role: "schema",
1291
+ file: path,
1292
+ line: n,
1293
+ name: pkg ? `${pkg}.${name}` : name,
1294
+ fields: []
1295
+ };
1296
+ out.push(spec);
1297
+ stack.push({ kind: "message", name: message[1], spec });
1298
+ rest = line.slice(line.indexOf("{") + 1);
1299
+ } else if (oneof || other) {
1300
+ stack.push({ kind: oneof ? "oneof" : "other", name: "" });
1301
+ rest = line.slice(line.indexOf("{") + 1);
1302
+ } else {
1303
+ const top = stack.at(-1);
1304
+ const owner = top?.kind === "message" ? top : top?.kind === "oneof" ? stack.at(-2) : void 0;
1305
+ const f = /^\s*(optional|required|repeated)?\s*(map\s*<[^>]+>|[\w.]+)\s+(\w+)\s*=\s*(\d+)\s*(\[[^\]]*\])?\s*;/.exec(line);
1306
+ if (f && owner?.kind === "message" && owner.spec && !["reserved", "option"].includes(f[2])) {
1307
+ const label = f[1];
1308
+ owner.spec.fields.push({
1309
+ side: "message",
1310
+ name: f[3],
1311
+ type: label === "repeated" ? `repeated ${f[2]}` : f[2].replace(/\s+/g, ""),
1312
+ // proto2's `required` must be there; anything else may be left out (proto3 has no required).
1313
+ required: label === "required" && !proto3,
1314
+ number: Number(f[4]),
1315
+ at: `${path}:${n}`
1316
+ });
1317
+ }
1318
+ }
1319
+ for (const _ of rest.matchAll(/\}/g))
1320
+ stack.pop();
1321
+ });
1322
+ return out;
1323
+ }
1324
+ function lineOfName(lines, from, name) {
1325
+ const re = new RegExp(`"name"\\s*:\\s*"${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"`);
1326
+ for (let i = Math.max(0, from); i < lines.length; i++)
1327
+ if (re.test(lines[i]))
1328
+ return i + 1;
1329
+ return from + 1;
1330
+ }
1331
+ function readAvroSpecs(path, text3) {
1332
+ let data;
1333
+ try {
1334
+ data = JSON.parse(text3);
1335
+ } catch {
1336
+ return [];
1337
+ }
1338
+ const lines = text3.split(/\r?\n/);
1339
+ const out = [];
1340
+ let cursor = 0;
1341
+ const typeName = (t) => {
1342
+ if (typeof t === "string")
1343
+ return t;
1344
+ if (Array.isArray(t))
1345
+ return t.map(typeName).join("|");
1346
+ if (t && typeof t === "object") {
1347
+ const o = t;
1348
+ if (o.type === "array")
1349
+ return `repeated ${typeName(o.items)}`;
1350
+ if (o.type === "map")
1351
+ return `map<string,${typeName(o.values)}>`;
1352
+ if (typeof o.logicalType === "string")
1353
+ return String(o.type);
1354
+ if (typeof o.name === "string")
1355
+ return o.name;
1356
+ return typeName(o.type);
1357
+ }
1358
+ return "";
1359
+ };
1360
+ const record = (r, ns) => {
1361
+ if (r.type !== "record" || typeof r.name !== "string" || !Array.isArray(r.fields))
1362
+ return;
1363
+ const space = typeof r.namespace === "string" ? r.namespace : ns;
1364
+ const line = lineOfName(lines, cursor, r.name);
1365
+ cursor = line;
1366
+ const spec = {
1367
+ kind: "message",
1368
+ format: "avro",
1369
+ role: "schema",
1370
+ file: path,
1371
+ line,
1372
+ name: space ? `${space}.${r.name}` : r.name,
1373
+ fields: []
1374
+ };
1375
+ out.push(spec);
1376
+ r.fields.forEach((f, i) => {
1377
+ if (!f || typeof f !== "object")
1378
+ return;
1379
+ const x = f;
1380
+ if (typeof x.name !== "string")
1381
+ return;
1382
+ const at = lineOfName(lines, cursor, x.name);
1383
+ cursor = at;
1384
+ const nullable = Array.isArray(x.type) && x.type.includes("null");
1385
+ const type = typeName(Array.isArray(x.type) ? x.type.filter((t) => t !== "null") : x.type);
1386
+ spec.fields.push({
1387
+ side: "message",
1388
+ name: x.name,
1389
+ ...type ? { type } : {},
1390
+ required: !nullable && !("default" in x),
1391
+ number: i,
1392
+ at: `${path}:${at}`
1393
+ });
1394
+ const inner = Array.isArray(x.type) ? x.type : [x.type];
1395
+ for (const t of inner)
1396
+ if (t && typeof t === "object")
1397
+ record(t, space);
1398
+ });
1399
+ };
1400
+ for (const r of Array.isArray(data) ? data : [data])
1401
+ if (r && typeof r === "object")
1402
+ record(r, "");
1403
+ return out;
1404
+ }
1405
+ var lineAt = (d, node) => {
1406
+ const r = node?.range;
1407
+ return r ? d.lc.linePos(r[0]).line : 1;
1408
+ };
1409
+ function deref2(d, node, depth = 0) {
1410
+ if (!(0, import_yaml4.isMap)(node) || depth > 8)
1411
+ return node;
1412
+ const ref = node.get("$ref");
1413
+ if (typeof ref !== "string" || !ref.startsWith("#/"))
1414
+ return node;
1415
+ let at = d.root;
1416
+ for (const p of ref.slice(2).split("/"))
1417
+ at = (0, import_yaml4.isMap)(at) ? at.get(p.replace(/~1/g, "/").replace(/~0/g, "~"), true) : void 0;
1418
+ return deref2(d, at, depth + 1);
1419
+ }
1420
+ function propsOf(d, schema, prefix, depth, out) {
1421
+ const s = deref2(d, schema);
1422
+ if (!(0, import_yaml4.isMap)(s) || depth > 6)
1423
+ return;
1424
+ const props = s.get("properties", true);
1425
+ const req = s.get("required", true);
1426
+ const required = new Set((0, import_yaml4.isSeq)(req) ? req.items.map((x) => (0, import_yaml4.isScalar)(x) ? String(x.value) : "") : []);
1427
+ if (!(0, import_yaml4.isMap)(props))
1428
+ return;
1429
+ for (const p of props.items) {
1430
+ if (!(0, import_yaml4.isScalar)(p.key))
1431
+ continue;
1432
+ const name = prefix ? `${prefix}.${String(p.key.value)}` : String(p.key.value);
1433
+ const v = deref2(d, p.value);
1434
+ const type = (0, import_yaml4.isMap)(v) ? v.get("type") : void 0;
1435
+ out.push({
1436
+ side: "message",
1437
+ name,
1438
+ ...typeof type === "string" ? { type } : {},
1439
+ required: required.has(String(p.key.value)),
1440
+ at: `${d.path}:${lineAt(d, p.key)}`
1441
+ });
1442
+ if ((0, import_yaml4.isMap)(v)) {
1443
+ if (type === "array")
1444
+ propsOf(d, v.get("items", true), `${name}[]`, depth + 1, out);
1445
+ else
1446
+ propsOf(d, v, name, depth + 1, out);
1447
+ }
1448
+ }
1449
+ }
1450
+ function docOf(path, text3) {
1451
+ const lc = new import_yaml4.LineCounter();
1452
+ const doc = (0, import_yaml4.parseDocument)(text3, { lineCounter: lc });
1453
+ return (0, import_yaml4.isMap)(doc.contents) ? { path, lc, root: doc.contents } : void 0;
1454
+ }
1455
+ function readJsonSchemaSpecs(path, text3) {
1456
+ const d = docOf(path, text3);
1457
+ if (!d)
1458
+ return [];
1459
+ const title = d.root.get("title");
1460
+ const id = d.root.get("$id");
1461
+ const fields = [];
1462
+ propsOf(d, d.root, "", 0, fields);
1463
+ if (!fields.length)
1464
+ return [];
1465
+ const name = typeof title === "string" && title ? title : typeof id === "string" && id ? (id.split("/").pop() ?? id).replace(/\.json$/, "") : (path.split("/").pop() ?? path).replace(/\.(schema\.)?json$|\.ya?ml$/i, "");
1466
+ return [
1467
+ { kind: "message", format: "json-schema", role: "schema", file: path, line: 1, name, fields }
1468
+ ];
1469
+ }
1470
+ function readAsyncApiSpecs(path, text3) {
1471
+ const d = docOf(path, text3);
1472
+ if (!d || d.root.get("asyncapi") === void 0)
1473
+ return [];
1474
+ const out = [];
1475
+ const channels = d.root.get("channels", true);
1476
+ if (!(0, import_yaml4.isMap)(channels))
1477
+ return out;
1478
+ const add = (topic, message) => {
1479
+ const m = deref2(d, message);
1480
+ if (!(0, import_yaml4.isMap)(m))
1481
+ return;
1482
+ const oneOf = m.get("oneOf", true);
1483
+ if ((0, import_yaml4.isSeq)(oneOf)) {
1484
+ for (const x of oneOf.items)
1485
+ add(topic, x);
1486
+ return;
1487
+ }
1488
+ const payload = m.get("payload", true);
1489
+ const fields = [];
1490
+ propsOf(d, payload, "", 0, fields);
1491
+ const p = deref2(d, payload);
1492
+ const title = (0, import_yaml4.isMap)(p) ? p.get("title") : void 0;
1493
+ const name = m.get("name") ?? m.get("title") ?? title;
1494
+ out.push({
1495
+ kind: "message",
1496
+ format: "asyncapi",
1497
+ role: "schema",
1498
+ file: path,
1499
+ line: lineAt(d, m),
1500
+ topic,
1501
+ ...typeof name === "string" && name ? { name } : {},
1502
+ fields
1503
+ });
1504
+ };
1505
+ for (const c of channels.items) {
1506
+ if (!(0, import_yaml4.isScalar)(c.key))
1507
+ continue;
1508
+ const ch = deref2(d, c.value);
1509
+ if (!(0, import_yaml4.isMap)(ch))
1510
+ continue;
1511
+ const address = ch.get("address");
1512
+ const topic = typeof address === "string" && address ? address : String(c.key.value);
1513
+ for (const op of ["publish", "subscribe"]) {
1514
+ const o = ch.get(op, true);
1515
+ if ((0, import_yaml4.isMap)(o))
1516
+ add(topic, o.get("message", true));
1517
+ }
1518
+ const msgs = ch.get("messages", true);
1519
+ if ((0, import_yaml4.isMap)(msgs))
1520
+ for (const m of msgs.items)
1521
+ add(topic, m.value);
1522
+ }
1523
+ return out;
1524
+ }
1525
+ function openApiContractSpecs(spec) {
1526
+ return spec.operations.map((o) => {
1527
+ const [file, line] = splitAt(o.cite, spec.path);
1528
+ const field2 = (side) => (f) => ({
1529
+ side,
1530
+ name: f.name,
1531
+ ...f.type ? { type: f.type } : {},
1532
+ ...f.required !== void 0 ? { required: f.required } : {},
1533
+ ...f.in ? { in: f.in } : {},
1534
+ at: f.cite
1535
+ });
1536
+ return {
1537
+ kind: "operation",
1538
+ format: "openapi",
1539
+ role: "consumer",
1540
+ file,
1541
+ line,
1542
+ method: o.method,
1543
+ path: o.fullPath,
1544
+ id: o.id,
1545
+ fields: [...o.request.map(field2("request")), ...o.response.map(field2("response"))],
1546
+ ...o.errors?.length ? { errors: o.errors.map((e) => ({ status: e.status, at: e.cite })) } : {}
1547
+ };
1548
+ });
1549
+ }
1550
+ function splitAt(cite, path) {
1551
+ const m = /^(.*):(\d+)$/.exec(cite);
1552
+ return m ? [m[1], Number(m[2])] : [path, 1];
1553
+ }
1554
+ function specFormatOf(name, text3) {
1555
+ const lower = name.toLowerCase();
1556
+ if (lower.endsWith(".proto"))
1557
+ return "protobuf";
1558
+ if (lower.endsWith(".avsc"))
1559
+ return "avro";
1560
+ if (!/\.(ya?ml|json)$/.test(lower))
1561
+ return void 0;
1562
+ const head = text3.slice(0, 4e3);
1563
+ if (/^\s*["']?(openapi|swagger)["']?\s*:/m.test(head))
1564
+ return "openapi";
1565
+ if (/^\s*["']?asyncapi["']?\s*:/m.test(head))
1566
+ return "asyncapi";
1567
+ if (/"type"\s*:\s*"record"/.test(head) && /"fields"\s*:/.test(head))
1568
+ return "avro";
1569
+ if (/["']?\$schema["']?\s*:/.test(head) && /json-schema\.org/.test(head))
1570
+ return "json-schema";
1571
+ return void 0;
1572
+ }
1573
+ function readContractSpecs(path, text3) {
1574
+ switch (specFormatOf(path, text3)) {
1575
+ case "protobuf":
1576
+ return readProtoSpecs(path, text3);
1577
+ case "avro":
1578
+ return readAvroSpecs(path, text3);
1579
+ case "json-schema":
1580
+ return readJsonSchemaSpecs(path, text3);
1581
+ case "asyncapi":
1582
+ return readAsyncApiSpecs(path, text3);
1583
+ case "openapi": {
1584
+ const spec = readVendorSpec(path, text3, "spec");
1585
+ return spec ? openApiContractSpecs(spec) : [];
1586
+ }
1587
+ default:
1588
+ return [];
1589
+ }
1590
+ }
1591
+ var sameShape = (a, b) => normalizePath(a).replace(/\{[^}]*\}/g, "{}") === normalizePath(b).replace(/\{[^}]*\}/g, "{}");
1592
+ var SPEC_FILE = /\.(proto|avsc|ya?ml|json)$/i;
1593
+ function cmpPath(a, b) {
1594
+ const x = a.split("/");
1595
+ const y = b.split("/");
1596
+ for (let i = 0; i < Math.min(x.length, y.length); i++) {
1597
+ const c = cmp2(x[i], y[i]);
1598
+ if (c)
1599
+ return c;
1600
+ }
1601
+ return x.length - y.length;
1602
+ }
1603
+ var skipped = (p) => p.split("/").slice(0, -1).some((d) => SKIP.has(d) || d.startsWith("."));
1604
+ function folderTree(dir) {
1605
+ return {
1606
+ async files() {
1607
+ const out = [];
1608
+ const walk2 = async (rel) => {
1609
+ const entries = await readdir(join(dir, ...rel.split("/").filter(Boolean)), {
1610
+ withFileTypes: true
1611
+ }).catch(() => []);
1612
+ for (const e of [...entries].sort((a, b) => cmp2(a.name, b.name))) {
1613
+ const p = rel ? `${rel}/${e.name}` : e.name;
1614
+ if (e.isDirectory()) {
1615
+ if (!SKIP.has(e.name) && !e.name.startsWith("."))
1616
+ await walk2(p);
1617
+ } else if (e.isFile() && SPEC_FILE.test(e.name)) {
1618
+ const size = (await stat(join(dir, ...p.split("/"))).catch(() => void 0))?.size;
1619
+ out.push({ path: p, size: size ?? 0 });
1620
+ }
1621
+ }
1622
+ };
1623
+ await walk2("");
1624
+ return out;
1625
+ },
1626
+ read: (p) => readFile(join(dir, ...p.split("/")), "utf8").catch(() => void 0)
1627
+ };
1628
+ }
1629
+ async function readRepoSpecs(dir, o) {
1630
+ const tree = o.tree ?? folderTree(dir);
1631
+ const files = (await tree.files()).filter((f) => SPEC_FILE.test(f.path) && !skipped(f.path) && f.size > 0 && f.size <= MAX_BYTES).sort((a, b) => cmpPath(a.path, b.path)).map((f) => f.path);
1632
+ const own = o.facts.filter((f) => f.kind === "entry" && f.entryType === "rest");
1633
+ const specs = [];
1634
+ for (const p of files) {
1635
+ const text3 = await tree.read(p);
1636
+ if (text3 === void 0 || !specFormatOf(p, text3))
1637
+ continue;
1638
+ const got = readContractSpecs(p, text3);
1639
+ if (!got.length)
1640
+ continue;
1641
+ if (o.denyHashes?.size && denyListHits(text3, o.denyHashes).length) {
1642
+ o.onRefused?.(`${p}: the deny-list names a word in it, so its specs are left out.`);
1643
+ continue;
1644
+ }
1645
+ for (const s of got) {
1646
+ if (s.kind !== "operation") {
1647
+ specs.push(s);
1648
+ continue;
1649
+ }
1650
+ const vendorPath = readVendorSpec(p, text3, "spec")?.operations.find((x) => x.id === s.id);
1651
+ const paths = [s.path ?? "", vendorPath?.path ?? ""].filter(Boolean);
1652
+ const entry = own.filter((e) => (!e.method || !s.method || e.method.toUpperCase() === s.method) && paths.some((x) => sameShape(x, e.path))).sort((a, b) => cmp2(a.id, b.id))[0];
1653
+ const { id: _id, ...rest } = s;
1654
+ specs.push(entry ? { ...rest, role: "own", entry: entry.id } : rest);
1655
+ }
1656
+ }
1657
+ return {
1658
+ schemaVersion: 1,
1659
+ repo: o.repo,
1660
+ ...o.commit ? { commit: o.commit } : {},
1661
+ specs
1662
+ };
1663
+ }
1664
+
725
1665
  // packages/intake/dist/scan-inputs.js
726
1666
  var SPECS = ["openapi", "swagger", "asyncapi"];
727
1667
  var EVIDENCE_SOURCE = {
728
1668
  openapi: "spec",
729
1669
  swagger: "spec",
730
1670
  asyncapi: "spec",
1671
+ protobuf: "spec",
1672
+ avro: "spec",
731
1673
  diagram: "diagram",
732
1674
  image: "document",
733
1675
  document: "document",
@@ -745,14 +1687,14 @@ async function walk(dir, skip) {
745
1687
  return;
746
1688
  let entries;
747
1689
  try {
748
- entries = await readdir(d, { withFileTypes: true });
1690
+ entries = await readdir2(d, { withFileTypes: true });
749
1691
  } catch {
750
1692
  return;
751
1693
  }
752
1694
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
753
1695
  if (e.name.startsWith("."))
754
1696
  continue;
755
- const full = join(d, e.name);
1697
+ const full = join2(d, e.name);
756
1698
  if (e.isDirectory())
757
1699
  await go(full);
758
1700
  else if (e.isFile())
@@ -763,7 +1705,7 @@ async function walk(dir, skip) {
763
1705
  return out;
764
1706
  }
765
1707
  var DATE = /(?:^|[-_ .])((\d{4})-?(\d{2})-?(\d{2}))(?=$|[-_ .])/;
766
- var VERSION = /(?:^|[-_ .])v(\d+(?:[._]\d+)*)(?=$|[-_ .])/i;
1708
+ var VERSION2 = /(?:^|[-_ .])v(\d+(?:[._]\d+)*)(?=$|[-_ .])/i;
767
1709
  function nameParts(stem) {
768
1710
  let rest = stem;
769
1711
  let date;
@@ -776,7 +1718,7 @@ function nameParts(stem) {
776
1718
  }
777
1719
  }
778
1720
  let version;
779
- const v = VERSION.exec(rest);
1721
+ const v = VERSION2.exec(rest);
780
1722
  if (v) {
781
1723
  version = v[1].replace(/_/g, ".");
782
1724
  rest = rest.replace(v[0], "");
@@ -802,23 +1744,23 @@ function systemsInName(stem, systems) {
802
1744
  return systems.filter((sys) => [sys.id, sys.name, ...sys.aliases].some((n) => slug(n) && s.includes(`-${slug(n)}-`))).map((sys) => sys.id).sort();
803
1745
  }
804
1746
  async function scanInputs(o) {
805
- const orgPackDir = typeof o.orgPack === "string" ? o.orgPack : join(orgPackDirOf(o.root));
1747
+ const orgPackDir = typeof o.orgPack === "string" ? o.orgPack : join2(orgPackDirOf(o.root));
806
1748
  const op = typeof o.orgPack === "object" ? o.orgPack : await loadOrgPack(orgPackDir);
807
1749
  const systems = op.profiles.flatMap((p) => p.profile?.systems ?? []);
808
1750
  const legend = op.profiles.find((p) => p.profile?.legend)?.profile?.legend;
809
1751
  const records = o.records ?? [];
810
1752
  const ingestors = o.ingestors ?? [drawioIngestor];
811
1753
  const scannedAt = o.scannedAt ?? (/* @__PURE__ */ new Date()).toISOString();
812
- const inputsDir = o.inputsDir ?? join(o.root, "inputs");
1754
+ const inputsDir = o.inputsDir ?? join2(o.root, "inputs");
813
1755
  const problems = [];
814
1756
  const triage = [];
815
1757
  const authors = /* @__PURE__ */ new Map();
816
1758
  const wikiDirs = op.sources.wikis.flatMap((w) => /^[a-z][a-z0-9+.-]*:\/\//i.test(w.location) ? [] : [resolve(orgPackDir, w.location), resolve(o.root, w.location)]);
817
- const st = await stat(inputsDir).catch(() => void 0);
1759
+ const st = await stat2(inputsDir).catch(() => void 0);
818
1760
  const paths = st?.isDirectory() ? await walk(inputsDir, wikiDirs) : [];
819
1761
  const files = [];
820
1762
  for (const abs of paths) {
821
- const bytes = new Uint8Array(await readFile(abs));
1763
+ const bytes = new Uint8Array(await readFile2(abs));
822
1764
  const path = `inputs/${posix(relative(inputsDir, abs))}`;
823
1765
  const name = path.split("/").pop();
824
1766
  const c = classify(name, bytes);
@@ -826,14 +1768,19 @@ async function scanInputs(o) {
826
1768
  abs,
827
1769
  path,
828
1770
  bytes,
829
- hash: createHash4("sha256").update(bytes).digest("hex"),
1771
+ hash: createHash5("sha256").update(bytes).digest("hex"),
830
1772
  stem: name.includes(".") ? name.slice(0, name.lastIndexOf(".")) : name,
831
1773
  inbox: path.startsWith("inputs/inbox/"),
832
1774
  ...c.data !== void 0 ? { data: c.data } : {},
1775
+ ...c.text !== void 0 ? { text: c.text } : {},
833
1776
  doc: {
834
1777
  path,
835
1778
  classification: c.classification,
836
- status: "no-reader",
1779
+ status: c.unreadable ? "unreadable" : "no-reader",
1780
+ ...c.unreadable ? {
1781
+ reason: `${c.unreadable.reason}${c.unreadable.line !== void 0 ? ` at ${c.unreadable.line}:${c.unreadable.column}` : ""}`
1782
+ } : {},
1783
+ ...c.notes?.length ? { notes: c.notes } : {},
837
1784
  hash: "",
838
1785
  ...c.title ? { title: c.title } : {},
839
1786
  ...c.version ? { version: c.version } : {},
@@ -896,7 +1843,7 @@ async function scanInputs(o) {
896
1843
  const heads = members.filter((m) => !m.doc.supersededBy);
897
1844
  if (heads.length < 2)
898
1845
  continue;
899
- const distinct = (vals, cmp3) => vals.every((v) => v !== void 0) && vals.every((v, i) => vals.every((w, j) => i === j || cmp3(v, w) !== 0));
1846
+ const distinct = (vals, cmp5) => vals.every((v) => v !== void 0) && vals.every((v, i) => vals.every((w, j) => i === j || cmp5(v, w) !== 0));
900
1847
  const byVersion = distinct(heads.map((h) => h.doc.version), compareVersions);
901
1848
  const byDate = !byVersion && distinct(heads.map((h) => h.doc.date), (a, b) => a < b ? -1 : a > b ? 1 : 0);
902
1849
  if (byVersion || byDate) {
@@ -939,7 +1886,7 @@ async function scanInputs(o) {
939
1886
  for (const f of kept) {
940
1887
  const cls = f.doc.classification;
941
1888
  const current = !f.doc.supersededBy;
942
- const text3 = () => new TextDecoder().decode(f.bytes);
1889
+ const text3 = () => f.text ?? new TextDecoder().decode(f.bytes);
943
1890
  const linked = /* @__PURE__ */ new Set();
944
1891
  const unknown = /* @__PURE__ */ new Set();
945
1892
  if (SPECS.includes(cls)) {
@@ -1053,6 +2000,43 @@ async function scanInputs(o) {
1053
2000
  } catch {
1054
2001
  }
1055
2002
  }
2003
+ if (cls === "protobuf" || cls === "avro") {
2004
+ const specs = cls === "protobuf" ? readProtoSpecs(f.path, text3()) : readAvroSpecs(f.path, text3());
2005
+ const named = new Set(systemsInName(f.stem, systems));
2006
+ for (const s of specs) {
2007
+ const res = s.name ? resolveName(s.name.split(".").slice(0, -1).join(" ")) : void 0;
2008
+ if (res?.id && !named.size)
2009
+ named.add(systemOf(res.id));
2010
+ }
2011
+ for (const s of named)
2012
+ linked.add(s);
2013
+ if (current && specs.length) {
2014
+ for (const s of specs) {
2015
+ const p = parseRecord({
2016
+ schemaVersion: 1,
2017
+ kind: "Schema",
2018
+ id: boundedId("schema.", slug(s.name ?? f.stem)),
2019
+ status: "current",
2020
+ confidence: "verified",
2021
+ format: cls,
2022
+ ref: `${f.path}#${s.name ?? ""}`,
2023
+ fields: s.fields.map((x) => ({
2024
+ name: x.name,
2025
+ ...x.type ? { type: x.type } : {},
2026
+ ...x.required !== void 0 ? { required: x.required } : {}
2027
+ })),
2028
+ evidence: [{ source: "spec", path: f.path, line: s.line, side: "definition" }]
2029
+ });
2030
+ if (!p.ok)
2031
+ continue;
2032
+ const schema = p.record;
2033
+ out.push(schema);
2034
+ f.doc.records.push(schema.id);
2035
+ }
2036
+ f.doc.status = "read";
2037
+ f.doc.reader = cls === "protobuf" ? READERS.protobuf : READERS.avro;
2038
+ }
2039
+ }
1056
2040
  if (current && cls === "payload" && f.data !== void 0) {
1057
2041
  const schema = readPayload(f.path, boundedId("payload.", f.doc.id.slice(4)), f.data);
1058
2042
  out.push(schema);
@@ -1249,9 +2233,9 @@ function safeSniff(ing, path, head) {
1249
2233
  return 0;
1250
2234
  }
1251
2235
  }
1252
- function lineOf(text3, key2) {
2236
+ function lineOf(text3, key3) {
1253
2237
  const lines = text3.split(/\r?\n/);
1254
- const re = new RegExp(`(^|[\\s{,])"?${key2}"?\\s*:`);
2238
+ const re = new RegExp(`(^|[\\s{,])"?${key3}"?\\s*:`);
1255
2239
  const i = lines.findIndex((l) => re.test(l));
1256
2240
  return i >= 0 ? { line: i + 1 } : {};
1257
2241
  }
@@ -1362,11 +2346,11 @@ function imageItems(records) {
1362
2346
  };
1363
2347
  });
1364
2348
  }
1365
- var key = (action, target, value) => `${action}|${target}|${JSON.stringify(value ?? null)}`;
2349
+ var key2 = (action, target, value) => `${action}|${target}|${JSON.stringify(value ?? null)}`;
1366
2350
  function buildTriage(input) {
1367
2351
  const decisions = (input.decisions ?? []).filter((d) => d.kind === "CuratedDecision" && d.status === "current");
1368
2352
  const decidedIds = new Set(decisions.map((d) => d.id));
1369
- const decidedKeys = new Set(decisions.map((d) => key(d.action, d.target, d.value)));
2353
+ const decidedKeys = new Set(decisions.map((d) => key2(d.action, d.target, d.value)));
1370
2354
  const docs = new Map((input.inputs?.documents ?? []).map((d) => [d.path, d.id]));
1371
2355
  const docIdOf = (path) => docs.get(path) ?? boundedId("doc.", slug(path.split("/").pop().replace(/\.[^.]+$/, "")));
1372
2356
  const records = input.records;
@@ -1379,7 +2363,7 @@ function buildTriage(input) {
1379
2363
  ...imageItems([...records, ...inputRecords]),
1380
2364
  ...readingItems(input)
1381
2365
  ];
1382
- const open = all.filter((i) => !i.options.some((o) => decidedIds.has(o.decision.id) || decidedKeys.has(key(o.decision.action, o.decision.target, o.decision.value))));
2366
+ const open = all.filter((i) => !i.options.some((o) => decidedIds.has(o.decision.id) || decidedKeys.has(key2(o.decision.action, o.decision.target, o.decision.value))));
1383
2367
  const items = sortItems(open);
1384
2368
  return {
1385
2369
  items,
@@ -1420,9 +2404,9 @@ function buildTriage(input) {
1420
2404
  }
1421
2405
 
1422
2406
  // packages/intake/dist/work-items.js
1423
- var import_yaml4 = __toESM(require_dist(), 1);
1424
- import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
1425
- import { join as join2, relative as relative2, sep as sep2 } from "node:path";
2407
+ var import_yaml5 = __toESM(require_dist(), 1);
2408
+ import { readdir as readdir3, readFile as readFile3 } from "node:fs/promises";
2409
+ import { join as join3, relative as relative2, sep as sep2 } from "node:path";
1426
2410
  var WORK_ITEM_READER = "work-items@0.1.0";
1427
2411
  var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1428
2412
  var text = (v) => {
@@ -1528,7 +2512,7 @@ function itemOf(o, path, lineOf2) {
1528
2512
  source: { path, ...line ? { line } : {} }
1529
2513
  };
1530
2514
  }
1531
- function parseCsv(s) {
2515
+ function parseCsv2(s) {
1532
2516
  const rows = [];
1533
2517
  let row = [];
1534
2518
  let cell = "";
@@ -1572,7 +2556,7 @@ function parseCsv(s) {
1572
2556
  return rows;
1573
2557
  }
1574
2558
  function fromCsv(textIn, path) {
1575
- const rows = parseCsv(textIn.replace(/^\uFEFF/, ""));
2559
+ const rows = parseCsv2(textIn.replace(/^\uFEFF/, ""));
1576
2560
  const header = rows[0]?.cells.map((h) => h.trim());
1577
2561
  if (!header)
1578
2562
  return void 0;
@@ -1601,7 +2585,7 @@ function readWorkItemExport(path, bytes) {
1601
2585
  return void 0;
1602
2586
  let data;
1603
2587
  try {
1604
- data = (0, import_yaml4.parse)(content);
2588
+ data = (0, import_yaml5.parse)(content);
1605
2589
  } catch {
1606
2590
  return void 0;
1607
2591
  }
@@ -1624,22 +2608,22 @@ function readWorkItemExport(path, bytes) {
1624
2608
  return items;
1625
2609
  }
1626
2610
  async function readWorkItemExports(o) {
1627
- const dir = o.inputsDir ?? join2(o.root, "inputs");
2611
+ const dir = o.inputsDir ?? join3(o.root, "inputs");
1628
2612
  const files = [];
1629
2613
  async function walk2(d) {
1630
2614
  let entries;
1631
2615
  try {
1632
- entries = await readdir2(d, { withFileTypes: true });
2616
+ entries = await readdir3(d, { withFileTypes: true });
1633
2617
  } catch {
1634
2618
  return;
1635
2619
  }
1636
2620
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1637
2621
  if (e.name.startsWith("."))
1638
2622
  continue;
1639
- const full = join2(d, e.name);
2623
+ const full = join3(d, e.name);
1640
2624
  if (e.isDirectory())
1641
2625
  await walk2(full);
1642
- else if (/\.(json|ya?ml|csv)$/i.test(e.name))
2626
+ else if (e.isFile() && /\.(json|ya?ml|csv)$/i.test(e.name))
1643
2627
  files.push(full);
1644
2628
  }
1645
2629
  }
@@ -1653,7 +2637,7 @@ async function readWorkItemExports(o) {
1653
2637
  const path = `inputs/${relative2(dir, full).split(sep2).join("/")}`;
1654
2638
  let bytes;
1655
2639
  try {
1656
- bytes = new Uint8Array(await readFile2(full));
2640
+ bytes = new Uint8Array(await readFile3(full));
1657
2641
  } catch (e) {
1658
2642
  out.problems.push({ path, message: `can't read it: ${e.message}` });
1659
2643
  continue;
@@ -1668,9 +2652,9 @@ async function readWorkItemExports(o) {
1668
2652
  }
1669
2653
 
1670
2654
  // packages/intake/dist/service-requests.js
1671
- var import_yaml5 = __toESM(require_dist(), 1);
1672
- import { readdir as readdir3, readFile as readFile3 } from "node:fs/promises";
1673
- import { join as join3, relative as relative3, sep as sep3 } from "node:path";
2655
+ var import_yaml6 = __toESM(require_dist(), 1);
2656
+ import { readdir as readdir4, readFile as readFile4 } from "node:fs/promises";
2657
+ import { join as join4, relative as relative3, sep as sep3 } from "node:path";
1674
2658
  var SERVICE_REQUEST_READER = "service-requests@0.1.0";
1675
2659
  var isObj4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1676
2660
  var text2 = (v) => {
@@ -1821,7 +2805,7 @@ function readServiceRequestExport(path, bytes) {
1821
2805
  return void 0;
1822
2806
  let data;
1823
2807
  try {
1824
- data = (0, import_yaml5.parse)(content);
2808
+ data = (0, import_yaml6.parse)(content);
1825
2809
  } catch {
1826
2810
  return void 0;
1827
2811
  }
@@ -1851,22 +2835,22 @@ function readServiceRequestExport(path, bytes) {
1851
2835
  return out;
1852
2836
  }
1853
2837
  async function readServiceRequestExports(o) {
1854
- const dir = o.inputsDir ?? join3(o.root, "inputs");
2838
+ const dir = o.inputsDir ?? join4(o.root, "inputs");
1855
2839
  const found = [];
1856
2840
  async function walk2(d) {
1857
2841
  let entries;
1858
2842
  try {
1859
- entries = await readdir3(d, { withFileTypes: true });
2843
+ entries = await readdir4(d, { withFileTypes: true });
1860
2844
  } catch {
1861
2845
  return;
1862
2846
  }
1863
2847
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1864
2848
  if (e.name.startsWith("."))
1865
2849
  continue;
1866
- const full = join3(d, e.name);
2850
+ const full = join4(d, e.name);
1867
2851
  if (e.isDirectory())
1868
2852
  await walk2(full);
1869
- else if (/\.(json|ya?ml|csv)$/i.test(e.name))
2853
+ else if (e.isFile() && /\.(json|ya?ml|csv)$/i.test(e.name))
1870
2854
  found.push(full);
1871
2855
  }
1872
2856
  }
@@ -1880,7 +2864,7 @@ async function readServiceRequestExports(o) {
1880
2864
  const path = `inputs/${relative3(dir, full).split(sep3).join("/")}`;
1881
2865
  let bytes;
1882
2866
  try {
1883
- bytes = new Uint8Array(await readFile3(full));
2867
+ bytes = new Uint8Array(await readFile4(full));
1884
2868
  } catch (e) {
1885
2869
  out.problems.push({ path, message: `can't read it: ${e.message}` });
1886
2870
  continue;
@@ -1895,15 +2879,15 @@ async function readServiceRequestExports(o) {
1895
2879
  }
1896
2880
 
1897
2881
  // packages/intake/dist/change-inputs.js
1898
- var import_yaml6 = __toESM(require_dist(), 1);
1899
- import { createHash as createHash5 } from "node:crypto";
1900
- import { mkdir, readdir as readdir4, readFile as readFile4 } from "node:fs/promises";
1901
- import { join as join4 } from "node:path";
2882
+ var import_yaml7 = __toESM(require_dist(), 1);
2883
+ import { createHash as createHash6 } from "node:crypto";
2884
+ import { mkdir, readdir as readdir5, readFile as readFile5 } from "node:fs/promises";
2885
+ import { join as join5 } from "node:path";
1902
2886
  var INPUTS_DIR = "inputs";
1903
2887
  var INPUTS_INDEX = "inputs/index.yaml";
1904
2888
  var INPUTS_READ_DIR = "inputs/read";
1905
2889
  var CHANGE_INPUTS_SCHEMA_VERSION = 1;
1906
- var sha256 = (b) => createHash5("sha256").update(b).digest("hex");
2890
+ var sha256 = (b) => createHash6("sha256").update(b).digest("hex");
1907
2891
  var KEYS = [
1908
2892
  "path",
1909
2893
  "name",
@@ -1923,10 +2907,10 @@ var KEYS = [
1923
2907
  "defences"
1924
2908
  ];
1925
2909
  async function readChangeInputs(dir) {
1926
- const text3 = await readFile4(join4(dir, ...INPUTS_INDEX.split("/")), "utf8").catch(() => "");
2910
+ const text3 = await readFile5(join5(dir, ...INPUTS_INDEX.split("/")), "utf8").catch(() => "");
1927
2911
  let data;
1928
2912
  try {
1929
- data = text3 ? (0, import_yaml6.parse)(text3) : void 0;
2913
+ data = text3 ? (0, import_yaml7.parse)(text3) : void 0;
1930
2914
  } catch {
1931
2915
  data = void 0;
1932
2916
  }
@@ -1947,7 +2931,7 @@ async function writeIndex(dir, index) {
1947
2931
  o[k] = f[k];
1948
2932
  return o;
1949
2933
  });
1950
- await writeFileAtomic(join4(dir, ...INPUTS_INDEX.split("/")), `# Files attached to this change (ADR 0113): atticus change attach writes this file.
2934
+ await writeFileAtomic(join5(dir, ...INPUTS_INDEX.split("/")), `# Files attached to this change (ADR 0113): atticus change attach writes this file.
1951
2935
  ${toCanonicalYaml({ schemaVersion: index.schemaVersion, files }, ["schemaVersion", "files"])}`);
1952
2936
  }
1953
2937
  var isText = (b) => {
@@ -2038,7 +3022,7 @@ function readText(input, bytes, older) {
2038
3022
  async function attachToChange(dir, files, o) {
2039
3023
  const index = await readChangeInputs(dir);
2040
3024
  const out = { added: [], refused: [], notes: [] };
2041
- const taken = new Set(await readdir4(join4(dir, INPUTS_DIR)).catch(() => []));
3025
+ const taken = new Set((await readdir5(join5(dir, INPUTS_DIR)).catch(() => [])).map((n) => n.toLowerCase()));
2042
3026
  taken.add("index.yaml").add("read");
2043
3027
  const replaced = o.replaces ? index.files.find((x) => x.path === o.replaces.trim().replace(/\\/g, "/")) : void 0;
2044
3028
  let changed = false;
@@ -2076,9 +3060,9 @@ async function attachToChange(dir, files, o) {
2076
3060
  const dot = safe.lastIndexOf(".");
2077
3061
  const [stem, ext] = dot > 0 ? [safe.slice(0, dot), safe.slice(dot)] : [safe, ""];
2078
3062
  let target = safe;
2079
- for (let n = 2; taken.has(target); n++)
3063
+ for (let n = 2; taken.has(target.toLowerCase()); n++)
2080
3064
  target = `${stem}-${n}${ext}`;
2081
- taken.add(target);
3065
+ taken.add(target.toLowerCase());
2082
3066
  const found = classify(target, f.bytes).classification;
2083
3067
  const { format, citeBy } = formatOf2(target, f.bytes, found);
2084
3068
  const kind = found === "unknown" && citeBy ? "document" : found;
@@ -2125,11 +3109,11 @@ async function attachToChange(dir, files, o) {
2125
3109
  const where = o.elsewhere?.(hash);
2126
3110
  if (where)
2127
3111
  out.notes.push(`${name} is also in the metarepo's inputs as ${where}.`);
2128
- await mkdir(join4(dir, INPUTS_DIR), { recursive: true });
2129
- await writeFileAtomic(join4(dir, INPUTS_DIR, target), f.bytes);
3112
+ await mkdir(join5(dir, INPUTS_DIR), { recursive: true });
3113
+ await writeFileAtomic(join5(dir, INPUTS_DIR, target), f.bytes);
2130
3114
  const text3 = readText(input, f.bytes, older);
2131
3115
  if (text3 !== void 0)
2132
- await writeFileAtomic(join4(dir, ...input.readAs.split("/")), text3);
3116
+ await writeFileAtomic(join5(dir, ...input.readAs.split("/")), text3);
2133
3117
  index.files.push(input);
2134
3118
  out.added.push(input);
2135
3119
  }
@@ -2155,7 +3139,7 @@ async function changeInputSources(dir, rel) {
2155
3139
  for (const f of (await readChangeInputs(dir)).files) {
2156
3140
  if (f.supersededBy || f.defences?.risk === "high")
2157
3141
  continue;
2158
- const read = f.readAs ? await readFile4(join4(dir, ...f.readAs.split("/")), "utf8").catch(() => void 0) : void 0;
3142
+ const read = f.readAs ? await readFile5(join5(dir, ...f.readAs.split("/")), "utf8").catch(() => void 0) : void 0;
2159
3143
  const text3 = read ?? `${f.path} (${f.name}) is ${f.kind === "image" ? "a picture; Atticus doesn't read pictures" : `a ${f.format} file no reader takes`}. Open it to see it; say what you rely on from it, citing ${f.path}.`;
2160
3144
  out.push({
2161
3145
  id: f.path,
@@ -2179,9 +3163,12 @@ var KIND_ORDER2 = [
2179
3163
  "field-added",
2180
3164
  "field-required",
2181
3165
  "field-type",
2182
- "field-enum"
3166
+ "field-enum",
3167
+ "error-added",
3168
+ "error-schema",
3169
+ "error-removed"
2183
3170
  ];
2184
- var cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
3171
+ var cmp3 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2185
3172
  var opKey = (o) => `${o.method} ${normalizePath(o.fullPath)}`;
2186
3173
  var opName = (o) => `${o.method} ${o.path}`;
2187
3174
  var list = (xs) => xs.length <= 1 ? xs[0] ?? "" : `${xs.slice(0, -1).join(", ")} and ${xs.at(-1)}`;
@@ -2246,16 +3233,21 @@ function diffVendorSpecs(older, newer) {
2246
3233
  });
2247
3234
  for (const [o, n] of pairs)
2248
3235
  out.push(...operationChanges(o, n));
2249
- return out.sort((a, b) => cmp(a.severity === "breaking" ? "0" : "1", b.severity === "breaking" ? "0" : "1") || cmp(a.operation.path, b.operation.path) || cmp(a.operation.method, b.operation.method) || KIND_ORDER2.indexOf(a.kind) - KIND_ORDER2.indexOf(b.kind) || cmp(a.side ?? "", b.side ?? "") || cmp(a.field ?? "", b.field ?? ""));
3236
+ return out.sort((a, b) => cmp3(a.severity === "breaking" ? "0" : "1", b.severity === "breaking" ? "0" : "1") || cmp3(a.operation.path, b.operation.path) || cmp3(a.operation.method, b.operation.method) || KIND_ORDER2.indexOf(a.kind) - KIND_ORDER2.indexOf(b.kind) || cmp3(a.side ?? "", b.side ?? "") || cmp3(a.field ?? "", b.field ?? ""));
2250
3237
  }
2251
3238
  var opOf = (o) => ({
2252
3239
  method: o.method,
2253
3240
  path: o.path,
2254
3241
  ...o.operationId ? { operationId: o.operationId } : {}
2255
3242
  });
2256
- function changeId(kind, o, side, field2) {
3243
+ function changeId(kind, o, side, field2, status) {
2257
3244
  const op = slug(`${o.method} ${o.path}`);
2258
- return [kind, op, ...side && field2 ? [side, slug(field2)] : []].join(".");
3245
+ return [
3246
+ kind,
3247
+ op,
3248
+ ...status ? [status] : [],
3249
+ ...side && field2 ? [side, slug(field2)] : []
3250
+ ].join(".");
2259
3251
  }
2260
3252
  function operationChanges(o, n) {
2261
3253
  const out = [];
@@ -2291,15 +3283,61 @@ function operationChanges(o, n) {
2291
3283
  }
2292
3284
  for (const side of ["request", "response"])
2293
3285
  out.push(...fieldChanges(o[side], n[side], side, at, base));
3286
+ out.push(...errorChanges(o, n, at));
3287
+ return out;
3288
+ }
3289
+ function errorChanges(o, n, at) {
3290
+ const out = [];
3291
+ const olds = new Map((o.errors ?? []).map((e) => [e.status, e]));
3292
+ const news = new Map((n.errors ?? []).map((e) => [e.status, e]));
3293
+ const head = (kind, status) => ({
3294
+ id: changeId(kind, n, void 0, void 0, status),
3295
+ kind,
3296
+ operation: opOf(n),
3297
+ endpoints: { older: o.id, newer: n.id },
3298
+ status
3299
+ });
3300
+ for (const [status, e] of news)
3301
+ if (!olds.has(status))
3302
+ out.push({
3303
+ ...head("error-added", status),
3304
+ severity: "breaking",
3305
+ after: { value: status, cite: e.cite },
3306
+ says: `${at}: it may now answer ${status}; a caller that doesn't handle ${status} must.`
3307
+ });
3308
+ for (const [status, e] of olds)
3309
+ if (!news.has(status))
3310
+ out.push({
3311
+ ...head("error-removed", status),
3312
+ severity: "additive",
3313
+ before: { value: status, cite: e.cite },
3314
+ says: `${at}: it no longer answers ${status}; no caller has to change.`
3315
+ });
3316
+ for (const [status, a] of olds) {
3317
+ const b = news.get(status);
3318
+ if (!b)
3319
+ continue;
3320
+ const base = (_kind, side, field2) => ({
3321
+ id: changeId("error-schema", n, side, field2, status),
3322
+ kind: "error-schema",
3323
+ operation: opOf(n),
3324
+ endpoints: { older: o.id, newer: n.id },
3325
+ ...side ? { side } : {},
3326
+ ...field2 ? { field: field2 } : {},
3327
+ status
3328
+ });
3329
+ out.push(...fieldChanges(a.fields ?? [], b.fields ?? [], "response", `${at} (its ${status} response)`, base));
3330
+ }
2294
3331
  return out;
2295
3332
  }
2296
3333
  function fieldChanges(olds, news, side, at, base) {
2297
3334
  const out = [];
2298
- const key2 = (f) => `${f.in}|${f.name}`;
2299
- const byOld = new Map(olds.map((f) => [key2(f), f]));
2300
- const byNew = new Map(news.map((f) => [key2(f), f]));
2301
- let removed = olds.filter((f) => !byNew.has(key2(f)));
2302
- let added = news.filter((f) => !byOld.has(key2(f)));
3335
+ const what = (f) => `${side} ${f.in === "header" ? "header" : "field"}`;
3336
+ const key3 = (f) => `${f.in}|${f.name}`;
3337
+ const byOld = new Map(olds.map((f) => [key3(f), f]));
3338
+ const byNew = new Map(news.map((f) => [key3(f), f]));
3339
+ let removed = olds.filter((f) => !byNew.has(key3(f)));
3340
+ let added = news.filter((f) => !byOld.has(key3(f)));
2303
3341
  const req = side === "request";
2304
3342
  const parent = (f) => `${f.in}|${f.name.includes(".") ? f.name.slice(0, f.name.lastIndexOf(".")) : ""}`;
2305
3343
  const renamed = [];
@@ -2317,7 +3355,7 @@ function fieldChanges(olds, news, side, at, base) {
2317
3355
  severity: "breaking",
2318
3356
  before: { value: r.name, cite: r.cite },
2319
3357
  after: { value: a.name, cite: a.cite },
2320
- says: `${at}: the ${side} field ${r.name} is now ${a.name}; ${req ? `a caller that still sends ${r.name} no longer sets it` : `a caller that reads ${r.name} gets nothing`}.`
3358
+ says: `${at}: the ${what(r)} ${r.name} is now ${a.name}; ${req ? `a caller that still sends ${r.name} no longer sets it` : `a caller that reads ${r.name} gets nothing`}.`
2321
3359
  });
2322
3360
  }
2323
3361
  removed = removed.filter((f) => !renamed.some(([r]) => r === f));
@@ -2329,7 +3367,7 @@ function fieldChanges(olds, news, side, at, base) {
2329
3367
  ...base("field-removed", side, f.name),
2330
3368
  severity: "breaking",
2331
3369
  before: { value: f.name, cite: f.cite },
2332
- says: req ? `${at}: the request field ${f.name} is gone; a caller that sends it may be refused, and what it meant is lost.` : `${at}: the response field ${f.name} is gone; a caller that reads it gets nothing.`
3370
+ says: req ? `${at}: the ${what(f)} ${f.name} is gone; a caller that sends it may be refused, and what it meant is lost.` : `${at}: the ${what(f)} ${f.name} is gone; a caller that reads it gets nothing.`
2333
3371
  });
2334
3372
  for (const f of topAdded) {
2335
3373
  const breaks = req && f.required === true;
@@ -2337,7 +3375,7 @@ function fieldChanges(olds, news, side, at, base) {
2337
3375
  ...base("field-added", side, f.name),
2338
3376
  severity: breaks ? "breaking" : "additive",
2339
3377
  after: { value: f.name, cite: f.requiredCite ?? f.cite },
2340
- says: !req ? `${at}: the response has a new field ${f.name}; no caller has to change.` : breaks ? `${at}: the request needs a new field ${f.name}; a caller that doesn't send it is refused.` : `${at}: the request takes a new optional field ${f.name}; no caller has to change.`
3378
+ says: !req ? `${at}: the response has a new ${f.in === "header" ? "header" : "field"} ${f.name}; no caller has to change.` : breaks ? `${at}: the request needs a new ${f.in === "header" ? "header" : "field"} ${f.name}; a caller that doesn't send it is refused.` : `${at}: the request takes a new optional ${f.in === "header" ? "header" : "field"} ${f.name}; no caller has to change.`
2341
3379
  });
2342
3380
  }
2343
3381
  for (const [k, a] of byOld) {
@@ -2352,7 +3390,7 @@ function fieldChanges(olds, news, side, at, base) {
2352
3390
  severity: breaks ? "breaking" : "additive",
2353
3391
  before: { value: a.required ? "required" : "optional", cite: a.requiredCite ?? a.cite },
2354
3392
  after: { value: b.required ? "required" : "optional", cite: b.requiredCite ?? b.cite },
2355
- says: req ? nowRequired ? `${at}: the request field ${a.name} is now required; a caller that leaves it out is refused.` : `${at}: the request field ${a.name} is now optional; no caller has to change.` : nowRequired ? `${at}: the response field ${a.name} is now always there; no caller has to change.` : `${at}: the response field ${a.name} may now be left out; a caller that counts on it must allow for that.`
3393
+ says: req ? nowRequired ? `${at}: the ${what(a)} ${a.name} is now required; a caller that leaves it out is refused.` : `${at}: the ${what(a)} ${a.name} is now optional; no caller has to change.` : nowRequired ? `${at}: the ${what(a)} ${a.name} is now always there; no caller has to change.` : `${at}: the ${what(a)} ${a.name} may now be left out; a caller that counts on it must allow for that.`
2356
3394
  });
2357
3395
  }
2358
3396
  if (a.type && b.type && a.type !== b.type)
@@ -2361,7 +3399,7 @@ function fieldChanges(olds, news, side, at, base) {
2361
3399
  severity: "breaking",
2362
3400
  before: { value: a.type, cite: a.cite },
2363
3401
  after: { value: b.type, cite: b.cite },
2364
- says: `${at}: the ${side} field ${a.name} was ${a.type} and is now ${b.type}; a caller that ${req ? "sends" : "reads"} it must change.`
3402
+ says: `${at}: the ${what(a)} ${a.name} was ${a.type} and is now ${b.type}; a caller that ${req ? "sends" : "reads"} it must change.`
2365
3403
  });
2366
3404
  if (a.enum || b.enum) {
2367
3405
  const was = a.enum ?? [];
@@ -2371,7 +3409,7 @@ function fieldChanges(olds, news, side, at, base) {
2371
3409
  if (!gained.length && !lost.length)
2372
3410
  continue;
2373
3411
  const breaks = req ? lost.length > 0 : gained.length > 0;
2374
- const words = req ? lost.length ? `${at}: the request field ${a.name} no longer takes ${list(lost)}${gained.length ? ` and now takes ${list(gained)}` : ""}; a caller that sends a value it no longer takes is refused.` : `${at}: the request field ${a.name} now also takes ${list(gained)}; no caller has to change.` : gained.length ? `${at}: the response field ${a.name} may now be ${orList(gained)}; a caller that reads it must handle the new value${gained.length > 1 ? "s" : ""}.` : `${at}: the response field ${a.name} no longer returns ${list(lost)}; no caller has to change.`;
3412
+ const words = req ? lost.length ? `${at}: the ${what(a)} ${a.name} no longer takes ${list(lost)}${gained.length ? ` and now takes ${list(gained)}` : ""}; a caller that sends a value it no longer takes is refused.` : `${at}: the ${what(a)} ${a.name} now also takes ${list(gained)}; no caller has to change.` : gained.length ? `${at}: the ${what(a)} ${a.name} may now be ${orList(gained)}; a caller that reads it must handle the new value${gained.length > 1 ? "s" : ""}.` : `${at}: the ${what(a)} ${a.name} no longer returns ${list(lost)}; no caller has to change.`;
2375
3413
  out.push({
2376
3414
  ...base("field-enum", side, a.name),
2377
3415
  severity: breaks ? "breaking" : "additive",
@@ -2386,12 +3424,13 @@ function fieldChanges(olds, news, side, at, base) {
2386
3424
 
2387
3425
  // packages/intake/dist/vendor-impact.js
2388
3426
  var MAX_UPSTREAM = 4;
2389
- var cmp2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
3427
+ var cmp4 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2390
3428
  var sorted = (xs) => [...new Set(xs)].sort();
2391
3429
  var joinVendorOf = (input, spec) => ({
2392
3430
  system: input.vendor.system,
2393
3431
  names: input.vendor.names,
2394
3432
  hosts: [.../* @__PURE__ */ new Set([...spec.hosts, ...input.vendor.hosts ?? []])],
3433
+ ...input.vendor.boundary ? { boundary: input.vendor.boundary } : {},
2395
3434
  operations: spec.operations.map((o) => ({
2396
3435
  id: o.id,
2397
3436
  method: o.method,
@@ -2407,20 +3446,24 @@ var versionOf = (v) => ({
2407
3446
  });
2408
3447
  function vendorImpact(input) {
2409
3448
  const diff = diffVendorSpecs(input.older.spec, input.newer.spec);
2410
- const join5 = joinFacts({
3449
+ const bundle = input.bundleFolders ? { bundleFolders: input.bundleFolders } : {};
3450
+ const join7 = joinFacts({
2411
3451
  repos: input.repos,
2412
3452
  ...input.targets ? { targets: input.targets } : {},
2413
- ...input.facing ? { facing: input.facing } : {}
3453
+ ...input.facing ? { facing: input.facing } : {},
3454
+ ...bundle
2414
3455
  });
2415
3456
  const today = joinVendorOperations({
2416
3457
  repos: input.repos,
2417
3458
  vendors: [joinVendorOf(input, input.older.spec)],
2418
- ...input.targets ? { targets: input.targets } : {}
3459
+ ...input.targets ? { targets: input.targets } : {},
3460
+ ...bundle
2419
3461
  });
2420
3462
  const next = joinVendorOperations({
2421
3463
  repos: input.repos,
2422
3464
  vendors: [joinVendorOf(input, input.newer.spec)],
2423
- ...input.targets ? { targets: input.targets } : {}
3465
+ ...input.targets ? { targets: input.targets } : {},
3466
+ ...bundle
2424
3467
  });
2425
3468
  const k = (e) => `${e.repo}\0${e.fact}`;
2426
3469
  const facts = /* @__PURE__ */ new Map();
@@ -2444,8 +3487,8 @@ function vendorImpact(input) {
2444
3487
  const f = facts.get(k(call))?.fact;
2445
3488
  return f?.kind === "call" && f.from ? endOf(call.repo, f.from) : void 0;
2446
3489
  };
2447
- const hops = new Set(join5.joins.flatMap((j) => (j.gateway ?? []).map((h) => k(h.call))));
2448
- const joins = join5.joins.filter((j) => j.how !== "topic" && !hops.has(k(j.call)));
3490
+ const hops = new Set(join7.joins.flatMap((j) => (j.gateway ?? []).map((h) => k(h.call))));
3491
+ const joins = join7.joins.filter((j) => j.how !== "topic" && !hops.has(k(j.call)));
2449
3492
  const via = (j) => j.gateway?.length ? { via: j.gateway.map((h) => h.route) } : {};
2450
3493
  const upstreamOf = (start) => {
2451
3494
  const out = [];
@@ -2475,10 +3518,10 @@ function vendorImpact(input) {
2475
3518
  return out;
2476
3519
  };
2477
3520
  const fieldUse = (call, change) => {
2478
- if (!change.side || !change.field)
3521
+ if (!change.side || !change.field || change.status)
2479
3522
  return void 0;
2480
3523
  const side = change.side;
2481
- const mine = (input.repos.find((r) => r.repo === call.repo)?.facts ?? []).filter((f) => f.kind === "field" && f.owner === call.fact && (f.side ?? "request") === side).sort((a, b) => cmp2(a.id, b.id));
3524
+ const mine = (input.repos.find((r) => r.repo === call.repo)?.facts ?? []).filter((f) => f.kind === "field" && f.owner === call.fact && (f.side ?? "request") === side).sort((a, b) => cmp4(a.id, b.id));
2482
3525
  if (!mine.length)
2483
3526
  return void 0;
2484
3527
  const want = fieldNameKey(change.field);
@@ -2490,6 +3533,24 @@ function vendorImpact(input) {
2490
3533
  const older = c.endpoints.older;
2491
3534
  const matches = older ? today.matches.filter((m) => m.operation === older) : next.matches.filter((m) => m.operation === c.endpoints.newer);
2492
3535
  const forwards = matches.map((m) => {
3536
+ if (m.direct) {
3537
+ const f = facts.get(k(m.call))?.fact;
3538
+ const field2 = fieldUse(m.call, c);
3539
+ const self = {
3540
+ call: m.call,
3541
+ interface: interfaceId(m.call.component, factIdPart(f?.to ?? input.vendor.system), m.method, m.path),
3542
+ ...field2 ? { field: field2 } : {},
3543
+ ...m.route ? { under: m.route } : {},
3544
+ upstream: upstreamOf(m.route)
3545
+ };
3546
+ return {
3547
+ call: m.call,
3548
+ ...m.route ? { route: m.route } : {},
3549
+ operation: m.operation,
3550
+ direct: true,
3551
+ callers: [self]
3552
+ };
3553
+ }
2493
3554
  const callers = m.route ? joins.filter((j) => k(j.entry) === k(m.route) || (j.gateway ?? []).some((h) => k(h.entry) === k(m.route))).map((j) => {
2494
3555
  const u = under(j.call);
2495
3556
  const field2 = fieldUse(j.call, c);
@@ -2540,7 +3601,7 @@ function vendorImpact(input) {
2540
3601
  if (got?.fact.kind === "entry")
2541
3602
  endpointIds.add(entryEndpointId(got.fact, componentOf(got.repo, got.fact)));
2542
3603
  }
2543
- const flows = (input.flows ?? []).filter((f) => f.trigger && endpointIds.has(f.trigger) || (f.refs ?? []).some((r) => endpointIds.has(r))).map((f) => ({ id: f.id, repo: f.repo })).sort((a, b) => cmp2(a.id, b.id));
3604
+ const flows = (input.flows ?? []).filter((f) => f.trigger && endpointIds.has(f.trigger) || (f.refs ?? []).some((r) => endpointIds.has(r))).map((f) => ({ id: f.id, repo: f.repo })).sort((a, b) => cmp4(a.id, b.id));
2544
3605
  for (const f of flows)
2545
3606
  repos.add(f.repo);
2546
3607
  const systems = /* @__PURE__ */ new Set([input.vendor.system]);
@@ -2567,7 +3628,174 @@ function vendorImpact(input) {
2567
3628
  };
2568
3629
  }
2569
3630
 
3631
+ // packages/intake/dist/contract-files.js
3632
+ var import_yaml8 = __toESM(require_dist(), 1);
3633
+ import { readdir as readdir6, readFile as readFile6, stat as stat3 } from "node:fs/promises";
3634
+ import { join as join6 } from "node:path";
3635
+ function safeServerUrl(url) {
3636
+ const m = /^([a-z][a-z0-9+.-]*:\/\/)([^/?#]*)(.*)$/i.exec(url.trim());
3637
+ if (!m) {
3638
+ const p = safePathOf(url);
3639
+ return p === "/" ? void 0 : p;
3640
+ }
3641
+ const host = m[2].replace(/^.*@/, "");
3642
+ if (!host)
3643
+ return void 0;
3644
+ const rest = (m[3] ?? "").split(/[?#]/, 1)[0] ?? "";
3645
+ const path = rest && rest !== "/" ? safePathOf(rest) : "";
3646
+ return `${m[1].toLowerCase()}${host}${path === "/" ? "" : path ?? ""}`;
3647
+ }
3648
+ var str2 = (m, key3) => {
3649
+ const v = m?.get(key3);
3650
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
3651
+ };
3652
+ var mapAt = (m, key3) => {
3653
+ const v = (0, import_yaml8.isMap)(m) ? m.get(key3, true) : void 0;
3654
+ return (0, import_yaml8.isMap)(v) ? v : void 0;
3655
+ };
3656
+ function readPactFile(text3, file) {
3657
+ const lc = new import_yaml8.LineCounter();
3658
+ let doc;
3659
+ try {
3660
+ doc = (0, import_yaml8.parseDocument)(text3, { lineCounter: lc });
3661
+ } catch {
3662
+ return void 0;
3663
+ }
3664
+ if (doc.errors.length || !(0, import_yaml8.isMap)(doc.contents))
3665
+ return void 0;
3666
+ const root = doc.contents;
3667
+ const consumer = str2(mapAt(root, "consumer"), "name");
3668
+ const provider = str2(mapAt(root, "provider"), "name");
3669
+ const list2 = root.get("interactions", true);
3670
+ if (!consumer || !provider || !(0, import_yaml8.isSeq)(list2))
3671
+ return void 0;
3672
+ const out = [];
3673
+ for (const it of list2.items) {
3674
+ if (!(0, import_yaml8.isMap)(it))
3675
+ continue;
3676
+ const type = str2(it, "type");
3677
+ if (type && !/http/i.test(type))
3678
+ continue;
3679
+ const req = mapAt(it, "request");
3680
+ if (!req)
3681
+ continue;
3682
+ const method = str2(req, "method");
3683
+ const pair = req.items.find((p) => (0, import_yaml8.isScalar)(p.key) && p.key.value === "path");
3684
+ const path = pair && (0, import_yaml8.isScalar)(pair.value) ? String(pair.value.value) : void 0;
3685
+ const safe = path?.startsWith("/") ? safePathOf(path) : void 0;
3686
+ if (!safe)
3687
+ continue;
3688
+ const range = pair.key.range;
3689
+ out.push({
3690
+ format: "pact",
3691
+ file,
3692
+ line: range ? lc.linePos(range[0]).line : 1,
3693
+ consumer,
3694
+ provider,
3695
+ ...method ? { method: method.toUpperCase() } : {},
3696
+ path: safe
3697
+ });
3698
+ }
3699
+ return out;
3700
+ }
3701
+ function readConsumerOpenApi(text3, file, own) {
3702
+ let read;
3703
+ try {
3704
+ read = readOpenApiDocument(text3);
3705
+ } catch {
3706
+ return void 0;
3707
+ }
3708
+ if (!read)
3709
+ return void 0;
3710
+ const served = read.operations.some((op) => own.some((e) => (!e.method || e.method.toUpperCase() === op.method.toUpperCase()) && routeScore(op.path, e.path) >= 500));
3711
+ if (served)
3712
+ return [];
3713
+ const title = read.doc.getIn(["info", "title"]);
3714
+ const provider = typeof title === "string" && title.trim() ? title.trim() : void 0;
3715
+ const hosts = [...new Set(read.servers.map(safeServerUrl).filter((h) => !!h))];
3716
+ return read.operations.flatMap((op) => {
3717
+ const path = safePathOf(op.path);
3718
+ return path ? [
3719
+ {
3720
+ format: "openapi",
3721
+ file,
3722
+ line: op.methodLine ?? op.line ?? 1,
3723
+ ...provider ? { provider } : {},
3724
+ ...hosts.length ? { hosts } : {},
3725
+ method: op.method.toUpperCase(),
3726
+ path
3727
+ }
3728
+ ] : [];
3729
+ });
3730
+ }
3731
+ var SKIP2 = /* @__PURE__ */ new Set([
3732
+ ".git",
3733
+ "node_modules",
3734
+ "vendor",
3735
+ "target",
3736
+ "build",
3737
+ "dist",
3738
+ "out",
3739
+ ".venv",
3740
+ "venv",
3741
+ "__pycache__",
3742
+ ".gradle",
3743
+ ".idea",
3744
+ ".atticus"
3745
+ ]);
3746
+ var MAX_BYTES2 = 5 * 1024 * 1024;
3747
+ var PACT = /pact/i;
3748
+ var SPEC = /(openapi|swagger)/i;
3749
+ async function readContractFiles(dir, o) {
3750
+ const files = [];
3751
+ const walk2 = async (rel) => {
3752
+ const entries2 = await readdir6(join6(dir, ...rel.split("/").filter(Boolean)), {
3753
+ withFileTypes: true
3754
+ }).catch(() => []);
3755
+ for (const e of [...entries2].sort((a, b) => a.name < b.name ? -1 : 1)) {
3756
+ const p = rel ? `${rel}/${e.name}` : e.name;
3757
+ if (e.isDirectory()) {
3758
+ if (!SKIP2.has(e.name))
3759
+ await walk2(p);
3760
+ } else if (e.isFile()) {
3761
+ if (/\.json$/i.test(e.name) && PACT.test(p))
3762
+ files.push(p);
3763
+ else if (/\.(ya?ml|json)$/i.test(e.name) && SPEC.test(e.name))
3764
+ files.push(p);
3765
+ }
3766
+ }
3767
+ };
3768
+ await walk2("");
3769
+ const entries = [];
3770
+ for (const p of files) {
3771
+ const full = join6(dir, ...p.split("/"));
3772
+ const size = (await stat3(full).catch(() => void 0))?.size ?? 0;
3773
+ if (size === 0 || size > MAX_BYTES2)
3774
+ continue;
3775
+ const text3 = await readFile6(full, "utf8");
3776
+ const got = (/\.json$/i.test(p) && PACT.test(p) ? readPactFile(text3, p) : void 0) ?? (SPEC.test(p) ? readConsumerOpenApi(text3, p, o.own ?? []) : void 0);
3777
+ if (!got?.length)
3778
+ continue;
3779
+ if (o.denyHashes?.size) {
3780
+ const text4 = got.map((e) => [e.file, e.consumer, e.provider, ...e.hosts ?? [], e.method, e.path].join("\n")).join("\n");
3781
+ if (denyListHits(text4, o.denyHashes).length) {
3782
+ o.onRefused?.(`${p}: the deny-list names a word in it, so its requests are left out.`);
3783
+ continue;
3784
+ }
3785
+ }
3786
+ entries.push(...got);
3787
+ }
3788
+ entries.sort((a, b) => a.file < b.file ? -1 : a.file > b.file ? 1 : a.line - b.line);
3789
+ return {
3790
+ schemaVersion: 1,
3791
+ repo: o.repo,
3792
+ ...o.commit ? { commit: o.commit } : {},
3793
+ entries
3794
+ };
3795
+ }
3796
+
2570
3797
  export {
3798
+ joinServerVariables,
2571
3799
  classify,
2572
3800
  READERS,
2573
3801
  readOpenApiSpec,
@@ -2580,9 +3808,24 @@ export {
2580
3808
  sortItems,
2581
3809
  opt,
2582
3810
  screenFile,
3811
+ looksSensitive,
3812
+ segmentOf,
3813
+ safePathOf,
3814
+ pathTemplateOf,
3815
+ appLabelOf,
3816
+ denyListHits,
3817
+ aggregateTraffic,
2583
3818
  specEndpointIds,
2584
3819
  readVendorSpec,
2585
3820
  operationSchemas,
3821
+ readProtoSpecs,
3822
+ readAvroSpecs,
3823
+ readJsonSchemaSpecs,
3824
+ readAsyncApiSpecs,
3825
+ openApiContractSpecs,
3826
+ specFormatOf,
3827
+ readContractSpecs,
3828
+ readRepoSpecs,
2586
3829
  nameParts,
2587
3830
  compareVersions,
2588
3831
  scanInputs,
@@ -2605,5 +3848,9 @@ export {
2605
3848
  changeInputSources,
2606
3849
  diffVendorSpecs,
2607
3850
  MAX_UPSTREAM,
2608
- vendorImpact
3851
+ vendorImpact,
3852
+ safeServerUrl,
3853
+ readPactFile,
3854
+ readConsumerOpenApi,
3855
+ readContractFiles
2609
3856
  };