@metabase/cli 0.3.2 → 0.4.0

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 (291) hide show
  1. package/dist/{add-collection-BjVAdZ1n.mjs → add-collection-CC6KSwjX.mjs} +5 -5
  2. package/dist/{alert-DCLhfwdv.mjs → alert-Dt6La9tK.mjs} +7 -7
  3. package/dist/{alerts-DRin_wt2.mjs → alerts-ClKnJqgB.mjs} +6 -6
  4. package/dist/{append-DQ9rPJHZ.mjs → append-pnaQWP_A.mjs} +4 -4
  5. package/dist/{archive-D6xzHaM3.mjs → archive-By1pLYtO.mjs} +3 -3
  6. package/dist/{archive-xcgoVPwv.mjs → archive-CLu2TGW5.mjs} +5 -5
  7. package/dist/{archive-HeRygdKz2.mjs → archive-COP9joWU.mjs} +4 -4
  8. package/dist/{archive-COFQAHAL.mjs → archive-CSnBFcQ_.mjs} +3 -3
  9. package/dist/{archive-1YVo-Wsu.mjs → archive-Ct1eyolN.mjs} +3 -3
  10. package/dist/{archive-_c-ISZmi.mjs → archive-D7nAQcCz.mjs} +3 -3
  11. package/dist/{archive-BzVxRqpL.mjs → archive-DEDA48w3.mjs} +5 -5
  12. package/dist/{archive-BVRKE9Ev.mjs → archive-DJAsSzCz.mjs} +5 -5
  13. package/dist/{archive-BPCgmLcV.mjs → archive-DtabbPUk.mjs} +4 -4
  14. package/dist/{archive-o5cWV3vZ.mjs → archive-YNpa8daf.mjs} +3 -3
  15. package/dist/{archive-D3yPvUtz.mjs → archive-ewitrKdx.mjs} +5 -5
  16. package/dist/{auth-DJn5T6zA.mjs → auth-DdLhXCn-.mjs} +5 -5
  17. package/dist/body-Dd-TwYYL.mjs +17 -0
  18. package/dist/branch-flag-pFQPNYKr.mjs +9 -0
  19. package/dist/{branches-CUyPxeeW.mjs → branches-ZvGNhed6.mjs} +3 -3
  20. package/dist/breaking-BLswgvkA.mjs +36 -0
  21. package/dist/broken-BN0nL2hf.mjs +37 -0
  22. package/dist/bulk-discard-values-DFJUjSnE.mjs +49 -0
  23. package/dist/bulk-edit-Brqr67bu.mjs +53 -0
  24. package/dist/bulk-rescan-values-DndXXi2N.mjs +28 -0
  25. package/dist/bulk-sync-schema-mO-t2QlL.mjs +28 -0
  26. package/dist/{cancel-BNuVls58.mjs → cancel-DP03dXBf.mjs} +3 -3
  27. package/dist/{cancel-task-DUmlQQpi.mjs → cancel-task-CELBfBPP.mjs} +4 -4
  28. package/dist/{card-voh1k4hl.mjs → card-Bv4ZN0oV.mjs} +5 -3
  29. package/dist/card-CFd-GUEM.mjs +25 -0
  30. package/dist/{card-CEkp1mcI.mjs → card-DSrgU7lT.mjs} +1 -1
  31. package/dist/{cards-_gbvw3wp.mjs → cards-Cn2ywFTJ.mjs} +6 -6
  32. package/dist/cli.mjs +410 -100
  33. package/dist/{client-BnK0evYf.mjs → client-ToLiPu9q.mjs} +316 -316
  34. package/dist/{collection-DYM0p3Xl.mjs → collection-BG3Ksea-.mjs} +1 -1
  35. package/dist/collection-BKNShKcY.mjs +21 -0
  36. package/dist/{collection-BxdPxD38.mjs → collection-D3KXhvnc.mjs} +7 -5
  37. package/dist/{collection-namespace-DM90lA8C.mjs → collection-namespace-CWW6hZxK.mjs} +2 -2
  38. package/dist/{content-translation-CqB3peU9.mjs → content-translation-C19SqZWp.mjs} +3 -3
  39. package/dist/copy-BGK8Wz6d.mjs +55 -0
  40. package/dist/copy-COLUuiuF.mjs +36 -0
  41. package/dist/copy-flags-eU8aa0zj.mjs +32 -0
  42. package/dist/{create-CnJKj9Nl.mjs → create-B2tuInV9.mjs} +4 -4
  43. package/dist/{create-D4Y69cDF.mjs → create-B3TKri1E.mjs} +4 -4
  44. package/dist/{create-BSvTs-EV.mjs → create-B4gXKDRr.mjs} +3 -3
  45. package/dist/create-B63JphYe.mjs +34 -0
  46. package/dist/{create-IFjwHs0G.mjs → create-BH6kLjHS.mjs} +4 -4
  47. package/dist/{create-BIUVvIGH.mjs → create-BwifyhyL.mjs} +3 -3
  48. package/dist/{create-CwXUMOMd.mjs → create-Colz5bOO.mjs} +3 -3
  49. package/dist/{create-Cm9Z-rfe2.mjs → create-CulUZgN1.mjs} +4 -4
  50. package/dist/{create-DNx9TGHs.mjs → create-Cxuqr3kT.mjs} +6 -6
  51. package/dist/{create-CUHpxANR.mjs → create-CzW_UTE7.mjs} +6 -6
  52. package/dist/{create-BMKuihoI.mjs → create-DNR8RMvV.mjs} +6 -6
  53. package/dist/{create-DMVw9nrZ.mjs → create-DSHeoV7e.mjs} +4 -4
  54. package/dist/{create-DVo8-IzZ.mjs → create-DWbW2WSc.mjs} +6 -6
  55. package/dist/{create-va8bByVt.mjs → create-Dx8nfjGs.mjs} +3 -3
  56. package/dist/{create-B7S5fCkD.mjs → create-XGomrTz5.mjs} +5 -5
  57. package/dist/{create-branch-Cw-uXows.mjs → create-branch-DxL7KUZp.mjs} +4 -4
  58. package/dist/{create-B48rmY8v.mjs → create-g1f2yJ4s.mjs} +3 -3
  59. package/dist/{csv-CaKx1oFZ.mjs → csv-C6TEfLMi.mjs} +4 -4
  60. package/dist/{current-task-lGh69Z1i.mjs → current-task-CHs0zNFM.mjs} +4 -4
  61. package/dist/dashboard-AWrXqQ7a.mjs +35 -0
  62. package/dist/{dashboard-D0hwTC-f.mjs → dashboard-Phz3XpRM.mjs} +2 -1
  63. package/dist/{dashboard-DgK81azj.mjs → dashboard-XSTr9QCr.mjs} +6 -2
  64. package/dist/database-D-CRyRIv.mjs +45 -0
  65. package/dist/{database-C3E9PZSx.mjs → database-MlUPpitM.mjs} +1 -1
  66. package/dist/dataset-p5oNPQgL.mjs +66 -0
  67. package/dist/{db-BRHPjshe.mjs → db-BFSeETMO.mjs} +7 -7
  68. package/dist/{delete-DMETa-37.mjs → delete-BUKgSJhh.mjs} +4 -4
  69. package/dist/{delete-CQWCfqHf.mjs → delete-CPBByycV.mjs} +4 -4
  70. package/dist/{delete-Ci0aDYpf.mjs → delete-Cucqn4-V.mjs} +4 -4
  71. package/dist/{delete-BxBadE3q.mjs → delete-D79TlpcE.mjs} +4 -4
  72. package/dist/delete-DZJxBmdU.mjs +44 -0
  73. package/dist/{delete-G6EiGn2Q.mjs → delete-DndykJn2.mjs} +4 -4
  74. package/dist/delete-runtime-BbmRg_in.mjs +55 -0
  75. package/dist/{delete-table-N4rZtt1T.mjs → delete-table-CbsWcjh5.mjs} +4 -4
  76. package/dist/{dependencies-edN0P1SS.mjs → dependencies-B-880phi.mjs} +5 -5
  77. package/dist/dependency-DBUJwXqv.mjs +15 -0
  78. package/dist/dependency-DKSjKT8P.mjs +165 -0
  79. package/dist/dependency-DSxKm9oS.mjs +111 -0
  80. package/dist/dependents-C_FDnpZs.mjs +52 -0
  81. package/dist/{dirty-U51bMoCP.mjs → dirty-B-Is68--.mjs} +5 -5
  82. package/dist/discard-values-yzH-kIsr.mjs +55 -0
  83. package/dist/document-BRaba87v.mjs +20 -0
  84. package/dist/{document-CA0Q6lqu.mjs → document-C18b5rM6.mjs} +1 -1
  85. package/dist/{document-BHpLJbKU.mjs → document-DFCj1Az_.mjs} +2 -1
  86. package/dist/{download-BJA6k-e6.mjs → download-DluF-vnU.mjs} +2 -2
  87. package/dist/{eid-BtlRU1E0.mjs → eid-Dz-mP40j.mjs} +11 -10
  88. package/dist/entity-CA4zfRt4.mjs +20 -0
  89. package/dist/entry-flags-7x7bIyOQ.mjs +42 -0
  90. package/dist/{events-B5rnOo-L.mjs → events-2sOk6H09.mjs} +4 -4
  91. package/dist/export-BKkAJOFb.mjs +74 -0
  92. package/dist/export-flags-NiZ7C3Gm.mjs +81 -0
  93. package/dist/export-preflight-CwJ_3-iX.mjs +35 -0
  94. package/dist/{field-CcN4oZy6.mjs → field-5nivEfd6.mjs} +33 -3
  95. package/dist/field-BARgq5I9.mjs +21 -0
  96. package/dist/field-wmN6raOG.mjs +128 -0
  97. package/dist/{fields-zQ6O_W_H.mjs → fields-Bod0s_uV.mjs} +6 -6
  98. package/dist/filter-flags-BYcbB85j.mjs +71 -0
  99. package/dist/fks-IUw66K_Q.mjs +36 -0
  100. package/dist/{get-BDrmBZ1z.mjs → get-B8DUMrCw.mjs} +5 -5
  101. package/dist/{get-is8x5f2n.mjs → get-BGqvoGQM.mjs} +3 -3
  102. package/dist/{get-CekXFP3x.mjs → get-BSUsfysk.mjs} +3 -3
  103. package/dist/{get-CeSQptdl.mjs → get-BXsLkoit.mjs} +5 -5
  104. package/dist/{get-DhpMuTSt.mjs → get-BXssHyJ1.mjs} +5 -5
  105. package/dist/get-Bct52yPw.mjs +36 -0
  106. package/dist/{get-DXwlZjw0.mjs → get-Besqwy32.mjs} +3 -3
  107. package/dist/{get-BLjcCXp8.mjs → get-BfSX-OeS.mjs} +3 -3
  108. package/dist/{get-BLcS4il2.mjs → get-Biy4gOzu2.mjs} +3 -3
  109. package/dist/{get-BSoMWp4t2.mjs → get-CYIeiTZ9.mjs} +4 -4
  110. package/dist/{get-CwiJWeH4.mjs → get-CaEiQnSw.mjs} +4 -4
  111. package/dist/{get-xPv7e5Ez.mjs → get-Cl81y0Md.mjs} +5 -5
  112. package/dist/{get-Cf6a4fFN.mjs → get-D1NjMXAH.mjs} +4 -4
  113. package/dist/{get-EFsmL4le.mjs → get-D2cPuOPR.mjs} +5 -5
  114. package/dist/{get-Dg-S07ri.mjs → get-DITlshJH.mjs} +3 -3
  115. package/dist/{get-CTp5l7aU.mjs → get-DLyg6Al9.mjs} +3 -3
  116. package/dist/{get-93wuhTn2.mjs → get-DQZfaVNq.mjs} +4 -4
  117. package/dist/{get-CG6G-mzV.mjs → get-DtBqoGTa.mjs} +5 -5
  118. package/dist/{get-DC_huYD8.mjs → get-_ik_5_lQ.mjs} +5 -5
  119. package/dist/{get-run-DwY4sFGy.mjs → get-run-CEc_tr5b.mjs} +4 -4
  120. package/dist/{git-sync-BwBRmEhE.mjs → git-sync-COokpYgc.mjs} +12 -3
  121. package/dist/git-sync-DKcaddkV.mjs +29 -0
  122. package/dist/git-sync-DspFahwV.mjs +165 -0
  123. package/dist/glossary-BlNCrYbw.mjs +30 -0
  124. package/dist/glossary-CWIX8Zh6.mjs +14 -0
  125. package/dist/glossary-LmZWwCNP.mjs +21 -0
  126. package/dist/graph-f6Bp1e8U.mjs +34 -0
  127. package/dist/{group-YQQ5GIcP.mjs → group-bpD_KcjA.mjs} +1 -1
  128. package/dist/{has-remote-changes-DE2_14FK.mjs → has-remote-changes-B8MmN6yh.mjs} +4 -4
  129. package/dist/{import-Cs7wk058.mjs → import-Bhq15KgP.mjs} +19 -8
  130. package/dist/{input-DEvkIjGr.mjs → input-D8qW-KtR.mjs} +6 -2
  131. package/dist/{is-dirty-XqDfqXGi.mjs → is-dirty-CAsVuVx8.mjs} +2 -2
  132. package/dist/{items-BloAjPwA.mjs → items-BZJomiDE.mjs} +8 -8
  133. package/dist/{key-PYetuQ13.mjs → key-BynJSK9u.mjs} +1 -1
  134. package/dist/{library-Dgq_5BFh.mjs → library-B7wDH-Nc.mjs} +5 -5
  135. package/dist/{library-PGCfm0UA.mjs → library-BOv5SY24.mjs} +1 -1
  136. package/dist/{library-BPIzb3K_.mjs → library-Ck0EK5bi.mjs} +4 -2
  137. package/dist/{list-CZCaqPoo.mjs → list-B2uUl26x.mjs} +6 -6
  138. package/dist/{list-3ErmGdY0.mjs → list-B4luDSYj.mjs} +6 -6
  139. package/dist/{list-D04uiS3F.mjs → list-B8ND9t2h.mjs} +3 -3
  140. package/dist/{list-CghNKfYJ.mjs → list-BT5t8ZOl.mjs} +4 -4
  141. package/dist/{list-VzrtA9lt.mjs → list-BT7xiUQe.mjs} +3 -3
  142. package/dist/{list-D9d5ocYi.mjs → list-BWFCv_zk.mjs} +5 -5
  143. package/dist/{list-DboUvg-Y.mjs → list-BtZVe1Nq.mjs} +6 -6
  144. package/dist/{list-sdCIS2Df.mjs → list-BwdSG-P5.mjs} +5 -5
  145. package/dist/{list-yV6CyPzn.mjs → list-C-A-2HFq.mjs} +3 -3
  146. package/dist/list-C9x--9Jq.mjs +101 -0
  147. package/dist/{list-CUJ1wem9.mjs → list-CCdXig7b.mjs} +4 -4
  148. package/dist/{list-BfLo1xI8.mjs → list-CJDFoOHb.mjs} +3 -3
  149. package/dist/{list-Bzm5mXRo.mjs → list-CLFu3mQB.mjs} +3 -3
  150. package/dist/{list-BZnf3RmA.mjs → list-Cd40Kr0R.mjs} +3 -3
  151. package/dist/{list-CUXlZiS1.mjs → list-Cj_mTxbY.mjs} +4 -4
  152. package/dist/{list-f8Csdjyc.mjs → list-CtS50R7m.mjs} +5 -5
  153. package/dist/{list-vsXIMssK.mjs → list-CvZyTwmV.mjs} +5 -5
  154. package/dist/list-DcnNlYQA.mjs +35 -0
  155. package/dist/{list-DuJezLm_.mjs → list-DtgbtE3_.mjs} +3 -3
  156. package/dist/{login-Vw51Gts5.mjs → login-Bi_nGMJ9.mjs} +6 -6
  157. package/dist/{logout-BDIqoVhv.mjs → logout-CiHQJWTu.mjs} +2 -2
  158. package/dist/{measure-LY9Tp9QZ.mjs → measure-D2qq5e8f.mjs} +6 -6
  159. package/dist/moderation-review-BdqEH6N1.mjs +31 -0
  160. package/dist/{notification-DVrLkjFT.mjs → notification-DOYdl0ao.mjs} +1 -1
  161. package/dist/{parameter-values-DWjmO7Ai.mjs → parameter-values-CZow98nb.mjs} +3 -3
  162. package/dist/{parse-enum-Dc0dMZ3P.mjs → parse-enum-CLIXMsd8.mjs} +1 -1
  163. package/dist/parse-id-BW09NysN.mjs +13 -0
  164. package/dist/{parse-ref-DTDld_LJ.mjs → parse-ref-Cw5fa4FI.mjs} +1 -1
  165. package/dist/parse-text-T0lTXzTZ.mjs +11 -0
  166. package/dist/{path-BUUAGYO5.mjs → path-K6LPLYPb.mjs} +4 -4
  167. package/dist/{poll-CZeXepUQ.mjs → poll-Dz4tUm2f.mjs} +2 -2
  168. package/dist/{preflight-DcULqq8E.mjs → preflight-CX6cqB90.mjs} +3 -3
  169. package/dist/{process-CTrfxxaC.mjs → process-D0HdqZ3r.mjs} +1 -1
  170. package/dist/{publish-qVFmJQ1E.mjs → publish-COatW4Un.mjs} +4 -4
  171. package/dist/{pulse-x0gFxWfG.mjs → pulse-D1uh8UIU.mjs} +1 -1
  172. package/dist/query-BJXTIDhy.mjs +328 -0
  173. package/dist/{query-Cq1lmqL5.mjs → query-DmvkyDfo.mjs} +14 -33
  174. package/dist/remapping-CPAvDKHV.mjs +53 -0
  175. package/dist/{remove-collection-DBqh2Lqm.mjs → remove-collection-Bg-sNX3U.mjs} +5 -5
  176. package/dist/{render-Gx1hR7IF.mjs → render-BSfDD6ip.mjs} +2 -2
  177. package/dist/{replace-CujInVY9.mjs → replace-RCHeZLUT.mjs} +4 -4
  178. package/dist/{rescan-values-HypqBCSK.mjs → rescan-values-CpDGYZvf.mjs} +5 -5
  179. package/dist/rescan-values-PeMnpaFY.mjs +32 -0
  180. package/dist/{run-DEkQSOQa.mjs → run-CaQ7kubO.mjs} +3 -3
  181. package/dist/{run-b3jyF29q.mjs → run-DkRkZRgf.mjs} +4 -4
  182. package/dist/{runs-GHqHLGy4.mjs → runs-BDjoVJ0P.mjs} +5 -5
  183. package/dist/{runtime-nCPku2nN.mjs → runtime-CZ5zh32z.mjs} +21 -82
  184. package/dist/{schema-tables-B5L05Y1L.mjs → schema-tables-C2qjLcPq.mjs} +6 -6
  185. package/dist/{schemas-Clx26p_4.mjs → schemas-D8hfNduk.mjs} +4 -4
  186. package/dist/search-BrQQuNmh.mjs +131 -0
  187. package/dist/search-CnTXKJgx.mjs +85 -0
  188. package/dist/{segment-DiRJcbam.mjs → segment-Bi6eqj3e.mjs} +6 -6
  189. package/dist/{send-DIHkDNBN.mjs → send-CAjgVNlA.mjs} +3 -3
  190. package/dist/{set-D77qUZML.mjs → set-BXTkYWid.mjs} +4 -4
  191. package/dist/{set-active-DCdFgD0O.mjs → set-active-CBQVCePU.mjs} +3 -3
  192. package/dist/set-sensitivity-D39kGTob.mjs +57 -0
  193. package/dist/{setting-DR9bj232.mjs → setting-CPkvkc4H.mjs} +4 -4
  194. package/dist/{setup-DGa2LLEp.mjs → setup-Be3xDXHi.mjs} +3 -3
  195. package/dist/{signal-k7cm5N6h.mjs → signal-CxWeLszu.mjs} +1 -1
  196. package/dist/{skill-list-DAvGGHzS.mjs → skill-list-CBGq30sI.mjs} +2 -2
  197. package/dist/{skills-CqtNuSXM.mjs → skills-CJ9eXouJ.mjs} +2 -2
  198. package/dist/{skills-CCn7cyMP.mjs → skills-DyiLycMY.mjs} +3 -3
  199. package/dist/snippet-QirK70R_.mjs +19 -0
  200. package/dist/{stash-BTtsV0AG.mjs → stash-BVN3s5N_.mjs} +6 -6
  201. package/dist/{status-CW7Dt-nV.mjs → status-BtbMmIWo.mjs} +7 -7
  202. package/dist/{status-XgSS3StV.mjs → status-CxP6w3aL.mjs} +3 -3
  203. package/dist/{subscription-CofRU47d.mjs → subscription-Dr-YHARg.mjs} +6 -6
  204. package/dist/{subscriptions-DCuuPF6U.mjs → subscriptions-8tM8TTeQ.mjs} +6 -6
  205. package/dist/{summary-uGlgKE3C.mjs → summary-DKx6ptQe.mjs} +5 -5
  206. package/dist/sync-schema-B8RY0Ra4.mjs +32 -0
  207. package/dist/{sync-schema-Cu9rD3eH.mjs → sync-schema-kNriXZjG.mjs} +6 -6
  208. package/dist/sync-task-CXFoqlpF.mjs +53 -0
  209. package/dist/table-CZnT6d9x.mjs +26 -0
  210. package/dist/{table-DfuY0N8e.mjs → table-Ci6bhZkb.mjs} +35 -12
  211. package/dist/table-CxvaDiIZ.mjs +155 -0
  212. package/dist/table-selector-flags-1bYkAKld.mjs +42 -0
  213. package/dist/text-DaNkPRwt.mjs +6 -0
  214. package/dist/timeline-CUzx6uXi.mjs +21 -0
  215. package/dist/{timeline-event-D-h0A_oh.mjs → timeline-event-DpNm4dkn.mjs} +6 -6
  216. package/dist/{transform-CtqB1WYo.mjs → transform-CNBIV7No.mjs} +1 -1
  217. package/dist/transform-g4-HHzDp.mjs +28 -0
  218. package/dist/transform-job-DqBtnTrG.mjs +22 -0
  219. package/dist/{transform-tag-BLp_p9J-.mjs → transform-tag-nTb0Ivpj.mjs} +5 -5
  220. package/dist/{transforms-n2IwEcbU.mjs → transforms-BSsAfwAg.mjs} +5 -5
  221. package/dist/tree-lMvw1jnZ.mjs +34 -0
  222. package/dist/{unpublish-DVQCAa3g.mjs → unpublish-CYFDd828.mjs} +3 -3
  223. package/dist/unreferenced-8Xdq76Kw.mjs +36 -0
  224. package/dist/{update-oQeQyqKO.mjs → update-6P_GYCLT.mjs} +5 -5
  225. package/dist/{update-DFdBeJwc.mjs → update-B28EJzrx.mjs} +13 -8
  226. package/dist/{update-DffrdV4b.mjs → update-BDunZa7G.mjs} +4 -4
  227. package/dist/{update-DKO9HF1f.mjs → update-BT2yNB_g.mjs} +6 -6
  228. package/dist/{update-rFRPLlb6.mjs → update-BnMUSFYZ.mjs} +4 -4
  229. package/dist/update-BwrYeKso.mjs +41 -0
  230. package/dist/{update-B7CikkI0.mjs → update-C7DEMiu-.mjs} +7 -7
  231. package/dist/{update-CAsqNhDC.mjs → update-CITzAFG8.mjs} +4 -4
  232. package/dist/update-CLl8tE20.mjs +181 -0
  233. package/dist/{update-C05J2nZ2.mjs → update-CM5uuhjB.mjs} +4 -4
  234. package/dist/{update-ChpOukqq.mjs → update-CQXcsvaa.mjs} +5 -5
  235. package/dist/{update-D4ggtuG4.mjs → update-Cs2zv_L2.mjs} +7 -7
  236. package/dist/{update-NGq0yXZk.mjs → update-D--Fw7-_.mjs} +5 -5
  237. package/dist/{update-D9H6Lh5U.mjs → update-D9p0N8ky.mjs} +4 -4
  238. package/dist/{update-CKDRuduL.mjs → update-DAzRx0of.mjs} +5 -5
  239. package/dist/{update-CnkPYL2i.mjs → update-D_DCOOAB.mjs} +6 -6
  240. package/dist/{update-DScUzKLI.mjs → update-_sYM1GuU.mjs} +7 -7
  241. package/dist/{update-dashcard-DvPqLJ3N.mjs → update-dashcard-VNnIqHDI.mjs} +6 -6
  242. package/dist/{upgrade-BRgw0fvn.mjs → upgrade-Tj_reACv.mjs} +4 -4
  243. package/dist/upload-BKxOpSz3.mjs +13 -0
  244. package/dist/{upload-Do2PBSeH.mjs → upload-C2fhpKkP.mjs} +2 -2
  245. package/dist/{upload-BrfbcbBW.mjs → upload-Dg91ldGg.mjs} +3 -3
  246. package/dist/{uuid-B4eij1d7.mjs → uuid-Blpv_e0S.mjs} +2 -2
  247. package/dist/{validate-xR_MHBNR.mjs → validate-D7e110oU.mjs} +1 -1
  248. package/dist/{validate-query-D6_ad-Gi.mjs → validate-query-C7LuKiUT.mjs} +2 -2
  249. package/dist/{values-xgOftPq5.mjs → values-PonkbYAK.mjs} +5 -5
  250. package/dist/verify-DixUBbd2.mjs +38 -0
  251. package/dist/verify-Dv7ER11c.mjs +38 -0
  252. package/dist/{verify-DTOA_wVM.mjs → verify-Mpb65a5v.mjs} +3 -3
  253. package/dist/verify-flags-CMpRkMPa.mjs +58 -0
  254. package/dist/{wait-BjeFgR13.mjs → wait-CaH6XHQV.mjs} +6 -6
  255. package/dist/{wait-flags-BCeCnaz3.mjs → wait-flags-rUU4NUrv.mjs} +2 -2
  256. package/dist/{window-DSb1tqSe.mjs → window-CI_QD04s.mjs} +1 -1
  257. package/package.json +1 -1
  258. package/skill-data/core/SKILL.md +18 -11
  259. package/skill-data/dashboard/SKILL.md +1 -1
  260. package/skill-data/document/SKILL.md +12 -1
  261. package/skill-data/git-sync/SKILL.md +61 -9
  262. package/skill-data/mbql/SKILL.md +5 -0
  263. package/skill-data/metadata/SKILL.md +36 -6
  264. package/dist/body-Cu94pH4P.mjs +0 -17
  265. package/dist/card-ByOzVxpI.mjs +0 -24
  266. package/dist/collection-BGbW7u_Q.mjs +0 -20
  267. package/dist/dashboard-Bzjz2v6u.mjs +0 -33
  268. package/dist/database-JtHTqSpq.mjs +0 -26
  269. package/dist/delete-runtime-BKEzJn22.mjs +0 -49
  270. package/dist/document-DqJ7Cysa.mjs +0 -19
  271. package/dist/export-DO2josC0.mjs +0 -63
  272. package/dist/field-CHZByaXa.mjs +0 -18
  273. package/dist/field-fDtIrY6D.mjs +0 -80
  274. package/dist/get-yHIEezeG.mjs +0 -31
  275. package/dist/git-sync-NhfLSZA6.mjs +0 -28
  276. package/dist/git-sync-TjX1r_wF.mjs +0 -136
  277. package/dist/list-DgteFn01.mjs +0 -34
  278. package/dist/parse-id-whJX4DAb.mjs +0 -10
  279. package/dist/query-BPtIy79s.mjs +0 -114
  280. package/dist/query-result-E4Q-Gra6.mjs +0 -15
  281. package/dist/search-DxiuY5EV.mjs +0 -97
  282. package/dist/selectors-rEFuyXPZ.mjs +0 -35
  283. package/dist/snippet-g9JTDxqu.mjs +0 -19
  284. package/dist/sync-task-BXeWuARG.mjs +0 -37
  285. package/dist/table-C6h4tIRw.mjs +0 -37
  286. package/dist/table-Di-EY7pg.mjs +0 -18
  287. package/dist/timeline-D7EsWZm6.mjs +0 -21
  288. package/dist/transform-8XK1LIgC.mjs +0 -28
  289. package/dist/transform-job-CTizQkWy.mjs +0 -22
  290. package/dist/tree-cqxiDh2b.mjs +0 -26
  291. package/dist/upload-VXBFKzLT.mjs +0 -13
