@maycombhq/atticus 2.0.0-beta.10 → 2.0.0-beta.12

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 (235) hide show
  1. package/dist/bin.js +3 -3
  2. package/dist/{chunk-AY2IUF4K.js → chunk-22GLUHGE.js} +659 -73
  3. package/dist/{chunk-CIUHAHM6.js → chunk-2A24BNRZ.js} +8 -8
  4. package/dist/{chunk-2RX7PI2Y.js → chunk-2ELFEKOO.js} +4 -4
  5. package/dist/{chunk-QKEFZRHS.js → chunk-2P6IHSRO.js} +17 -17
  6. package/dist/chunk-2Q2YBAR5.js +40 -0
  7. package/dist/{chunk-7DUDLVFJ.js → chunk-2VQLFNBO.js} +20 -20
  8. package/dist/{chunk-E3Z67HRK.js → chunk-3256EDLL.js} +4 -4
  9. package/dist/{chunk-OIU657QQ.js → chunk-34BCKMBS.js} +4 -4
  10. package/dist/{chunk-UR7RMZ3R.js → chunk-34NWVIBC.js} +2 -2
  11. package/dist/{chunk-6VBXAGJX.js → chunk-36KD4OGC.js} +14 -14
  12. package/dist/{chunk-I7IWQIEB.js → chunk-3CFBU2O6.js} +4 -4
  13. package/dist/{chunk-OSGQW2Z6.js → chunk-3JLTN3Y7.js} +8 -8
  14. package/dist/{chunk-FOGG4AUR.js → chunk-3M7QBKKG.js} +25 -7
  15. package/dist/{chunk-UF7TAFJM.js → chunk-3RP34PYV.js} +18 -18
  16. package/dist/{chunk-YLAJAI2W.js → chunk-3ZKLWM5Y.js} +11 -11
  17. package/dist/{chunk-LTQANUDH.js → chunk-47HPZ34V.js} +25 -25
  18. package/dist/chunk-4BPROPGG.js +45 -0
  19. package/dist/{chunk-Y4BRGOJR.js → chunk-4G56W6H7.js} +13 -10
  20. package/dist/{chunk-YXJ4XOHF.js → chunk-4HIQ2FTI.js} +4 -4
  21. package/dist/{chunk-AJJK7GLO.js → chunk-4HTILEXW.js} +3 -3
  22. package/dist/{chunk-OJLRFGBP.js → chunk-4Q2PGM5T.js} +78 -15
  23. package/dist/{chunk-GR6YKM55.js → chunk-4RDW2X43.js} +108 -14
  24. package/dist/{chunk-23M2LUYM.js → chunk-4VOG5H2K.js} +1 -1
  25. package/dist/chunk-5CSZTVXH.js +34 -0
  26. package/dist/{chunk-65C57N7P.js → chunk-5FFMJMVH.js} +19 -19
  27. package/dist/{chunk-XNYNEEBR.js → chunk-5GGGAI5C.js} +18 -18
  28. package/dist/{chunk-IUD3ME4E.js → chunk-5H46QFSL.js} +4 -4
  29. package/dist/{chunk-KIHOIVST.js → chunk-5ION6STH.js} +3 -3
  30. package/dist/chunk-5M3CLAOV.js +39 -0
  31. package/dist/chunk-5OACMWWI.js +886 -0
  32. package/dist/{chunk-2HMWX4T6.js → chunk-6ENDKY52.js} +11 -11
  33. package/dist/{chunk-OS7PQ35Z.js → chunk-6FG7QKJC.js} +22 -22
  34. package/dist/{chunk-FEZE6NIA.js → chunk-6JV3YHRR.js} +18 -18
  35. package/dist/{chunk-WGZWR4RF.js → chunk-6ROZRBWH.js} +5 -5
  36. package/dist/{chunk-WARBF2KY.js → chunk-6S27MUQQ.js} +10 -6
  37. package/dist/{chunk-TZDSDDSV.js → chunk-72DY5NCN.js} +2 -2
  38. package/dist/chunk-76QVBNEM.js +37 -0
  39. package/dist/{chunk-N4QZJJVB.js → chunk-77UOXZVM.js} +5 -5
  40. package/dist/{chunk-LVGBKKSM.js → chunk-7AXMUE2U.js} +15 -15
  41. package/dist/{chunk-FJCFYKVO.js → chunk-7TEQF64E.js} +196 -76
  42. package/dist/{chunk-IDGSU7JF.js → chunk-7TH6I6TL.js} +9 -9
  43. package/dist/{chunk-ZONE6E3Z.js → chunk-7UKETVPW.js} +2 -2
  44. package/dist/{chunk-XKS6THI5.js → chunk-7VNEDDCC.js} +2 -2
  45. package/dist/{chunk-BMHGA7WD.js → chunk-A5GY2EWH.js} +12 -12
  46. package/dist/{chunk-E3JYO547.js → chunk-AEZ3EICK.js} +20 -20
  47. package/dist/{chunk-7F2RUWPU.js → chunk-ARLH2ZMD.js} +1 -1
  48. package/dist/{chunk-VKMTFIWS.js → chunk-AYVLEB55.js} +18 -18
  49. package/dist/chunk-B6X5PJSA.js +320 -0
  50. package/dist/{chunk-JMSEEBN4.js → chunk-BRCDEGNE.js} +1 -1
  51. package/dist/{chunk-67J3VZBA.js → chunk-BSVTNNUK.js} +5 -5
  52. package/dist/{chunk-3GTZ2OON.js → chunk-BTOGAUWX.js} +20 -11
  53. package/dist/{chunk-4SVJNVEE.js → chunk-BXBCMGIQ.js} +2 -0
  54. package/dist/chunk-BXP2Q4TD.js +48 -0
  55. package/dist/{chunk-XPEEICAO.js → chunk-BZRWJUB4.js} +15 -15
  56. package/dist/{chunk-MH5OCRUM.js → chunk-CH6LUQLD.js} +2 -2
  57. package/dist/{chunk-T6USVBEJ.js → chunk-CIIRPLI6.js} +5 -5
  58. package/dist/chunk-CJXM6SG4.js +339 -0
  59. package/dist/{chunk-5XDNUJ4P.js → chunk-CQD26SMZ.js} +4 -2
  60. package/dist/{chunk-7TGYNOXD.js → chunk-CW5SEPUT.js} +7 -7
  61. package/dist/{chunk-5KTOPOEP.js → chunk-CWSZP2LU.js} +25 -25
  62. package/dist/chunk-CXK27ZUY.js +32 -0
  63. package/dist/{chunk-YGKYFMSL.js → chunk-CXY4YDXS.js} +3 -3
  64. package/dist/{chunk-R64GLVBO.js → chunk-DDZZXVQ5.js} +10 -10
  65. package/dist/{chunk-7YYEKTYF.js → chunk-DGZXJO5I.js} +8 -8
  66. package/dist/{chunk-IV7BCWWN.js → chunk-DONCF2XC.js} +3 -3
  67. package/dist/{chunk-RRVT4MPS.js → chunk-DPNCAFMB.js} +18 -18
  68. package/dist/{chunk-UBWCUP3G.js → chunk-DQKNOHUZ.js} +2 -2
  69. package/dist/{chunk-NGPU2ARF.js → chunk-DW4BM73R.js} +1 -1
  70. package/dist/{chunk-PEF5OEMB.js → chunk-DWN7RSNQ.js} +4 -4
  71. package/dist/{chunk-KC5DROFC.js → chunk-DWYPYVPJ.js} +14 -14
  72. package/dist/{chunk-B7434AE2.js → chunk-E73QLYK7.js} +24 -3
  73. package/dist/{chunk-EX6ZXS5K.js → chunk-EE3UNC44.js} +4 -4
  74. package/dist/chunk-EJDZEK22.js +53 -0
  75. package/dist/{chunk-ISNZYKAS.js → chunk-ENZWVTTN.js} +21 -21
  76. package/dist/{chunk-ROTY5J2L.js → chunk-EREL3TQG.js} +1 -1
  77. package/dist/{chunk-ZZXF6OOJ.js → chunk-ESGIBN3S.js} +2 -2
  78. package/dist/{chunk-YGR6OCHQ.js → chunk-EU7VTBAI.js} +8 -14
  79. package/dist/chunk-F5GA6G3U.js +48 -0
  80. package/dist/{chunk-JAA53T23.js → chunk-F6FGIYPT.js} +20 -20
  81. package/dist/{chunk-NPCD54I7.js → chunk-FAET4BB6.js} +8 -5
  82. package/dist/{chunk-YPBQNJHA.js → chunk-FBFSTYAB.js} +8 -8
  83. package/dist/{chunk-OEI7LVRP.js → chunk-FEBYMFZA.js} +24 -24
  84. package/dist/chunk-FMV6IZ3P.js +54 -0
  85. package/dist/{chunk-F7UQR4ZX.js → chunk-FQ6IBYFC.js} +3 -3
  86. package/dist/{chunk-J5LHDJU4.js → chunk-FSJMFPA3.js} +7 -7
  87. package/dist/chunk-GFZ5MIQG.js +47 -0
  88. package/dist/{chunk-LK44ULGI.js → chunk-GHSVJNVL.js} +104 -11
  89. package/dist/{chunk-LRS573EX.js → chunk-GKPOCUQR.js} +12 -7
  90. package/dist/{chunk-LDKUC2QJ.js → chunk-GLSNVC67.js} +17 -17
  91. package/dist/{chunk-47QE246J.js → chunk-GMDOXWIS.js} +5 -5
  92. package/dist/{chunk-5MI2SEV5.js → chunk-GN5ZLSLD.js} +3 -3
  93. package/dist/{chunk-JQ7XQPQS.js → chunk-GUNBOZ75.js} +4 -4
  94. package/dist/{chunk-HHUFVJF7.js → chunk-GYS64N6F.js} +6 -6
  95. package/dist/{chunk-AKJTKMXU.js → chunk-HIQWJ6JZ.js} +5 -5
  96. package/dist/{chunk-6GNS32SI.js → chunk-HJ52XDST.js} +4 -4
  97. package/dist/{chunk-2KDSXJFJ.js → chunk-HJUEQERG.js} +34 -7
  98. package/dist/chunk-HKGQUOQ3.js +88 -0
  99. package/dist/chunk-HP32HUWR.js +41 -0
  100. package/dist/{chunk-R4TBNKKC.js → chunk-HY2VVVFZ.js} +1249 -610
  101. package/dist/{chunk-G5SFOH7P.js → chunk-I2PNEG3M.js} +38 -23
  102. package/dist/{chunk-Y5PZHS4K.js → chunk-INCECZ2E.js} +5 -5
  103. package/dist/{chunk-RK6MKKKP.js → chunk-ISXNWUG7.js} +1 -1
  104. package/dist/{chunk-73VPWF5R.js → chunk-ITJ7ST5E.js} +4 -4
  105. package/dist/{chunk-5IALSMZ2.js → chunk-J3VAFDEX.js} +14 -14
  106. package/dist/chunk-JGLZUQVN.js +29 -0
  107. package/dist/{chunk-5XN76FTF.js → chunk-JLIEAQP4.js} +5 -5
  108. package/dist/{chunk-MGVYVW7Q.js → chunk-JQG4VO47.js} +1 -1
  109. package/dist/chunk-JXXQHETS.js +130 -0
  110. package/dist/{chunk-APSVL2AI.js → chunk-KNGESBFW.js} +15 -15
  111. package/dist/{chunk-7UKVYFQ2.js → chunk-KUYA2E7M.js} +8 -8
  112. package/dist/{chunk-WLIIQ2A4.js → chunk-KY2ZHTBJ.js} +7 -7
  113. package/dist/{chunk-YPIEYQF4.js → chunk-L4UIKAWD.js} +6 -6
  114. package/dist/chunk-LDUJ6NIT.js +247 -0
  115. package/dist/{chunk-5YIBJXGB.js → chunk-LTLR4JZJ.js} +10 -10
  116. package/dist/{chunk-IZNSAEBX.js → chunk-MFRPLAOH.js} +2 -2
  117. package/dist/{chunk-6GWHKMQR.js → chunk-MH7UBG47.js} +4 -4
  118. package/dist/{chunk-4GZXS6S2.js → chunk-MLAACAES.js} +278 -17
  119. package/dist/{chunk-D3PO4DOZ.js → chunk-MMB2OHUY.js} +4 -2
  120. package/dist/{chunk-DDAHCPGA.js → chunk-MNCQ2GL7.js} +12 -12
  121. package/dist/{chunk-UYYN2IUZ.js → chunk-MNUZX67F.js} +6 -6
  122. package/dist/{chunk-YFSSNGLR.js → chunk-MQHYCS6A.js} +32 -29
  123. package/dist/{chunk-MKRBG5EF.js → chunk-MRLCNXXR.js} +1 -1
  124. package/dist/{chunk-BUYJL3GJ.js → chunk-NBQO75XT.js} +1 -1
  125. package/dist/{chunk-GXJVY6WT.js → chunk-NCONDPHH.js} +5 -5
  126. package/dist/{chunk-ZP4FJHR4.js → chunk-NHS55U7T.js} +18 -18
  127. package/dist/{chunk-CRE4BJHM.js → chunk-NL6XQZSV.js} +23 -23
  128. package/dist/{chunk-YVLMBAYE.js → chunk-NSJ6ZR2A.js} +3 -3
  129. package/dist/{chunk-XRO65C7V.js → chunk-NTNJNRHW.js} +8 -6
  130. package/dist/{chunk-FTV6I76U.js → chunk-NTTXTLCQ.js} +25 -25
  131. package/dist/chunk-NWL7XEQ4.js +37 -0
  132. package/dist/{chunk-CNKGYDMG.js → chunk-NWXY3B4R.js} +23 -23
  133. package/dist/{chunk-52R2YXP5.js → chunk-O5W4ECUY.js} +16 -16
  134. package/dist/{chunk-OGRWQ562.js → chunk-O6ILVBYB.js} +2 -2
  135. package/dist/{chunk-BJPMKJTL.js → chunk-OJAJXU65.js} +102 -2
  136. package/dist/{chunk-FZL2HNWP.js → chunk-OMH3I5BH.js} +3 -3
  137. package/dist/{chunk-MF7QH4AX.js → chunk-P6UJ22XR.js} +5 -5
  138. package/dist/{chunk-HE4ZQXZM.js → chunk-P76AW3PA.js} +309 -15
  139. package/dist/{chunk-GZ4TKR3Q.js → chunk-PCCPXWJC.js} +48 -139
  140. package/dist/{chunk-6TJCUYC5.js → chunk-PGFRXGHA.js} +3 -3
  141. package/dist/{chunk-NIXVDQVO.js → chunk-PJRMMWU4.js} +2 -2
  142. package/dist/{chunk-X4W4XXWP.js → chunk-PKJ3K3GM.js} +5 -5
  143. package/dist/{chunk-KM2FBM3T.js → chunk-PVW2N63M.js} +302 -55
  144. package/dist/{chunk-Y7KBQ4BD.js → chunk-Q55UP5EZ.js} +22 -22
  145. package/dist/{chunk-7URGP4DD.js → chunk-QAFMLBPF.js} +12 -12
  146. package/dist/{chunk-KIAI6PWL.js → chunk-QEZSA2O7.js} +17 -17
  147. package/dist/{chunk-PKCMRPPB.js → chunk-QJ3OX7OC.js} +33 -27
  148. package/dist/{chunk-6EDQE7GO.js → chunk-QL4VNY4U.js} +2 -2
  149. package/dist/{chunk-6JLPXDWN.js → chunk-QR65C3DV.js} +5 -5
  150. package/dist/{chunk-ILFKECGI.js → chunk-QXGOEP44.js} +4 -4
  151. package/dist/chunk-QY7RGTUP.js +326 -0
  152. package/dist/{chunk-PGKHJYOB.js → chunk-RA64IK43.js} +1 -1
  153. package/dist/{chunk-XB5RFZHH.js → chunk-RLJDYLID.js} +12 -12
  154. package/dist/{chunk-AWECWW5Y.js → chunk-RMLUZYEA.js} +13 -11
  155. package/dist/chunk-RSVBX6A3.js +54 -0
  156. package/dist/chunk-RZWZO2JQ.js +42 -0
  157. package/dist/chunk-S5LSDXV4.js +40 -0
  158. package/dist/{chunk-TM7LC37P.js → chunk-SAC6FNKR.js} +181 -117
  159. package/dist/{chunk-DPHCFZ7W.js → chunk-SCBU46AJ.js} +3 -3
  160. package/dist/{chunk-EZIUFEN6.js → chunk-SGNHNN3G.js} +12 -12
  161. package/dist/{chunk-XKZHAD6Y.js → chunk-SHAAGH3T.js} +15 -15
  162. package/dist/chunk-SK5OYWIY.js +122 -0
  163. package/dist/{chunk-FR7JPYBD.js → chunk-SNSFQ47W.js} +12 -12
  164. package/dist/{chunk-FV5YFR6I.js → chunk-SSL6JMPA.js} +9 -9
  165. package/dist/{chunk-XEG3FE2R.js → chunk-TA2ZNDYD.js} +1 -1
  166. package/dist/{chunk-JF2NSTFO.js → chunk-TEHH47TG.js} +3 -3
  167. package/dist/{chunk-W5OYJMBT.js → chunk-TEZSZ24W.js} +5 -5
  168. package/dist/{chunk-SS66Q4VE.js → chunk-TH526O6E.js} +12 -12
  169. package/dist/{chunk-R6B6XAKK.js → chunk-TIAPEYWI.js} +4 -4
  170. package/dist/chunk-TLCRIAU3.js +44 -0
  171. package/dist/{chunk-FMKKVWZD.js → chunk-TQYBXDVH.js} +2 -2
  172. package/dist/chunk-TV4CGNEY.js +43 -0
  173. package/dist/{chunk-QICFHVRW.js → chunk-TVSNWIAM.js} +8 -6
  174. package/dist/{chunk-CHC5FKTU.js → chunk-TWHZU36X.js} +1 -1
  175. package/dist/{chunk-BMCKL3VQ.js → chunk-TXV2AYZB.js} +24 -24
  176. package/dist/{chunk-577AJVRS.js → chunk-U25OX22K.js} +2039 -289
  177. package/dist/{chunk-7EKESFWV.js → chunk-U4NNG3ES.js} +11 -11
  178. package/dist/{chunk-XQ3YIV5R.js → chunk-U5T4A2QV.js} +6 -6
  179. package/dist/{chunk-2XM6PYQQ.js → chunk-UT5OA7KA.js} +43 -11
  180. package/dist/{chunk-BXIX7S7O.js → chunk-V3VCUSQ6.js} +15 -15
  181. package/dist/{chunk-4QUQEBFT.js → chunk-V5XV3JSP.js} +6 -6
  182. package/dist/{chunk-F7YL2RZ4.js → chunk-VF4VOPMB.js} +23 -23
  183. package/dist/{chunk-3QAKDIEU.js → chunk-VLDM4QZM.js} +23 -23
  184. package/dist/chunk-VP5H6DII.js +34 -0
  185. package/dist/{chunk-N3NBWIYQ.js → chunk-VRYQJZFL.js} +10 -9
  186. package/dist/{chunk-FQSRHTTC.js → chunk-VS6FS472.js} +15 -15
  187. package/dist/{chunk-YMOJD5BO.js → chunk-VTMIRRIZ.js} +3 -3
  188. package/dist/{chunk-4PJADZRR.js → chunk-VXSJKWB7.js} +16 -16
  189. package/dist/{chunk-MTAUZW2Z.js → chunk-WE5VMPUP.js} +216 -106
  190. package/dist/{chunk-ZE3P35DA.js → chunk-WEG7DY5K.js} +9 -9
  191. package/dist/{chunk-V2TH46ZY.js → chunk-WIF7A6JU.js} +12 -12
  192. package/dist/{chunk-GFXLPJWY.js → chunk-WM4N2L4T.js} +2 -2
  193. package/dist/{chunk-XIWYUQZQ.js → chunk-X64BFQ3R.js} +9 -9
  194. package/dist/{chunk-QWVBEK4P.js → chunk-XJRC3ZDI.js} +13 -13
  195. package/dist/{chunk-F2FOQLJ7.js → chunk-XVIVWG7B.js} +6 -6
  196. package/dist/{chunk-XTVDAHH2.js → chunk-Y3ZKT6IF.js} +5 -5
  197. package/dist/{chunk-62YMDXY6.js → chunk-YURIUFKF.js} +16 -16
  198. package/dist/{chunk-HKTUIMH4.js → chunk-YY2WGL6S.js} +3 -3
  199. package/dist/{chunk-BDEKREZH.js → chunk-Z2BA4NNR.js} +3 -3
  200. package/dist/{chunk-MTEBM4Y4.js → chunk-Z47YGBUY.js} +19 -12
  201. package/dist/chunk-Z4JSRKNR.js +41 -0
  202. package/dist/{chunk-G2E5MNYP.js → chunk-Z53ZB34U.js} +7 -7
  203. package/dist/{chunk-NNUASOAA.js → chunk-ZBOPIYOY.js} +12 -12
  204. package/dist/{chunk-7GB4ZRE2.js → chunk-ZBQCLKTH.js} +12 -12
  205. package/dist/chunk-ZGI7DNJ6.js +38 -0
  206. package/dist/{chunk-P3TKKBAH.js → chunk-ZPT4QX3J.js} +4 -4
  207. package/dist/chunk-ZS47PQ3O.js +41 -0
  208. package/dist/{chunk-PIVKU64W.js → chunk-ZTIMXVV5.js} +2 -2
  209. package/dist/{chunk-T4RTWMJD.js → chunk-ZYASEL7K.js} +5 -5
  210. package/dist/files.json +469 -417
  211. package/dist/packages/sdk/npm/index.js +2309 -1983
  212. package/dist/packages/ui/dist/assets/{elk-api-Mo5w5xCa.js → elk-api-D2NcYpUJ.js} +2 -2
  213. package/dist/packages/ui/dist/assets/{index-Bp3XhPHX.css → index-C0JEkXyN.css} +1 -1
  214. package/dist/packages/ui/dist/assets/index-CT7skl01.js +29 -0
  215. package/dist/packages/ui/dist/index.html +2 -2
  216. package/package.json +4 -4
  217. package/dist/chunk-26PLPSQW.js +0 -48
  218. package/dist/chunk-2G4DFUWJ.js +0 -43
  219. package/dist/chunk-2M6WXO73.js +0 -38
  220. package/dist/chunk-5F3RJCHB.js +0 -45
  221. package/dist/chunk-B2VSVN4P.js +0 -34
  222. package/dist/chunk-B3O52AUQ.js +0 -275
  223. package/dist/chunk-CITDNDIZ.js +0 -53
  224. package/dist/chunk-DAQBIK5G.js +0 -47
  225. package/dist/chunk-DZRQDNPT.js +0 -34
  226. package/dist/chunk-FLOEZA6K.js +0 -29
  227. package/dist/chunk-FNHSVBRA.js +0 -48
  228. package/dist/chunk-FPGVOSOG.js +0 -41
  229. package/dist/chunk-FZ2E5LGK.js +0 -54
  230. package/dist/chunk-HB6XSGI6.js +0 -131
  231. package/dist/chunk-HUZQDKQK.js +0 -48
  232. package/dist/chunk-L4VJ4ETL.js +0 -41
  233. package/dist/chunk-XPCWQXTY.js +0 -37
  234. package/dist/chunk-YIEOFHOL.js +0 -30
  235. package/dist/packages/ui/dist/assets/index-DM212ZbV.js +0 -29
