@hawkeyexl/manni 4.11.0 → 4.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/README.md +1 -1
  2. package/dist/{batch-UAULUMGH.js → batch-KMGZMIAQ.js} +20 -19
  3. package/dist/build-NO4AWCYG.js +36 -0
  4. package/dist/calibrate-XQUG5XAK.js +41 -0
  5. package/dist/capture-5XE3ZMXK.js +38 -0
  6. package/dist/{check-YEOYBFST.js → check-HTNPLWOV.js} +19 -18
  7. package/dist/check-RJ45IBA6.js +34 -0
  8. package/dist/{check-VELUQAUW.js → check-W24BQNCT.js} +35 -34
  9. package/dist/{check-VELUQAUW.js.map → check-W24BQNCT.js.map} +1 -1
  10. package/dist/check-WFXSXICD.js +30 -0
  11. package/dist/{chunk-IGSHYP74.js → chunk-23P7KMJM.js} +4 -4
  12. package/dist/{chunk-HA6MQMOY.js → chunk-24J7TYPU.js} +6 -6
  13. package/dist/{chunk-PCS4VJBV.js → chunk-37QJLVS3.js} +9 -9
  14. package/dist/{chunk-4CK6ZSOK.js → chunk-3P6KCU36.js} +3 -3
  15. package/dist/{chunk-54F74XR3.js → chunk-5JBVFWVP.js} +19 -19
  16. package/dist/{chunk-B7XYNRJQ.js → chunk-6KIYVVKL.js} +2 -2
  17. package/dist/{chunk-J6IDQGJL.js → chunk-6TVH4FI7.js} +469 -85
  18. package/dist/chunk-6TVH4FI7.js.map +1 -0
  19. package/dist/{chunk-GDVZ5VII.js → chunk-7A452BPZ.js} +4 -4
  20. package/dist/{chunk-M42DZCOU.js → chunk-7FCLXEAQ.js} +2 -2
  21. package/dist/{chunk-2MJ62AYQ.js → chunk-7MCQHTQ5.js} +4 -3
  22. package/dist/chunk-7MCQHTQ5.js.map +1 -0
  23. package/dist/{chunk-LBSCW232.js → chunk-7NXPQKSB.js} +7 -7
  24. package/dist/{chunk-OPXWPJDA.js → chunk-A3TEDWBZ.js} +14 -14
  25. package/dist/{chunk-BBT6AVUG.js → chunk-BHHXU2D2.js} +2 -2
  26. package/dist/{chunk-D4N2V43Z.js → chunk-CEI2J42X.js} +13 -7
  27. package/dist/chunk-CEI2J42X.js.map +1 -0
  28. package/dist/{chunk-FQXWVS6J.js → chunk-CMMBWHT2.js} +9 -9
  29. package/dist/{chunk-EIFCP6CZ.js → chunk-CO47QJKZ.js} +2 -2
  30. package/dist/{chunk-2DRHT73U.js → chunk-CVZMKWZ5.js} +913 -1398
  31. package/dist/chunk-CVZMKWZ5.js.map +1 -0
  32. package/dist/{chunk-ADMEPUBT.js → chunk-CXWTNT2O.js} +3 -3
  33. package/dist/{chunk-LKP7QDFN.js → chunk-DAQTRAP5.js} +4 -4
  34. package/dist/chunk-DSWKBZWW.js +16 -0
  35. package/dist/chunk-DSWKBZWW.js.map +1 -0
  36. package/dist/{chunk-PWBH7DCQ.js → chunk-EESH6COU.js} +4 -4
  37. package/dist/{chunk-JPQDNYXH.js → chunk-EM67O2ET.js} +8 -2
  38. package/dist/chunk-EM67O2ET.js.map +1 -0
  39. package/dist/{chunk-HQR2ZBHW.js → chunk-I2XQRRP7.js} +36 -7
  40. package/dist/chunk-I2XQRRP7.js.map +1 -0
  41. package/dist/{chunk-NCPWXHDO.js → chunk-JEUFYSFQ.js} +4 -4
  42. package/dist/{chunk-2IR4T5PO.js → chunk-JJ4RSDSY.js} +2 -2
  43. package/dist/chunk-KCB5JCK4.js +2272 -0
  44. package/dist/chunk-KCB5JCK4.js.map +1 -0
  45. package/dist/{chunk-VSEBFHAY.js → chunk-KFKL4VTL.js} +11369 -10218
  46. package/dist/chunk-KFKL4VTL.js.map +1 -0
  47. package/dist/{chunk-PCQ7ELJH.js → chunk-L2TD7DZB.js} +109 -5
  48. package/dist/chunk-L2TD7DZB.js.map +1 -0
  49. package/dist/{chunk-WDWXAYVH.js → chunk-L3RLGGRK.js} +4 -4
  50. package/dist/{chunk-T7JAOYE5.js → chunk-L75CAZG4.js} +6 -6
  51. package/dist/{chunk-U7CTFN2J.js → chunk-MYRPMSOX.js} +7 -7
  52. package/dist/{chunk-Y6DOMTQD.js → chunk-NCF5NQV5.js} +27 -27
  53. package/dist/chunk-NCF5NQV5.js.map +1 -0
  54. package/dist/{chunk-WQWKYAAK.js → chunk-NUQF5F5J.js} +2 -2
  55. package/dist/{chunk-FUCPZVRY.js → chunk-OEN6FBUW.js} +2 -2
  56. package/dist/{chunk-FBMZJEB3.js → chunk-OKMTUAWO.js} +4 -4
  57. package/dist/{chunk-QLWC7MKD.js → chunk-OTJOBZJ5.js} +135 -135
  58. package/dist/chunk-OTJOBZJ5.js.map +1 -0
  59. package/dist/{chunk-R4WXQIOZ.js → chunk-PCEM5FOZ.js} +3 -3
  60. package/dist/{chunk-4D5IZSXM.js → chunk-PXNCRGUL.js} +3 -3
  61. package/dist/chunk-Q2QC5AZB.js +1868 -0
  62. package/dist/chunk-Q2QC5AZB.js.map +1 -0
  63. package/dist/{chunk-ODRPL3WB.js → chunk-Q3ODX5PF.js} +2 -2
  64. package/dist/{chunk-KGEQJ5CC.js → chunk-RRFFUWDL.js} +8 -8
  65. package/dist/{chunk-NSBXVPZL.js → chunk-S3XUYW5K.js} +17 -17
  66. package/dist/{chunk-LPIF5LIE.js → chunk-SAU2WQFC.js} +2 -2
  67. package/dist/{chunk-MSRU4D4P.js → chunk-SFLICIQV.js} +2 -2
  68. package/dist/{chunk-NGTVREIH.js → chunk-U6IHLEWT.js} +2 -2
  69. package/dist/{chunk-QCHVR4ZM.js → chunk-VM7VAFJW.js} +33 -7
  70. package/dist/chunk-VM7VAFJW.js.map +1 -0
  71. package/dist/{chunk-6HWBRZIN.js → chunk-VQYGLU4C.js} +252 -193
  72. package/dist/chunk-VQYGLU4C.js.map +1 -0
  73. package/dist/{chunk-2IAZEB45.js → chunk-WGMFDG6U.js} +229 -821
  74. package/dist/chunk-WGMFDG6U.js.map +1 -0
  75. package/dist/{chunk-GV56WGL2.js → chunk-WO4JYWZK.js} +1036 -883
  76. package/dist/chunk-WO4JYWZK.js.map +1 -0
  77. package/dist/chunk-XYRUDFKS.js +685 -0
  78. package/dist/chunk-XYRUDFKS.js.map +1 -0
  79. package/dist/{chunk-VQK4VHLF.js → chunk-YQV75FIL.js} +2 -2
  80. package/dist/chunk-YUTVAMWW.js +2 -0
  81. package/dist/{chunk-RLT5SEML.js → chunk-Z5MZCCTT.js} +6 -6
  82. package/dist/{chunk-BKVHX6FU.js → chunk-ZIRBFXDW.js} +5 -10
  83. package/dist/chunk-ZIRBFXDW.js.map +1 -0
  84. package/dist/{cli-O4ABTN4Z.js → cli-236TGVJG.js} +31 -30
  85. package/dist/{cli-O4ABTN4Z.js.map → cli-236TGVJG.js.map} +1 -1
  86. package/dist/{cli-3BTCK4AB.js → cli-3FAPJBEY.js} +27 -26
  87. package/dist/{cli-3BTCK4AB.js.map → cli-3FAPJBEY.js.map} +1 -1
  88. package/dist/{cli-JJMOVIKS.js → cli-BS43EVCD.js} +14 -14
  89. package/dist/{cli-RORDPAPE.js → cli-CMR4FYF6.js} +59 -38
  90. package/dist/cli-CMR4FYF6.js.map +1 -0
  91. package/dist/{cli-ONTC5PKT.js → cli-FX53PBQ3.js} +9 -9
  92. package/dist/{cli-6KZTHWGP.js → cli-IQNJLKSN.js} +37 -36
  93. package/dist/{cli-6KZTHWGP.js.map → cli-IQNJLKSN.js.map} +1 -1
  94. package/dist/{cli-4MF37HAQ.js → cli-KOMXVPXX.js} +26 -25
  95. package/dist/{cli-4MF37HAQ.js.map → cli-KOMXVPXX.js.map} +1 -1
  96. package/dist/{cli-I62SRH3R.js → cli-NGL63E53.js} +14 -13
  97. package/dist/{cli-DRMZBZLB.js → cli-QPGS2MR5.js} +43 -42
  98. package/dist/{cli-DRMZBZLB.js.map → cli-QPGS2MR5.js.map} +1 -1
  99. package/dist/{cli-VID7PJS3.js → cli-RKQX4TI3.js} +23 -22
  100. package/dist/{cli-VID7PJS3.js.map → cli-RKQX4TI3.js.map} +1 -1
  101. package/dist/{cli-VUKMWSSF.js → cli-WNEI5L7P.js} +4 -4
  102. package/dist/cli.js +19 -13
  103. package/dist/cli.js.map +1 -1
  104. package/dist/{config-XDA42RJL.js → config-JJW75SBX.js} +5 -5
  105. package/dist/docmeta.js +13 -12
  106. package/dist/docmeta.js.map +1 -1
  107. package/dist/github-4UR67MEN.js +35 -0
  108. package/dist/github-UPGKMVVF.js +30 -0
  109. package/dist/graph/runtime.d.ts +4 -1
  110. package/dist/graph/runtime.js +20 -9
  111. package/dist/graph/runtime.js.map +1 -1
  112. package/dist/{host-6GURH5HE.js → host-YSTYO5DX.js} +3 -3
  113. package/dist/index.d.ts +192 -26
  114. package/dist/index.js +129 -124
  115. package/dist/index.js.map +1 -1
  116. package/dist/{json-BXY44ED7.js → json-DQIELR36.js} +18 -17
  117. package/dist/labels-XSTJJMSG.js +73 -0
  118. package/dist/labels-XSTJJMSG.js.map +1 -0
  119. package/dist/lint-BLBGGOYM.js +34 -0
  120. package/dist/list-B3RRRWFQ.js +32 -0
  121. package/dist/list-ZFRT3JQH.js +35 -0
  122. package/dist/{page-EV7OUBAU.js → page-5ISEVJR5.js} +18 -16
  123. package/dist/{prepare-JHJDJB6I.js → prepare-KFXXG2CJ.js} +22 -21
  124. package/dist/{prepare-JHJDJB6I.js.map → prepare-KFXXG2CJ.js.map} +1 -1
  125. package/dist/{pretty-Q5Y2PA64.js → pretty-Y7CGQLAF.js} +18 -17
  126. package/dist/{pretty-SCRK66M5.js → pretty-ZISH3Q4F.js} +18 -17
  127. package/dist/{provider-527CO4DM.js → provider-LBX4IXGX.js} +3 -3
  128. package/dist/{release-3D5PK6M7.js → release-VV3UTKE5.js} +3 -3
  129. package/dist/{reporters-M6LJ2IYU.js → reporters-26H3N2KW.js} +3 -3
  130. package/dist/{reporters-A5ADKDYR.js → reporters-4STXJJE2.js} +16 -15
  131. package/dist/{reporters-RBYTASMI.js → reporters-74B4U2GZ.js} +7 -7
  132. package/dist/run-DVGTKM52.js +37 -0
  133. package/dist/{term-CQAGNG3Q.js → term-PLJEYJQV.js} +981 -141
  134. package/dist/term-PLJEYJQV.js.map +1 -0
  135. package/dist/validate-CJNFQHMD.js +19 -0
  136. package/package.json +3 -2
  137. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  138. package/shapes/graph/shapes-1.1.0.ttl +785 -0
  139. package/dist/build-QSPNK5AL.js +0 -35
  140. package/dist/calibrate-KXN4URPM.js +0 -40
  141. package/dist/capture-JHTSUPUC.js +0 -37
  142. package/dist/check-MDGXEUWL.js +0 -20
  143. package/dist/check-WOQRKNZK.js +0 -29
  144. package/dist/chunk-2DRHT73U.js.map +0 -1
  145. package/dist/chunk-2IAZEB45.js.map +0 -1
  146. package/dist/chunk-2MJ62AYQ.js.map +0 -1
  147. package/dist/chunk-4VBSTXN6.js +0 -392
  148. package/dist/chunk-4VBSTXN6.js.map +0 -1
  149. package/dist/chunk-6HWBRZIN.js.map +0 -1
  150. package/dist/chunk-BKVHX6FU.js.map +0 -1
  151. package/dist/chunk-D4N2V43Z.js.map +0 -1
  152. package/dist/chunk-EFW7CAG4.js +0 -387
  153. package/dist/chunk-EFW7CAG4.js.map +0 -1
  154. package/dist/chunk-GV56WGL2.js.map +0 -1
  155. package/dist/chunk-HQR2ZBHW.js.map +0 -1
  156. package/dist/chunk-J6IDQGJL.js.map +0 -1
  157. package/dist/chunk-JPQDNYXH.js.map +0 -1
  158. package/dist/chunk-JROBZ7JA.js +0 -818
  159. package/dist/chunk-JROBZ7JA.js.map +0 -1
  160. package/dist/chunk-PCQ7ELJH.js.map +0 -1
  161. package/dist/chunk-QCHVR4ZM.js.map +0 -1
  162. package/dist/chunk-QLWC7MKD.js.map +0 -1
  163. package/dist/chunk-TU2WUBVZ.js +0 -2
  164. package/dist/chunk-VSEBFHAY.js.map +0 -1
  165. package/dist/chunk-Y6DOMTQD.js.map +0 -1
  166. package/dist/cli-RORDPAPE.js.map +0 -1
  167. package/dist/github-RY3FRA6P.js +0 -29
  168. package/dist/github-YKQSH7FS.js +0 -34
  169. package/dist/lint-YJ2L22BW.js +0 -33
  170. package/dist/list-NSG24VVX.js +0 -31
  171. package/dist/list-V6EGCSHX.js +0 -34
  172. package/dist/run-BUE2DDXN.js +0 -36
  173. package/dist/term-CQAGNG3Q.js.map +0 -1
  174. package/dist/validate-ZBW44RHT.js +0 -18
  175. /package/dist/{batch-UAULUMGH.js.map → batch-KMGZMIAQ.js.map} +0 -0
  176. /package/dist/{build-QSPNK5AL.js.map → build-NO4AWCYG.js.map} +0 -0
  177. /package/dist/{calibrate-KXN4URPM.js.map → calibrate-XQUG5XAK.js.map} +0 -0
  178. /package/dist/{capture-JHTSUPUC.js.map → capture-5XE3ZMXK.js.map} +0 -0
  179. /package/dist/{check-MDGXEUWL.js.map → check-HTNPLWOV.js.map} +0 -0
  180. /package/dist/{check-WOQRKNZK.js.map → check-RJ45IBA6.js.map} +0 -0
  181. /package/dist/{check-YEOYBFST.js.map → check-WFXSXICD.js.map} +0 -0
  182. /package/dist/{chunk-IGSHYP74.js.map → chunk-23P7KMJM.js.map} +0 -0
  183. /package/dist/{chunk-HA6MQMOY.js.map → chunk-24J7TYPU.js.map} +0 -0
  184. /package/dist/{chunk-PCS4VJBV.js.map → chunk-37QJLVS3.js.map} +0 -0
  185. /package/dist/{chunk-4CK6ZSOK.js.map → chunk-3P6KCU36.js.map} +0 -0
  186. /package/dist/{chunk-54F74XR3.js.map → chunk-5JBVFWVP.js.map} +0 -0
  187. /package/dist/{chunk-B7XYNRJQ.js.map → chunk-6KIYVVKL.js.map} +0 -0
  188. /package/dist/{chunk-GDVZ5VII.js.map → chunk-7A452BPZ.js.map} +0 -0
  189. /package/dist/{chunk-M42DZCOU.js.map → chunk-7FCLXEAQ.js.map} +0 -0
  190. /package/dist/{chunk-LBSCW232.js.map → chunk-7NXPQKSB.js.map} +0 -0
  191. /package/dist/{chunk-OPXWPJDA.js.map → chunk-A3TEDWBZ.js.map} +0 -0
  192. /package/dist/{chunk-BBT6AVUG.js.map → chunk-BHHXU2D2.js.map} +0 -0
  193. /package/dist/{chunk-FQXWVS6J.js.map → chunk-CMMBWHT2.js.map} +0 -0
  194. /package/dist/{chunk-EIFCP6CZ.js.map → chunk-CO47QJKZ.js.map} +0 -0
  195. /package/dist/{chunk-ADMEPUBT.js.map → chunk-CXWTNT2O.js.map} +0 -0
  196. /package/dist/{chunk-LKP7QDFN.js.map → chunk-DAQTRAP5.js.map} +0 -0
  197. /package/dist/{chunk-PWBH7DCQ.js.map → chunk-EESH6COU.js.map} +0 -0
  198. /package/dist/{chunk-NCPWXHDO.js.map → chunk-JEUFYSFQ.js.map} +0 -0
  199. /package/dist/{chunk-2IR4T5PO.js.map → chunk-JJ4RSDSY.js.map} +0 -0
  200. /package/dist/{chunk-WDWXAYVH.js.map → chunk-L3RLGGRK.js.map} +0 -0
  201. /package/dist/{chunk-T7JAOYE5.js.map → chunk-L75CAZG4.js.map} +0 -0
  202. /package/dist/{chunk-U7CTFN2J.js.map → chunk-MYRPMSOX.js.map} +0 -0
  203. /package/dist/{chunk-WQWKYAAK.js.map → chunk-NUQF5F5J.js.map} +0 -0
  204. /package/dist/{chunk-FUCPZVRY.js.map → chunk-OEN6FBUW.js.map} +0 -0
  205. /package/dist/{chunk-FBMZJEB3.js.map → chunk-OKMTUAWO.js.map} +0 -0
  206. /package/dist/{chunk-R4WXQIOZ.js.map → chunk-PCEM5FOZ.js.map} +0 -0
  207. /package/dist/{chunk-4D5IZSXM.js.map → chunk-PXNCRGUL.js.map} +0 -0
  208. /package/dist/{chunk-ODRPL3WB.js.map → chunk-Q3ODX5PF.js.map} +0 -0
  209. /package/dist/{chunk-KGEQJ5CC.js.map → chunk-RRFFUWDL.js.map} +0 -0
  210. /package/dist/{chunk-NSBXVPZL.js.map → chunk-S3XUYW5K.js.map} +0 -0
  211. /package/dist/{chunk-LPIF5LIE.js.map → chunk-SAU2WQFC.js.map} +0 -0
  212. /package/dist/{chunk-MSRU4D4P.js.map → chunk-SFLICIQV.js.map} +0 -0
  213. /package/dist/{chunk-NGTVREIH.js.map → chunk-U6IHLEWT.js.map} +0 -0
  214. /package/dist/{chunk-VQK4VHLF.js.map → chunk-YQV75FIL.js.map} +0 -0
  215. /package/dist/{chunk-TU2WUBVZ.js.map → chunk-YUTVAMWW.js.map} +0 -0
  216. /package/dist/{chunk-RLT5SEML.js.map → chunk-Z5MZCCTT.js.map} +0 -0
  217. /package/dist/{cli-JJMOVIKS.js.map → cli-BS43EVCD.js.map} +0 -0
  218. /package/dist/{cli-ONTC5PKT.js.map → cli-FX53PBQ3.js.map} +0 -0
  219. /package/dist/{cli-I62SRH3R.js.map → cli-NGL63E53.js.map} +0 -0
  220. /package/dist/{cli-VUKMWSSF.js.map → cli-WNEI5L7P.js.map} +0 -0
  221. /package/dist/{config-XDA42RJL.js.map → config-JJW75SBX.js.map} +0 -0
  222. /package/dist/{github-RY3FRA6P.js.map → github-4UR67MEN.js.map} +0 -0
  223. /package/dist/{github-YKQSH7FS.js.map → github-UPGKMVVF.js.map} +0 -0
  224. /package/dist/{host-6GURH5HE.js.map → host-YSTYO5DX.js.map} +0 -0
  225. /package/dist/{json-BXY44ED7.js.map → json-DQIELR36.js.map} +0 -0
  226. /package/dist/{lint-YJ2L22BW.js.map → lint-BLBGGOYM.js.map} +0 -0
  227. /package/dist/{list-NSG24VVX.js.map → list-B3RRRWFQ.js.map} +0 -0
  228. /package/dist/{list-V6EGCSHX.js.map → list-ZFRT3JQH.js.map} +0 -0
  229. /package/dist/{page-EV7OUBAU.js.map → page-5ISEVJR5.js.map} +0 -0
  230. /package/dist/{pretty-Q5Y2PA64.js.map → pretty-Y7CGQLAF.js.map} +0 -0
  231. /package/dist/{pretty-SCRK66M5.js.map → pretty-ZISH3Q4F.js.map} +0 -0
  232. /package/dist/{provider-527CO4DM.js.map → provider-LBX4IXGX.js.map} +0 -0
  233. /package/dist/{release-3D5PK6M7.js.map → release-VV3UTKE5.js.map} +0 -0
  234. /package/dist/{reporters-A5ADKDYR.js.map → reporters-26H3N2KW.js.map} +0 -0
  235. /package/dist/{reporters-M6LJ2IYU.js.map → reporters-4STXJJE2.js.map} +0 -0
  236. /package/dist/{reporters-RBYTASMI.js.map → reporters-74B4U2GZ.js.map} +0 -0
  237. /package/dist/{run-BUE2DDXN.js.map → run-DVGTKM52.js.map} +0 -0
  238. /package/dist/{validate-ZBW44RHT.js.map → validate-CJNFQHMD.js.map} +0 -0