@@ -1,22 +1,26 @@
1
- import { $ as InternalError, Q as ConfigError, at as ValidationError, n as methodRequirements, nt as ResponseShapeError, ot as errorMessage, rt as TimeoutError, tt as NetworkError } from "./cli.mjs";
1
+ import { at as ConfigError, ct as NetworkError, ft as ValidationError, lt as ResponseShapeError, mt as formatZodIssue, n as methodRequirements, ot as InternalError, pt as errorMessage, ut as TimeoutError } from "./cli.mjs";
2
2
  import { n as Notification, r as NotificationCardPayload, t as CARD_PAYLOAD_TYPE } from "./notification-DaA4bBHW.mjs";
3
- import { $ as createServerProfile, B as JSON_CONTENT_TYPE, F as buildNetworkError, G as credentialSecrets, H as parseJsonOrPlain, I as isConnectionClosed, J as normalizeUrl, L as HttpError, U as assertCredentialHeaderSafe, V as parseJson, W as credentialAuthHeader, Z as checkFeatures, et as probeServer, tt as CapabilityError, z as isRetryableStatus } from "./runtime-nCPku2nN.mjs";
4
- import { n as throwIfAborted, r as untilAborted, t as combineAborts } from "./signal-k7cm5N6h.mjs";
5
- import { a as FieldSearchMatches, i as FieldRemappedValue, l as FieldValues, n as FieldBaseType, o as FieldSemanticType, t as Field } from "./field-CcN4oZy6.mjs";
3
+ import { $ as CapabilityError, B as assertCredentialHeaderSafe, G as normalizeUrl, H as credentialSecrets, I as isRetryableStatus, J as checkFeatures, L as JSON_CONTENT_TYPE, M as buildNetworkError, N as isConnectionClosed, P as HttpError, Q as probeServer, R as parseJson, V as credentialAuthHeader, X as createServerProfile, Z as PROBE_PATH, z as parseJsonOrPlain } from "./runtime-CZ5zh32z.mjs";
4
+ import { n as throwIfAborted, r as untilAborted, t as combineAborts } from "./signal-CxWeLszu.mjs";
5
+ import { f as FieldWithDataSensitivity, h as fieldRemappedValueSchema, m as fieldDetailSchema, n as FieldBaseType, o as FieldSearchMatches, s as FieldSemanticType, u as FieldValues } from "./field-5nivEfd6.mjs";
6
6
  import { a as TemporalUnit, r as ParameterValues } from "./parameter-Celg0wZa.mjs";