@@ -12,18 +12,18 @@ import {
12
12
  readDrawio,
13
13
  readMermaid,
14
14
  resolveNames
15
- } from "./chunk-NIXVDQVO.js";
15
+ } from "./chunk-PJRMMWU4.js";
16
16
  import {
17
17
  openapiExtractor,
18
18
  readOpenApiDocument
19
- } from "./chunk-UR7RMZ3R.js";
19
+ } from "./chunk-34NWVIBC.js";
20
20
  import {
21
21
  combine,
22
22
  formatOf,
23
23
  screenDiagramXml,
24
24
  screenOfficeXml,
25
25
  screenText
26
- } from "./chunk-5XDNUJ4P.js";
26
+ } from "./chunk-CQD26SMZ.js";
27
27
  import {
28
28
  TrafficFile,
29
29
  endpointId,
@@ -42,10 +42,10 @@ import {
42
42
  routeScore,
43
43
  toCanonicalYaml,
44
44
  trafficFileText
45
- } from "./chunk-577AJVRS.js";
45
+ } from "./chunk-U25OX22K.js";
46
46
  import {
47
47
  writeFileAtomic
48
- } from "./chunk-D3PO4DOZ.js";
48
+ } from "./chunk-MMB2OHUY.js";
49
49
  import {
50
50
  __toESM
51
51
  } from "./chunk-TV45EUGM.js";