@@ -42,7 +42,7 @@ import {
42
42
  schemaLoadOptions,
43
43
  schemaTrustRoot,
44
44
  writeFileAtomic
45
- } from "./chunk-VSEBFHAY.js";
45
+ } from "./chunk-KFKL4VTL.js";
46
46
  import {
47
47
  STDIN_LINES_MARKER
48
48
  } from "./chunk-YEUYKR62.js";
@@ -67,42 +67,12 @@ import {
67
67
  pageManifestPath,
68
68
  parseCollections,
69
69
  sameFile
70
- } from "./chunk-QLWC7MKD.js";
70
+ } from "./chunk-OTJOBZJ5.js";
71
71
  import {
72
72
  ToolError,
73
73
  errorMessage
74
74
  } from "./chunk-G3T47CFV.js";
75
75
 
76
- // src/shared/cli-options.ts
77
- import { basename, relative } from "node:path";
78
- function collect(value, prev) {
79
- return prev.concat([value]);
80
- }
81
- function splitList(value) {
82
- return value.split(",").map((s) => s.trim()).filter(Boolean);
83
- }
84
- var STDIN_REQUIRES_AS = "Reading from stdin (`-`) requires --as <format> to choose an extractor.";
85
- async function readStdin() {
86
- const chunks = [];
87
- for await (const chunk of process.stdin) chunks.push(chunk);
88
- return Buffer.concat(chunks).toString("utf8");
89
- }
90
- function configOption(value) {
91
- if (value === false) return { noConfig: true };
92
- return typeof value === "string" ? { configPath: value } : {};
93
- }
94
- function explicitFalse(value) {
95
- return value === false ? false : void 0;
96
- }
97
- function reportConfig(toStdout, cwd) {
98
- return (info) => {
99
- const where = (relative(cwd, info.dir) || ".").replace(/\\/g, "/");
100
- const line = `Using ${basename(info.path)} (${where})
101
- `;
102
- (toStdout ? process.stdout : process.stderr).write(line);
103
- };
104
- }
105
-
106
76
  // src/meta/core/external-metadata-fetch.ts
107
77
  var EXTERNAL_METADATA_FETCH_TIMEOUT_MS = 1e4;
108
78
  var EXTERNAL_METADATA_FETCH_MAX_BYTES = 5 * 1024 * 1024;