7
- import { a as CardQueryResult, l as DatasetQuery, s as CardType, t as Card } from "./card-voh1k4hl.mjs";
8
- import { c as TableVisibilityType, i as TableForeignKey, o as TableQueryMetadata, r as TableDataLayerTier, t as Table } from "./table-DfuY0N8e.mjs";
9
- import { t as Database } from "./database-JtHTqSpq.mjs";
7
+ import { a as CardQueryResult, d as PivotExportFormat, l as DatasetQuery, t as Card } from "./card-Bv4ZN0oV.mjs";
8
+ import { b as TableVisibilityType, p as TableQueryMetadata, s as TableDataLayerTier, t as Table, u as TableForeignKey, v as TableSelectors } from "./table-Ci6bhZkb.mjs";
9
+ import { t as Database } from "./database-D-CRyRIv.mjs";
10
10
  import { t as Snippet } from "./snippet-CyKAgIZl.mjs";
11
- import { c as CollectionItem, i as CollectionAuthorityLevel, m as CollectionTreeNode, r as Collection, s as CollectionId } from "./collection-BxdPxD38.mjs";
11
+ import { o as compiledQuerySchema, r as QueryMetadata } from "./dataset-p5oNPQgL.mjs";
12
+ import { c as CollectionItem, m as CollectionTreeNode, r as Collection } from "./collection-D3KXhvnc.mjs";
12
13
  import { t as ContentTranslationUploadResult } from "./content-translation-BrHOrmj9.mjs";