@@ -127,6 +127,151 @@ function fromData(data) {
127
127
  }
128
128
  return void 0;
129
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
+ }
130
275
  function classify(fileName, bytes) {
131
276
  const name = fileName.toLowerCase();
132
277
  const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1) : "";
@@ -168,19 +313,26 @@ function classify(fileName, bytes) {
168
313
  return { classification: "diagram" };
169
314
  if (/^<(!doctype html|html)\b/i.test(head))
170
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" };
171
320
  if (["json", "yaml", "yml"].includes(ext) || /^[[{]/.test(head)) {
172
- let data;
173
- try {
174
- data = (0, import_yaml.parse)(text3);
175
- } catch {
176
- data = void 0;
177
- }
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
+ };
178
330
  const known = fromData(data);
179
331
  if (known)
180
- return known;
332
+ return { ...known, ...lenient };
181
333
  if (ext === "json" || /^[[{]/.test(head)) {
182
334
  if (isObj(data) || Array.isArray(data))
183
- return { classification: "payload", data };
335
+ return { classification: "payload", data, ...lenient };
184
336
  }
185
337
  if (ext === "yaml" || ext === "yml")
186
338
  return { classification: "unknown" };
@@ -200,7 +352,10 @@ import { createHash } from "node:crypto";
200
352
  var READERS = {
201
353
  openapi: `${openapiExtractor.id}@${openapiExtractor.version}`,
202
354
  asyncapi: "asyncapi@0.1.0",
203
- 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"
204
359
  };
205
360
  var short = (s) => createHash("sha256").update(s).digest("hex").slice(0, 6);
206
361
  function oneFile(path, text3) {
@@ -416,9 +571,9 @@ var opt = {
416
571
  };
417
572
 
418
573
  // packages/intake/dist/scan-inputs.js
419
- import { createHash as createHash4 } from "node:crypto";
420
- import { readdir, readFile, stat } from "node:fs/promises";
421
- 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";
422
577
 
423
578
  // packages/intake/dist/screen-file.js
424
579
  var PK = (b) => b[0] === 80 && b[1] === 75;
@@ -460,131 +615,435 @@ function screenFile(path, bytes) {
460
615
  }
461
616
  }
462
617
 
463
- // packages/intake/dist/vendor-ops.js
464
- var import_yaml3 = __toESM(require_dist(), 1);
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
465
624
  import { createHash as createHash3 } from "node:crypto";
466
- var short2 = (s) => createHash3("sha256").update(s).digest("hex").slice(0, 6);
467
- function specEndpointIds(component, ops) {
468
- const ids = ops.map((o) => endpointId(component, o.method, o.normalizedPath));
469
- const count = /* @__PURE__ */ new Map();
470
- for (const id of ids)
471
- count.set(id, (count.get(id) ?? 0) + 1);
472
- return ids.map((id, i) => (count.get(id) ?? 0) > 1 ? `${id}-${short2(ops[i].normalizedPath)}` : id);
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));
473
637
  }
474
- var MAX_DEPTH = 6;
475
- function readVendorSpec(path, text3, system) {
476
- const read = readOpenApiDocument(text3);
477
- if (!read)
638
+ function rowsOf(text3) {
639
+ const t = text3.replace(/^\uFEFF/, "").trim();
640
+ if (!t)
478
641
  return void 0;
479
- const { doc, lc } = read;
480
- const at = (offset) => offset === void 0 ? void 0 : `${path}:${lc.linePos(offset).line}`;
481
- const swagger2 = read.version.startsWith("2");
482
- const hosts = [];
483
- let serverPath = "";
484
- read.servers.forEach((url, i) => {
485
- const m = /^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)([^?#]*)/i.exec(url);
486
- const host = m?.[1]?.replace(/^[^@]*@/, "").replace(/:\d+$/, "").toLowerCase();
487
- if (host && !host.includes("{") && !hosts.includes(host))
488
- hosts.push(host);
489
- if (i === 0) {
490
- const p = m ? m[2] : url.startsWith("/") ? url.split(/[?#]/)[0] : "";
491
- serverPath = p.replace(/\/+$/, "");
642
+ if (t.startsWith("[") || t.startsWith("{")) {
643
+ let v;
644
+ try {
645
+ v = JSON.parse(t);
646
+ } catch {
647
+ return void 0;
492
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;
493
674
  });
494
- if (swagger2)
495
- serverPath = "";
496
- const info = doc.get("info");
497
- const title = (0, import_yaml3.isMap)(info) ? info.get("title") : void 0;
498
- const version = (0, import_yaml3.isMap)(info) ? info.get("version") : void 0;
499
- const ctx = { doc, lc, path, at };
500
- const ops = read.operations.map((op) => {
501
- const method = op.method.toUpperCase();
502
- const fullPath = `${serverPath}${op.path}` || op.path;
503
- const node = (0, import_yaml3.isMap)(op.node) ? op.node : void 0;
504
- const opId = node?.get("operationId");
505
- return {
506
- method,
507
- path: op.path,
508
- fullPath,
509
- normalizedPath: normalizePath(op.path),
510
- ...typeof opId === "string" && opId ? { operationId: opId } : {},
511
- ...op.auth ? { auth: op.auth } : {},
512
- scopes: op.scopes,
513
- cite: `${path}:${op.methodLine ?? op.line ?? 1}`,
514
- request: requestFields(ctx, op, swagger2),
515
- response: responseFields(ctx, op, swagger2),
516
- ...errorsOf(ctx, op, swagger2)
517
- };
518
- });
519
- const ids = specEndpointIds(system, ops);
520
- return {
521
- path,
522
- system,
523
- ...typeof title === "string" && title ? { title } : {},
524
- ...version !== void 0 && version !== null && String(version) ? { version: String(version) } : {},
525
- hosts,
526
- serverPath,
527
- basePath: swagger2 ? String(doc.get("basePath") ?? "") : "",
528
- operations: ops.map((o, i) => ({ id: ids[i], ...o }))
529
- };
530
675
  }
531
- function errorsOf(ctx, op, swagger2) {
532
- const responses = (0, import_yaml3.isMap)(op.node) ? op.node.get("responses") : void 0;
533
- if (!(0, import_yaml3.isMap)(responses))
534
- return {};
535
- const errors = responses.items.flatMap((p) => {
536
- const status = (0, import_yaml3.isScalar)(p.key) ? String(p.key.value) : "";
537
- if (!/^[45]\d\d$/.test(status))
538
- return [];
539
- const cite = ctx.at((0, import_yaml3.isScalar)(p.key) ? p.key.range?.[0] : void 0);
540
- if (!cite)
541
- return [];
542
- const fields = [];
543
- schemaFields(ctx, bodySchema(ctx, p.value, swagger2), "body", "", 0, /* @__PURE__ */ new Set(), fields);
544
- return [{ status, cite, ...fields.length ? { fields } : {} }];
545
- });
546
- return errors.length ? { errors } : {};
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;
547
683
  }
548
- function bodySchema(ctx, response, swagger2) {
549
- if (!swagger2)
550
- return contentSchema(ctx, response);
551
- const r = deref(ctx, response);
552
- return (0, import_yaml3.isMap)(r) ? r.get("schema", true) : void 0;
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, "");
553
691
  }
554
- function responseHeaders(ctx, response, swagger2) {
555
- const r = deref(ctx, response);
556
- const headers = (0, import_yaml3.isMap)(r) ? r.get("headers") : void 0;
557
- if (!(0, import_yaml3.isMap)(headers))
558
- return [];
559
- const out = [];
560
- for (const pair of headers.items) {
561
- if (!(0, import_yaml3.isScalar)(pair.key))
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)
562
722
  continue;
563
- const h = deref(ctx, pair.value);
564
- if (!(0, import_yaml3.isMap)(h))
723
+ const s = routeScore(`/${segs.slice(0, n).join("/")}`, t);
724
+ if (s <= MATCH)
565
725
  continue;
566
- const schema = swagger2 ? h : deref(ctx, h.get("schema", true));
567
- const sm = (0, import_yaml3.isMap)(schema) ? schema : void 0;
568
- const type = sm ? typeOf2(sm) : void 0;
569
- const values = sm ? strings(sm.get("enum")) : void 0;
570
- out.push({
571
- name: String(pair.key.value),
572
- in: "header",
573
- ...type ? { type } : {},
574
- ...swagger2 ? {} : { required: h.get("required") === true },
575
- ...values ? { enum: values } : {},
576
- cite: ctx.at(pair.key.range?.[0]) ?? `${ctx.path}:1`
577
- });
726
+ if (n > len || s > score) {
727
+ len = n;
728
+ score = s;
729
+ prefix = t;
730
+ }
578
731
  }
579
- return out;
732
+ return prefix ? `${prefix.replace(/\/+$/, "")}/**` : void 0;
580
733
  }
581
- function deref(ctx, node, seen = /* @__PURE__ */ new Set()) {
582
- let n = node;
583
- for (let i = 0; i < 8 && (0, import_yaml3.isMap)(n); i++) {
584
- const ref = n.get("$ref");
585
- if (typeof ref !== "string")
586
- return n;
587
- if (!ref.startsWith("#/") || seen.has(ref))
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
+
922
+ // packages/intake/dist/vendor-ops.js
923
+ var import_yaml3 = __toESM(require_dist(), 1);
924
+ import { createHash as createHash4 } from "node:crypto";
925
+ var short2 = (s) => createHash4("sha256").update(s).digest("hex").slice(0, 6);
926
+ function specEndpointIds(component, ops) {
927
+ const ids = ops.map((o) => endpointId(component, o.method, o.normalizedPath));
928
+ const count = /* @__PURE__ */ new Map();
929
+ for (const id of ids)
930
+ count.set(id, (count.get(id) ?? 0) + 1);
931
+ return ids.map((id, i) => (count.get(id) ?? 0) > 1 ? `${id}-${short2(ops[i].normalizedPath)}` : id);
932
+ }
933
+ var MAX_DEPTH = 6;
934
+ function readVendorSpec(path, text3, system) {
935
+ const read = readOpenApiDocument(text3);
936
+ if (!read)
937
+ return void 0;
938
+ const { doc, lc } = read;
939
+ const at = (offset) => offset === void 0 ? void 0 : `${path}:${lc.linePos(offset).line}`;
940
+ const swagger2 = read.version.startsWith("2");
941
+ const hosts = [];
942
+ let serverPath = "";
943
+ read.servers.forEach((url, i) => {
944
+ const m = /^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)([^?#]*)/i.exec(url);
945
+ const host = m?.[1]?.replace(/^[^@]*@/, "").replace(/:\d+$/, "").toLowerCase();
946
+ if (host && !host.includes("{") && !hosts.includes(host))
947
+ hosts.push(host);
948
+ if (i === 0) {
949
+ const p = m ? m[2] : url.startsWith("/") ? url.split(/[?#]/)[0] : "";
950
+ serverPath = p.replace(/\/+$/, "");
951
+ }
952
+ });
953
+ if (swagger2)
954
+ serverPath = "";
955
+ const info = doc.get("info");
956
+ const title = (0, import_yaml3.isMap)(info) ? info.get("title") : void 0;
957
+ const version = (0, import_yaml3.isMap)(info) ? info.get("version") : void 0;
958
+ const ctx = { doc, lc, path, at };
959
+ const ops = read.operations.map((op) => {
960
+ const method = op.method.toUpperCase();
961
+ const fullPath = `${serverPath}${op.path}` || op.path;
962
+ const node = (0, import_yaml3.isMap)(op.node) ? op.node : void 0;
963
+ const opId = node?.get("operationId");
964
+ return {
965
+ method,
966
+ path: op.path,
967
+ fullPath,
968
+ normalizedPath: normalizePath(op.path),
969
+ ...typeof opId === "string" && opId ? { operationId: opId } : {},
970
+ ...op.auth ? { auth: op.auth } : {},
971
+ scopes: op.scopes,
972
+ cite: `${path}:${op.methodLine ?? op.line ?? 1}`,
973
+ request: requestFields(ctx, op, swagger2),
974
+ response: responseFields(ctx, op, swagger2),
975
+ ...errorsOf(ctx, op, swagger2)
976
+ };
977
+ });
978
+ const ids = specEndpointIds(system, ops);
979
+ return {
980
+ path,
981
+ system,
982
+ ...typeof title === "string" && title ? { title } : {},
983
+ ...version !== void 0 && version !== null && String(version) ? { version: String(version) } : {},
984
+ hosts,
985
+ serverPath,
986
+ basePath: swagger2 ? String(doc.get("basePath") ?? "") : "",
987
+ operations: ops.map((o, i) => ({ id: ids[i], ...o }))
988
+ };
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
+ }
1040
+ function deref(ctx, node, seen = /* @__PURE__ */ new Set()) {
1041
+ let n = node;
1042
+ for (let i = 0; i < 8 && (0, import_yaml3.isMap)(n); i++) {
1043
+ const ref = n.get("$ref");
1044
+ if (typeof ref !== "string")
1045
+ return n;
1046
+ if (!ref.startsWith("#/") || seen.has(ref))
588
1047
  return void 0;
589
1048
  seen.add(ref);
590
1049
  const parts = ref.slice(2).split("/").map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
@@ -775,12 +1234,442 @@ function operationSchemas(spec) {
775
1234
  });
776
1235
  }
777
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
+
778
1665
  // packages/intake/dist/scan-inputs.js
779
1666
  var SPECS = ["openapi", "swagger", "asyncapi"];
780
1667
  var EVIDENCE_SOURCE = {
781
1668
  openapi: "spec",
782
1669
  swagger: "spec",
783
1670
  asyncapi: "spec",
1671
+ protobuf: "spec",
1672
+ avro: "spec",
784
1673
  diagram: "diagram",
785
1674
  image: "document",
786
1675
  document: "document",
@@ -798,14 +1687,14 @@ async function walk(dir, skip) {
798
1687
  return;
799
1688
  let entries;
800
1689
  try {
801
- entries = await readdir(d, { withFileTypes: true });
1690
+ entries = await readdir2(d, { withFileTypes: true });
802
1691
  } catch {
803
1692
  return;
804
1693
  }
805
1694
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
806
1695
  if (e.name.startsWith("."))
807
1696
  continue;
808
- const full = join(d, e.name);
1697
+ const full = join2(d, e.name);
809
1698
  if (e.isDirectory())
810
1699
  await go(full);
811
1700
  else if (e.isFile())
@@ -816,7 +1705,7 @@ async function walk(dir, skip) {
816
1705
  return out;
817
1706
  }
818
1707
  var DATE = /(?:^|[-_ .])((\d{4})-?(\d{2})-?(\d{2}))(?=$|[-_ .])/;
819
- var VERSION = /(?:^|[-_ .])v(\d+(?:[._]\d+)*)(?=$|[-_ .])/i;
1708
+ var VERSION2 = /(?:^|[-_ .])v(\d+(?:[._]\d+)*)(?=$|[-_ .])/i;
820
1709
  function nameParts(stem) {
821
1710
  let rest = stem;
822
1711
  let date;
@@ -829,7 +1718,7 @@ function nameParts(stem) {
829
1718
  }
830
1719
  }
831
1720
  let version;
832
- const v = VERSION.exec(rest);
1721
+ const v = VERSION2.exec(rest);
833
1722
  if (v) {
834
1723
  version = v[1].replace(/_/g, ".");
835
1724
  rest = rest.replace(v[0], "");
@@ -855,23 +1744,23 @@ function systemsInName(stem, systems) {
855
1744
  return systems.filter((sys) => [sys.id, sys.name, ...sys.aliases].some((n) => slug(n) && s.includes(`-${slug(n)}-`))).map((sys) => sys.id).sort();
856
1745
  }
857
1746
  async function scanInputs(o) {
858
- 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));
859
1748
  const op = typeof o.orgPack === "object" ? o.orgPack : await loadOrgPack(orgPackDir);
860
1749
  const systems = op.profiles.flatMap((p) => p.profile?.systems ?? []);
861
1750
  const legend = op.profiles.find((p) => p.profile?.legend)?.profile?.legend;
862
1751
  const records = o.records ?? [];
863
1752
  const ingestors = o.ingestors ?? [drawioIngestor];
864
1753
  const scannedAt = o.scannedAt ?? (/* @__PURE__ */ new Date()).toISOString();
865
- const inputsDir = o.inputsDir ?? join(o.root, "inputs");
1754
+ const inputsDir = o.inputsDir ?? join2(o.root, "inputs");
866
1755
  const problems = [];
867
1756
  const triage = [];
868
1757
  const authors = /* @__PURE__ */ new Map();
869
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)]);
870
- const st = await stat(inputsDir).catch(() => void 0);
1759
+ const st = await stat2(inputsDir).catch(() => void 0);
871
1760
  const paths = st?.isDirectory() ? await walk(inputsDir, wikiDirs) : [];
872
1761
  const files = [];
873
1762
  for (const abs of paths) {
874
- const bytes = new Uint8Array(await readFile(abs));
1763
+ const bytes = new Uint8Array(await readFile2(abs));
875
1764
  const path = `inputs/${posix(relative(inputsDir, abs))}`;
876
1765
  const name = path.split("/").pop();
877
1766
  const c = classify(name, bytes);
@@ -879,14 +1768,19 @@ async function scanInputs(o) {
879
1768
  abs,
880
1769
  path,
881
1770
  bytes,
882
- hash: createHash4("sha256").update(bytes).digest("hex"),
1771
+ hash: createHash5("sha256").update(bytes).digest("hex"),
883
1772
  stem: name.includes(".") ? name.slice(0, name.lastIndexOf(".")) : name,
884
1773
  inbox: path.startsWith("inputs/inbox/"),
885
1774
  ...c.data !== void 0 ? { data: c.data } : {},
1775
+ ...c.text !== void 0 ? { text: c.text } : {},
886
1776
  doc: {
887
1777
  path,
888
1778
  classification: c.classification,
889
- 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 } : {},
890
1784
  hash: "",
891
1785
  ...c.title ? { title: c.title } : {},
892
1786
  ...c.version ? { version: c.version } : {},
@@ -949,7 +1843,7 @@ async function scanInputs(o) {
949
1843
  const heads = members.filter((m) => !m.doc.supersededBy);
950
1844
  if (heads.length < 2)
951
1845
  continue;
952
- const distinct = (vals, cmp4) => vals.every((v) => v !== void 0) && vals.every((v, i) => vals.every((w, j) => i === j || cmp4(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));
953
1847
  const byVersion = distinct(heads.map((h) => h.doc.version), compareVersions);
954
1848
  const byDate = !byVersion && distinct(heads.map((h) => h.doc.date), (a, b) => a < b ? -1 : a > b ? 1 : 0);
955
1849
  if (byVersion || byDate) {
@@ -992,7 +1886,7 @@ async function scanInputs(o) {
992
1886
  for (const f of kept) {
993
1887
  const cls = f.doc.classification;
994
1888
  const current = !f.doc.supersededBy;
995
- const text3 = () => new TextDecoder().decode(f.bytes);
1889
+ const text3 = () => f.text ?? new TextDecoder().decode(f.bytes);
996
1890
  const linked = /* @__PURE__ */ new Set();
997
1891
  const unknown = /* @__PURE__ */ new Set();
998
1892
  if (SPECS.includes(cls)) {
@@ -1106,6 +2000,43 @@ async function scanInputs(o) {
1106
2000
  } catch {
1107
2001
  }
1108
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
+ }
1109
2040
  if (current && cls === "payload" && f.data !== void 0) {
1110
2041
  const schema = readPayload(f.path, boundedId("payload.", f.doc.id.slice(4)), f.data);
1111
2042
  out.push(schema);
@@ -1415,11 +2346,11 @@ function imageItems(records) {
1415
2346
  };
1416
2347
  });
1417
2348
  }
1418
- var key = (action, target, value) => `${action}|${target}|${JSON.stringify(value ?? null)}`;
2349
+ var key2 = (action, target, value) => `${action}|${target}|${JSON.stringify(value ?? null)}`;
1419
2350
  function buildTriage(input) {
1420
2351
  const decisions = (input.decisions ?? []).filter((d) => d.kind === "CuratedDecision" && d.status === "current");
1421
2352
  const decidedIds = new Set(decisions.map((d) => d.id));
1422
- 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)));
1423
2354
  const docs = new Map((input.inputs?.documents ?? []).map((d) => [d.path, d.id]));
1424
2355
  const docIdOf = (path) => docs.get(path) ?? boundedId("doc.", slug(path.split("/").pop().replace(/\.[^.]+$/, "")));
1425
2356
  const records = input.records;
@@ -1432,7 +2363,7 @@ function buildTriage(input) {
1432
2363
  ...imageItems([...records, ...inputRecords]),
1433
2364
  ...readingItems(input)
1434
2365
  ];
1435
- 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))));
1436
2367
  const items = sortItems(open);
1437
2368
  return {
1438
2369
  items,
@@ -1473,9 +2404,9 @@ function buildTriage(input) {
1473
2404
  }
1474
2405
 
1475
2406
  // packages/intake/dist/work-items.js
1476
- var import_yaml4 = __toESM(require_dist(), 1);
1477
- import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
1478
- 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";
1479
2410
  var WORK_ITEM_READER = "work-items@0.1.0";
1480
2411
  var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1481
2412
  var text = (v) => {
@@ -1654,7 +2585,7 @@ function readWorkItemExport(path, bytes) {
1654
2585
  return void 0;
1655
2586
  let data;
1656
2587
  try {
1657
- data = (0, import_yaml4.parse)(content);
2588
+ data = (0, import_yaml5.parse)(content);
1658
2589
  } catch {
1659
2590
  return void 0;
1660
2591
  }
@@ -1677,19 +2608,19 @@ function readWorkItemExport(path, bytes) {
1677
2608
  return items;
1678
2609
  }
1679
2610
  async function readWorkItemExports(o) {
1680
- const dir = o.inputsDir ?? join2(o.root, "inputs");
2611
+ const dir = o.inputsDir ?? join3(o.root, "inputs");
1681
2612
  const files = [];
1682
2613
  async function walk2(d) {
1683
2614
  let entries;
1684
2615
  try {
1685
- entries = await readdir2(d, { withFileTypes: true });
2616
+ entries = await readdir3(d, { withFileTypes: true });
1686
2617
  } catch {
1687
2618
  return;
1688
2619
  }
1689
2620
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1690
2621
  if (e.name.startsWith("."))
1691
2622
  continue;
1692
- const full = join2(d, e.name);
2623
+ const full = join3(d, e.name);
1693
2624
  if (e.isDirectory())
1694
2625
  await walk2(full);
1695
2626
  else if (/\.(json|ya?ml|csv)$/i.test(e.name))
@@ -1706,7 +2637,7 @@ async function readWorkItemExports(o) {
1706
2637
  const path = `inputs/${relative2(dir, full).split(sep2).join("/")}`;
1707
2638
  let bytes;
1708
2639
  try {
1709
- bytes = new Uint8Array(await readFile2(full));
2640
+ bytes = new Uint8Array(await readFile3(full));
1710
2641
  } catch (e) {
1711
2642
  out.problems.push({ path, message: `can't read it: ${e.message}` });
1712
2643
  continue;
@@ -1721,9 +2652,9 @@ async function readWorkItemExports(o) {
1721
2652
  }
1722
2653
 
1723
2654
  // packages/intake/dist/service-requests.js
1724
- var import_yaml5 = __toESM(require_dist(), 1);
1725
- import { readdir as readdir3, readFile as readFile3 } from "node:fs/promises";
1726
- 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";
1727
2658
  var SERVICE_REQUEST_READER = "service-requests@0.1.0";
1728
2659
  var isObj4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1729
2660
  var text2 = (v) => {
@@ -1874,7 +2805,7 @@ function readServiceRequestExport(path, bytes) {
1874
2805
  return void 0;
1875
2806
  let data;
1876
2807
  try {
1877
- data = (0, import_yaml5.parse)(content);
2808
+ data = (0, import_yaml6.parse)(content);
1878
2809
  } catch {
1879
2810
  return void 0;
1880
2811
  }
@@ -1904,19 +2835,19 @@ function readServiceRequestExport(path, bytes) {
1904
2835
  return out;
1905
2836
  }
1906
2837
  async function readServiceRequestExports(o) {
1907
- const dir = o.inputsDir ?? join3(o.root, "inputs");
2838
+ const dir = o.inputsDir ?? join4(o.root, "inputs");
1908
2839
  const found = [];
1909
2840
  async function walk2(d) {
1910
2841
  let entries;
1911
2842
  try {
1912
- entries = await readdir3(d, { withFileTypes: true });
2843
+ entries = await readdir4(d, { withFileTypes: true });
1913
2844
  } catch {
1914
2845
  return;
1915
2846
  }
1916
2847
  for (const e of entries.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
1917
2848
  if (e.name.startsWith("."))
1918
2849
  continue;
1919
- const full = join3(d, e.name);
2850
+ const full = join4(d, e.name);
1920
2851
  if (e.isDirectory())
1921
2852
  await walk2(full);
1922
2853
  else if (/\.(json|ya?ml|csv)$/i.test(e.name))
@@ -1933,7 +2864,7 @@ async function readServiceRequestExports(o) {
1933
2864
  const path = `inputs/${relative3(dir, full).split(sep3).join("/")}`;
1934
2865
  let bytes;
1935
2866
  try {
1936
- bytes = new Uint8Array(await readFile3(full));
2867
+ bytes = new Uint8Array(await readFile4(full));
1937
2868
  } catch (e) {
1938
2869
  out.problems.push({ path, message: `can't read it: ${e.message}` });
1939
2870
  continue;
@@ -1948,15 +2879,15 @@ async function readServiceRequestExports(o) {
1948
2879
  }
1949
2880
 
1950
2881
  // packages/intake/dist/change-inputs.js
1951
- var import_yaml6 = __toESM(require_dist(), 1);
1952
- import { createHash as createHash5 } from "node:crypto";
1953
- import { mkdir, readdir as readdir4, readFile as readFile4 } from "node:fs/promises";
1954
- 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";
1955
2886
  var INPUTS_DIR = "inputs";
1956
2887
  var INPUTS_INDEX = "inputs/index.yaml";
1957
2888
  var INPUTS_READ_DIR = "inputs/read";
1958
2889
  var CHANGE_INPUTS_SCHEMA_VERSION = 1;
1959
- var sha256 = (b) => createHash5("sha256").update(b).digest("hex");
2890
+ var sha256 = (b) => createHash6("sha256").update(b).digest("hex");
1960
2891
  var KEYS = [
1961
2892
  "path",
1962
2893
  "name",
@@ -1976,10 +2907,10 @@ var KEYS = [
1976
2907
  "defences"
1977
2908
  ];
1978
2909
  async function readChangeInputs(dir) {
1979
- const text3 = await readFile4(join4(dir, ...INPUTS_INDEX.split("/")), "utf8").catch(() => "");
2910
+ const text3 = await readFile5(join5(dir, ...INPUTS_INDEX.split("/")), "utf8").catch(() => "");
1980
2911
  let data;
1981
2912
  try {
1982
- data = text3 ? (0, import_yaml6.parse)(text3) : void 0;
2913
+ data = text3 ? (0, import_yaml7.parse)(text3) : void 0;
1983
2914
  } catch {
1984
2915
  data = void 0;
1985
2916
  }
@@ -2000,7 +2931,7 @@ async function writeIndex(dir, index) {
2000
2931
  o[k] = f[k];
2001
2932
  return o;
2002
2933
  });
2003
- 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.
2004
2935
  ${toCanonicalYaml({ schemaVersion: index.schemaVersion, files }, ["schemaVersion", "files"])}`);
2005
2936
  }
2006
2937
  var isText = (b) => {
@@ -2091,7 +3022,7 @@ function readText(input, bytes, older) {
2091
3022
  async function attachToChange(dir, files, o) {
2092
3023
  const index = await readChangeInputs(dir);
2093
3024
  const out = { added: [], refused: [], notes: [] };
2094
- const taken = new Set(await readdir4(join4(dir, INPUTS_DIR)).catch(() => []));
3025
+ const taken = new Set(await readdir5(join5(dir, INPUTS_DIR)).catch(() => []));
2095
3026
  taken.add("index.yaml").add("read");
2096
3027
  const replaced = o.replaces ? index.files.find((x) => x.path === o.replaces.trim().replace(/\\/g, "/")) : void 0;
2097
3028
  let changed = false;
@@ -2178,11 +3109,11 @@ async function attachToChange(dir, files, o) {
2178
3109
  const where = o.elsewhere?.(hash);
2179
3110
  if (where)
2180
3111
  out.notes.push(`${name} is also in the metarepo's inputs as ${where}.`);
2181
- await mkdir(join4(dir, INPUTS_DIR), { recursive: true });
2182
- 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);
2183
3114
  const text3 = readText(input, f.bytes, older);
2184
3115
  if (text3 !== void 0)
2185
- await writeFileAtomic(join4(dir, ...input.readAs.split("/")), text3);
3116
+ await writeFileAtomic(join5(dir, ...input.readAs.split("/")), text3);
2186
3117
  index.files.push(input);
2187
3118
  out.added.push(input);
2188
3119
  }
@@ -2208,7 +3139,7 @@ async function changeInputSources(dir, rel) {
2208
3139
  for (const f of (await readChangeInputs(dir)).files) {
2209
3140
  if (f.supersededBy || f.defences?.risk === "high")
2210
3141
  continue;
2211
- 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;
2212
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}.`;
2213
3144
  out.push({
2214
3145
  id: f.path,
@@ -2237,7 +3168,7 @@ var KIND_ORDER2 = [
2237
3168
  "error-schema",
2238
3169
  "error-removed"
2239
3170
  ];
2240
- var cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
3171
+ var cmp3 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2241
3172
  var opKey = (o) => `${o.method} ${normalizePath(o.fullPath)}`;
2242
3173
  var opName = (o) => `${o.method} ${o.path}`;
2243
3174
  var list = (xs) => xs.length <= 1 ? xs[0] ?? "" : `${xs.slice(0, -1).join(", ")} and ${xs.at(-1)}`;
@@ -2302,7 +3233,7 @@ function diffVendorSpecs(older, newer) {
2302
3233
  });
2303
3234
  for (const [o, n] of pairs)
2304
3235
  out.push(...operationChanges(o, n));
2305
- 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 ?? ""));
2306
3237
  }
2307
3238
  var opOf = (o) => ({
2308
3239
  method: o.method,
@@ -2493,7 +3424,7 @@ function fieldChanges(olds, news, side, at, base) {
2493
3424
 
2494
3425
  // packages/intake/dist/vendor-impact.js
2495
3426
  var MAX_UPSTREAM = 4;
2496
- var cmp2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
3427
+ var cmp4 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2497
3428
  var sorted = (xs) => [...new Set(xs)].sort();
2498
3429
  var joinVendorOf = (input, spec) => ({
2499
3430
  system: input.vendor.system,
@@ -2516,7 +3447,7 @@ var versionOf = (v) => ({
2516
3447
  function vendorImpact(input) {
2517
3448
  const diff = diffVendorSpecs(input.older.spec, input.newer.spec);
2518
3449
  const bundle = input.bundleFolders ? { bundleFolders: input.bundleFolders } : {};
2519
- const join6 = joinFacts({
3450
+ const join7 = joinFacts({
2520
3451
  repos: input.repos,
2521
3452
  ...input.targets ? { targets: input.targets } : {},
2522
3453
  ...input.facing ? { facing: input.facing } : {},
@@ -2556,8 +3487,8 @@ function vendorImpact(input) {
2556
3487
  const f = facts.get(k(call))?.fact;
2557
3488
  return f?.kind === "call" && f.from ? endOf(call.repo, f.from) : void 0;
2558
3489
  };
2559
- const hops = new Set(join6.joins.flatMap((j) => (j.gateway ?? []).map((h) => k(h.call))));
2560
- const joins = join6.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)));
2561
3492
  const via = (j) => j.gateway?.length ? { via: j.gateway.map((h) => h.route) } : {};
2562
3493
  const upstreamOf = (start) => {
2563
3494
  const out = [];
@@ -2586,422 +3517,121 @@ function vendorImpact(input) {
2586
3517
  }
2587
3518
  return out;
2588
3519
  };
2589
- const fieldUse = (call, change) => {
2590
- if (!change.side || !change.field || change.status)
2591
- return void 0;
2592
- const side = change.side;
2593
- 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));
2594
- if (!mine.length)
2595
- return void 0;
2596
- const want = fieldNameKey(change.field);
2597
- const hit = mine.find((f) => fieldNameKey(f.name) === want);
2598
- const req = side === "request";
2599
- return hit ? { uses: req ? "sends" : "reads", at: `${hit.cite.file}:${hit.cite.line}` } : { uses: req ? "does-not-send" : "does-not-read" };
2600
- };
2601
- const changes = diff.map((c) => {
2602
- const older = c.endpoints.older;
2603
- const matches = older ? today.matches.filter((m) => m.operation === older) : next.matches.filter((m) => m.operation === c.endpoints.newer);
2604
- const forwards = matches.map((m) => {
2605
- if (m.direct) {
2606
- const f = facts.get(k(m.call))?.fact;
2607
- const field2 = fieldUse(m.call, c);
2608
- const self = {
2609
- call: m.call,
2610
- interface: interfaceId(m.call.component, factIdPart(f?.to ?? input.vendor.system), m.method, m.path),
2611
- ...field2 ? { field: field2 } : {},
2612
- ...m.route ? { under: m.route } : {},
2613
- upstream: upstreamOf(m.route)
2614
- };
2615
- return {
2616
- call: m.call,
2617
- ...m.route ? { route: m.route } : {},
2618
- operation: m.operation,
2619
- direct: true,
2620
- callers: [self]
2621
- };
2622
- }
2623
- 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) => {
2624
- const u = under(j.call);
2625
- const field2 = fieldUse(j.call, c);
2626
- return {
2627
- call: j.call,
2628
- interface: j.interface,
2629
- ...via(j),
2630
- ...field2 ? { field: field2 } : {},
2631
- ...u ? { under: u } : {},
2632
- upstream: upstreamOf(u)
2633
- };
2634
- }) : [];
2635
- return {
2636
- call: m.call,
2637
- ...m.route ? { route: m.route } : {},
2638
- ...m.tie ? { tie: m.tie } : {},
2639
- operation: m.operation,
2640
- callers
2641
- };
2642
- });
2643
- return { id: c.id, severity: c.severity, says: c.says, forwards };
2644
- });
2645
- const repos = /* @__PURE__ */ new Set();
2646
- const interfaces = /* @__PURE__ */ new Set();
2647
- const endpoints = /* @__PURE__ */ new Set();
2648
- const entries = /* @__PURE__ */ new Set();
2649
- for (const c of changes)
2650
- for (const f of c.forwards) {
2651
- repos.add(f.call.repo);
2652
- endpoints.add(f.operation);
2653
- for (const s of f.callers) {
2654
- repos.add(s.call.repo);
2655
- interfaces.add(s.interface);
2656
- if (s.under)
2657
- entries.add(k(s.under));
2658
- for (const u of s.upstream) {
2659
- repos.add(u.call.repo);
2660
- interfaces.add(u.interface);
2661
- entries.add(k(u.reaches));
2662
- if (u.under)
2663
- entries.add(k(u.under));
2664
- }
2665
- }
2666
- }
2667
- const endpointIds = /* @__PURE__ */ new Set();
2668
- for (const e of entries) {
2669
- const got = facts.get(e);
2670
- if (got?.fact.kind === "entry")
2671
- endpointIds.add(entryEndpointId(got.fact, componentOf(got.repo, got.fact)));
2672
- }
2673
- 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));
2674
- for (const f of flows)
2675
- repos.add(f.repo);
2676
- const systems = /* @__PURE__ */ new Set([input.vendor.system]);
2677
- for (const r of repos) {
2678
- const s = input.systemOfRepo?.[r];
2679
- if (s)
2680
- systems.add(s);
2681
- }
2682
- return {
2683
- diff,
2684
- impact: {
2685
- vendor: input.vendor.system,
2686
- older: versionOf(input.older),
2687
- newer: versionOf(input.newer),
2688
- changes,
2689
- repos: sorted(repos),
2690
- systems: sorted(systems),
2691
- flows,
2692
- interfaces: sorted(interfaces),
2693
- endpoints: sorted(endpoints),
2694
- gaps: today.gaps,
2695
- asks: today.asks
2696
- }
2697
- };
2698
- }
2699
-
2700
- // packages/intake/dist/contract-files.js
2701
- var import_yaml7 = __toESM(require_dist(), 1);
2702
- import { readdir as readdir5, readFile as readFile5, stat as stat2 } from "node:fs/promises";
2703
- import { join as join5 } from "node:path";
2704
-
2705
- // packages/intake/dist/traffic.js
2706
- import { createHash as createHash6 } from "node:crypto";
2707
- var cmp3 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
2708
- var key2 = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
2709
- var sha = (s) => createHash6("sha256").update(s, "utf8").digest("hex");
2710
- var IPV4 = /\b\d{1,3}(?:\.\d{1,3}){3}\b/;
2711
- 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;
2712
- var EMAIL = /[^\s@/]+@[^\s@/]+/;
2713
- var JWT = /\beyJ[A-Za-z0-9_-]{6,}/;
2714
- var OPAQUE = /\b(?=[A-Za-z0-9+_-]*\d)(?=[A-Za-z0-9+_-]*[A-Za-z])[A-Za-z0-9+_-]{24,}={0,2}/;
2715
- 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;
2716
- var HEX = /\b[0-9a-f]{16,}\b/i;
2717
- function looksSensitive(v) {
2718
- return [IPV4, IPV6, EMAIL, JWT, OPAQUE, UUID, HEX].some((re) => re.test(v));
2719
- }
2720
- function rowsOf(text3) {
2721
- const t = text3.replace(/^\uFEFF/, "").trim();
2722
- if (!t)
2723
- return void 0;
2724
- if (t.startsWith("[") || t.startsWith("{")) {
2725
- let v;
2726
- try {
2727
- v = JSON.parse(t);
2728
- } catch {
2729
- return void 0;
2730
- }
2731
- 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;
2732
- if (!Array.isArray(list2) || !list2.length)
2733
- return void 0;
2734
- const out = [];
2735
- for (const r of list2) {
2736
- if (!r || typeof r !== "object" || Array.isArray(r))
2737
- return void 0;
2738
- const row = {};
2739
- for (const [k, x] of Object.entries(r))
2740
- if (typeof x === "string" || typeof x === "number")
2741
- row[k] = String(x);
2742
- out.push(row);
2743
- }
2744
- return out;
2745
- }
2746
- const recs = parseCsv(t);
2747
- if (recs.length < 2)
2748
- return void 0;
2749
- const head = recs[0].cells.map((c) => c.trim());
2750
- if (head.length < 2)
2751
- return void 0;
2752
- return recs.slice(1).map((r) => {
2753
- const row = {};
2754
- head.forEach((h, i) => row[h] = (r.cells[i] ?? "").trim());
2755
- return row;
2756
- });
2757
- }
2758
- function dayOf(v) {
2759
- const m = /^(\d{4}-\d{2}-\d{2})/.exec(v.trim());
2760
- if (m)
2761
- return m[1];
2762
- if (/^\d{12,13}$/.test(v.trim()))
2763
- return new Date(Number(v)).toISOString().slice(0, 10);
2764
- return void 0;
2765
- }
2766
- var VERSION2 = /^v\d+(?:\.\d+)*$/i;
2767
- 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}>)$/;
2768
- var segmentOf = (s) => VERSION2.test(s) || PARAM.test(s) || /^[a-z][a-z._-]*$/.test(s) && s.length <= 20 && /[aeiou]/.test(s) && !looksSensitive(s) ? s : "{id}";
2769
- function barePath(path) {
2770
- let p = path.trim().split(/[?#]/, 1)[0] ?? "";
2771
- p = p.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]*/i, "");
2772
- return p.replace(/;[^/]*/g, "");
2773
- }
2774
- function safePathOf(path) {
2775
- const p = barePath(path);
2776
- if (!p.startsWith("/"))
2777
- return void 0;
2778
- return `/${p.split("/").filter(Boolean).map(segmentOf).join("/")}`;
2779
- }
2780
- var MATCH = 100;
2781
- function pathTemplateOf(path, templates) {
2782
- const p = barePath(path);
2783
- if (!p.startsWith("/"))
2784
- return void 0;
2785
- const sorted2 = [...templates].sort();
2786
- let best;
2787
- let score = 0;
2788
- for (const t of sorted2) {
2789
- const s = routeScore(p, t);
2790
- if (s > MATCH && s > score) {
2791
- score = s;
2792
- best = t;
2793
- }
2794
- }
2795
- if (best)
2796
- return best;
2797
- const segs = p.split("/").filter(Boolean);
2798
- let prefix;
2799
- let len = 0;
2800
- score = 0;
2801
- for (const t of sorted2) {
2802
- const n = t.split("/").filter(Boolean).length;
2803
- if (n === 0 || n >= segs.length || n < len)
2804
- continue;
2805
- const s = routeScore(`/${segs.slice(0, n).join("/")}`, t);
2806
- if (s <= MATCH)
2807
- continue;
2808
- if (n > len || s > score) {
2809
- len = n;
2810
- score = s;
2811
- prefix = t;
2812
- }
2813
- }
2814
- return prefix ? `${prefix.replace(/\/+$/, "")}/**` : void 0;
2815
- }
2816
- var appLabelOf = (name) => `app-${sha(name).slice(0, 8)}`;
2817
- function denyListHits(text3, hashes) {
2818
- const hits = [];
2819
- text3.toLowerCase().split("\n").forEach((line, i) => {
2820
- const w = line.match(/[a-z0-9]+/g) ?? [];
2821
- for (let k = 0; k < w.length; k++)
2822
- if (hashes.has(sha(w[k])) || k + 1 < w.length && hashes.has(sha(`${w[k]} ${w[k + 1]}`))) {
2823
- hits.push(i + 1);
2824
- break;
2825
- }
2826
- });
2827
- return hits;
2828
- }
2829
- function aggregateTraffic(input) {
2830
- const text3 = Buffer.from(input.bytes).toString("utf8");
2831
- const rows = rowsOf(text3);
2832
- 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("/")})`;
2833
- if (!rows)
2834
- return { ok: false, message: `The file doesn't read as a traffic export: give ${shape}.` };
2835
- const names = [...new Set(rows.flatMap((r) => Object.keys(r)))];
2836
- const col = (aliases) => {
2837
- for (const a of aliases) {
2838
- const hit = names.find((n) => key2(n) === key2(a));
2839
- if (hit)
2840
- return hit;
2841
- }
2842
- return void 0;
2843
- };
2844
- const c = {
2845
- app: col(input.columns.app),
2846
- method: col(input.columns.method),
2847
- basepath: col(input.columns.basepath),
2848
- suffix: col(input.columns.suffix),
2849
- proxy: col(input.columns.proxy),
2850
- count: col(input.columns.count),
2851
- time: col(input.columns.time),
2852
- path: void 0
3520
+ const fieldUse = (call, change) => {
3521
+ if (!change.side || !change.field || change.status)
3522
+ return void 0;
3523
+ const side = change.side;
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));
3525
+ if (!mine.length)
3526
+ return void 0;
3527
+ const want = fieldNameKey(change.field);
3528
+ const hit = mine.find((f) => fieldNameKey(f.name) === want);
3529
+ const req = side === "request";
3530
+ return hit ? { uses: req ? "sends" : "reads", at: `${hit.cite.file}:${hit.cite.line}` } : { uses: req ? "does-not-send" : "does-not-read" };
2853
3531
  };
2854
- if (!c.basepath || !c.suffix)
2855
- c.path = col(input.columns.path);
2856
- const missing = [
2857
- !c.app ? "app" : "",
2858
- !c.method ? "method" : "",
2859
- !c.path && !(c.basepath && c.suffix) ? "path" : ""
2860
- ].filter(Boolean);
2861
- if (missing.length)
2862
- return {
2863
- ok: false,
2864
- message: `The file has no ${missing.join(", ")} column, so it can't be kept as aggregates: give ${shape}.`
2865
- };
2866
- const range = (v) => v && /^\d{4}-\d{2}-\d{2}$/.test(v) ? v : void 0;
2867
- if (input.from && !range(input.from) || input.to && !range(input.to))
2868
- return { ok: false, message: "--from and --to are days: YYYY-MM-DD." };
2869
- if ((!input.from || !input.to) && !c.time)
2870
- return {
2871
- ok: false,
2872
- message: "The export has no date column: give --from and --to (YYYY-MM-DD) for the range it covers."
2873
- };
2874
- const kept = new Set(Object.values(c).filter((x) => !!x));
2875
- const dropped = names.filter((n) => !kept.has(n)).sort();
2876
- const secrets = /* @__PURE__ */ new Set();
2877
- const keptValues = /* @__PURE__ */ new Set();
2878
- const agg = /* @__PURE__ */ new Map();
2879
- let outOfRange = 0;
2880
- let skipped = 0;
2881
- let unmatched = 0;
2882
- const known = /* @__PURE__ */ new Map();
2883
- for (const a of input.apps ?? [])
2884
- if (a.trim() && !known.has(key2(a)))
2885
- known.set(key2(a), a.trim());
2886
- const days = [];
2887
- for (const r of rows) {
2888
- for (const n of dropped) {
2889
- const v = (r[n] ?? "").trim();
2890
- const q = /^(?:[a-z][a-z0-9+.-]*:\/\/|\/)/i.test(v) ? v.split(/[?#]/)[1] ?? "" : v;
2891
- if (q.length >= 6)
2892
- secrets.add(q);
2893
- }
2894
- for (const n of [c.path, c.suffix, c.basepath]) {
2895
- const v = n ? r[n] ?? "" : "";
2896
- const q = v.split(/[?#]/)[1] ?? "";
2897
- if (q.length >= 4)
2898
- secrets.add(q);
2899
- for (const m of (v.split(/[?#]/, 1)[0] ?? "").match(/;[^/]*/g) ?? [])
2900
- if (m.length >= 5)
2901
- secrets.add(m.slice(1));
2902
- }
2903
- if (c.time) {
2904
- const d = dayOf(r[c.time] ?? "");
2905
- if (d) {
2906
- if (input.from && d < input.from || input.to && d > input.to) {
2907
- outOfRange++;
2908
- continue;
3532
+ const changes = diff.map((c) => {
3533
+ const older = c.endpoints.older;
3534
+ const matches = older ? today.matches.filter((m) => m.operation === older) : next.matches.filter((m) => m.operation === c.endpoints.newer);
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
+ }
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) => {
3555
+ const u = under(j.call);
3556
+ const field2 = fieldUse(j.call, c);
3557
+ return {
3558
+ call: j.call,
3559
+ interface: j.interface,
3560
+ ...via(j),
3561
+ ...field2 ? { field: field2 } : {},
3562
+ ...u ? { under: u } : {},
3563
+ upstream: upstreamOf(u)
3564
+ };
3565
+ }) : [];
3566
+ return {
3567
+ call: m.call,
3568
+ ...m.route ? { route: m.route } : {},
3569
+ ...m.tie ? { tie: m.tie } : {},
3570
+ operation: m.operation,
3571
+ callers
3572
+ };
3573
+ });
3574
+ return { id: c.id, severity: c.severity, says: c.says, forwards };
3575
+ });
3576
+ const repos = /* @__PURE__ */ new Set();
3577
+ const interfaces = /* @__PURE__ */ new Set();
3578
+ const endpoints = /* @__PURE__ */ new Set();
3579
+ const entries = /* @__PURE__ */ new Set();
3580
+ for (const c of changes)
3581
+ for (const f of c.forwards) {
3582
+ repos.add(f.call.repo);
3583
+ endpoints.add(f.operation);
3584
+ for (const s of f.callers) {
3585
+ repos.add(s.call.repo);
3586
+ interfaces.add(s.interface);
3587
+ if (s.under)
3588
+ entries.add(k(s.under));
3589
+ for (const u of s.upstream) {
3590
+ repos.add(u.call.repo);
3591
+ interfaces.add(u.interface);
3592
+ entries.add(k(u.reaches));
3593
+ if (u.under)
3594
+ entries.add(k(u.under));
2909
3595
  }
2910
- days.push(d);
2911
- } else if (!input.from || !input.to) {
2912
- skipped++;
2913
- continue;
2914
3596
  }
2915
3597
  }
2916
- const method = (r[c.method] ?? "").trim().toUpperCase();
2917
- const rawPath = c.path ? r[c.path] ?? "" : `${(r[c.basepath] ?? "").replace(/\/+$/, "")}/${(r[c.suffix] ?? "").replace(/^\/+/, "")}`;
2918
- const countText = c.count ? (r[c.count] ?? "").trim() : "1";
2919
- const count = Number(countText);
2920
- if (!/^[A-Z]{3,10}$/.test(method) || !barePath(rawPath).startsWith("/") || !Number.isInteger(count) || count < 0) {
2921
- skipped++;
2922
- continue;
2923
- }
2924
- const path = pathTemplateOf(rawPath, input.templates);
2925
- if (!path) {
2926
- unmatched++;
2927
- continue;
2928
- }
2929
- if (count === 0)
2930
- continue;
2931
- const appRaw = (r[c.app] ?? "").trim();
2932
- const app = !appRaw ? "(none)" : known.get(key2(appRaw)) ?? appLabelOf(appRaw);
2933
- const proxyRaw = c.proxy ? (r[c.proxy] ?? "").trim() : "";
2934
- const proxy = proxyRaw && !looksSensitive(proxyRaw) ? proxyRaw : void 0;
2935
- const baseRaw = c.basepath ? (r[c.basepath] ?? "").trim() : "";
2936
- const basepath = baseRaw ? safePathOf(baseRaw) : void 0;
2937
- for (const v of [app, proxy, basepath, path])
2938
- if (v)
2939
- keptValues.add(v);
2940
- const k = [app, method, path, proxy ?? "", basepath ?? ""].join("\0");
2941
- const row = agg.get(k) ?? {
2942
- app,
2943
- method,
2944
- path,
2945
- ...proxy ? { proxy } : {},
2946
- ...basepath ? { basepath } : {},
2947
- count: 0
2948
- };
2949
- row.count += count;
2950
- agg.set(k, row);
3598
+ const endpointIds = /* @__PURE__ */ new Set();
3599
+ for (const e of entries) {
3600
+ const got = facts.get(e);
3601
+ if (got?.fact.kind === "entry")
3602
+ endpointIds.add(entryEndpointId(got.fact, componentOf(got.repo, got.fact)));
3603
+ }
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));
3605
+ for (const f of flows)
3606
+ repos.add(f.repo);
3607
+ const systems = /* @__PURE__ */ new Set([input.vendor.system]);
3608
+ for (const r of repos) {
3609
+ const s = input.systemOfRepo?.[r];
3610
+ if (s)
3611
+ systems.add(s);
2951
3612
  }
2952
- if (!agg.size)
2953
- return {
2954
- ok: false,
2955
- message: `No row of the file is a request in the range to a route of the estate (${rows.length} read, ${outOfRange} outside it, ${skipped} without a method, path or count, ${unmatched} matching no route template of the estate): nothing to keep.`
2956
- };
2957
- days.sort();
2958
- const from = input.from ?? days[0];
2959
- const to = input.to ?? days[days.length - 1];
2960
- if (!from || !to)
2961
- return { ok: false, message: "The rows carry no dates: give --from and --to (YYYY-MM-DD)." };
2962
- const parsed = TrafficFile.safeParse({
2963
- schemaVersion: 1,
2964
- source: input.source,
2965
- from,
2966
- to,
2967
- inputSha256: createHash6("sha256").update(input.bytes).digest("hex"),
2968
- rows: [...agg.values()].sort((a, b) => cmp3(a.app, b.app) || cmp3(a.proxy ?? "", b.proxy ?? "") || cmp3(a.path, b.path) || cmp3(a.method, b.method))
2969
- });
2970
- if (!parsed.success)
2971
- return { ok: false, message: `The aggregate isn't valid: ${parsed.error.issues[0]?.message}.` };
2972
- const out = trafficFileText(parsed.data);
2973
- const lower = out.toLowerCase();
2974
- const leaked = [...secrets].filter((s) => !keptValues.has(s) && lower.includes(s.toLowerCase()));
2975
- if (leaked.length)
2976
- return {
2977
- ok: false,
2978
- message: `Refused: ${leaked.length} value${leaked.length === 1 ? "" : "s"} of the export's dropped columns would be written. Nothing was written.`
2979
- };
2980
- const body = out.replace(/^inputSha256: .*$/m, "");
2981
- if ([IPV4, IPV6, EMAIL, JWT, OPAQUE, UUID, HEX].some((re) => re.test(body)))
2982
- return {
2983
- ok: false,
2984
- message: "Refused: the aggregate would hold an IP, an email or a token-looking value. Nothing was written."
2985
- };
2986
- const hits = input.denyHashes?.size ? denyListHits(out, input.denyHashes) : [];
2987
- if (hits.length)
2988
- return {
2989
- ok: false,
2990
- message: `Refused: the deny-list names a word on line${hits.length === 1 ? "" : "s"} ${hits.join(", ")} of the aggregate. Nothing was written.`
2991
- };
2992
3613
  return {
2993
- ok: true,
2994
- file: parsed.data,
2995
- text: out,
2996
- read: rows.length,
2997
- outOfRange,
2998
- skipped,
2999
- unmatched,
3000
- dropped
3614
+ diff,
3615
+ impact: {
3616
+ vendor: input.vendor.system,
3617
+ older: versionOf(input.older),
3618
+ newer: versionOf(input.newer),
3619
+ changes,
3620
+ repos: sorted(repos),
3621
+ systems: sorted(systems),
3622
+ flows,
3623
+ interfaces: sorted(interfaces),
3624
+ endpoints: sorted(endpoints),
3625
+ gaps: today.gaps,
3626
+ asks: today.asks
3627
+ }
3001
3628
  };
3002
3629
  }
3003
3630
 
3004
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";
3005
3635
  function safeServerUrl(url) {
3006
3636
  const m = /^([a-z][a-z0-9+.-]*:\/\/)([^/?#]*)(.*)$/i.exec(url.trim());
3007
3637
  if (!m) {
@@ -3020,28 +3650,28 @@ var str2 = (m, key3) => {
3020
3650
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
3021
3651
  };
3022
3652
  var mapAt = (m, key3) => {
3023
- const v = (0, import_yaml7.isMap)(m) ? m.get(key3, true) : void 0;
3024
- return (0, import_yaml7.isMap)(v) ? v : void 0;
3653
+ const v = (0, import_yaml8.isMap)(m) ? m.get(key3, true) : void 0;
3654
+ return (0, import_yaml8.isMap)(v) ? v : void 0;
3025
3655
  };
3026
3656
  function readPactFile(text3, file) {
3027
- const lc = new import_yaml7.LineCounter();
3657
+ const lc = new import_yaml8.LineCounter();
3028
3658
  let doc;
3029
3659
  try {
3030
- doc = (0, import_yaml7.parseDocument)(text3, { lineCounter: lc });
3660
+ doc = (0, import_yaml8.parseDocument)(text3, { lineCounter: lc });
3031
3661
  } catch {
3032
3662
  return void 0;
3033
3663
  }
3034
- if (doc.errors.length || !(0, import_yaml7.isMap)(doc.contents))
3664
+ if (doc.errors.length || !(0, import_yaml8.isMap)(doc.contents))
3035
3665
  return void 0;
3036
3666
  const root = doc.contents;
3037
3667
  const consumer = str2(mapAt(root, "consumer"), "name");
3038
3668
  const provider = str2(mapAt(root, "provider"), "name");
3039
3669
  const list2 = root.get("interactions", true);
3040
- if (!consumer || !provider || !(0, import_yaml7.isSeq)(list2))
3670
+ if (!consumer || !provider || !(0, import_yaml8.isSeq)(list2))
3041
3671
  return void 0;
3042
3672
  const out = [];
3043
3673
  for (const it of list2.items) {
3044
- if (!(0, import_yaml7.isMap)(it))
3674
+ if (!(0, import_yaml8.isMap)(it))
3045
3675
  continue;
3046
3676
  const type = str2(it, "type");
3047
3677
  if (type && !/http/i.test(type))
@@ -3050,8 +3680,8 @@ function readPactFile(text3, file) {
3050
3680
  if (!req)
3051
3681
  continue;
3052
3682
  const method = str2(req, "method");
3053
- const pair = req.items.find((p) => (0, import_yaml7.isScalar)(p.key) && p.key.value === "path");
3054
- const path = pair && (0, import_yaml7.isScalar)(pair.value) ? String(pair.value.value) : void 0;
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;
3055
3685
  const safe = path?.startsWith("/") ? safePathOf(path) : void 0;
3056
3686
  if (!safe)
3057
3687
  continue;
@@ -3098,7 +3728,7 @@ function readConsumerOpenApi(text3, file, own) {
3098
3728
  ] : [];
3099
3729
  });
3100
3730
  }
3101
- var SKIP = /* @__PURE__ */ new Set([
3731
+ var SKIP2 = /* @__PURE__ */ new Set([
3102
3732
  ".git",
3103
3733
  "node_modules",
3104
3734
  "vendor",
@@ -3113,19 +3743,19 @@ var SKIP = /* @__PURE__ */ new Set([
3113
3743
  ".idea",
3114
3744
  ".atticus"
3115
3745
  ]);
3116
- var MAX_BYTES = 5 * 1024 * 1024;
3746
+ var MAX_BYTES2 = 5 * 1024 * 1024;
3117
3747
  var PACT = /pact/i;
3118
3748
  var SPEC = /(openapi|swagger)/i;
3119
3749
  async function readContractFiles(dir, o) {
3120
3750
  const files = [];
3121
3751
  const walk2 = async (rel) => {
3122
- const entries2 = await readdir5(join5(dir, ...rel.split("/").filter(Boolean)), {
3752
+ const entries2 = await readdir6(join6(dir, ...rel.split("/").filter(Boolean)), {
3123
3753
  withFileTypes: true
3124
3754
  }).catch(() => []);
3125
3755
  for (const e of [...entries2].sort((a, b) => a.name < b.name ? -1 : 1)) {
3126
3756
  const p = rel ? `${rel}/${e.name}` : e.name;
3127
3757
  if (e.isDirectory()) {
3128
- if (!SKIP.has(e.name))
3758
+ if (!SKIP2.has(e.name))
3129
3759
  await walk2(p);
3130
3760
  } else if (e.isFile()) {
3131
3761
  if (/\.json$/i.test(e.name) && PACT.test(p))
@@ -3138,11 +3768,11 @@ async function readContractFiles(dir, o) {
3138
3768
  await walk2("");
3139
3769
  const entries = [];
3140
3770
  for (const p of files) {
3141
- const full = join5(dir, ...p.split("/"));
3142
- const size = (await stat2(full).catch(() => void 0))?.size ?? 0;
3143
- if (size === 0 || size > MAX_BYTES)
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)
3144
3774
  continue;
3145
- const text3 = await readFile5(full, "utf8");
3775
+ const text3 = await readFile6(full, "utf8");
3146
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);
3147
3777
  if (!got?.length)
3148
3778
  continue;
@@ -3165,6 +3795,7 @@ async function readContractFiles(dir, o) {
3165
3795
  }
3166
3796
 
3167
3797
  export {
3798
+ joinServerVariables,
3168
3799
  classify,
3169
3800
  READERS,
3170
3801
  readOpenApiSpec,
@@ -3177,9 +3808,24 @@ export {
3177
3808
  sortItems,
3178
3809
  opt,
3179
3810
  screenFile,
3811
+ looksSensitive,
3812
+ segmentOf,
3813
+ safePathOf,
3814
+ pathTemplateOf,
3815
+ appLabelOf,
3816
+ denyListHits,
3817
+ aggregateTraffic,
3180
3818
  specEndpointIds,
3181
3819
  readVendorSpec,
3182
3820
  operationSchemas,
3821
+ readProtoSpecs,
3822
+ readAvroSpecs,
3823
+ readJsonSchemaSpecs,
3824
+ readAsyncApiSpecs,
3825
+ openApiContractSpecs,
3826
+ specFormatOf,
3827
+ readContractSpecs,
3828
+ readRepoSpecs,
3183
3829
  nameParts,
3184
3830
  compareVersions,
3185
3831
  scanInputs,
@@ -3203,13 +3849,6 @@ export {
3203
3849
  diffVendorSpecs,
3204
3850
  MAX_UPSTREAM,
3205
3851
  vendorImpact,
3206
- looksSensitive,
3207
- segmentOf,
3208
- safePathOf,
3209
- pathTemplateOf,
3210
- appLabelOf,
3211
- denyListHits,
3212
- aggregateTraffic,
3213
3852
  safeServerUrl,
3214
3853
  readPactFile,
3215
3854
  readConsumerOpenApi,