@@ -197,13 +167,13 @@ async function readCapped(url, res, maxBytes) {
197
167
  // src/shared/encryption-key.ts
198
168
  import { spawnSync } from "node:child_process";
199
169
  import { readFile } from "node:fs/promises";
200
- import { basename as basename3, dirname as dirname2, join as join2, relative as relative2, resolve } from "node:path";
170
+ import { basename as basename2, dirname as dirname2, join as join2, relative, resolve } from "node:path";
201
171
  import { isDeepStrictEqual } from "node:util";
202
172
  import { isMap, parseDocument, parse as parseYaml, stringify } from "yaml";
203
173
 
204
174
  // src/shared/write-file.ts
205
175
  import { chmod, rename, rm, stat, writeFile } from "node:fs/promises";
206
- import { basename as basename2, dirname, join } from "node:path";
176
+ import { basename, dirname, join } from "node:path";
207
177
  var LOCKED = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES"]);
208
178
  var RENAME_ATTEMPTS = 3;
209
179
  function errorCode(err) {
@@ -215,7 +185,7 @@ var wait = (ms) => new Promise((resolve4) => {
215
185
  async function writeTextAtomic(path, text) {
216
186
  const tmp = join(
217
187
  dirname(path),
218
- `.${basename2(path)}.manni-${process.pid}-${Math.random().toString(36).slice(2, 8)}.tmp`
188
+ `.${basename(path)}.manni-${process.pid}-${Math.random().toString(36).slice(2, 8)}.tmp`
219
189
  );
220
190
  try {
221
191
  await writeFile(tmp, text, "utf8");
@@ -259,7 +229,7 @@ function resolveEncryptionKey(opts) {
259
229
  return { key: void 0, source: "none" };
260
230
  }
261
231
  function relativeSource(cwd, path) {
262
- return relative2(resolve(cwd), path).replace(/\\/g, "/");
232
+ return relative(resolve(cwd), path).replace(/\\/g, "/");
263
233
  }
264
234
  function errorCode2(err) {
265
235
  return typeof err === "object" && err !== null && "code" in err ? String(err.code) : void 0;
@@ -346,7 +316,7 @@ async function writeEncryptionKey(opts) {
346
316
  return { path: target.path, source: target.source, created: target.text === null };
347
317
  }
348
318
  function isIgnoredByGit(path) {
349
- const result = spawnSync("git", ["check-ignore", "-q", "--", basename3(path)], {
319
+ const result = spawnSync("git", ["check-ignore", "-q", "--", basename2(path)], {
350
320
  cwd: dirname2(path),
351
321
  stdio: "ignore",
352
322
  windowsHide: true
@@ -565,7 +535,7 @@ function redactedDerived(f) {
565
535
 
566
536
  // src/meta/core/external-metadata.ts
567
537
  import { readFile as readFile3 } from "node:fs/promises";
568
- import { isAbsolute, relative as relative3, resolve as resolve2, sep } from "node:path";
538
+ import { isAbsolute, relative as relative2, resolve as resolve2, sep } from "node:path";
569
539
  import {
570
540
  LineCounter,
571
541
  isMap as isMap2,
@@ -665,7 +635,7 @@ var perPageRules = /* @__PURE__ */ new WeakMap();
665
635
  var strayEntries = /* @__PURE__ */ new WeakSet();
666
636
  var posix2 = (p) => p.split(sep).join("/");
667
637
  function reportedPath(abs, base) {
668
- const rel = relative3(base, abs);
638
+ const rel = relative2(base, abs);
669
639
  return rel === "" ? "." : posix2(rel);
670
640
  }
671
641
  function reported(of, file) {
@@ -805,7 +775,7 @@ async function loadPerPage(declared, manifest, opts, resolvedBy, into) {
805
775
  }
806
776
  continue;
807
777
  }
808
- const rel = posix2(relative3(opts.configDir, pageAbs));
778
+ const rel = posix2(relative2(opts.configDir, pageAbs));
809
779
  if (!isMember(declared, rel)) continue;
810
780
  const earlier = resolvedBy.get(resolved.abs);
811
781
  if (earlier !== void 0 && earlier !== pageAbs) {
@@ -1207,899 +1177,1037 @@ function pageOwners(index, key, memberOf2, marked) {
1207
1177
  ];
1208
1178
  }
1209
1179
 
1210
- // src/meta/core/location.ts
1211
- var LOCATION_KEYWORD = "x-manni-location";
1212
- var LOCATION_EXTERNAL_SCHEMA = "location:external";
1213
- var LOCATION_PAGE_SCHEMA = "location:page";
1214
- var LOCATION_FINDING_KEYWORD = "location";
1215
- function isFieldLocation(value) {
1216
- return value === "page" || value === "external";
1180
+ // src/meta/core/projection.ts
1181
+ var SYSTEM_COLUMNS = ["_path", "_format", "_present", "_data"];
1182
+ var RESERVED = new Set(SYSTEM_COLUMNS);
1183
+ function quoteIdent(name) {
1184
+ return `"${name.replaceAll('"', '""')}"`;
1217
1185
  }
1218
-
1219
- // src/meta/core/graph-output.ts
1220
- var GRAPH_OUTPUT_KEYWORD = "x-manni-graph-output";
1221
-
1222
- // src/meta/core/validator.ts
1223
- import * as AjvDraft07Ns from "ajv";
1224
- import * as Ajv2019Ns from "ajv/dist/2019.js";
1225
- import * as Ajv2020Ns from "ajv/dist/2020.js";
1226
- import * as AjvDraft04Ns from "ajv-draft-04";
1227
- import * as addFormatsNs from "ajv-formats";
1228
- import { createRequire } from "node:module";
1229
- var draft06MetaSchema = createRequire(import.meta.url)(
1230
- "ajv/dist/refs/json-schema-draft-06.json"
1231
- );
1232
- var AjvDraft07 = AjvDraft07Ns.default;
1233
- var Ajv2019 = Ajv2019Ns.default;
1234
- var Ajv2020 = Ajv2020Ns.default;
1235
- var AjvDraft04 = AjvDraft04Ns.default;
1236
- var addFormats = addFormatsNs.default;
1237
- function dialectOf(schema) {
1238
- const meta = typeof schema.$schema === "string" ? schema.$schema : "";
1239
- if (meta.includes("2019-09")) return "2019";
1240
- if (meta.includes("draft-07") || meta.includes("draft/7") || meta.includes("draft-06") || meta.includes("draft/6")) {
1241
- return "draft7";
1186
+ function bindValue(value) {
1187
+ if (value === void 0 || value === null) return null;
1188
+ switch (typeof value) {
1189
+ case "boolean":
1190
+ return value ? 1 : 0;
1191
+ case "number":
1192
+ return Number.isFinite(value) ? value : null;
1193
+ case "bigint":
1194
+ case "string":
1195
+ return value;
1196
+ default:
1197
+ return JSON.stringify(value);
1242
1198
  }
1243
- if (meta.includes("draft-04") || meta.includes("draft/4")) return "draft4";
1244
- return "2020";
1245
1199
  }
1246
- function buildAjv(dialect, coerceTypes = false) {
1247
- const opts = { allErrors: true, strict: false, coerceTypes };
1248
- const ajv = dialect === "2019" ? new Ajv2019(opts) : dialect === "draft7" ? new AjvDraft07(opts) : dialect === "draft4" ? new AjvDraft04(opts) : new Ajv2020(opts);
1249
- addFormats(ajv);
1250
- if (dialect === "draft7") ajv.addMetaSchema(draft06MetaSchema);
1251
- registerEncryptKeyword(ajv);
1252
- registerLocationKeyword(ajv);
1253
- registerGraphOutputKeyword(ajv);
1254
- registerBuiltins(ajv, dialect);
1255
- return ajv;
1200
+ function corpusDataColumns(entries, extraKeys = []) {
1201
+ const keys = /* @__PURE__ */ new Set();
1202
+ for (const { extracted } of entries) {
1203
+ for (const key of Object.keys(extracted.data)) {
1204
+ if (key !== "" && !RESERVED.has(key)) keys.add(key);
1205
+ }
1206
+ }
1207
+ for (const key of extraKeys) {
1208
+ if (key !== "" && !RESERVED.has(key)) keys.add(key);
1209
+ }
1210
+ return [...keys].sort();
1256
1211
  }
1257
- var markRecorder;
1258
- function registerEncryptKeyword(ajv) {
1259
- ajv.addKeyword({
1260
- keyword: ENCRYPT_KEYWORD,
1261
- metaSchema: { type: "boolean" },
1262
- errors: false,
1263
- validate: (schema, _data, _parent, cxt) => {
1264
- if (schema === true && markRecorder !== void 0) {
1265
- markRecorder.add(cxt?.instancePath ?? "");
1266
- }
1267
- return true;
1212
+ function createDocsTable(db, entries, dataColumns) {
1213
+ db.exec(
1214
+ `CREATE TABLE docs ("_path" TEXT PRIMARY KEY, "_format" TEXT, "_present" INTEGER, "_data" TEXT${dataColumns.map((c) => `, ${quoteIdent(c)}`).join("")})`
1215
+ );
1216
+ const insert = db.prepare(
1217
+ `INSERT INTO docs VALUES (${["?", "?", "?", "?", ...dataColumns.map(() => "?")].join(", ")})`
1218
+ );
1219
+ db.exec("BEGIN");
1220
+ let committed = false;
1221
+ try {
1222
+ for (const { label, extracted } of entries) {
1223
+ insert.run(
1224
+ label,
1225
+ extracted.format,
1226
+ extracted.present ? 1 : 0,
1227
+ JSON.stringify(extracted.data),
1228
+ ...dataColumns.map((c) => bindValue(extracted.data[c]))
1229
+ );
1268
1230
  }
1269
- });
1231
+ db.exec("COMMIT");
1232
+ committed = true;
1233
+ } finally {
1234
+ if (!committed) db.exec("ROLLBACK");
1235
+ }
1270
1236
  }
1271
- function isMarkShapeError(err) {
1272
- return err instanceof Error && err.message.includes(`"${ENCRYPT_KEYWORD}"`);
1237
+ function registerLineFor(db, entries) {
1238
+ const byLabel = new Map(entries.map((e) => [e.label, e.extracted]));
1239
+ db.function("lineFor", { deterministic: true }, (path, key) => {
1240
+ if (typeof path !== "string" || typeof key !== "string") return null;
1241
+ return byLabel.get(path)?.lineFor(key) ?? null;
1242
+ });
1273
1243
  }
1274
- var locationRecorder;
1275
- function topLevelKey(instancePath) {
1276
- if (!instancePath.startsWith("/") || instancePath.indexOf("/", 1) !== -1) {
1277
- return void 0;
1244
+ function assertSingleStatement(sql) {
1245
+ const cut = topLevelSemicolon(sql);
1246
+ if (cut === -1) return;
1247
+ if (!isTrivia(sql.slice(cut + 1))) {
1248
+ throw new DocmetaError(
1249
+ "Run a single SQL statement per query; text after the first `;` would be silently ignored."
1250
+ );
1278
1251
  }
1279
- return instancePath.slice(1).replace(/~1/g, "/").replace(/~0/g, "~");
1280
1252
  }
1281
- function registerLocationKeyword(ajv) {
1282
- ajv.addKeyword({
1283
- keyword: LOCATION_KEYWORD,
1284
- metaSchema: { type: "string", enum: ["page", "external"] },
1285
- errors: false,
1286
- validate: (schema, _data, _parent, cxt) => {
1287
- if (locationRecorder !== void 0 && isFieldLocation(schema)) {
1288
- const key = topLevelKey(cxt?.instancePath ?? "");
1289
- if (key !== void 0) {
1290
- const seen = locationRecorder.get(key);
1291
- if (seen) seen.add(schema);
1292
- else locationRecorder.set(key, /* @__PURE__ */ new Set([schema]));
1293
- }
1294
- }
1295
- return true;
1296
- }
1297
- });
1253
+ function startsStringOrIdent(sql, i) {
1254
+ const ch = sql[i];
1255
+ return ch === "'" || ch === '"' || ch === "`" || ch === "[";
1298
1256
  }
1299
- function isLocationShapeError(err) {
1300
- return err instanceof Error && err.message.includes(`"${LOCATION_KEYWORD}"`);
1257
+ function startsComment(sql, i) {
1258
+ const ch = sql[i];
1259
+ return ch === "-" && sql[i + 1] === "-" || ch === "/" && sql[i + 1] === "*";
1301
1260
  }
1302
- var graphOutputRecorder;
1303
- function registerGraphOutputKeyword(ajv) {
1304
- ajv.addKeyword({
1305
- keyword: GRAPH_OUTPUT_KEYWORD,
1306
- metaSchema: { type: "boolean" },
1307
- errors: false,
1308
- validate: (schema, _data, _parent, cxt) => {
1309
- if (graphOutputRecorder !== void 0 && typeof schema === "boolean") {
1310
- const key = topLevelKey(cxt?.instancePath ?? "");
1311
- if (key !== void 0) {
1312
- const seen = graphOutputRecorder.get(key);
1313
- if (seen) seen.add(schema);
1314
- else graphOutputRecorder.set(key, /* @__PURE__ */ new Set([schema]));
1315
- }
1261
+ function skipStringOrIdent(sql, i) {
1262
+ const quote = sql[i];
1263
+ if (quote === "[") {
1264
+ let j2 = i + 1;
1265
+ while (j2 < sql.length && sql[j2] !== "]") j2++;
1266
+ return j2 + 1;
1267
+ }
1268
+ let j = i + 1;
1269
+ while (j < sql.length) {
1270
+ if (sql[j] === quote) {
1271
+ if (sql[j + 1] === quote) {
1272
+ j += 2;
1273
+ continue;
1316
1274
  }
1317
- return true;
1275
+ return j + 1;
1318
1276
  }
1319
- });
1277
+ j++;
1278
+ }
1279
+ return j;
1320
1280
  }
1321
- function isGraphOutputShapeError(err) {
1322
- return err instanceof Error && err.message.includes(`"${GRAPH_OUTPUT_KEYWORD}"`);
1281
+ function skipComment(sql, i) {
1282
+ if (sql[i] === "-") {
1283
+ let j = i + 2;
1284
+ while (j < sql.length && sql[j] !== "\n") j++;
1285
+ return j < sql.length ? j + 1 : j;
1286
+ }
1287
+ const end = sql.indexOf("*/", i + 2);
1288
+ return end === -1 ? sql.length : end + 2;
1323
1289
  }
1324
- function marksSchemaExternal(schema) {
1325
- const properties = schema["properties"];
1326
- if (typeof properties !== "object" || properties === null) return false;
1327
- const own = properties[FILE_SCHEMA_KEY];
1328
- if (typeof own !== "object" || own === null) return false;
1329
- return own[LOCATION_KEYWORD] === "external";
1290
+ function topLevelSemicolon(sql) {
1291
+ let i = 0;
1292
+ while (i < sql.length) {
1293
+ if (startsStringOrIdent(sql, i)) {
1294
+ i = skipStringOrIdent(sql, i);
1295
+ } else if (startsComment(sql, i)) {
1296
+ i = skipComment(sql, i);
1297
+ } else if (sql[i] === ";") {
1298
+ return i;
1299
+ } else {
1300
+ i++;
1301
+ }
1302
+ }
1303
+ return -1;
1330
1304
  }
1331
- function isRecord2(value) {
1332
- return typeof value === "object" && value !== null && !Array.isArray(value);
1305
+ var PARAM_NAME_HEAD = /^[A-Za-z_][A-Za-z0-9_]*/;
1306
+ function isParamName(name) {
1307
+ return PARAM_NAME_HEAD.exec(name)?.[0] === name;
1333
1308
  }
1334
- function definiteMarkConflict(root, keyword, isMark) {
1335
- const marks = /* @__PURE__ */ new Map();
1336
- const localRef = (node, embedded) => {
1337
- const ref = node["$ref"];
1338
- if (embedded || typeof ref !== "string" || !ref.startsWith("#")) return void 0;
1339
- const pointer = ref.slice(1);
1340
- if (pointer === "") return root;
1341
- if (!pointer.startsWith("/")) return void 0;
1342
- let at2 = root;
1343
- for (const raw of pointer.slice(1).split("/")) {
1344
- let segment;
1345
- try {
1346
- segment = decodeURIComponent(raw).replace(/~1/g, "/").replace(/~0/g, "~");
1347
- } catch {
1348
- return void 0;
1309
+ function collectNamedParameters(sql) {
1310
+ const tokens = [];
1311
+ const seen = /* @__PURE__ */ new Set();
1312
+ const prefixOf = /* @__PURE__ */ new Map();
1313
+ let i = 0;
1314
+ while (i < sql.length) {
1315
+ const ch = sql[i];
1316
+ if (startsStringOrIdent(sql, i)) {
1317
+ i = skipStringOrIdent(sql, i);
1318
+ } else if (startsComment(sql, i)) {
1319
+ i = skipComment(sql, i);
1320
+ } else if (ch === "$" || ch === ":" || ch === "@") {
1321
+ if (ch === ":" && sql[i + 1] === ":") {
1322
+ i += 2;
1323
+ continue;
1349
1324
  }
1350
- if (Array.isArray(at2)) at2 = at2[Number(segment)];
1351
- else if (isRecord2(at2)) at2 = at2[segment];
1352
- else return void 0;
1353
- }
1354
- return at2;
1355
- };
1356
- const isEmbedded = (node, embedded) => embedded || node !== root && typeof node["$id"] === "string";
1357
- const allOf = (node) => Array.isArray(node["allOf"]) ? node["allOf"] : [];
1358
- const property = (key, node, embedded, visited) => {
1359
- if (!isRecord2(node) || visited.has(node)) return;
1360
- visited.add(node);
1361
- const inner = isEmbedded(node, embedded);
1362
- const mark = node[keyword];
1363
- if (isMark(mark)) {
1364
- const seen = marks.get(key);
1365
- if (seen) seen.add(mark);
1366
- else marks.set(key, /* @__PURE__ */ new Set([mark]));
1367
- }
1368
- for (const entry of allOf(node)) property(key, entry, inner, visited);
1369
- property(key, localRef(node, inner), inner, visited);
1370
- };
1371
- const object = (node, embedded, visited) => {
1372
- if (!isRecord2(node) || visited.has(node)) return;
1373
- visited.add(node);
1374
- const inner = isEmbedded(node, embedded);
1375
- const properties = node["properties"];
1376
- if (isRecord2(properties)) {
1377
- for (const [key, sub] of Object.entries(properties)) property(key, sub, inner, /* @__PURE__ */ new Set());
1325
+ const m = PARAM_NAME_HEAD.exec(sql.slice(i + 1));
1326
+ if (!m) {
1327
+ i++;
1328
+ continue;
1329
+ }
1330
+ const token = ch + m[0];
1331
+ const priorPrefix = prefixOf.get(m[0]);
1332
+ if (priorPrefix !== void 0 && priorPrefix !== ch) {
1333
+ throw new DocmetaError(
1334
+ `The statement references both ${priorPrefix}${m[0]} and ${token} \u2014 one name under two prefixes, which the engine rejects as conflicting. Use one spelling throughout.`
1335
+ );
1336
+ }
1337
+ prefixOf.set(m[0], ch);
1338
+ if (!seen.has(token)) {
1339
+ seen.add(token);
1340
+ tokens.push(token);
1341
+ }
1342
+ i += 1 + m[0].length;
1343
+ } else {
1344
+ i++;
1378
1345
  }
1379
- for (const entry of allOf(node)) object(entry, inner, visited);
1380
- object(localRef(node, inner), inner, visited);
1381
- };
1382
- object(root, false, /* @__PURE__ */ new Set());
1383
- for (const [key, seen] of marks) if (seen.size > 1) return key;
1384
- return void 0;
1346
+ }
1347
+ return tokens;
1385
1348
  }
1386
- function registerBuiltins(ajv, dialect) {
1387
- for (const { id, url, legacyUrl, schema } of publishedBuiltins()) {
1388
- ajv.addSchema(schema, url, void 0, false);
1389
- ajv.addSchema(schema, legacyUrl, void 0, false);
1390
- if (dialect === "draft4") ajv.addSchema(schema, id, void 0, false);
1349
+ function stripLeadingTrivia(sql) {
1350
+ let i = 0;
1351
+ for (; ; ) {
1352
+ while (i < sql.length && /\s/.test(sql[i] ?? "")) i++;
1353
+ if (startsComment(sql, i)) {
1354
+ i = skipComment(sql, i);
1355
+ continue;
1356
+ }
1357
+ return sql.slice(i);
1391
1358
  }
1392
1359
  }
1393
- function registerRegistered(ajv, dialect, registered) {
1394
- for (const { id, schema } of registered?.values() ?? []) {
1395
- ajv.addSchema(schema, dialect === "draft4" ? id : void 0, void 0, false);
1360
+ function isTrivia(text) {
1361
+ let i = 0;
1362
+ while (i < text.length) {
1363
+ const ch = text[i];
1364
+ if (ch === void 0 || /\s/.test(ch) || ch === ";") {
1365
+ i++;
1366
+ continue;
1367
+ }
1368
+ if (startsComment(text, i)) {
1369
+ i = skipComment(text, i);
1370
+ continue;
1371
+ }
1372
+ return false;
1396
1373
  }
1374
+ return true;
1397
1375
  }
1398
- function compileWithFormats(schema, registered, options = {}) {
1399
- const ajv = buildAjv("2020", options.coerce === true ? "array" : false);
1400
- registerRegistered(ajv, "2020", registered);
1401
- return ajv.compile(schema);
1376
+ var sqliteModule;
1377
+ function loadSqlite() {
1378
+ sqliteModule ??= (async () => {
1379
+ const original = process.emitWarning.bind(process);
1380
+ const filtered = (warning, ...rest) => {
1381
+ const text = typeof warning === "string" ? warning : warning.message;
1382
+ if (text.includes("SQLite is an experimental feature")) return;
1383
+ Reflect.apply(original, process, [warning, ...rest]);
1384
+ };
1385
+ process.emitWarning = filtered;
1386
+ try {
1387
+ return await import("node:sqlite");
1388
+ } finally {
1389
+ process.emitWarning = original;
1390
+ }
1391
+ })();
1392
+ return sqliteModule;
1402
1393
  }
1403
- var formatRegistry;
1404
- function formatsAjv() {
1405
- if (!formatRegistry) {
1406
- formatRegistry = new Ajv2020({ strict: false });
1407
- addFormats(formatRegistry);
1408
- }
1409
- return formatRegistry;
1394
+
1395
+ // src/meta/core/collections.ts
1396
+ import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolvePath, sep as sep2 } from "node:path";
1397
+ function memberOf(collections, configDir, base, label) {
1398
+ if (collections.length === 0) return [];
1399
+ if (label === STDIN_LABEL) return [];
1400
+ const rel = relative3(configDir, resolvePath(base, label)).split(sep2).join("/");
1401
+ if (isAbsolute2(rel)) return [];
1402
+ return collections.filter((c) => isMember(c, rel)).map((c) => c.name);
1410
1403
  }
1411
- var stringFormatsMemo;
1412
- function stringFormatNames() {
1413
- if (!stringFormatsMemo) {
1414
- const names = /* @__PURE__ */ new Set();
1415
- const registered = formatsAjv().formats;
1416
- for (const [name, def] of Object.entries(registered)) {
1417
- const enforcesStrings = def instanceof RegExp || typeof def === "function" || typeof def === "object" && def !== null && (def.type === void 0 || def.type === "string");
1418
- if (enforcesStrings) names.add(name);
1404
+ function retainMembers(files, membersFor) {
1405
+ return files.filter((label) => membersFor(label).length > 0);
1406
+ }
1407
+ function collectionNames(collections) {
1408
+ return (collections ?? []).map((c) => c.name);
1409
+ }
1410
+ function collectCollections(entries, params) {
1411
+ const declared = params.collections ?? [];
1412
+ if (declared.length === 0) return [];
1413
+ const base = params.base ?? ".";
1414
+ const configDir = params.configDir ?? base;
1415
+ const members = /* @__PURE__ */ new Map();
1416
+ for (const entry of entries) {
1417
+ for (const name of memberOf(declared, configDir, base, entry.label)) {
1418
+ const list2 = members.get(name);
1419
+ if (list2) list2.push(entry.label);
1420
+ else members.set(name, [entry.label]);
1419
1421
  }
1420
- stringFormatsMemo = names;
1421
1422
  }
1422
- return stringFormatsMemo;
1423
+ return declared.map((c) => ({ name: c.name, members: members.get(c.name) ?? [] }));
1423
1424
  }
1424
- var formatCheckers = /* @__PURE__ */ new Map();
1425
- function validatesFormat(name, value) {
1426
- let fn = formatCheckers.get(name);
1427
- if (!fn) {
1428
- fn = formatsAjv().compile({ type: "string", format: name });
1429
- formatCheckers.set(name, fn);
1425
+ function quoteSqlString(value) {
1426
+ return `'${value.replaceAll("'", "''")}'`;
1427
+ }
1428
+ function createCollectionViews(db, collections) {
1429
+ for (const c of collections) {
1430
+ const where = c.members.length === 0 ? "0" : `_path IN (${c.members.map(quoteSqlString).join(", ")})`;
1431
+ db.exec(
1432
+ `CREATE VIEW ${quoteIdent(c.name)} AS SELECT * FROM docs WHERE ${where}`
1433
+ );
1430
1434
  }
1431
- return fn(value);
1432
1435
  }
1433
- var Validator = class {
1434
- /**
1435
- * How this validator's schemas are loaded: the disk cache location, its TTL,
1436
- * and `--offline`. Held per instance rather than read from module state, so
1437
- * two differently-configured validations in one process each get their own
1438
- * settings.
1439
- *
1440
- * That is not full isolation, and the difference matters to a library
1441
- * caller: `schema-registry` keeps a process-wide memo of fetched schemas, so
1442
- * one validator's successful fetch is visible to another. `offline` is
1443
- * excluded from that sharing on purpose — an offline validator will not be
1444
- * served something this process pulled over the network — but the memo is
1445
- * still shared, so a URL fetched once is not re-fetched per instance.
1446
- */
1447
- constructor(schemaOptions = {}) {
1448
- this.schemaOptions = schemaOptions;
1436
+
1437
+ // src/meta/core/location.ts
1438
+ var LOCATION_KEYWORD = "x-manni-location";
1439
+ var LOCATION_EXTERNAL_SCHEMA = "location:external";
1440
+ var LOCATION_PAGE_SCHEMA = "location:page";
1441
+ var LOCATION_FINDING_KEYWORD = "location";
1442
+ function isFieldLocation(value) {
1443
+ return value === "page" || value === "external";
1444
+ }
1445
+
1446
+ // src/meta/core/graph-output.ts
1447
+ var GRAPH_OUTPUT_KEYWORD = "x-manni-graph-output";
1448
+
1449
+ // src/meta/core/term-keyword.ts
1450
+ var TERM_KEYWORD = "x-manni-term";
1451
+ var TERM_UNDEFINED_SCHEMA = "term:undefined";
1452
+ var TERM_OUTSIDE_BRANCH_SCHEMA = "term:outside-branch";
1453
+ var TERM_ALT_LABEL_SCHEMA = "term:alt-label";
1454
+ var TERM_FINDING_KEYWORD = "term";
1455
+ var TERM_MARK_META_SCHEMA = {
1456
+ type: "object",
1457
+ properties: { under: { type: "string", minLength: 1 } },
1458
+ additionalProperties: false
1459
+ };
1460
+ function isTermMark(value) {
1461
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1462
+ const under = value["under"];
1463
+ return under === void 0 || typeof under === "string";
1464
+ }
1465
+ var fold = (value) => value.toLowerCase();
1466
+ function termScheme(terms) {
1467
+ const byName = /* @__PURE__ */ new Map();
1468
+ for (const term of terms) {
1469
+ byName.set(fold(term.id), term);
1470
+ byName.set(fold(term.label), term);
1471
+ }
1472
+ const byAlt = /* @__PURE__ */ new Map();
1473
+ for (const term of terms) {
1474
+ for (const alt of term.altLabels ?? []) {
1475
+ if (!byName.has(fold(alt))) byAlt.set(fold(alt), term);
1476
+ }
1477
+ }
1478
+ const keyOf = (name) => {
1479
+ const term = byName.get(fold(name));
1480
+ return term === void 0 ? void 0 : fold(term.id);
1481
+ };
1482
+ const children = /* @__PURE__ */ new Map();
1483
+ const link = (parent, child) => {
1484
+ if (parent === void 0 || child === void 0) return;
1485
+ const set = children.get(parent) ?? /* @__PURE__ */ new Set();
1486
+ set.add(child);
1487
+ children.set(parent, set);
1488
+ };
1489
+ for (const term of terms) {
1490
+ const self = fold(term.id);
1491
+ for (const name of term.narrower ?? []) link(self, keyOf(name));
1492
+ for (const name of term.broader ?? []) link(keyOf(name), self);
1449
1493
  }
1450
- schemaOptions;
1451
- ajvByDialect = /* @__PURE__ */ new Map();
1452
- /**
1453
- * Keyed on the in-flight *promise*, not the resolved validator. Caching the
1454
- * result made this a check-then-act race: `fill` walks files through a worker
1455
- * pool, so every worker missed the cache while the first `loadSchema` was
1456
- * still pending and they all then compiled the same schema into the one
1457
- * shared per-dialect Ajv. Ajv registers a schema's `$id` on the first compile
1458
- * and rejects the second with "schema with key or id ... already exists",
1459
- * which took down any multi-file run against an $id-bearing schema. Storing
1460
- * the promise before the first await lets the losers await the one compile.
1461
- */
1462
- cache = /* @__PURE__ */ new Map();
1463
- ajvFor(dialect) {
1464
- let ajv = this.ajvByDialect.get(dialect);
1465
- if (!ajv) {
1466
- ajv = buildAjv(dialect);
1467
- registerRegistered(ajv, dialect, this.schemaOptions.registered);
1468
- this.ajvByDialect.set(dialect, ajv);
1469
- }
1470
- return ajv;
1471
- }
1472
- /**
1473
- * Synchronous by design: the `cache.set` has to happen in the same tick as
1474
- * the miss, or a second caller can slip in before the entry exists.
1475
- */
1476
- compile(ref) {
1477
- const cached = this.cache.get(ref);
1478
- if (cached) return cached;
1479
- const pending = this.compileUncached(ref);
1480
- this.cache.set(ref, pending);
1481
- pending.catch(() => {
1482
- if (this.cache.get(ref) === pending) this.cache.delete(ref);
1483
- });
1484
- return pending;
1485
- }
1486
- async compileUncached(ref) {
1487
- const schema = await loadSchema(ref, this.schemaOptions);
1488
- if (marksSchemaExternal(schema)) {
1489
- throw new DocmetaError(
1490
- `${ref}: "${FILE_SCHEMA_KEY}" cannot be stored in external metadata.`
1491
- );
1492
- }
1493
- const contradicted = definiteMarkConflict(schema, LOCATION_KEYWORD, isFieldLocation);
1494
- if (contradicted !== void 0) {
1495
- throw new DocmetaError(
1496
- `${ref}: "${LOCATION_KEYWORD}" says both "page" and "external" for "${contradicted}".`
1497
- );
1498
- }
1499
- const graphContradicted = definiteMarkConflict(
1500
- schema,
1501
- GRAPH_OUTPUT_KEYWORD,
1502
- (value) => typeof value === "boolean"
1503
- );
1504
- if (graphContradicted !== void 0) {
1505
- throw new DocmetaError(
1506
- `${ref}: "${GRAPH_OUTPUT_KEYWORD}" says both true and false for "${graphContradicted}".`
1507
- );
1508
- }
1509
- try {
1510
- const ajv = this.ajvFor(dialectOf(schema));
1511
- const id = typeof schema["$id"] === "string" ? schema["$id"] : void 0;
1512
- const registered = id != null ? ajv.getSchema(id) : void 0;
1513
- if (registered) {
1514
- if (registered.schema === schema) return registered;
1515
- const { $id: _taken, ...anonymous } = schema;
1516
- return ajv.compile(anonymous);
1517
- }
1518
- return ajv.compile(schema);
1519
- } catch (err) {
1520
- if (isMarkShapeError(err)) {
1521
- throw new DocmetaError(
1522
- `${ref}: "${ENCRYPT_KEYWORD}" must be true or false.`
1523
- );
1524
- }
1525
- if (isLocationShapeError(err)) {
1526
- throw new DocmetaError(
1527
- `${ref}: "${LOCATION_KEYWORD}" must be "page" or "external".`
1528
- );
1529
- }
1530
- if (isGraphOutputShapeError(err)) {
1531
- throw new DocmetaError(
1532
- `${ref}: "${GRAPH_OUTPUT_KEYWORD}" must be true or false.`
1533
- );
1534
- }
1535
- throw new DocmetaError(
1536
- `Schema "${ref}" failed to compile: ${errorMessage(err)}`
1537
- );
1494
+ const branches = /* @__PURE__ */ new Map();
1495
+ return {
1496
+ find(value) {
1497
+ const named = byName.get(fold(value));
1498
+ const term = named ?? byAlt.get(fold(value));
1499
+ if (term === void 0) return void 0;
1500
+ return { key: fold(term.id), label: term.label, alt: named === void 0 };
1501
+ },
1502
+ below(under) {
1503
+ const root = keyOf(under);
1504
+ if (root === void 0) return void 0;
1505
+ let found = branches.get(root);
1506
+ if (found === void 0) {
1507
+ const seen = /* @__PURE__ */ new Set();
1508
+ const queue = [...children.get(root) ?? []];
1509
+ for (let next = queue.shift(); next !== void 0; next = queue.shift()) {
1510
+ if (seen.has(next)) continue;
1511
+ seen.add(next);
1512
+ queue.push(...children.get(next) ?? []);
1513
+ }
1514
+ seen.delete(root);
1515
+ found = seen;
1516
+ branches.set(root, found);
1517
+ }
1518
+ return found;
1519
+ },
1520
+ labels(keys) {
1521
+ return terms.filter((t) => keys === void 0 || keys.has(fold(t.id))).map((t) => t.label);
1538
1522
  }
1523
+ };
1524
+ }
1525
+
1526
+ // src/meta/core/validator.ts
1527
+ import * as AjvDraft07Ns from "ajv";
1528
+ import * as Ajv2019Ns from "ajv/dist/2019.js";
1529
+ import * as Ajv2020Ns from "ajv/dist/2020.js";
1530
+ import * as AjvDraft04Ns from "ajv-draft-04";
1531
+ import * as addFormatsNs from "ajv-formats";
1532
+ import { createRequire } from "node:module";
1533
+ var draft06MetaSchema = createRequire(import.meta.url)(
1534
+ "ajv/dist/refs/json-schema-draft-06.json"
1535
+ );
1536
+ var AjvDraft07 = AjvDraft07Ns.default;
1537
+ var Ajv2019 = Ajv2019Ns.default;
1538
+ var Ajv2020 = Ajv2020Ns.default;
1539
+ var AjvDraft04 = AjvDraft04Ns.default;
1540
+ var addFormats = addFormatsNs.default;
1541
+ function dialectOf(schema) {
1542
+ const meta = typeof schema.$schema === "string" ? schema.$schema : "";
1543
+ if (meta.includes("2019-09")) return "2019";
1544
+ if (meta.includes("draft-07") || meta.includes("draft/7") || meta.includes("draft-06") || meta.includes("draft/6")) {
1545
+ return "draft7";
1539
1546
  }
1540
- /**
1541
- * The instance pointers of `data` that carry `x-manni-encrypt: true` under
1542
- * any schema in `refs`, in the order the validator evaluated them.
1543
- *
1544
- * A first pass with the recording keyword, so a mark counts exactly where
1545
- * validation would evaluate it. Only present values are marked: Ajv applies
1546
- * a property's subschema to a property that exists. A branch Ajv does not
1547
- * take (`then` behind a failing `if`, an `anyOf` branch after a passing
1548
- * one) contributes nothing; a branch it takes contributes its marks
1549
- * whether or not the branch passes, because a ciphertext routinely fails
1550
- * the rest of its own subschema until it is decrypted.
1551
- */
1552
- async markedPointers(data, refs) {
1553
- const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1554
- void _omit;
1555
- const marks = /* @__PURE__ */ new Set();
1556
- for (const ref of refs) {
1557
- const fn = await this.compile(ref);
1558
- markRecorder = marks;
1559
- try {
1560
- fn(subject);
1561
- } finally {
1562
- markRecorder = void 0;
1547
+ if (meta.includes("draft-04") || meta.includes("draft/4")) return "draft4";
1548
+ return "2020";
1549
+ }
1550
+ function buildAjv(dialect, coerceTypes = false) {
1551
+ const opts = { allErrors: true, strict: false, coerceTypes };
1552
+ const ajv = dialect === "2019" ? new Ajv2019(opts) : dialect === "draft7" ? new AjvDraft07(opts) : dialect === "draft4" ? new AjvDraft04(opts) : new Ajv2020(opts);
1553
+ addFormats(ajv);
1554
+ if (dialect === "draft7") ajv.addMetaSchema(draft06MetaSchema);
1555
+ registerEncryptKeyword(ajv);
1556
+ registerLocationKeyword(ajv);
1557
+ registerGraphOutputKeyword(ajv);
1558
+ registerTermKeyword(ajv);
1559
+ registerBuiltins(ajv, dialect);
1560
+ return ajv;
1561
+ }
1562
+ var markRecorder;
1563
+ function registerEncryptKeyword(ajv) {
1564
+ ajv.addKeyword({
1565
+ keyword: ENCRYPT_KEYWORD,
1566
+ metaSchema: { type: "boolean" },
1567
+ errors: false,
1568
+ validate: (schema, _data, _parent, cxt) => {
1569
+ if (schema === true && markRecorder !== void 0) {
1570
+ markRecorder.add(cxt?.instancePath ?? "");
1563
1571
  }
1572
+ return true;
1564
1573
  }
1565
- return marks;
1574
+ });
1575
+ }
1576
+ function isMarkShapeError(err) {
1577
+ return err instanceof Error && err.message.includes(`"${ENCRYPT_KEYWORD}"`);
1578
+ }
1579
+ var locationRecorder;
1580
+ function topLevelKey(instancePath) {
1581
+ if (!instancePath.startsWith("/") || instancePath.indexOf("/", 1) !== -1) {
1582
+ return void 0;
1566
1583
  }
1567
- /**
1568
- * The location each top-level key of `data` prefers under `refs`: `page` or
1569
- * `external`, and the ref whose `x-manni-location` mark decided it. A key no
1570
- * schema marks has no entry.
1571
- *
1572
- * A first pass with the recording keyword, as `markedPointers` runs, so a
1573
- * mark counts exactly where validation would evaluate it, and a nested mark
1574
- * is ignored. Only present values are marked: Ajv applies a property's
1575
- * subschema to a property that exists. A caller asking where a key it is
1576
- * about to write belongs passes `data` that already holds the candidate
1577
- * value. `$schema` is stripped first, as validation does.
1578
- *
1579
- * Refs are evaluated in order and a later ref's mark wins. A ref that says
1580
- * both values for one key unconditionally is refused when it compiles; one
1581
- * whose evaluated branches say both gives that key no preference.
1582
- */
1583
- async locationPreferences(data, refs) {
1584
- const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1585
- void _omit;
1586
- const preferences = /* @__PURE__ */ new Map();
1587
- for (const ref of refs) {
1588
- const fn = await this.compile(ref);
1589
- const seen = /* @__PURE__ */ new Map();
1590
- locationRecorder = seen;
1591
- try {
1592
- fn(subject);
1593
- } finally {
1594
- locationRecorder = void 0;
1595
- }
1596
- for (const [key, locations] of seen) {
1597
- const [location, ...others] = [...locations];
1598
- if (location === void 0 || others.length > 0) continue;
1599
- preferences.set(key, { location, schema: ref });
1584
+ return instancePath.slice(1).replace(/~1/g, "/").replace(/~0/g, "~");
1585
+ }
1586
+ function registerLocationKeyword(ajv) {
1587
+ ajv.addKeyword({
1588
+ keyword: LOCATION_KEYWORD,
1589
+ metaSchema: { type: "string", enum: ["page", "external"] },
1590
+ errors: false,
1591
+ validate: (schema, _data, _parent, cxt) => {
1592
+ if (locationRecorder !== void 0 && isFieldLocation(schema)) {
1593
+ const key = topLevelKey(cxt?.instancePath ?? "");
1594
+ if (key !== void 0) {
1595
+ const seen = locationRecorder.get(key);
1596
+ if (seen) seen.add(schema);
1597
+ else locationRecorder.set(key, /* @__PURE__ */ new Set([schema]));
1598
+ }
1600
1599
  }
1600
+ return true;
1601
1601
  }
1602
- return preferences;
1603
- }
1604
- /**
1605
- * The top-level property names the schemas in `refs` claim: the keys of
1606
- * each schema's own `properties`, each once. What a page's schema set
1607
- * claims decides which merge-safe fields a `derive:` block with no `fields`
1608
- * manages on it (proposal 0069). A property reached only through `allOf`,
1609
- * `$ref` or a conditional is not counted, so a schema that should manage a
1610
- * field names it in its root `properties`. A schema that fails to load or
1611
- * compile throws, as it would for `validate`.
1612
- */
1613
- async claimedProperties(refs) {
1614
- const claimed = /* @__PURE__ */ new Set();
1615
- for (const ref of refs) {
1616
- const schema = (await this.compile(ref)).schema;
1617
- if (typeof schema !== "object" || schema === null) continue;
1618
- const properties = schema["properties"];
1619
- if (typeof properties !== "object" || properties === null || Array.isArray(properties)) continue;
1620
- for (const key of Object.keys(properties)) claimed.add(key);
1621
- }
1622
- return claimed;
1623
- }
1624
- /**
1625
- * Whether each top-level key of `data` belongs in a published graph under
1626
- * `refs`, as its `x-manni-graph-output` mark says. A key no schema marks has no
1627
- * entry, which the caller reads as `true`: absent means harvested.
1628
- *
1629
- * A first pass with the recording keyword, as `locationPreferences` runs, so
1630
- * a mark counts exactly where validation would evaluate it, and a mark nested
1631
- * inside `graph` is ignored. Only present values are marked: Ajv applies a
1632
- * property's subschema to a property that exists. `$schema` is stripped
1633
- * first, as validation does.
1634
- *
1635
- * Refs are evaluated in order and a later ref's mark wins, so a house schema
1636
- * listed after a vocabulary refines it. A schema that says both on paths
1637
- * every document takes is refused when it compiles. A ref whose conditional
1638
- * branches say both `true` and `false` gives that key no preference: with
1639
- * `allErrors`, Ajv evaluates failing branches too, so neither value is that
1640
- * ref's answer and an earlier ref's stands.
1641
- */
1642
- async graphOutputPreferences(data, refs) {
1643
- const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1644
- void _omit;
1645
- const preferences = /* @__PURE__ */ new Map();
1646
- for (const ref of refs) {
1647
- const fn = await this.compile(ref);
1648
- const seen = /* @__PURE__ */ new Map();
1649
- graphOutputRecorder = seen;
1650
- try {
1651
- fn(subject);
1652
- } finally {
1653
- graphOutputRecorder = void 0;
1654
- }
1655
- for (const [key, values] of seen) {
1656
- const [value, ...others] = [...values];
1657
- if (value === void 0 || others.length > 0) continue;
1658
- preferences.set(key, value);
1602
+ });
1603
+ }
1604
+ function isLocationShapeError(err) {
1605
+ return err instanceof Error && err.message.includes(`"${LOCATION_KEYWORD}"`);
1606
+ }
1607
+ var graphOutputRecorder;
1608
+ function registerGraphOutputKeyword(ajv) {
1609
+ ajv.addKeyword({
1610
+ keyword: GRAPH_OUTPUT_KEYWORD,
1611
+ metaSchema: { type: "boolean" },
1612
+ errors: false,
1613
+ validate: (schema, _data, _parent, cxt) => {
1614
+ if (graphOutputRecorder !== void 0 && typeof schema === "boolean") {
1615
+ const key = topLevelKey(cxt?.instancePath ?? "");
1616
+ if (key !== void 0) {
1617
+ const seen = graphOutputRecorder.get(key);
1618
+ if (seen) seen.add(schema);
1619
+ else graphOutputRecorder.set(key, /* @__PURE__ */ new Set([schema]));
1620
+ }
1659
1621
  }
1622
+ return true;
1660
1623
  }
1661
- return preferences;
1662
- }
1663
- /**
1664
- * Validate `data` against every schema in `refs`. Returns all violations,
1665
- * each tagged with the schema that produced it and a source line via
1666
- * `lineFor`.
1667
- *
1668
- * `colFor` is optional and additive: this signature is public, so a fourth
1669
- * *required* parameter — or a widened third one — would be a consumer break.
1670
- * Callers with an extractor that supplies no column pass nothing and get the
1671
- * previous behavior exactly.
1672
- */
1673
- async validate(data, refs, lineFor, colFor, locate) {
1674
- const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1675
- void _omit;
1676
- const errors = [];
1677
- for (const ref of refs) {
1678
- const fn = await this.compile(ref);
1679
- const ok = fn(subject);
1680
- if (ok) continue;
1681
- for (const e of fn.errors ?? []) {
1682
- errors.push(toFieldError(ref, e, lineFor, colFor, locate));
1624
+ });
1625
+ }
1626
+ function isGraphOutputShapeError(err) {
1627
+ return err instanceof Error && err.message.includes(`"${GRAPH_OUTPUT_KEYWORD}"`);
1628
+ }
1629
+ var termRecorder;
1630
+ function registerTermKeyword(ajv) {
1631
+ ajv.addKeyword({
1632
+ keyword: TERM_KEYWORD,
1633
+ metaSchema: TERM_MARK_META_SCHEMA,
1634
+ errors: false,
1635
+ validate: (schema, data, _parent, cxt) => {
1636
+ if (termRecorder !== void 0 && isTermMark(schema)) {
1637
+ termRecorder.push({
1638
+ pointer: cxt?.instancePath ?? "",
1639
+ value: data,
1640
+ ...schema.under === void 0 ? {} : { under: schema.under }
1641
+ });
1683
1642
  }
1643
+ return true;
1684
1644
  }
1685
- return errors;
1686
- }
1687
- };
1688
- function subjectOf(e) {
1689
- switch (e.keyword) {
1690
- case "required":
1691
- return e.params.missingProperty;
1692
- case "additionalProperties":
1693
- return e.params.additionalProperty;
1694
- case "format":
1695
- return e.params.format;
1696
- case "type":
1697
- return e.params.type;
1698
- default:
1699
- return void 0;
1700
- }
1645
+ });
1701
1646
  }
1702
- function toFieldError(schema, e, lineFor, colFor, locate) {
1703
- const defined = e;
1704
- const instancePath = e.instancePath;
1705
- const subject = subjectOf(defined);
1706
- let message = e.message ?? "is invalid";
1707
- let wantsColumn = true;
1708
- if (defined.keyword === "required") {
1709
- message = `must have required property '${defined.params.missingProperty}'`;
1710
- wantsColumn = false;
1711
- } else if (defined.keyword === "additionalProperties") {
1712
- message = `must NOT have additional property '${defined.params.additionalProperty}'`;
1713
- wantsColumn = false;
1714
- }
1715
- const located = defined.keyword === "additionalProperties" ? locate?.(
1716
- `${instancePath}/${escapePointerSegment(defined.params.additionalProperty)}`
1717
- ) ?? locate?.(instancePath) : locate?.(instancePath);
1718
- if (located) {
1719
- return {
1720
- schema,
1721
- instancePath,
1722
- message,
1723
- keyword: e.keyword,
1724
- ...subject != null ? { subject } : {},
1725
- file: located.file,
1726
- ...located.line != null ? { line: located.line } : {},
1727
- ...wantsColumn && located.col != null ? { col: located.col } : {}
1728
- };
1729
- }
1730
- const line = lineFor(instancePath);
1731
- const col = wantsColumn ? colFor?.(instancePath) : void 0;
1732
- return {
1733
- schema,
1734
- instancePath,
1735
- message,
1736
- keyword: e.keyword,
1737
- ...subject != null ? { subject } : {},
1738
- ...line != null ? { line } : {},
1739
- ...col != null ? { col } : {}
1740
- };
1647
+ function isTermShapeError(err) {
1648
+ return err instanceof Error && err.message.includes(`"${TERM_KEYWORD}"`);
1741
1649
  }
1742
-
1743
- // src/meta/core/page-marks.ts
1744
- function pageMarks(opts) {
1745
- const validator = lazyValidator(opts);
1746
- return async (label, probe, memberOf2) => {
1747
- const refs = pageRefs(opts, label, probe, memberOf2);
1748
- if (refs === void 0) return void 0;
1749
- try {
1750
- const preferences = await validator().locationPreferences({ ...probe }, refs);
1751
- const marked = /* @__PURE__ */ new Set();
1752
- for (const [key, p] of preferences) if (p.location === "external") marked.add(key);
1753
- return marked;
1754
- } catch (err) {
1755
- if (err instanceof DocmetaError) return void 0;
1756
- throw err;
1650
+ function marksSchemaExternal(schema) {
1651
+ const properties = schema["properties"];
1652
+ if (typeof properties !== "object" || properties === null) return false;
1653
+ const own = properties[FILE_SCHEMA_KEY];
1654
+ if (typeof own !== "object" || own === null) return false;
1655
+ return own[LOCATION_KEYWORD] === "external";
1656
+ }
1657
+ function isRecord2(value) {
1658
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1659
+ }
1660
+ function definiteMarkConflict(root, keyword, isMark) {
1661
+ const marks = /* @__PURE__ */ new Map();
1662
+ const localRef = (node, embedded) => {
1663
+ const ref = node["$ref"];
1664
+ if (embedded || typeof ref !== "string" || !ref.startsWith("#")) return void 0;
1665
+ const pointer = ref.slice(1);
1666
+ if (pointer === "") return root;
1667
+ if (!pointer.startsWith("/")) return void 0;
1668
+ let at2 = root;
1669
+ for (const raw of pointer.slice(1).split("/")) {
1670
+ let segment;
1671
+ try {
1672
+ segment = decodeURIComponent(raw).replace(/~1/g, "/").replace(/~0/g, "~");
1673
+ } catch {
1674
+ return void 0;
1675
+ }
1676
+ if (Array.isArray(at2)) at2 = at2[Number(segment)];
1677
+ else if (isRecord2(at2)) at2 = at2[segment];
1678
+ else return void 0;
1757
1679
  }
1680
+ return at2;
1758
1681
  };
1759
- }
1760
- function pageClaims(opts) {
1761
- const validator = lazyValidator(opts);
1762
- return async (label, probe, memberOf2) => {
1763
- const refs = pageRefs(opts, label, probe, memberOf2);
1764
- if (refs === void 0) return void 0;
1765
- try {
1766
- return await validator().claimedProperties(refs);
1767
- } catch (err) {
1768
- if (err instanceof DocmetaError) return void 0;
1769
- throw err;
1682
+ const isEmbedded = (node, embedded) => embedded || node !== root && typeof node["$id"] === "string";
1683
+ const allOf = (node) => Array.isArray(node["allOf"]) ? node["allOf"] : [];
1684
+ const property = (key, node, embedded, visited) => {
1685
+ if (!isRecord2(node) || visited.has(node)) return;
1686
+ visited.add(node);
1687
+ const inner = isEmbedded(node, embedded);
1688
+ const mark = node[keyword];
1689
+ if (isMark(mark)) {
1690
+ const seen = marks.get(key);
1691
+ if (seen) seen.add(mark);
1692
+ else marks.set(key, /* @__PURE__ */ new Set([mark]));
1693
+ }
1694
+ for (const entry of allOf(node)) property(key, entry, inner, visited);
1695
+ property(key, localRef(node, inner), inner, visited);
1696
+ };
1697
+ const object = (node, embedded, visited) => {
1698
+ if (!isRecord2(node) || visited.has(node)) return;
1699
+ visited.add(node);
1700
+ const inner = isEmbedded(node, embedded);
1701
+ const properties = node["properties"];
1702
+ if (isRecord2(properties)) {
1703
+ for (const [key, sub] of Object.entries(properties)) property(key, sub, inner, /* @__PURE__ */ new Set());
1770
1704
  }
1705
+ for (const entry of allOf(node)) object(entry, inner, visited);
1706
+ object(localRef(node, inner), inner, visited);
1771
1707
  };
1708
+ object(root, false, /* @__PURE__ */ new Set());
1709
+ for (const [key, seen] of marks) if (seen.size > 1) return key;
1710
+ return void 0;
1772
1711
  }
1773
- function lazyValidator(opts) {
1774
- let built;
1775
- return () => opts.validator instanceof Validator ? opts.validator : built ??= opts.validator();
1776
- }
1777
- function pageSchemaSet(opts, label, probe, memberOf2) {
1778
- return resolveSchemaSetWithSource({
1779
- filePath: label,
1780
- fileSchema: probe[FILE_SCHEMA_KEY],
1781
- ...opts.cliSchemas !== void 0 ? { cliSchemas: [...opts.cliSchemas] } : {},
1782
- config: opts.config,
1783
- memberOf: opts.memberOf?.(label) ?? memberOf2,
1784
- fileBase: opts.cwd,
1785
- trustRoot: opts.trustRoot
1786
- }).schemas;
1787
- }
1788
- function pageRefs(opts, label, probe, memberOf2) {
1789
- try {
1790
- return pageSchemaSet(opts, label, probe, memberOf2);
1791
- } catch (err) {
1792
- if (err instanceof DocmetaError) return void 0;
1793
- throw err;
1794
- }
1795
- }
1796
- function marksValidator(opts) {
1797
- return () => new Validator(
1798
- schemaLoadOptions({
1799
- root: opts.configDir ?? opts.cwd,
1800
- fileBase: opts.cwd,
1801
- ttlHours: opts.config?.schemaCache?.ttlHours,
1802
- offline: opts.offline ?? opts.config?.offline,
1803
- pins: collectSchemaPins(opts.config),
1804
- registered: opts.config?.registered
1805
- })
1806
- );
1807
- }
1808
- async function configMarks(configPath, cwd) {
1809
- const loaded = await loadConfig(configPath, cwd);
1810
- if (loaded === null) return void 0;
1811
- const config = rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd);
1812
- return pageMarks({
1813
- validator: marksValidator({ config, cwd, configDir: loaded.dir }),
1814
- config,
1815
- cwd,
1816
- trustRoot: schemaTrustRoot(cwd, loaded.dir)
1817
- });
1818
- }
1819
- async function metaSection(configPath, cwd) {
1820
- const loaded = await loadConfig(configPath, cwd);
1821
- if (loaded === null) return null;
1822
- return rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd);
1712
+ function registerBuiltins(ajv, dialect) {
1713
+ for (const { id, url, legacyUrl, schema } of publishedBuiltins()) {
1714
+ ajv.addSchema(schema, url, void 0, false);
1715
+ ajv.addSchema(schema, legacyUrl, void 0, false);
1716
+ if (dialect === "draft4") ajv.addSchema(schema, id, void 0, false);
1717
+ }
1823
1718
  }
1824
- function familyMarks(opts) {
1825
- let built;
1826
- const defaults = () => pageMarks({
1827
- validator: marksValidator({ config: null, cwd: opts.cwd, configDir: opts.configDir }),
1828
- config: null,
1829
- cwd: opts.cwd,
1830
- trustRoot: schemaTrustRoot(opts.cwd, opts.configDir)
1831
- });
1832
- return () => built ??= (async () => {
1833
- if (opts.configPath === void 0) return defaults();
1834
- try {
1835
- return await configMarks(opts.configPath, opts.cwd) ?? defaults();
1836
- } catch (err) {
1837
- if (err instanceof DocmetaError) return defaults();
1838
- throw err;
1839
- }
1840
- })();
1719
+ function registerRegistered(ajv, dialect, registered) {
1720
+ for (const { id, schema } of registered?.values() ?? []) {
1721
+ ajv.addSchema(schema, dialect === "draft4" ? id : void 0, void 0, false);
1722
+ }
1841
1723
  }
1842
-
1843
- // src/meta/core/projection.ts
1844
- var SYSTEM_COLUMNS = ["_path", "_format", "_present", "_data"];
1845
- var RESERVED = new Set(SYSTEM_COLUMNS);
1846
- function quoteIdent(name) {
1847
- return `"${name.replaceAll('"', '""')}"`;
1724
+ function compileWithFormats(schema, registered, options = {}) {
1725
+ const ajv = buildAjv("2020", options.coerce === true ? "array" : false);
1726
+ registerRegistered(ajv, "2020", registered);
1727
+ return ajv.compile(schema);
1848
1728
  }
1849
- function bindValue(value) {
1850
- if (value === void 0 || value === null) return null;
1851
- switch (typeof value) {
1852
- case "boolean":
1853
- return value ? 1 : 0;
1854
- case "number":
1855
- return Number.isFinite(value) ? value : null;
1856
- case "bigint":
1857
- case "string":
1858
- return value;
1859
- default:
1860
- return JSON.stringify(value);
1729
+ var formatRegistry;
1730
+ function formatsAjv() {
1731
+ if (!formatRegistry) {
1732
+ formatRegistry = new Ajv2020({ strict: false });
1733
+ addFormats(formatRegistry);
1861
1734
  }
1735
+ return formatRegistry;
1862
1736
  }
1863
- function corpusDataColumns(entries, extraKeys = []) {
1864
- const keys = /* @__PURE__ */ new Set();
1865
- for (const { extracted } of entries) {
1866
- for (const key of Object.keys(extracted.data)) {
1867
- if (key !== "" && !RESERVED.has(key)) keys.add(key);
1737
+ var stringFormatsMemo;
1738
+ function stringFormatNames() {
1739
+ if (!stringFormatsMemo) {
1740
+ const names = /* @__PURE__ */ new Set();
1741
+ const registered = formatsAjv().formats;
1742
+ for (const [name, def] of Object.entries(registered)) {
1743
+ const enforcesStrings = def instanceof RegExp || typeof def === "function" || typeof def === "object" && def !== null && (def.type === void 0 || def.type === "string");
1744
+ if (enforcesStrings) names.add(name);
1868
1745
  }
1746
+ stringFormatsMemo = names;
1869
1747
  }
1870
- for (const key of extraKeys) {
1871
- if (key !== "" && !RESERVED.has(key)) keys.add(key);
1748
+ return stringFormatsMemo;
1749
+ }
1750
+ var formatCheckers = /* @__PURE__ */ new Map();
1751
+ function validatesFormat(name, value) {
1752
+ let fn = formatCheckers.get(name);
1753
+ if (!fn) {
1754
+ fn = formatsAjv().compile({ type: "string", format: name });
1755
+ formatCheckers.set(name, fn);
1872
1756
  }
1873
- return [...keys].sort();
1757
+ return fn(value);
1874
1758
  }
1875
- function createDocsTable(db, entries, dataColumns) {
1876
- db.exec(
1877
- `CREATE TABLE docs ("_path" TEXT PRIMARY KEY, "_format" TEXT, "_present" INTEGER, "_data" TEXT${dataColumns.map((c) => `, ${quoteIdent(c)}`).join("")})`
1878
- );
1879
- const insert = db.prepare(
1880
- `INSERT INTO docs VALUES (${["?", "?", "?", "?", ...dataColumns.map(() => "?")].join(", ")})`
1881
- );
1882
- db.exec("BEGIN");
1883
- let committed = false;
1884
- try {
1885
- for (const { label, extracted } of entries) {
1886
- insert.run(
1887
- label,
1888
- extracted.format,
1889
- extracted.present ? 1 : 0,
1890
- JSON.stringify(extracted.data),
1891
- ...dataColumns.map((c) => bindValue(extracted.data[c]))
1892
- );
1759
+ var Validator = class {
1760
+ /**
1761
+ * How this validator's schemas are loaded: the disk cache location, its TTL,
1762
+ * and `--offline`. Held per instance rather than read from module state, so
1763
+ * two differently-configured validations in one process each get their own
1764
+ * settings.
1765
+ *
1766
+ * That is not full isolation, and the difference matters to a library
1767
+ * caller: `schema-registry` keeps a process-wide memo of fetched schemas, so
1768
+ * one validator's successful fetch is visible to another. `offline` is
1769
+ * excluded from that sharing on purpose — an offline validator will not be
1770
+ * served something this process pulled over the network — but the memo is
1771
+ * still shared, so a URL fetched once is not re-fetched per instance.
1772
+ */
1773
+ constructor(schemaOptions = {}) {
1774
+ this.schemaOptions = schemaOptions;
1775
+ }
1776
+ schemaOptions;
1777
+ ajvByDialect = /* @__PURE__ */ new Map();
1778
+ /**
1779
+ * Keyed on the in-flight *promise*, not the resolved validator. Caching the
1780
+ * result made this a check-then-act race: `fill` walks files through a worker
1781
+ * pool, so every worker missed the cache while the first `loadSchema` was
1782
+ * still pending and they all then compiled the same schema into the one
1783
+ * shared per-dialect Ajv. Ajv registers a schema's `$id` on the first compile
1784
+ * and rejects the second with "schema with key or id ... already exists",
1785
+ * which took down any multi-file run against an $id-bearing schema. Storing
1786
+ * the promise before the first await lets the losers await the one compile.
1787
+ */
1788
+ cache = /* @__PURE__ */ new Map();
1789
+ ajvFor(dialect) {
1790
+ let ajv = this.ajvByDialect.get(dialect);
1791
+ if (!ajv) {
1792
+ ajv = buildAjv(dialect);
1793
+ registerRegistered(ajv, dialect, this.schemaOptions.registered);
1794
+ this.ajvByDialect.set(dialect, ajv);
1893
1795
  }
1894
- db.exec("COMMIT");
1895
- committed = true;
1896
- } finally {
1897
- if (!committed) db.exec("ROLLBACK");
1796
+ return ajv;
1898
1797
  }
1899
- }
1900
- function registerLineFor(db, entries) {
1901
- const byLabel = new Map(entries.map((e) => [e.label, e.extracted]));
1902
- db.function("lineFor", { deterministic: true }, (path, key) => {
1903
- if (typeof path !== "string" || typeof key !== "string") return null;
1904
- return byLabel.get(path)?.lineFor(key) ?? null;
1905
- });
1906
- }
1907
- function assertSingleStatement(sql) {
1908
- const cut = topLevelSemicolon(sql);
1909
- if (cut === -1) return;
1910
- if (!isTrivia(sql.slice(cut + 1))) {
1911
- throw new DocmetaError(
1912
- "Run a single SQL statement per query; text after the first `;` would be silently ignored."
1913
- );
1798
+ /**
1799
+ * Synchronous by design: the `cache.set` has to happen in the same tick as
1800
+ * the miss, or a second caller can slip in before the entry exists.
1801
+ */
1802
+ compile(ref) {
1803
+ const cached = this.cache.get(ref);
1804
+ if (cached) return cached;
1805
+ const pending = this.compileUncached(ref);
1806
+ this.cache.set(ref, pending);
1807
+ pending.catch(() => {
1808
+ if (this.cache.get(ref) === pending) this.cache.delete(ref);
1809
+ });
1810
+ return pending;
1914
1811
  }
1915
- }
1916
- function startsStringOrIdent(sql, i) {
1917
- const ch = sql[i];
1918
- return ch === "'" || ch === '"' || ch === "`" || ch === "[";
1919
- }
1920
- function startsComment(sql, i) {
1921
- const ch = sql[i];
1922
- return ch === "-" && sql[i + 1] === "-" || ch === "/" && sql[i + 1] === "*";
1923
- }
1924
- function skipStringOrIdent(sql, i) {
1925
- const quote = sql[i];
1926
- if (quote === "[") {
1927
- let j2 = i + 1;
1928
- while (j2 < sql.length && sql[j2] !== "]") j2++;
1929
- return j2 + 1;
1812
+ async compileUncached(ref) {
1813
+ const schema = await loadSchema(ref, this.schemaOptions);
1814
+ if (marksSchemaExternal(schema)) {
1815
+ throw new DocmetaError(
1816
+ `${ref}: "${FILE_SCHEMA_KEY}" cannot be stored in external metadata.`
1817
+ );
1818
+ }
1819
+ const contradicted = definiteMarkConflict(schema, LOCATION_KEYWORD, isFieldLocation);
1820
+ if (contradicted !== void 0) {
1821
+ throw new DocmetaError(
1822
+ `${ref}: "${LOCATION_KEYWORD}" says both "page" and "external" for "${contradicted}".`
1823
+ );
1824
+ }
1825
+ const graphContradicted = definiteMarkConflict(
1826
+ schema,
1827
+ GRAPH_OUTPUT_KEYWORD,
1828
+ (value) => typeof value === "boolean"
1829
+ );
1830
+ if (graphContradicted !== void 0) {
1831
+ throw new DocmetaError(
1832
+ `${ref}: "${GRAPH_OUTPUT_KEYWORD}" says both true and false for "${graphContradicted}".`
1833
+ );
1834
+ }
1835
+ try {
1836
+ const ajv = this.ajvFor(dialectOf(schema));
1837
+ const id = typeof schema["$id"] === "string" ? schema["$id"] : void 0;
1838
+ const registered = id != null ? ajv.getSchema(id) : void 0;
1839
+ if (registered) {
1840
+ if (registered.schema === schema) return registered;
1841
+ const { $id: _taken, ...anonymous } = schema;
1842
+ return ajv.compile(anonymous);
1843
+ }
1844
+ return ajv.compile(schema);
1845
+ } catch (err) {
1846
+ if (isMarkShapeError(err)) {
1847
+ throw new DocmetaError(
1848
+ `${ref}: "${ENCRYPT_KEYWORD}" must be true or false.`
1849
+ );
1850
+ }
1851
+ if (isLocationShapeError(err)) {
1852
+ throw new DocmetaError(
1853
+ `${ref}: "${LOCATION_KEYWORD}" must be "page" or "external".`
1854
+ );
1855
+ }
1856
+ if (isGraphOutputShapeError(err)) {
1857
+ throw new DocmetaError(
1858
+ `${ref}: "${GRAPH_OUTPUT_KEYWORD}" must be true or false.`
1859
+ );
1860
+ }
1861
+ if (isTermShapeError(err)) {
1862
+ throw new DocmetaError(
1863
+ `${ref}: "${TERM_KEYWORD}" must be an object with an optional "under" string.`
1864
+ );
1865
+ }
1866
+ throw new DocmetaError(
1867
+ `Schema "${ref}" failed to compile: ${errorMessage(err)}`
1868
+ );
1869
+ }
1930
1870
  }
1931
- let j = i + 1;
1932
- while (j < sql.length) {
1933
- if (sql[j] === quote) {
1934
- if (sql[j + 1] === quote) {
1935
- j += 2;
1936
- continue;
1871
+ /**
1872
+ * The instance pointers of `data` that carry `x-manni-encrypt: true` under
1873
+ * any schema in `refs`, in the order the validator evaluated them.
1874
+ *
1875
+ * A first pass with the recording keyword, so a mark counts exactly where
1876
+ * validation would evaluate it. Only present values are marked: Ajv applies
1877
+ * a property's subschema to a property that exists. A branch Ajv does not
1878
+ * take (`then` behind a failing `if`, an `anyOf` branch after a passing
1879
+ * one) contributes nothing; a branch it takes contributes its marks
1880
+ * whether or not the branch passes, because a ciphertext routinely fails
1881
+ * the rest of its own subschema until it is decrypted.
1882
+ */
1883
+ async markedPointers(data, refs) {
1884
+ const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1885
+ void _omit;
1886
+ const marks = /* @__PURE__ */ new Set();
1887
+ for (const ref of refs) {
1888
+ const fn = await this.compile(ref);
1889
+ markRecorder = marks;
1890
+ try {
1891
+ fn(subject);
1892
+ } finally {
1893
+ markRecorder = void 0;
1937
1894
  }
1938
- return j + 1;
1939
1895
  }
1940
- j++;
1896
+ return marks;
1941
1897
  }
1942
- return j;
1943
- }
1944
- function skipComment(sql, i) {
1945
- if (sql[i] === "-") {
1946
- let j = i + 2;
1947
- while (j < sql.length && sql[j] !== "\n") j++;
1948
- return j < sql.length ? j + 1 : j;
1898
+ /**
1899
+ * The location each top-level key of `data` prefers under `refs`: `page` or
1900
+ * `external`, and the ref whose `x-manni-location` mark decided it. A key no
1901
+ * schema marks has no entry.
1902
+ *
1903
+ * A first pass with the recording keyword, as `markedPointers` runs, so a
1904
+ * mark counts exactly where validation would evaluate it, and a nested mark
1905
+ * is ignored. Only present values are marked: Ajv applies a property's
1906
+ * subschema to a property that exists. A caller asking where a key it is
1907
+ * about to write belongs passes `data` that already holds the candidate
1908
+ * value. `$schema` is stripped first, as validation does.
1909
+ *
1910
+ * Refs are evaluated in order and a later ref's mark wins. A ref that says
1911
+ * both values for one key unconditionally is refused when it compiles; one
1912
+ * whose evaluated branches say both gives that key no preference.
1913
+ */
1914
+ async locationPreferences(data, refs) {
1915
+ const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1916
+ void _omit;
1917
+ const preferences = /* @__PURE__ */ new Map();
1918
+ for (const ref of refs) {
1919
+ const fn = await this.compile(ref);
1920
+ const seen = /* @__PURE__ */ new Map();
1921
+ locationRecorder = seen;
1922
+ try {
1923
+ fn(subject);
1924
+ } finally {
1925
+ locationRecorder = void 0;
1926
+ }
1927
+ for (const [key, locations] of seen) {
1928
+ const [location, ...others] = [...locations];
1929
+ if (location === void 0 || others.length > 0) continue;
1930
+ preferences.set(key, { location, schema: ref });
1931
+ }
1932
+ }
1933
+ return preferences;
1949
1934
  }
1950
- const end = sql.indexOf("*/", i + 2);
1951
- return end === -1 ? sql.length : end + 2;
1952
- }
1953
- function topLevelSemicolon(sql) {
1954
- let i = 0;
1955
- while (i < sql.length) {
1956
- if (startsStringOrIdent(sql, i)) {
1957
- i = skipStringOrIdent(sql, i);
1958
- } else if (startsComment(sql, i)) {
1959
- i = skipComment(sql, i);
1960
- } else if (sql[i] === ";") {
1961
- return i;
1962
- } else {
1963
- i++;
1935
+ /**
1936
+ * The top-level property names the schemas in `refs` claim: the keys of
1937
+ * each schema's own `properties`, each once. What a page's schema set
1938
+ * claims decides which merge-safe fields a `derive:` block with no `fields`
1939
+ * manages on it (proposal 0069). A property reached only through `allOf`,
1940
+ * `$ref` or a conditional is not counted, so a schema that should manage a
1941
+ * field names it in its root `properties`. A schema that fails to load or
1942
+ * compile throws, as it would for `validate`.
1943
+ */
1944
+ async claimedProperties(refs) {
1945
+ const claimed = /* @__PURE__ */ new Set();
1946
+ for (const ref of refs) {
1947
+ const schema = (await this.compile(ref)).schema;
1948
+ if (typeof schema !== "object" || schema === null) continue;
1949
+ const properties = schema["properties"];
1950
+ if (typeof properties !== "object" || properties === null || Array.isArray(properties)) continue;
1951
+ for (const key of Object.keys(properties)) claimed.add(key);
1964
1952
  }
1953
+ return claimed;
1965
1954
  }
1966
- return -1;
1967
- }
1968
- var PARAM_NAME_HEAD = /^[A-Za-z_][A-Za-z0-9_]*/;
1969
- function isParamName(name) {
1970
- return PARAM_NAME_HEAD.exec(name)?.[0] === name;
1971
- }
1972
- function collectNamedParameters(sql) {
1973
- const tokens = [];
1974
- const seen = /* @__PURE__ */ new Set();
1975
- const prefixOf = /* @__PURE__ */ new Map();
1976
- let i = 0;
1977
- while (i < sql.length) {
1978
- const ch = sql[i];
1979
- if (startsStringOrIdent(sql, i)) {
1980
- i = skipStringOrIdent(sql, i);
1981
- } else if (startsComment(sql, i)) {
1982
- i = skipComment(sql, i);
1983
- } else if (ch === "$" || ch === ":" || ch === "@") {
1984
- if (ch === ":" && sql[i + 1] === ":") {
1985
- i += 2;
1986
- continue;
1955
+ /**
1956
+ * Whether each top-level key of `data` belongs in a published graph under
1957
+ * `refs`, as its `x-manni-graph-output` mark says. A key no schema marks has no
1958
+ * entry, which the caller reads as `true`: absent means harvested.
1959
+ *
1960
+ * A first pass with the recording keyword, as `locationPreferences` runs, so
1961
+ * a mark counts exactly where validation would evaluate it, and a mark nested
1962
+ * inside `graph` is ignored. Only present values are marked: Ajv applies a
1963
+ * property's subschema to a property that exists. `$schema` is stripped
1964
+ * first, as validation does.
1965
+ *
1966
+ * Refs are evaluated in order and a later ref's mark wins, so a house schema
1967
+ * listed after a vocabulary refines it. A schema that says both on paths
1968
+ * every document takes is refused when it compiles. A ref whose conditional
1969
+ * branches say both `true` and `false` gives that key no preference: with
1970
+ * `allErrors`, Ajv evaluates failing branches too, so neither value is that
1971
+ * ref's answer and an earlier ref's stands.
1972
+ */
1973
+ async graphOutputPreferences(data, refs) {
1974
+ const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
1975
+ void _omit;
1976
+ const preferences = /* @__PURE__ */ new Map();
1977
+ for (const ref of refs) {
1978
+ const fn = await this.compile(ref);
1979
+ const seen = /* @__PURE__ */ new Map();
1980
+ graphOutputRecorder = seen;
1981
+ try {
1982
+ fn(subject);
1983
+ } finally {
1984
+ graphOutputRecorder = void 0;
1987
1985
  }
1988
- const m = PARAM_NAME_HEAD.exec(sql.slice(i + 1));
1989
- if (!m) {
1990
- i++;
1991
- continue;
1986
+ for (const [key, values] of seen) {
1987
+ const [value, ...others] = [...values];
1988
+ if (value === void 0 || others.length > 0) continue;
1989
+ preferences.set(key, value);
1992
1990
  }
1993
- const token = ch + m[0];
1994
- const priorPrefix = prefixOf.get(m[0]);
1995
- if (priorPrefix !== void 0 && priorPrefix !== ch) {
1996
- throw new DocmetaError(
1997
- `The statement references both ${priorPrefix}${m[0]} and ${token} \u2014 one name under two prefixes, which the engine rejects as conflicting. Use one spelling throughout.`
1998
- );
1991
+ }
1992
+ return preferences;
1993
+ }
1994
+ /**
1995
+ * Every place a schema in `refs` marks `x-manni-term` on `data`, at any
1996
+ * depth, in the order the validator evaluated them, each with the value it
1997
+ * was evaluated at.
1998
+ *
1999
+ * A first pass with the recording keyword, as `markedPointers` runs, so a
2000
+ * mark counts exactly where validation would evaluate it. Only present
2001
+ * values are marked. One ref evaluating the same mark at one pointer twice,
2002
+ * through `allOf` say, is one hit. `$schema` is stripped first, as
2003
+ * validation does.
2004
+ */
2005
+ async termMarks(data, refs) {
2006
+ const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
2007
+ void _omit;
2008
+ const hits = [];
2009
+ const once = /* @__PURE__ */ new Set();
2010
+ for (const ref of refs) {
2011
+ const fn = await this.compile(ref);
2012
+ const seen = [];
2013
+ termRecorder = seen;
2014
+ try {
2015
+ fn(subject);
2016
+ } finally {
2017
+ termRecorder = void 0;
1999
2018
  }
2000
- prefixOf.set(m[0], ch);
2001
- if (!seen.has(token)) {
2002
- seen.add(token);
2003
- tokens.push(token);
2019
+ for (const hit of seen) {
2020
+ const key = JSON.stringify([hit.pointer, hit.under ?? null]);
2021
+ if (once.has(key)) continue;
2022
+ once.add(key);
2023
+ hits.push({ ...hit, schema: ref });
2004
2024
  }
2005
- i += 1 + m[0].length;
2006
- } else {
2007
- i++;
2008
2025
  }
2026
+ return hits;
2009
2027
  }
2010
- return tokens;
2011
- }
2012
- function stripLeadingTrivia(sql) {
2013
- let i = 0;
2014
- for (; ; ) {
2015
- while (i < sql.length && /\s/.test(sql[i] ?? "")) i++;
2016
- if (startsComment(sql, i)) {
2017
- i = skipComment(sql, i);
2018
- continue;
2028
+ /**
2029
+ * Validate `data` against every schema in `refs`. Returns all violations,
2030
+ * each tagged with the schema that produced it and a source line via
2031
+ * `lineFor`.
2032
+ *
2033
+ * `colFor` is optional and additive: this signature is public, so a fourth
2034
+ * *required* parameter — or a widened third one — would be a consumer break.
2035
+ * Callers with an extractor that supplies no column pass nothing and get the
2036
+ * previous behavior exactly.
2037
+ */
2038
+ async validate(data, refs, lineFor, colFor, locate) {
2039
+ const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;
2040
+ void _omit;
2041
+ const errors = [];
2042
+ for (const ref of refs) {
2043
+ const fn = await this.compile(ref);
2044
+ const ok = fn(subject);
2045
+ if (ok) continue;
2046
+ for (const e of fn.errors ?? []) {
2047
+ errors.push(toFieldError(ref, e, lineFor, colFor, locate));
2048
+ }
2019
2049
  }
2020
- return sql.slice(i);
2050
+ return errors;
2051
+ }
2052
+ };
2053
+ function subjectOf(e) {
2054
+ switch (e.keyword) {
2055
+ case "required":
2056
+ return e.params.missingProperty;
2057
+ case "additionalProperties":
2058
+ return e.params.additionalProperty;
2059
+ case "format":
2060
+ return e.params.format;
2061
+ case "type":
2062
+ return e.params.type;
2063
+ default:
2064
+ return void 0;
2065
+ }
2066
+ }
2067
+ function toFieldError(schema, e, lineFor, colFor, locate) {
2068
+ const defined = e;
2069
+ const instancePath = e.instancePath;
2070
+ const subject = subjectOf(defined);
2071
+ let message = e.message ?? "is invalid";
2072
+ let wantsColumn = true;
2073
+ if (defined.keyword === "required") {
2074
+ message = `must have required property '${defined.params.missingProperty}'`;
2075
+ wantsColumn = false;
2076
+ } else if (defined.keyword === "additionalProperties") {
2077
+ message = `must NOT have additional property '${defined.params.additionalProperty}'`;
2078
+ wantsColumn = false;
2079
+ }
2080
+ const located = defined.keyword === "additionalProperties" ? locate?.(
2081
+ `${instancePath}/${escapePointerSegment(defined.params.additionalProperty)}`
2082
+ ) ?? locate?.(instancePath) : locate?.(instancePath);
2083
+ if (located) {
2084
+ return {
2085
+ schema,
2086
+ instancePath,
2087
+ message,
2088
+ keyword: e.keyword,
2089
+ ...subject != null ? { subject } : {},
2090
+ file: located.file,
2091
+ ...located.line != null ? { line: located.line } : {},
2092
+ ...wantsColumn && located.col != null ? { col: located.col } : {}
2093
+ };
2021
2094
  }
2095
+ const line = lineFor(instancePath);
2096
+ const col = wantsColumn ? colFor?.(instancePath) : void 0;
2097
+ return {
2098
+ schema,
2099
+ instancePath,
2100
+ message,
2101
+ keyword: e.keyword,
2102
+ ...subject != null ? { subject } : {},
2103
+ ...line != null ? { line } : {},
2104
+ ...col != null ? { col } : {}
2105
+ };
2022
2106
  }
2023
- function isTrivia(text) {
2024
- let i = 0;
2025
- while (i < text.length) {
2026
- const ch = text[i];
2027
- if (ch === void 0 || /\s/.test(ch) || ch === ";") {
2028
- i++;
2029
- continue;
2030
- }
2031
- if (startsComment(text, i)) {
2032
- i = skipComment(text, i);
2033
- continue;
2107
+
2108
+ // src/meta/core/page-marks.ts
2109
+ function pageMarks(opts) {
2110
+ const validator = lazyValidator(opts);
2111
+ return async (label, probe, memberOf2) => {
2112
+ const refs = pageRefs(opts, label, probe, memberOf2);
2113
+ if (refs === void 0) return void 0;
2114
+ try {
2115
+ const preferences = await validator().locationPreferences({ ...probe }, refs);
2116
+ const marked = /* @__PURE__ */ new Set();
2117
+ for (const [key, p] of preferences) if (p.location === "external") marked.add(key);
2118
+ return marked;
2119
+ } catch (err) {
2120
+ if (err instanceof DocmetaError) return void 0;
2121
+ throw err;
2034
2122
  }
2035
- return false;
2036
- }
2037
- return true;
2123
+ };
2038
2124
  }
2039
- var sqliteModule;
2040
- function loadSqlite() {
2041
- sqliteModule ??= (async () => {
2042
- const original = process.emitWarning.bind(process);
2043
- const filtered = (warning, ...rest) => {
2044
- const text = typeof warning === "string" ? warning : warning.message;
2045
- if (text.includes("SQLite is an experimental feature")) return;
2046
- Reflect.apply(original, process, [warning, ...rest]);
2047
- };
2048
- process.emitWarning = filtered;
2125
+ function pageClaims(opts) {
2126
+ const validator = lazyValidator(opts);
2127
+ return async (label, probe, memberOf2) => {
2128
+ const refs = pageRefs(opts, label, probe, memberOf2);
2129
+ if (refs === void 0) return void 0;
2049
2130
  try {
2050
- return await import("node:sqlite");
2051
- } finally {
2052
- process.emitWarning = original;
2131
+ return await validator().claimedProperties(refs);
2132
+ } catch (err) {
2133
+ if (err instanceof DocmetaError) return void 0;
2134
+ throw err;
2053
2135
  }
2054
- })();
2055
- return sqliteModule;
2056
- }
2057
-
2058
- // src/meta/core/collections.ts
2059
- import { isAbsolute as isAbsolute2, relative as relative4, resolve as resolvePath, sep as sep2 } from "node:path";
2060
- function memberOf(collections, configDir, base, label) {
2061
- if (collections.length === 0) return [];
2062
- if (label === STDIN_LABEL) return [];
2063
- const rel = relative4(configDir, resolvePath(base, label)).split(sep2).join("/");
2064
- if (isAbsolute2(rel)) return [];
2065
- return collections.filter((c) => isMember(c, rel)).map((c) => c.name);
2136
+ };
2066
2137
  }
2067
- function retainMembers(files, membersFor) {
2068
- return files.filter((label) => membersFor(label).length > 0);
2138
+ function lazyValidator(opts) {
2139
+ let built;
2140
+ return () => opts.validator instanceof Validator ? opts.validator : built ??= opts.validator();
2069
2141
  }
2070
- function collectionNames(collections) {
2071
- return (collections ?? []).map((c) => c.name);
2142
+ function pageSchemaSet(opts, label, probe, memberOf2) {
2143
+ return resolveSchemaSetWithSource({
2144
+ filePath: label,
2145
+ fileSchema: probe[FILE_SCHEMA_KEY],
2146
+ ...opts.cliSchemas !== void 0 ? { cliSchemas: [...opts.cliSchemas] } : {},
2147
+ config: opts.config,
2148
+ memberOf: opts.memberOf?.(label) ?? memberOf2,
2149
+ fileBase: opts.cwd,
2150
+ trustRoot: opts.trustRoot
2151
+ }).schemas;
2072
2152
  }
2073
- function collectCollections(entries, params) {
2074
- const declared = params.collections ?? [];
2075
- if (declared.length === 0) return [];
2076
- const base = params.base ?? ".";
2077
- const configDir = params.configDir ?? base;
2078
- const members = /* @__PURE__ */ new Map();
2079
- for (const entry of entries) {
2080
- for (const name of memberOf(declared, configDir, base, entry.label)) {
2081
- const list2 = members.get(name);
2082
- if (list2) list2.push(entry.label);
2083
- else members.set(name, [entry.label]);
2084
- }
2153
+ function pageRefs(opts, label, probe, memberOf2) {
2154
+ try {
2155
+ return pageSchemaSet(opts, label, probe, memberOf2);
2156
+ } catch (err) {
2157
+ if (err instanceof DocmetaError) return void 0;
2158
+ throw err;
2085
2159
  }
2086
- return declared.map((c) => ({ name: c.name, members: members.get(c.name) ?? [] }));
2087
2160
  }
2088
- function quoteSqlString(value) {
2089
- return `'${value.replaceAll("'", "''")}'`;
2161
+ function marksValidator(opts) {
2162
+ return () => new Validator(
2163
+ schemaLoadOptions({
2164
+ root: opts.configDir ?? opts.cwd,
2165
+ fileBase: opts.cwd,
2166
+ ttlHours: opts.config?.schemaCache?.ttlHours,
2167
+ offline: opts.offline ?? opts.config?.offline,
2168
+ pins: collectSchemaPins(opts.config),
2169
+ registered: opts.config?.registered
2170
+ })
2171
+ );
2090
2172
  }
2091
- function createCollectionViews(db, collections) {
2092
- for (const c of collections) {
2093
- const where = c.members.length === 0 ? "0" : `_path IN (${c.members.map(quoteSqlString).join(", ")})`;
2094
- db.exec(
2095
- `CREATE VIEW ${quoteIdent(c.name)} AS SELECT * FROM docs WHERE ${where}`
2096
- );
2097
- }
2173
+ async function configMarks(configPath, cwd) {
2174
+ const loaded = await loadConfig(configPath, cwd);
2175
+ if (loaded === null) return void 0;
2176
+ const config = rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd);
2177
+ return pageMarks({
2178
+ validator: marksValidator({ config, cwd, configDir: loaded.dir }),
2179
+ config,
2180
+ cwd,
2181
+ trustRoot: schemaTrustRoot(cwd, loaded.dir)
2182
+ });
2183
+ }
2184
+ async function metaSection(configPath, cwd) {
2185
+ const loaded = await loadConfig(configPath, cwd);
2186
+ if (loaded === null) return null;
2187
+ return rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd);
2188
+ }
2189
+ function familyMarks(opts) {
2190
+ let built;
2191
+ const defaults = () => pageMarks({
2192
+ validator: marksValidator({ config: null, cwd: opts.cwd, configDir: opts.configDir }),
2193
+ config: null,
2194
+ cwd: opts.cwd,
2195
+ trustRoot: schemaTrustRoot(opts.cwd, opts.configDir)
2196
+ });
2197
+ return () => built ??= (async () => {
2198
+ if (opts.configPath === void 0) return defaults();
2199
+ try {
2200
+ return await configMarks(opts.configPath, opts.cwd) ?? defaults();
2201
+ } catch (err) {
2202
+ if (err instanceof DocmetaError) return defaults();
2203
+ throw err;
2204
+ }
2205
+ })();
2098
2206
  }
2099
2207
 
2100
2208
  // src/meta/core/relocation.ts
2101
2209
  import { access, readFile as readFile4, stat as stat2, unlink } from "node:fs/promises";
2102
- import { basename as basename4, extname, isAbsolute as isAbsolute3, join as join3, relative as relative5, resolve as resolve3, sep as sep3 } from "node:path";
2210
+ import { basename as basename3, extname, isAbsolute as isAbsolute3, join as join3, relative as relative4, resolve as resolve3, sep as sep3 } from "node:path";
2103
2211
  import picomatch from "picomatch";
2104
2212
  import {
2105
2213
  LineCounter as LineCounter3,
@@ -2480,11 +2588,11 @@ function relocationContext(run, extras) {
2480
2588
  }
2481
2589
  var toPosix = (p) => p.split(sep3).join("/");
2482
2590
  function reported2(abs, base) {
2483
- const rel = relative5(base, abs);
2591
+ const rel = relative4(base, abs);
2484
2592
  return rel === "" ? "." : toPosix(rel);
2485
2593
  }
2486
2594
  function configSource(path, cwd) {
2487
- return toPosix(relative5(cwd, path)) || basename4(path);
2595
+ return toPosix(relative4(cwd, path)) || basename3(path);
2488
2596
  }
2489
2597
  function cloneCollection(c) {
2490
2598
  return {
@@ -2695,7 +2803,7 @@ var Model = class {
2695
2803
  /** A label relative to the config directory, posix; undefined outside it. */
2696
2804
  relative(label) {
2697
2805
  if (label === "<stdin>") return void 0;
2698
- const rel = toPosix(relative5(this.configDir, resolve3(this.ctx.base, label)));
2806
+ const rel = toPosix(relative4(this.configDir, resolve3(this.ctx.base, label)));
2699
2807
  return isAbsolute3(rel) || rel.startsWith("../") ? void 0 : rel;
2700
2808
  }
2701
2809
  };
@@ -2710,12 +2818,12 @@ async function collectionPath(target, cwd, configDir) {
2710
2818
  const posix4 = target.replace(/\\/g, "/");
2711
2819
  const scanned = picomatch.scan(posix4);
2712
2820
  if (scanned.isGlob) {
2713
- const rel2 = toPosix(relative5(configDir, resolve3(cwd, scanned.base === "" ? "." : scanned.base)));
2821
+ const rel2 = toPosix(relative4(configDir, resolve3(cwd, scanned.base === "" ? "." : scanned.base)));
2714
2822
  if (isAbsolute3(rel2) || rel2 === ".." || rel2.startsWith("../")) return void 0;
2715
2823
  return rel2 === "" ? scanned.glob : `${rel2}/${scanned.glob}`;
2716
2824
  }
2717
2825
  const abs = resolve3(cwd, posix4);
2718
- const rel = toPosix(relative5(configDir, abs));
2826
+ const rel = toPosix(relative4(configDir, abs));
2719
2827
  if (isAbsolute3(rel) || rel.startsWith("..")) return void 0;
2720
2828
  let directory = posix4.endsWith("/");
2721
2829
  if (!directory) {
@@ -2776,7 +2884,7 @@ function marksOf(ctx) {
2776
2884
  });
2777
2885
  }
2778
2886
  function entryFor(m, label, data, configDir, base, key) {
2779
- if (m.join === PATH_JOIN) return toPosix(relative5(configDir, resolve3(base, label)));
2887
+ if (m.join === PATH_JOIN) return toPosix(relative4(configDir, resolve3(base, label)));
2780
2888
  let raw = data[m.join];
2781
2889
  if (isEncryptedValue(raw)) {
2782
2890
  const k = key();
@@ -3280,7 +3388,7 @@ function assertNoStrandedEntries(m, index, pages, configDir, fileOf) {
3280
3388
  const stranded = m.join === PATH_JOIN ? [...index.byPath].filter(([abs, values]) => {
3281
3389
  const sv = values.get(key);
3282
3390
  return sv !== void 0 && sv.collection === m.collection && sv.file === fileOf(abs);
3283
- }).map(([abs]) => toPosix(relative5(configDir, abs))) : [...index.byField.get(m.join) ?? /* @__PURE__ */ new Map()].filter(([, values]) => {
3391
+ }).map(([abs]) => toPosix(relative4(configDir, abs))) : [...index.byField.get(m.join) ?? /* @__PURE__ */ new Map()].filter(([, values]) => {
3284
3392
  const sv = values.get(key);
3285
3393
  return sv !== void 0 && sv.file === m.file && sv.collection === m.collection;
3286
3394
  }).map(([value]) => value);
@@ -3798,6 +3906,13 @@ function lineSpec(lines) {
3798
3906
  function spellLines(lines) {
3799
3907
  return String(lineSpec(lines));
3800
3908
  }
3909
+ function bodyLineOf(content, bodyOffset) {
3910
+ if (bodyOffset <= 0) return 1;
3911
+ const stop = Math.min(bodyOffset, content.length);
3912
+ let line = 1;
3913
+ for (let at2 = content.indexOf("\n"); at2 !== -1 && at2 < stop; at2 = content.indexOf("\n", at2 + 1)) line++;
3914
+ return content.charCodeAt(bodyOffset - 1) === 10 ? line : line + 1;
3915
+ }
3801
3916
  function toFileLines(lines, bodyLine) {
3802
3917
  return { start: bodyLine + lines.start - 1, end: bodyLine + lines.end - 1 };
3803
3918
  }
@@ -4297,20 +4412,37 @@ function attributeRange(input) {
4297
4412
  return { "generated-by": input.generatedBy, lines: lineSpec(span), integrity: pinOf(page.body, span) };
4298
4413
  }
4299
4414
 
4415
+ // src/shared/cli-options.ts
4416
+ import { basename as basename4, relative as relative5 } from "node:path";
4417
+ function collect(value, prev) {
4418
+ return prev.concat([value]);
4419
+ }
4420
+ function splitList(value) {
4421
+ return value.split(",").map((s) => s.trim()).filter(Boolean);
4422
+ }
4423
+ var STDIN_REQUIRES_AS = "Reading from stdin (`-`) requires --as <format> to choose an extractor.";
4424
+ async function readStdin() {
4425
+ const chunks = [];
4426
+ for await (const chunk of process.stdin) chunks.push(chunk);
4427
+ return Buffer.concat(chunks).toString("utf8");
4428
+ }
4429
+ function configOption(value) {
4430
+ if (value === false) return { noConfig: true };
4431
+ return typeof value === "string" ? { configPath: value } : {};
4432
+ }
4433
+ function explicitFalse(value) {
4434
+ return value === false ? false : void 0;
4435
+ }
4436
+ function reportConfig(toStdout, cwd) {
4437
+ return (info) => {
4438
+ const where = (relative5(cwd, info.dir) || ".").replace(/\\/g, "/");
4439
+ const line = `Using ${basename4(info.path)} (${where})
4440
+ `;
4441
+ (toStdout ? process.stdout : process.stderr).write(line);
4442
+ };
4443
+ }
4444
+
4300
4445
  export {
4301
- collect,
4302
- splitList,
4303
- STDIN_REQUIRES_AS,
4304
- readStdin,
4305
- configOption,
4306
- explicitFalse,
4307
- reportConfig,
4308
- writeTextAtomic,
4309
- ENCRYPTION_KEY_ENV,
4310
- resolveEncryptionKey,
4311
- writeEncryptionKey,
4312
- isIgnoredByGit,
4313
- committedKeyWarning,
4314
4446
  heldManifest,
4315
4447
  rebaseable,
4316
4448
  rebaseline,
@@ -4320,6 +4452,12 @@ export {
4320
4452
  EXTERNAL_METADATA_FETCH_TIMEOUT_MS,
4321
4453
  EXTERNAL_METADATA_FETCH_MAX_BYTES,
4322
4454
  fetchExternalMetadata,
4455
+ writeTextAtomic,
4456
+ ENCRYPTION_KEY_ENV,
4457
+ resolveEncryptionKey,
4458
+ writeEncryptionKey,
4459
+ isIgnoredByGit,
4460
+ committedKeyWarning,
4323
4461
  ENCRYPTED_PLACEHOLDER,
4324
4462
  META_CONTEXT,
4325
4463
  EncryptionRefusal,
@@ -4351,22 +4489,10 @@ export {
4351
4489
  orphanJoins,
4352
4490
  orphanError,
4353
4491
  pageOwners,
4354
- LOCATION_KEYWORD,
4355
- LOCATION_EXTERNAL_SCHEMA,
4356
- LOCATION_PAGE_SCHEMA,
4357
- LOCATION_FINDING_KEYWORD,
4358
- GRAPH_OUTPUT_KEYWORD,
4359
- compileWithFormats,
4360
- stringFormatNames,
4361
- validatesFormat,
4362
- Validator,
4363
- pageMarks,
4364
- pageClaims,
4365
- pageSchemaSet,
4366
- marksValidator,
4367
- configMarks,
4368
- metaSection,
4369
- familyMarks,
4492
+ spliceManifestValue,
4493
+ readManifestValue,
4494
+ removeManifestKey,
4495
+ renameManifestEntry,
4370
4496
  SYSTEM_COLUMNS,
4371
4497
  RESERVED,
4372
4498
  quoteIdent,
@@ -4388,10 +4514,29 @@ export {
4388
4514
  collectionNames,
4389
4515
  collectCollections,
4390
4516
  createCollectionViews,
4391
- spliceManifestValue,
4392
- readManifestValue,
4393
- removeManifestKey,
4394
- renameManifestEntry,
4517
+ LOCATION_KEYWORD,
4518
+ LOCATION_EXTERNAL_SCHEMA,
4519
+ LOCATION_PAGE_SCHEMA,
4520
+ LOCATION_FINDING_KEYWORD,
4521
+ GRAPH_OUTPUT_KEYWORD,
4522
+ TERM_KEYWORD,
4523
+ TERM_UNDEFINED_SCHEMA,
4524
+ TERM_OUTSIDE_BRANCH_SCHEMA,
4525
+ TERM_ALT_LABEL_SCHEMA,
4526
+ TERM_FINDING_KEYWORD,
4527
+ isTermMark,
4528
+ termScheme,
4529
+ compileWithFormats,
4530
+ stringFormatNames,
4531
+ validatesFormat,
4532
+ Validator,
4533
+ pageMarks,
4534
+ pageClaims,
4535
+ pageSchemaSet,
4536
+ marksValidator,
4537
+ configMarks,
4538
+ metaSection,
4539
+ familyMarks,
4395
4540
  relocateFailed,
4396
4541
  relocationContext,
4397
4542
  keyHome,
@@ -4414,6 +4559,7 @@ export {
4414
4559
  parseLines,
4415
4560
  lineSpec,
4416
4561
  spellLines,
4562
+ bodyLineOf,
4417
4563
  toFileLines,
4418
4564
  toBodyLines,
4419
4565
  splitPageArgument,
@@ -4430,6 +4576,13 @@ export {
4430
4576
  provenanceFindings,
4431
4577
  renderProvenanceValue,
4432
4578
  parseProvenanceTarget,
4433
- attributeRange
4579
+ attributeRange,
4580
+ collect,
4581
+ splitList,
4582
+ STDIN_REQUIRES_AS,
4583
+ readStdin,
4584
+ configOption,
4585
+ explicitFalse,
4586
+ reportConfig
4434
4587
  };
4435
- //# sourceMappingURL=chunk-GV56WGL2.js.map
4588
+ //# sourceMappingURL=chunk-WO4JYWZK.js.map