13
- import { a as DashboardDetail, c as Dashcard, r as DashboardCopy, t as Dashboard } from "./dashboard-D0hwTC-f.mjs";
14
- import { r as pollUntil } from "./poll-CZeXepUQ.mjs";
15
- import { t as Document } from "./document-BHpLJbKU.mjs";
14
+ import { l as Dashcard, o as DashboardDetail, r as DashboardCopy, t as Dashboard } from "./dashboard-Phz3XpRM.mjs";
15
+ import { r as pollUntil } from "./poll-Dz4tUm2f.mjs";
16
+ import { i as DependencyEntity, s as DependencyGraph, t as BreakingSource, u as DependencyNode } from "./dependency-DKSjKT8P.mjs";
17
+ import { t as Document } from "./document-DFCj1Az_.mjs";
16
18
  import { i as EidTranslateResult } from "./eid-translation-zEHtr5Oc.mjs";
17
- import { c as SyncSettingsUpdateResult, i as SyncExportPreflight, n as SyncDirtyItem, p as isSyncTaskTerminal, s as SyncRemoteChanges, t as SyncBranchCreated, u as SyncTask } from "./git-sync-BwBRmEhE.mjs";
18
- import { a as toLibrary, i as libraryWireSchema, n as LibraryCollectionInfo } from "./library-BPIzb3K_.mjs";
19
+ import { c as SyncRemoteChanges, d as SyncTask, i as SyncExportPreflight, l as SyncSettingsUpdateResult, m as isSyncTaskTerminal, n as SyncDirtyItem, t as SyncBranchCreated } from "./git-sync-COokpYgc.mjs";
20
+ import { t as Glossary } from "./glossary-BlNCrYbw.mjs";
21
+ import { a as libraryWireSchema, i as LibraryPublishTablesInput, n as LibraryCollectionInfo, o as toLibrary } from "./library-Ck0EK5bi.mjs";
19
22
  import { t as Measure } from "./measure-CtfjqJFP.mjs";
23
+ import { r as ModerationReviewCreateInput, t as ModerationReview } from "./moderation-review-BdqEH6N1.mjs";
20
24
  import { t as Pulse } from "./pulse-Dz0ocv0l.mjs";
21
25
  import { a as TransformDagTransform, d as TransformTarget, g as transformRowSchema, h as transformDetailSchema, i as TransformDagRunResult, l as TransformRunSummary, m as isTransformRunTerminal, o as TransformRun, p as isTransformRunFailed, u as TransformSourceTableEntry } from "./transform-DiW7bREn.mjs";
22
26
  import { r as SearchResult } from "./search-BAXg-EJw.mjs";
@@ -349,43 +353,16 @@ async function readBodyForError(response) {
349
353
  }
350
354
  }
351
355
  //#endregion
352
- //#region ../client/src/domain/dataset.ts
353
- const CompiledQuery = z.object({
354
- query: z.union([z.string(), z.array(z.unknown())]),
355
- params: z.array(z.unknown()).nullable().optional(),
356
- collection: z.string().optional()
357
- }).loose();
358
- const FieldRef = z.tuple([
359
- z.literal("field"),
360
- z.string(),
361
- z.object({ "base-type": FieldBaseType }).loose()
362
- ]);
363
- const VirtualField = z.object({
364
- id: z.union([z.number().int(), FieldRef]),
365
- table_id: z.string(),
366
- name: z.string(),
367
- display_name: z.string(),
368
- base_type: FieldBaseType,
369
- semantic_type: FieldSemanticType.nullable(),
370
- fk_target_field_id: z.number().int().nullable().optional()
371
- }).loose();
372
- const VirtualTable = z.object({
373
- id: z.string(),
374
- db_id: z.number().int(),
375
- display_name: z.string(),
376
- schema: z.string(),
377
- description: z.string().nullable(),
378
- type: CardType,
379
- moderated_status: z.string().nullable(),
380
- entity_id: z.string().nullable(),
381
- fields: z.array(VirtualField)
382
- }).loose();
383
- const QueryMetadata = z.object({
384
- databases: z.array(Database),
385
- tables: z.array(z.union([TableQueryMetadata, VirtualTable])),
386
- fields: z.array(Field),
387
- snippets: z.array(Snippet)
388
- }).loose();
356
+ //#region ../client/src/resources/pivot-export.ts
357
+ const PivotedExportsSetting = z.object({ "enable-pivoted-exports": z.boolean() });
358
+ /**
359
+ * Refuse a pivoted export the server would answer with plain rows: a JSON export keeps only the
360
+ * ungrouped rows, and an admin can turn pivoted CSV and XLSX exports off.
361
+ */
362
+ async function assertPivotedExport(transport, format, options) {
363
+ if (!PivotExportFormat.safeParse(format).success) throw new ConfigError(`a ${format} export cannot be pivoted; only ${PivotExportFormat.options.join(" and ")} can`);
364
+ if (!(await transport.requestParsed(PivotedExportsSetting, "/api/session/properties", { ...options }))["enable-pivoted-exports"]) throw new ConfigError("the server has pivoted exports turned off (the enable-pivoted-exports setting), so it would export the plain rows");
365
+ }
389
366
  //#endregion
390
367
  //#region ../client/src/resources/card.ts
391
368
  const CardApiList = z.array(Card);
@@ -442,15 +419,22 @@ function cardResource(transport) {
442
419
  });
443
420
  }
444
421
  /**
445
- * Run a saved card and stream its result as a download. Unlike `query`, this endpoint takes a
446
- * form-encoded body and answers bytes, so a caller consumes the stream rather than a value.
422
+ * Run the query associated with a Card, and return its results as a file in the specified
423
+ * format. Unlike `query`, this endpoint takes a form-encoded body and answers bytes, so a caller
424
+ * consumes the stream rather than a value. A pivot the server would answer with plain rows (a
425
+ * JSON export, or pivoted exports turned off) is refused. `csv_include_bom` opens a CSV with a
426
+ * UTF-8 byte order mark; a server without it drops the key silently, so asking for one is refused
427
+ * there before the wire.
447
428
  */
448
429
  async function exportQuery(id, format, params, options = {}) {
449
430
  await transport.require("card.exportQuery", options);
431
+ await transport.requireFeatures(params.csv_include_bom ? ["exportCsvByteOrderMark"] : [], options);
432
+ if (params.pivot_results) await assertPivotedExport(transport, format, options);
450
433
  const body = new URLSearchParams({
451
434
  parameters: JSON.stringify(params.parameters),
452
435
  format_rows: String(params.format_rows),
453
- pivot_results: String(params.pivot_results)
436
+ pivot_results: String(params.pivot_results),
437
+ csv_include_bom: String(params.csv_include_bom)
454
438
  });
455
439
  return transport.requestStream(`/api/card/${id}/query/${format}`, {
456
440
  ...options,
@@ -534,20 +518,20 @@ function refPath(ref) {
534
518
  return encodeURIComponent(ref);
535
519
  }
536
520
  /**
537
- * List collections including the Library and its children, parsing each through the caller's own
538
- * projection. `Collection` pins `type`, `namespace` and `authority_level` to closed enums, so a
539
- * consumer reading a few fields off every collection on the instance narrows here: one collection
540
- * carrying a server value outside those sets then costs nothing to a caller that never reads the
541
- * field.
521
+ * List every collection the caller can read, the Library and its children among them, parsing each
522
+ * through the caller's own projection. `Collection` pins `type`, `namespace` and `authority_level`
523
+ * to closed enums, so a consumer reading a few fields off every collection on the instance narrows
524
+ * here: one collection carrying a server value outside those sets then costs nothing to a caller
525
+ * that never reads the field.
542
526
  */
543
- async function listCollectionsWithLibrary(transport, schema, options = {}) {
544
- return transport.requestParsed(z.array(schema), "/api/collection", {
545
- ...options,
546
- query: { "include-library": true }
547
- });
527
+ async function listCollectionsAs(transport, schema, options = {}) {
528
+ return transport.requestParsed(z.array(schema), "/api/collection", { ...options });
548
529
  }
549
530
  function collectionResource(transport) {
550
- /** List collections. `filter` picks a server-side preset: everything, archived, or personal. */
531
+ /**
532
+ * List collections. `filter` picks a server-side preset: everything, archived, or personal. Every
533
+ * preset includes the Library collections that match it.
534
+ */
551
535
  async function list(params = {}, options = {}) {
552
536
  await transport.require("collection.list", options);
553
537
  return {
@@ -558,18 +542,6 @@ function collectionResource(transport) {
558
542
  total: null
559
543
  };
560
544
  }
561
- /**
562
- * List collections including the Library and its children, which the plain listing omits.
563
- * The Library's own children carry neither `type` nor `is_remote_synced`, so this is where a
564
- * caller resolves both.
565
- */
566
- async function listWithLibrary(options = {}) {
567
- await transport.require("collection.listWithLibrary", options);
568
- return {
569
- data: await listCollectionsWithLibrary(transport, Collection, options),
570
- total: null
571
- };
572
- }
573
545
  /** Get one collection by id, entity id, or the `root`/`trash` alias. */
574
546
  async function get(ref, options = {}) {
575
547
  await transport.require("collection.get", options);
@@ -584,7 +556,11 @@ function collectionResource(transport) {
584
556
  body: params
585
557
  });
586
558
  }
587
- /** Update a collection, patching only the fields the body carries. */
559
+ /**
560
+ * Update a collection, patching the fields the body carries. The server reads an absent
561
+ * `archived` as `false`, so a patch without it restores an archived collection, and a patch that
562
+ * moves a collection into the trash ignores `parent_id`.
563
+ */
588
564
  async function update(ref, params, options = {}) {
589
565
  await transport.require("collection.update", options);
590
566
  return transport.requestParsed(Collection, `/api/collection/${refPath(ref)}`, {
@@ -617,16 +593,18 @@ function collectionResource(transport) {
617
593
  });
618
594
  }
619
595
  /** Fetch the collection hierarchy as a forest of nested nodes. */
620
- async function tree(options = {}) {
596
+ async function tree(params = {}, options = {}) {
621
597
  await transport.require("collection.tree", options);
622
598
  return {
623
- data: await transport.requestParsed(CollectionTreeApiList, "/api/collection/tree", { ...options }),
599
+ data: await transport.requestParsed(CollectionTreeApiList, "/api/collection/tree", {
600
+ ...options,
601
+ query: { "include-library": params["include-library"] }
602
+ }),
624
603
  total: null
625
604
  };
626
605
  }
627
606
  return {
628
607
  list,
629
- listWithLibrary,
630
608
  get,
631
609
  create,
632
610
  update,
@@ -715,9 +693,13 @@ function dashboardResource(transport) {
715
693
  }
716
694
  /**
717
695
  * Copy a dashboard, with its tabs and dashcards, into `collection_id` (root when absent). A deep
718
- * copy duplicates the cards it can; otherwise the copy references them, except dashboard
719
- * questions, which are always duplicated. Cards the caller cannot read are left behind and
720
- * reported as `uncopied`.
696
+ * copy duplicates its questions and metrics and references its models. With `is_deep_copy`
697
+ * false or absent the copy references every card, and a dashboard holding unarchived dashboard
698
+ * questions is refused. Archived cards, cards the caller cannot read, and every card on a
699
+ * dashcard whose main card the caller cannot read are left out and reported as `uncopied`, once
700
+ * per dashcard they sat on. A left-out main card takes its dashcard with it; a left-out series
701
+ * card stays on a dashcard whose main card is referenced and is dropped from one whose main card
702
+ * is duplicated. Action, link and placeholder dashcards are not copied.
721
703
  */
722
704
  async function copy(id, params = {}, options = {}) {
723
705
  await transport.require("dashboard.copy", options);
@@ -971,7 +953,8 @@ function datasetResource(transport) {
971
953
  */
972
954
  async function native(datasetQuery, params = {}, options = {}) {
973
955
  await transport.require("dataset.native", options);
974
- return transport.requestParsed(CompiledQuery, "/api/dataset/native", {
956
+ const { features } = await transport.server(options);
957
+ return transport.requestParsed(compiledQuerySchema(features), "/api/dataset/native", {
975
958
  ...options,
976
959
  method: "POST",
977
960
  body: {
@@ -994,18 +977,33 @@ function datasetResource(transport) {
994
977
  });
995
978
  }
996
979
  /**
997
- * Run an ad-hoc query and stream its result as a download. Unlike `query`, this endpoint answers
998
- * bytes, so a caller consumes the stream rather than a value.
980
+ * Execute a query and download the result data as a file in the specified format. Unlike
981
+ * `query`, this endpoint answers bytes, so a caller consumes the stream rather than a value.
982
+ * `visualization_settings` drive `format_rows` column formatting and, through
983
+ * `pivot_table.column_split`, the layout `pivot_results` lays the rows out in. The server only
984
+ * computes that layout for a query it runs as a pivot, which it reads from the query's own
985
+ * `was-pivot`, so `pivot_results` sets it. A pivot the server would answer with plain rows (a
986
+ * JSON export, or pivoted exports turned off) is refused. `csv_include_bom` opens a CSV with a
987
+ * UTF-8 byte order mark; a server without it drops the key silently, so asking for one is refused
988
+ * there before the wire.
999
989
  */
1000
990
  async function exportQuery(format, params, options = {}) {
1001
991
  await transport.require("dataset.exportQuery", options);
992
+ await transport.requireFeatures(params.csv_include_bom ? ["exportCsvByteOrderMark"] : [], options);
993
+ if (params.pivot_results) await assertPivotedExport(transport, format, options);
994
+ const exported = params.pivot_results ? {
995
+ ...params.query,
996
+ "was-pivot": true
997
+ } : params.query;
1002
998
  return transport.requestStream(`/api/dataset/${format}`, {
1003
999
  ...options,
1004
1000
  method: "POST",
1005
1001
  body: {
1006
- query: params.query,
1002
+ query: exported,
1003
+ visualization_settings: params.visualization_settings,
1007
1004
  format_rows: params.format_rows,
1008
- pivot_results: params.pivot_results
1005
+ pivot_results: params.pivot_results,
1006
+ csv_include_bom: params.csv_include_bom
1009
1007
  }
1010
1008
  });
1011
1009
  }
@@ -1017,133 +1015,18 @@ function datasetResource(transport) {
1017
1015
  };
1018
1016
  }
1019
1017
  //#endregion
1020
- //#region ../client/src/domain/dependency.ts
1021
- const DependencyType = z.enum([
1022
- "table",
1023
- "card",
1024
- "snippet",
1025
- "transform",
1026
- "dashboard",
1027
- "document",
1028
- "sandbox",
1029
- "segment",
1030
- "measure"
1031
- ]);
1032
- const DependencyUsageType = z.enum([
1033
- "table",
1034
- "snippet",
1035
- "transform",
1036
- "dashboard",
1037
- "document",
1038
- "sandbox",
1039
- "segment",
1040
- "question",
1041
- "model",
1042
- "metric",
1043
- "measure"
1044
- ]);
1045
- const DependencyFindingErrorType = z.enum([
1046
- "missing-column",
1047
- "missing-table-alias",
1048
- "missing-table",
1049
- "missing-card",
1050
- "duplicate-column",
1051
- "syntax-error",
1052
- "validation-exception-error"
1053
- ]);
1054
- const DependencyErrorSourceType = z.enum([
1055
- "table",
1056
- "card",
1057
- "transform"
1058
- ]);
1059
- z.enum([
1060
- "name",
1061
- "location",
1062
- "view-count"
1063
- ]);
1064
- z.enum([
1065
- "name",
1066
- "location",
1067
- "dependents-with-errors",
1068
- "dependents-errors"
1069
- ]);
1070
- const DependencyCollectionRef = z.object({
1071
- id: CollectionId,
1072
- name: z.string(),
1073
- authority_level: CollectionAuthorityLevel.nullable(),
1074
- is_personal: z.boolean().optional()
1075
- }).loose();
1076
- const DependencyContainerRef = z.object({
1077
- id: z.number().int(),
1078
- name: z.string()
1079
- }).loose();
1080
- const DependencyEntityData = z.object({
1081
- name: z.string().nullable().optional(),
1082
- display_name: z.string().nullable().optional(),
1083
- description: z.string().nullable().optional(),
1084
- type: CardType.nullable().optional(),
1085
- display: z.string().nullable().optional(),
1086
- database_id: z.number().int().nullable().optional(),
1087
- db_id: z.number().int().nullable().optional(),
1088
- schema: z.string().nullable().optional(),
1089
- collection_id: CollectionId.nullable().optional(),
1090
- collection: DependencyCollectionRef.nullable().optional(),
1091
- dashboard_id: z.number().int().nullable().optional(),
1092
- dashboard: DependencyContainerRef.nullable().optional(),
1093
- document_id: z.number().int().nullable().optional(),
1094
- document: DependencyContainerRef.nullable().optional(),
1095
- table_id: z.number().int().nullable().optional(),
1096
- view_count: z.number().int().nullable().optional()
1097
- }).loose();
1098
- const DependencyEntity = z.object({
1099
- id: z.number().int(),
1100
- type: DependencyType,
1101
- data: DependencyEntityData
1102
- }).loose();
1103
- const DependencyNode = DependencyEntity.extend({ dependents_count: z.partialRecord(DependencyUsageType, z.number().int()).nullable() });
1104
- const DependencyFindingError = z.object({
1105
- id: z.number().int(),
1106
- analyzed_entity_type: DependencyType,
1107
- analyzed_entity_id: z.number().int(),
1108
- error_type: DependencyFindingErrorType,
1109
- error_detail: z.string().nullable().optional(),
1110
- source_entity_type: DependencyErrorSourceType.nullable().optional(),
1111
- source_entity_id: z.number().int().nullable().optional()
1112
- }).loose();
1113
- const BreakingSource = DependencyNode.extend({ dependents_errors: z.array(DependencyFindingError).nullable().optional() });
1114
- const DependencyEdge = z.object({
1115
- from_entity_type: DependencyType,
1116
- from_entity_id: z.number().int(),
1117
- to_entity_type: DependencyType,
1118
- to_entity_id: z.number().int()
1119
- }).loose();
1120
- const DependencyGraph = z.object({
1121
- nodes: z.array(DependencyNode),
1122
- edges: z.array(DependencyEdge)
1123
- }).loose();
1124
- //#endregion
1125
1018
  //#region ../client/src/resources/dependency.ts
1126
1019
  const DependencyNodeApiList = z.array(DependencyNode);
1127
1020
  const DependencyEntityApiList = z.array(DependencyEntity);
1128
- const RENAMED_FILTERS = [
1129
- "dependent-types",
1130
- "dependent-card-types",
1131
- "card-types",
1132
- "include-personal-collections",
1133
- "sort-column",
1134
- "sort-direction"
1135
- ];
1136
- function filterFeatures(params) {
1137
- return RENAMED_FILTERS.some((key) => params[key] !== void 0) ? ["dependencyKebabCaseFilters"] : [];
1138
- }
1139
1021
  function dependencyResource(transport) {
1140
1022
  /**
1141
1023
  * The upstream dependency graph of one entity. `nodes` holds the starting entity plus every
1142
1024
  * entity it depends on, directly or transitively; each edge runs from the dependent to what it
1143
- * depends on.
1025
+ * depends on. A measure starts a graph only on a server with `measureDependencyGraph`.
1144
1026
  */
1145
1027
  async function graph(type, id, options = {}) {
1146
1028
  await transport.require("dependency.graph", options);
1029
+ if (type === "measure") await transport.requireFeatures(["measureDependencyGraph"], options);
1147
1030
  return transport.requestParsed(DependencyGraph, "/api/ee/dependencies/graph", {
1148
1031
  ...options,
1149
1032
  query: {
@@ -1160,7 +1043,6 @@ function dependencyResource(transport) {
1160
1043
  */
1161
1044
  async function dependents(type, id, params = {}, options = {}) {
1162
1045
  await transport.require("dependency.dependents", options);
1163
- await transport.requireFeatures(filterFeatures(params), options);
1164
1046
  return {
1165
1047
  data: await transport.requestParsed(DependencyNodeApiList, "/api/ee/dependencies/graph/dependents", {
1166
1048
  ...options,
@@ -1187,7 +1069,6 @@ function dependencyResource(transport) {
1187
1069
  */
1188
1070
  async function broken(type, id, params = {}, options = {}) {
1189
1071
  await transport.require("dependency.broken", options);
1190
- await transport.requireFeatures(filterFeatures(params), options);
1191
1072
  return {
1192
1073
  data: await transport.requestParsed(DependencyEntityApiList, "/api/ee/dependencies/graph/broken", {
1193
1074
  ...options,
@@ -1205,15 +1086,23 @@ function dependencyResource(transport) {
1205
1086
  };
1206
1087
  }
1207
1088
  /**
1208
- * Walk the entities nothing depends on, one page at a time. `types` and `card-types` narrow
1209
- * which kinds are listed, `query` matches against names and locations,
1089
+ * Walk the entities that no readable, unarchived dependent depends on, one page at a time: an
1090
+ * entity used only by archived content, or by content the caller cannot read, is listed. `types`
1091
+ * and `card-types` narrow which kinds are listed, `query` matches against names and locations,
1210
1092
  * `include-personal-collections` admits content in personal collections, and `sort-column` /
1211
- * `sort-direction` order the result. This endpoint pages on the server, so the caller consumes
1212
- * pages and decides how far to pull.
1093
+ * `sort-direction` order the result. A `query` leaves sandboxes out, since they have no name or
1094
+ * location to match, so sandboxes alone with a `query` answer one empty page without a request.
1095
+ * This endpoint pages on the server, so the caller consumes pages and decides how far to pull.
1213
1096
  */
1214
1097
  async function* unreferencedPages(params = {}, options = {}) {
1215
1098
  await transport.require("dependency.unreferencedPages", options);
1216
- await transport.requireFeatures(filterFeatures(params), options);
1099
+ if (queryLeavesNoKind(params)) {
1100
+ yield {
1101
+ items: [],
1102
+ total: 0
1103
+ };
1104
+ return;
1105
+ }
1217
1106
  yield* paginatePages(transport, "/api/ee/dependencies/graph/unreferenced", DependencyNode, {
1218
1107
  query: itemListQuery(params),
1219
1108
  ...options.offset !== void 0 && { offset: options.offset },
@@ -1231,7 +1120,13 @@ function dependencyResource(transport) {
1231
1120
  */
1232
1121
  async function* breakingPages(params = {}, options = {}) {
1233
1122
  await transport.require("dependency.breakingPages", options);
1234
- await transport.requireFeatures(filterFeatures(params), options);
1123
+ if (queryLeavesNoKind(params)) {
1124
+ yield {
1125
+ items: [],
1126
+ total: 0
1127
+ };
1128
+ return;
1129
+ }
1235
1130
  yield* paginatePages(transport, "/api/ee/dependencies/graph/breaking", BreakingSource, {
1236
1131
  query: itemListQuery(params),
1237
1132
  ...options.offset !== void 0 && { offset: options.offset },
@@ -1248,9 +1143,14 @@ function dependencyResource(transport) {
1248
1143
  breakingPages
1249
1144
  };
1250
1145
  }
1146
+ function queryLeavesNoKind(params) {
1147
+ const { query, types } = params;
1148
+ if (query === void 0 || types === void 0 || types.length === 0) return false;
1149
+ return types.every((type) => type === "sandbox");
1150
+ }
1251
1151
  function itemListQuery(params) {
1252
1152
  return {
1253
- types: params.types,
1153
+ types: params.types === void 0 ? void 0 : [...new Set(params.types)],
1254
1154
  "card-types": params["card-types"],
1255
1155
  query: params.query,
1256
1156
  "include-personal-collections": params["include-personal-collections"],
@@ -1417,21 +1317,39 @@ async function fetchOptionalParsed(client, path, schema, options = {}) {
1417
1317
  //#region ../client/src/resources/field.ts
1418
1318
  const FieldApiSummary = z.tuple([z.tuple([z.literal("count"), z.number().int()]), z.tuple([z.literal("distincts"), z.number().int()])]);
1419
1319
  function fieldResource(transport) {
1420
- /** Get one field by id. */
1320
+ /**
1321
+ * Get one field by id. A server that labels data sensitivity answers `data_sensitivity`, `null`
1322
+ * for an unlabelled field; any other answers the field without the key (`hasDataSensitivity`).
1323
+ */
1421
1324
  async function get(id, options = {}) {
1422
1325
  await transport.require("field.get", options);
1423
- return transport.requestParsed(Field, `/api/field/${id}`, { ...options });
1326
+ const { features } = await transport.server(options);
1327
+ return transport.requestParsed(fieldDetailSchema(features), `/api/field/${id}`, { ...options });
1424
1328
  }
1425
1329
  /**
1426
1330
  * Update a field by id, patching only the fields the body carries. A `data_sensitivity` label is
1427
1331
  * a person's call the server's classifier never overwrites, and `null` withdraws it so the
1428
1332
  * classifier's own applies again; a server without the column would drop the key silently, so
1429
- * the label is refused there before the wire.
1333
+ * the label is refused there before the wire. Answers the field the way `get` does.
1430
1334
  */
1431
1335
  async function update(id, params, options = {}) {
1432
1336
  await transport.require("field.update", options);
1433
1337
  await transport.requireFeatures(params.data_sensitivity === void 0 ? [] : ["fieldDataSensitivity"], options);
1434
- return transport.requestParsed(Field, `/api/field/${id}`, {
1338
+ const { features } = await transport.server(options);
1339
+ return transport.requestParsed(fieldDetailSchema(features), `/api/field/${id}`, {
1340
+ ...options,
1341
+ method: "PUT",
1342
+ body: params
1343
+ });
1344
+ }
1345
+ /**
1346
+ * Label a field's data sensitivity by hand. A person's label is never overwritten by the server's
1347
+ * classifier; `null` withdraws it, so whatever label the classifier wrote shows again. Answers
1348
+ * the field with the label it now carries.
1349
+ */
1350
+ async function setDataSensitivity(id, params, options = {}) {
1351
+ await transport.require("field.setDataSensitivity", options);
1352
+ return transport.requestParsed(FieldWithDataSensitivity, `/api/field/${id}`, {
1435
1353
  ...options,
1436
1354
  method: "PUT",
1437
1355
  body: params
@@ -1439,8 +1357,11 @@ function fieldResource(transport) {
1439
1357
  }
1440
1358
  /**
1441
1359
  * Search the values of `searchId` that contain `value`, case-insensitively, answering the
1442
- * matching values of `id` paired with them. An FK on either side is followed to the PK it
1443
- * points at. Without `value`, the first `limit` values.
1360
+ * matching values of `id` paired with them, ordered by value, at most `limit` of them. An FK on
1361
+ * either side is followed to the PK it points at, and a field that resolves to the same field as
1362
+ * `searchId` answers each value alone. Without `value`, the first `limit` values. A field with
1363
+ * custom display values answers every mapped value with its display value instead, matching
1364
+ * `value` against the display value, ignoring both `searchId` and `limit`.
1444
1365
  */
1445
1366
  async function search(id, searchId, params, options = {}) {
1446
1367
  await transport.require("field.search", options);
@@ -1454,11 +1375,13 @@ function fieldResource(transport) {
1454
1375
  }
1455
1376
  /**
1456
1377
  * The value of `remappedId` on the one row where `id` equals `value`, as `[value, remapped]`,
1457
- * or `null` when no row matches. `value` is parsed as a number for a numeric field.
1378
+ * or `null` when no row matches. For a numeric field the server reads the leading number of
1379
+ * `value` and ignores any text after it, refusing only a `value` that has none.
1458
1380
  */
1459
1381
  async function remapping(id, remappedId, params, options = {}) {
1460
1382
  await transport.require("field.remapping", options);
1461
- return fetchOptionalParsed(transport, `/api/field/${id}/remapping/${remappedId}`, FieldRemappedValue, {
1383
+ const { features } = await transport.server(options);
1384
+ return fetchOptionalParsed(transport, `/api/field/${id}/remapping/${remappedId}`, fieldRemappedValueSchema(features, id === remappedId), {
1462
1385
  ...options,
1463
1386
  query: { value: params.value }
1464
1387
  });
@@ -1481,6 +1404,7 @@ function fieldResource(transport) {
1481
1404
  return {
1482
1405
  get,
1483
1406
  update,
1407
+ setDataSensitivity,
1484
1408
  search,
1485
1409
  remapping,
1486
1410
  summary,
@@ -1512,6 +1436,7 @@ const SyncStashStarted = z.object({
1512
1436
  task_id: z.number().int().positive()
1513
1437
  });
1514
1438
  const RemoteSyncSetting = z.string().nullable();
1439
+ const RemoteSyncBranchProperty = z.object({ "remote-sync-branch": z.string().nullable().optional() });
1515
1440
  const FORBIDDEN_STATUS = 403;
1516
1441
  const UNREGISTERED_STATUS = 404;
1517
1442
  function isRemoteUnreadable(error) {
@@ -1559,16 +1484,24 @@ function gitSyncResource(transport) {
1559
1484
  /**
1560
1485
  * Import content from the remote into Metabase. The endpoint queues a task and returns at once;
1561
1486
  * pass `wait` to poll that task until it reaches a terminal status. A server already up to date
1562
- * answers no task id, and there is then nothing to poll.
1487
+ * answers no task id, and there is then nothing to poll. A server that guards the tracked branch
1488
+ * refuses with 409 when `expected_branch` disagrees with the setting; left out, it is the tracked
1489
+ * branch as read just before the request. `merge` folds the remote's changes into local content
1490
+ * by a three-way merge and keeps un-pushed local changes, where a plain import refuses on a dirty
1491
+ * instance.
1563
1492
  */
1564
1493
  async function importFromRemote(params = {}, options = {}) {
1565
1494
  await transport.require("gitSync.import", options);
1495
+ await requireMerge(params.merge, options);
1496
+ const expectedBranch = await guardedBranch(params.expected_branch, options);
1566
1497
  const started = await transport.requestParsed(SyncImportStarted, "/api/ee/remote-sync/import", {
1567
1498
  ...options,
1568
1499
  method: "POST",
1569
1500
  body: {
1570
1501
  branch: params.branch,
1571
- force: params.force
1502
+ force: params.force,
1503
+ merge: params.merge,
1504
+ expected_branch: expectedBranch
1572
1505
  }
1573
1506
  });
1574
1507
  const message = started.message ?? null;
@@ -1582,19 +1515,36 @@ function gitSyncResource(transport) {
1582
1515
  final: await settle(params.wait, options)
1583
1516
  };
1584
1517
  }
1518
+ async function requireMerge(merge, options) {
1519
+ if (merge === true) await transport.requireFeatures(["remoteSyncMerge"], options);
1520
+ }
1521
+ async function guardedBranch(given, options) {
1522
+ if (given !== void 0) return given;
1523
+ const { features } = await transport.server(options);
1524
+ if (!features.remoteSyncBranchGuard) return;
1525
+ return trackedBranch(options);
1526
+ }
1585
1527
  /**
1586
1528
  * Export Metabase's content to the remote. The endpoint queues a task and returns at once; pass
1587
- * `wait` to poll that task until it reaches a terminal status.
1529
+ * `wait` to poll that task until it reaches a terminal status. A server that guards the tracked
1530
+ * branch refuses with 409 when `branch` is not the tracked one; left out, it is the tracked branch
1531
+ * as read just before the request there, and the server's own default elsewhere. When the remote
1532
+ * has moved past the last sync, a plain export ends in a `conflict` task where `merge` is
1533
+ * available, and is refused with 400 before any task elsewhere; `merge` folds the remote's changes
1534
+ * in by a three-way merge instead, and `force` overwrites them.
1588
1535
  */
1589
1536
  async function exportToRemote(params = {}, options = {}) {
1590
1537
  await transport.require("gitSync.export", options);
1538
+ await requireMerge(params.merge, options);
1539
+ const branchName = await guardedBranch(params.branch, options);
1591
1540
  const started = await transport.requestParsed(SyncExportStarted, "/api/ee/remote-sync/export", {
1592
1541
  ...options,
1593
1542
  method: "POST",
1594
1543
  body: {
1595
- branch: params.branch,
1544
+ branch: branchName,
1596
1545
  message: params.message,
1597
- force: params.force
1546
+ force: params.force,
1547
+ merge: params.merge
1598
1548
  }
1599
1549
  });
1600
1550
  if (params.wait === void 0) return {
@@ -1679,7 +1629,7 @@ function gitSyncResource(transport) {
1679
1629
  async function syncedCollections(options = {}) {
1680
1630
  await transport.require("gitSync.syncedCollections", options);
1681
1631
  return {
1682
- data: (await listCollectionsWithLibrary(transport, SyncScopeCollection, options)).filter((entry) => entry.is_remote_synced === true),
1632
+ data: (await listCollectionsAs(transport, SyncScopeCollection, options)).filter((entry) => entry.is_remote_synced === true),
1683
1633
  total: null
1684
1634
  };
1685
1635
  }
@@ -1695,17 +1645,22 @@ function gitSyncResource(transport) {
1695
1645
  }
1696
1646
  }
1697
1647
  /**
1698
- * The branch git-sync tracks, or null when none is configured, the caller may not read it, or
1699
- * the server has no remote-sync module.
1648
+ * The branch git-sync tracks, or null when none is configured. Refuses when the caller may not
1649
+ * read the setting (it is admin-only) or the server has no remote-sync module, rather than
1650
+ * reading either as unset.
1700
1651
  */
1701
1652
  async function branch(options = {}) {
1702
1653
  await transport.require("gitSync.branch", options);
1703
- try {
1704
- return await fetchOptionalParsed(transport, "/api/setting/remote-sync-branch", RemoteSyncSetting, options);
1705
- } catch (error) {
1706
- if (isRemoteUnreadable(error)) return null;
1707
- throw error;
1708
- }
1654
+ const tracked = (await transport.requestParsed(RemoteSyncBranchProperty, PROBE_PATH, { ...options }))["remote-sync-branch"];
1655
+ if (tracked === void 0) throw new ConfigError("the remote-sync-branch setting is not readable: it is visible to admins only, and absent on a server without the remote-sync module");
1656
+ return tracked;
1657
+ }
1658
+ /** The branch git-sync tracks, refused when none is configured or the caller may not read it. */
1659
+ async function trackedBranch(options = {}) {
1660
+ await transport.require("gitSync.trackedBranch", options);
1661
+ const tracked = await branch(options);
1662
+ if (tracked === null) throw new ConfigError("git-sync tracks no branch: the remote-sync-branch setting is unset");
1663
+ return tracked;
1709
1664
  }
1710
1665
  /**
1711
1666
  * Poll the current task until it reaches a terminal status. A server with no task at all
@@ -1737,36 +1692,11 @@ function gitSyncResource(transport) {
1737
1692
  syncedCollections,
1738
1693
  remoteUrl,
1739
1694
  branch,
1695
+ trackedBranch,
1740
1696
  waitForTask
1741
1697
  };
1742
1698
  }
1743
1699
  //#endregion
1744
- //#region ../client/src/domain/glossary.ts
1745
- const GlossaryCreator = z.object({
1746
- id: z.number().int(),
1747
- email: z.string(),
1748
- first_name: z.string().nullable(),
1749
- last_name: z.string().nullable()
1750
- }).loose();
1751
- const Glossary = z.object({
1752
- id: z.number().int(),
1753
- term: z.string(),
1754
- definition: z.string(),
1755
- creator_id: z.number().int(),
1756
- creator: GlossaryCreator,
1757
- created_at: z.string(),
1758
- updated_at: z.string()
1759
- }).loose();
1760
- Glossary.pick({
1761
- id: true,
1762
- term: true,
1763
- definition: true
1764
- }).strip();
1765
- z.object({
1766
- term: z.string().min(1),
1767
- definition: z.string().min(1)
1768
- }).strict();
1769
- //#endregion
1770
1700
  //#region ../client/src/resources/glossary.ts
1771
1701
  const GlossaryApiList = z.object({ data: z.array(Glossary) }).loose();
1772
1702
  function glossaryResource(transport) {
@@ -1819,6 +1749,17 @@ function glossaryResource(transport) {
1819
1749
  };
1820
1750
  }
1821
1751
  //#endregion
1752
+ //#region ../client/src/resources/request-body.ts
1753
+ /**
1754
+ * Parse the body a caller hands a method, refusing one that does not match `schema` before any
1755
+ * request. `what` names the body in the refusal.
1756
+ */
1757
+ function parseRequestBody(schema, value, what) {
1758
+ const parsed = schema.safeParse(value);
1759
+ if (!parsed.success) throw new ConfigError(`invalid ${what}: ${parsed.error.issues.map(formatZodIssue).join("; ")}`);
1760
+ return parsed.data;
1761
+ }
1762
+ //#endregion
1822
1763
  //#region ../client/src/resources/library.ts
1823
1764
  const LIBRARY_ROOT_PATH = "/api/ee/library/";
1824
1765
  const PUBLISH_TABLES_PATH = "/api/ee/data-studio/table/publish-tables";
@@ -1835,7 +1776,7 @@ function libraryResource(transport) {
1835
1776
  return toLibrary(wire, await libraryListing(options));
1836
1777
  }
1837
1778
  async function libraryListing(options) {
1838
- const data = await listCollectionsWithLibrary(transport, LibraryCollectionInfo, options);
1779
+ const data = await listCollectionsAs(transport, LibraryCollectionInfo, options);
1839
1780
  const byId = /* @__PURE__ */ new Map();
1840
1781
  for (const collection of data) if (typeof collection.id === "number") byId.set(collection.id, collection);
1841
1782
  return byId;
@@ -1868,26 +1809,31 @@ function libraryResource(transport) {
1868
1809
  }
1869
1810
  /**
1870
1811
  * Publish tables — and every upstream table they depend on — into a collection, so they lead the
1871
- * data pickers and rank up in search. Answers the collection they landed in.
1812
+ * data pickers and rank up in search. Answers the collection they landed in. The endpoint
1813
+ * answers the same whether or not the selectors matched a table, so a body that does not match
1814
+ * `LibraryPublishTablesInput` is refused before any request.
1872
1815
  */
1873
1816
  async function publishTables(params, options = {}) {
1874
1817
  await transport.require("library.publishTables", options);
1818
+ const body = parseRequestBody(LibraryPublishTablesInput, params, "tables to publish");
1875
1819
  return (await transport.requestParsed(PublishTablesResponse, PUBLISH_TABLES_PATH, {
1876
1820
  ...options,
1877
1821
  method: "POST",
1878
- body: params
1822
+ body
1879
1823
  })).target_collection;
1880
1824
  }
1881
1825
  /**
1882
1826
  * Clear the Library collection from tables, and recursively from every downstream table that
1883
- * depends on them. The endpoint answers no JSON body.
1827
+ * depends on them. The endpoint answers no JSON body, whether or not the selectors matched a
1828
+ * table, so selectors that do not match `TableSelectors` are refused before any request.
1884
1829
  */
1885
1830
  async function unpublishTables(params, options = {}) {
1886
1831
  await transport.require("library.unpublishTables", options);
1832
+ const body = parseRequestBody(TableSelectors, params, "table selectors");
1887
1833
  await transport.requestRaw(UNPUBLISH_TABLES_PATH, {
1888
1834
  ...options,
1889
1835
  method: "POST",
1890
- body: params,
1836
+ body,
1891
1837
  expectContentType: "binary"
1892
1838
  });
1893
1839
  }
@@ -2140,48 +2086,21 @@ function metricResource(transport) {
2140
2086
  };
2141
2087
  }
2142
2088
  //#endregion
2143
- //#region ../client/src/domain/moderation-review.ts
2144
- const ModeratedItemType = z.enum(["card", "dashboard"]);
2145
- const ModerationStatus = z.enum(["verified"]);
2146
- const ModerationReview = z.object({
2147
- id: z.number().int(),
2148
- moderated_item_id: z.number().int(),
2149
- moderated_item_type: ModeratedItemType,
2150
- moderator_id: z.number().int(),
2151
- status: ModerationStatus.nullable(),
2152
- text: z.string().nullable(),
2153
- most_recent: z.boolean(),
2154
- created_at: z.string(),
2155
- updated_at: z.string()
2156
- }).loose();
2157
- ModerationReview.pick({
2158
- id: true,
2159
- moderated_item_id: true,
2160
- moderated_item_type: true,
2161
- status: true,
2162
- text: true,
2163
- most_recent: true
2164
- }).strip();
2165
- z.object({
2166
- moderated_item_id: z.number().int().positive(),
2167
- moderated_item_type: ModeratedItemType,
2168
- status: ModerationStatus.nullable().optional(),
2169
- text: z.string().nullable().optional()
2170
- }).strict();
2171
- //#endregion
2172
2089
  //#region ../client/src/resources/moderation-review.ts
2173
2090
  function moderationReviewResource(transport) {
2174
2091
  /**
2175
2092
  * Create a moderation review on a card or dashboard. `status: "verified"` marks the item
2176
2093
  * verified, `null` or an absent status records a note that leaves it unverified. The new review
2177
2094
  * becomes the item's most recent one; the server keeps the ten newest per item. Admins only.
2095
+ * A body that does not match `ModerationReviewCreateInput` is refused before any request.
2178
2096
  */
2179
2097
  async function create(params, options = {}) {
2180
2098
  await transport.require("moderationReview.create", options);
2099
+ const body = parseRequestBody(ModerationReviewCreateInput, params, "moderation review");
2181
2100
  return transport.requestParsed(ModerationReview, "/api/moderation-review", {
2182
2101
  ...options,
2183
2102
  method: "POST",
2184
- body: params
2103
+ body
2185
2104
  });
2186
2105
  }
2187
2106
  return { create };
@@ -2702,8 +2621,10 @@ function searchResource(transport) {
2702
2621
  * may match, `archived` swaps the active set for the archived one, `table_db_id` restricts to
2703
2622
  * items on one database, `verified` to verified content, `collection` to one collection and its
2704
2623
  * descendants, `created_by` to items created by any of those users, `search_native_query` also
2705
- * matches the text of native queries, `include_metadata` attaches each card's `result_metadata`,
2706
- * and `limit`/`offset` are the window the server applies before ranking hydration.
2624
+ * matches native query text but narrows to the models that carry one (cards, models, metrics,
2625
+ * actions, transforms), `include_metadata` attaches each card's `result_metadata`,
2626
+ * `include_dashboard_questions` also matches questions saved into a dashboard (excluded by
2627
+ * default), and `limit`/`offset` are the window the server applies before ranking hydration.
2707
2628
  */
2708
2629
  async function query(params = {}, options = {}) {
2709
2630
  await transport.require("search.query", options);
@@ -2720,7 +2641,8 @@ function searchResource(transport) {
2720
2641
  collection: params.collection,
2721
2642
  created_by: params.created_by,
2722
2643
  search_native_query: params.search_native_query,
2723
- include_metadata: params.include_metadata
2644
+ include_metadata: params.include_metadata,
2645
+ include_dashboard_questions: params.include_dashboard_questions
2724
2646
  }
2725
2647
  });
2726
2648
  return {
@@ -2904,14 +2826,18 @@ function snippetResource(transport) {
2904
2826
  const TableApiList = z.array(Table);
2905
2827
  const TableApiFks = z.array(TableForeignKey);
2906
2828
  const SyncSchemaResponse = z.object({ status: z.literal("ok") });
2907
- const RescanValuesResponse = z.object({ status: z.literal("success") });
2829
+ const FieldValuesResponse = z.object({ status: z.literal("success") });
2908
2830
  const BulkEditResponse = z.object({});
2909
2831
  const BULK_EDIT_PATH = "/api/data-studio/table/edit";
2832
+ const BULK_SYNC_SCHEMA_PATH = "/api/data-studio/table/sync-schema";
2833
+ const BULK_RESCAN_VALUES_PATH = "/api/data-studio/table/rescan-values";
2834
+ const BULK_DISCARD_VALUES_PATH = "/api/data-studio/table/discard-values";
2910
2835
  const LIST_PARAM_FEATURES = [
2911
2836
  ["can-query", "tableListAccessFilters"],
2912
2837
  ["can-write", "tableListAccessFilters"],
2913
2838
  ["include-transform-targets", "tableListTransformTargets"],
2914
- ["unused-only", "tableUnusedFilter"]
2839
+ ["unused-only", "tableUnusedFilter"],
2840
+ ["published-only", "tableListPublishedFilter"]
2915
2841
  ];
2916
2842
  function listParamFeatures(params) {
2917
2843
  return LIST_PARAM_FEATURES.filter(([param]) => params[param] !== void 0).map(([, feature]) => feature);
@@ -2925,7 +2851,7 @@ function tableResource(transport) {
2925
2851
  * List every table the caller can see, across all databases. `term` matches names and display
2926
2852
  * names; `can-query` and `can-write` keep only the tables the caller may query or edit the
2927
2853
  * metadata of; `include-transform-targets` adds tables a transform writes to; `unused-only` keeps
2928
- * tables nothing depends on.
2854
+ * tables nothing depends on; `published-only` keeps tables published to the library.
2929
2855
  */
2930
2856
  async function list(params = {}, options = {}) {
2931
2857
  await transport.require("table.list", options);
@@ -2943,6 +2869,7 @@ function tableResource(transport) {
2943
2869
  "owner-email": params["owner-email"],
2944
2870
  "orphan-only": params["orphan-only"],
2945
2871
  "unused-only": params["unused-only"],
2872
+ "published-only": params["published-only"],
2946
2873
  "can-query": params["can-query"],
2947
2874
  "can-write": params["can-write"],
2948
2875
  "include-transform-targets": params["include-transform-targets"]
@@ -2992,38 +2919,107 @@ function tableResource(transport) {
2992
2919
  };
2993
2920
  }
2994
2921
  /**
2995
- * Trigger a manual update of this table's schema metadata. The sync runs after the call returns;
2996
- * a warehouse the server cannot connect to is a 422.
2922
+ * Trigger a sync of this table: its columns, their fingerprints and its cached field values. It
2923
+ * never discovers new tables. The sync runs after the call returns; a warehouse the server cannot
2924
+ * connect to is a 422.
2997
2925
  */
2998
2926
  async function syncSchema(id, options = {}) {
2999
2927
  await transport.require("table.syncSchema", options);
3000
- await transport.requestParsed(SyncSchemaResponse, `/api/table/${id}/sync_schema`, {
3001
- ...options,
3002
- method: "POST"
3003
- });
2928
+ return {
2929
+ id,
2930
+ status: (await transport.requestParsed(SyncSchemaResponse, `/api/table/${id}/sync_schema`, {
2931
+ ...options,
2932
+ method: "POST"
2933
+ })).status
2934
+ };
3004
2935
  }
3005
2936
  /**
3006
- * Trigger an update of the field values of every eligible field of this table. The scan runs
3007
- * after the call returns.
2937
+ * Trigger an update of the field values of every eligible field of this table that already has a
2938
+ * cached set. The scan runs after the call returns.
3008
2939
  */
3009
2940
  async function rescanValues(id, options = {}) {
3010
2941
  await transport.require("table.rescanValues", options);
3011
- await transport.requestParsed(RescanValuesResponse, `/api/table/${id}/rescan_values`, {
3012
- ...options,
3013
- method: "POST"
3014
- });
2942
+ return {
2943
+ id,
2944
+ status: (await transport.requestParsed(FieldValuesResponse, `/api/table/${id}/rescan_values`, {
2945
+ ...options,
2946
+ method: "POST"
2947
+ })).status
2948
+ };
2949
+ }
2950
+ /**
2951
+ * Discard the cached field values of every field of this table, custom display values included.
2952
+ * No scan recreates a discarded set; the server rebuilds it, without the display values, the next
2953
+ * time the field's values are read.
2954
+ */
2955
+ async function discardValues(id, options = {}) {
2956
+ await transport.require("table.discardValues", options);
2957
+ return {
2958
+ id,
2959
+ status: (await transport.requestParsed(FieldValuesResponse, `/api/table/${id}/discard_values`, {
2960
+ ...options,
2961
+ method: "POST"
2962
+ })).status
2963
+ };
3015
2964
  }
3016
2965
  /**
3017
2966
  * Set the same metadata on every table the selectors pick out. A table leaving the `hidden` data
3018
- * layer is re-synced after the call returns.
2967
+ * layer is re-synced after the call returns. The server answers the same whether or not the
2968
+ * selectors matched a table.
3019
2969
  */
3020
2970
  async function bulkEdit(params, options = {}) {
3021
2971
  await transport.require("table.bulkEdit", options);
2972
+ await requireDataAuthorityNull(params.data_authority, options);
3022
2973
  await transport.requestParsed(BulkEditResponse, BULK_EDIT_PATH, {
3023
2974
  ...options,
3024
2975
  method: "POST",
3025
2976
  body: params
3026
2977
  });
2978
+ return {
2979
+ accepted: true,
2980
+ ...params
2981
+ };
2982
+ }
2983
+ async function requireDataAuthorityNull(value, options) {
2984
+ if (value === null) await transport.requireFeatures(["tableUserValueWithdrawal"], options);
2985
+ }
2986
+ async function postSelection(path, selectors, options) {
2987
+ const body = parseRequestBody(TableSelectors, selectors, "table selectors");
2988
+ await transport.requestRaw(path, {
2989
+ ...options,
2990
+ method: "POST",
2991
+ body,
2992
+ expectContentType: "binary"
2993
+ });
2994
+ return {
2995
+ accepted: true,
2996
+ ...body
2997
+ };
2998
+ }
2999
+ /**
3000
+ * Trigger a sync of every table the selectors pick out: its columns, their fingerprints and its
3001
+ * cached field values. Every database behind them must answer a connection test first, or the
3002
+ * call is a 422; the syncs run after it returns.
3003
+ */
3004
+ async function bulkSyncSchema(selectors, options = {}) {
3005
+ await transport.require("table.bulkSyncSchema", options);
3006
+ return postSelection(BULK_SYNC_SCHEMA_PATH, selectors, options);
3007
+ }
3008
+ /**
3009
+ * Trigger a field-values rescan of every table the selectors pick out, refreshing the sets that
3010
+ * are already cached. The scans run after the call returns.
3011
+ */
3012
+ async function bulkRescanValues(selectors, options = {}) {
3013
+ await transport.require("table.bulkRescanValues", options);
3014
+ return postSelection(BULK_RESCAN_VALUES_PATH, selectors, options);
3015
+ }
3016
+ /**
3017
+ * Discard the cached field values of every table the selectors pick out, custom display values
3018
+ * included. No scan recreates a discarded set.
3019
+ */
3020
+ async function bulkDiscardValues(selectors, options = {}) {
3021
+ await transport.require("table.bulkDiscardValues", options);
3022
+ return postSelection(BULK_DISCARD_VALUES_PATH, selectors, options);
3027
3023
  }
3028
3024
  async function updateFromCsv(id, action, file, options) {
3029
3025
  await transport.requestRaw(`/api/table/${id}/${UPLOAD_UPDATE_PATHS[action]}`, {
@@ -3065,7 +3061,11 @@ function tableResource(transport) {
3065
3061
  fks,
3066
3062
  syncSchema,
3067
3063
  rescanValues,
3064
+ discardValues,
3068
3065
  bulkEdit,
3066
+ bulkSyncSchema,
3067
+ bulkRescanValues,
3068
+ bulkDiscardValues,
3069
3069
  appendCsv,
3070
3070
  replaceCsv
3071
3071
  };