@metabase/cli 0.3.2 → 0.4.0-alpha.release-65-integration-branch.31ca6bb

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 (304) hide show
  1. package/dist/{add-collection-BjVAdZ1n.mjs → add-collection-B-Kczwcj.mjs} +5 -5
  2. package/dist/{alert-DCLhfwdv.mjs → alert-Ne0ivd5m.mjs} +7 -7
  3. package/dist/{alerts-DRin_wt2.mjs → alerts-Fakzg9iP.mjs} +6 -6
  4. package/dist/{append-DQ9rPJHZ.mjs → append-DCDVqPmR.mjs} +4 -4
  5. package/dist/archive-55sDfnHf.mjs +32 -0
  6. package/dist/{archive-_c-ISZmi.mjs → archive-BNJit8eD.mjs} +3 -3
  7. package/dist/{archive-o5cWV3vZ.mjs → archive-BbNqts-V.mjs} +3 -3
  8. package/dist/{archive-D6xzHaM3.mjs → archive-C93UR4Uc.mjs} +3 -3
  9. package/dist/{archive-BzVxRqpL.mjs → archive-CGmvQht4.mjs} +5 -5
  10. package/dist/{archive-COFQAHAL.mjs → archive-CL8wqAzm.mjs} +3 -3
  11. package/dist/{archive-BVRKE9Ev.mjs → archive-CSdktxvW.mjs} +5 -5
  12. package/dist/{archive-D3yPvUtz.mjs → archive-CpCSY4RT.mjs} +5 -5
  13. package/dist/{archive-xcgoVPwv.mjs → archive-DCCkQTjQ.mjs} +5 -5
  14. package/dist/{archive-BPCgmLcV.mjs → archive-DCE087yD.mjs} +4 -4
  15. package/dist/{archive-1YVo-Wsu.mjs → archive-DEef7eB8.mjs} +3 -3
  16. package/dist/{archive-HeRygdKz2.mjs → archive-DIZu7o4C.mjs} +4 -4
  17. package/dist/{auth-DJn5T6zA.mjs → auth-Bx4QQhqt.mjs} +5 -5
  18. package/dist/body-CB2eDFFb.mjs +17 -0
  19. package/dist/branch-flag-pFQPNYKr.mjs +9 -0
  20. package/dist/{branches-CUyPxeeW.mjs → branches-B6ilUG-7.mjs} +3 -3
  21. package/dist/breaking-Dg3-8yDF.mjs +36 -0
  22. package/dist/broken-BNBD4Eo3.mjs +37 -0
  23. package/dist/bulk-discard-values-DfKXuZpR.mjs +49 -0
  24. package/dist/bulk-edit-oUCfDQ_M.mjs +53 -0
  25. package/dist/bulk-rescan-values-B8pNlXUH.mjs +28 -0
  26. package/dist/bulk-sync-schema-tRp7jBJt.mjs +28 -0
  27. package/dist/{cancel-BNuVls58.mjs → cancel-Bl4BMkwI.mjs} +3 -3
  28. package/dist/{cancel-task-DUmlQQpi.mjs → cancel-task-CWWo7vLf.mjs} +4 -4
  29. package/dist/card-CQD4D8mw.mjs +25 -0
  30. package/dist/{card-CEkp1mcI.mjs → card-CQNUT9pm.mjs} +1 -1
  31. package/dist/{card-voh1k4hl.mjs → card-P5mBknsl.mjs} +3 -11
  32. package/dist/{cards-_gbvw3wp.mjs → cards-BIUYdSIR.mjs} +6 -6
  33. package/dist/cli.mjs +420 -100
  34. package/dist/{client-BnK0evYf.mjs → client-BHIFvEg2.mjs} +394 -316
  35. package/dist/{collection-DYM0p3Xl.mjs → collection-BG3Ksea-.mjs} +1 -1
  36. package/dist/collection-CuaTd10G.mjs +21 -0
  37. package/dist/{collection-BxdPxD38.mjs → collection-D3KXhvnc.mjs} +7 -5
  38. package/dist/{collection-namespace-DM90lA8C.mjs → collection-namespace-ZQePD67z.mjs} +2 -2
  39. package/dist/{content-translation-CqB3peU9.mjs → content-translation-BRdNdAmn.mjs} +3 -3
  40. package/dist/copy-BMEaYmTb.mjs +55 -0
  41. package/dist/copy-CbDfVZRC.mjs +36 -0
  42. package/dist/copy-flags-anRhAvB5.mjs +32 -0
  43. package/dist/{create-BIUVvIGH.mjs → create-5cDaZcRL.mjs} +3 -3
  44. package/dist/{create-CwXUMOMd.mjs → create-BEN-2XFK.mjs} +3 -3
  45. package/dist/create-BJG630xB.mjs +48 -0
  46. package/dist/{create-IFjwHs0G.mjs → create-BTQB1lqX.mjs} +4 -4
  47. package/dist/{create-BMKuihoI.mjs → create-C3TmU1Bi.mjs} +6 -6
  48. package/dist/create-C7O9tPL2.mjs +34 -0
  49. package/dist/{create-DVo8-IzZ.mjs → create-C8hsOv_D.mjs} +6 -6
  50. package/dist/{create-DNx9TGHs.mjs → create-CBSsW8Hm.mjs} +6 -6
  51. package/dist/{create-Cm9Z-rfe2.mjs → create-CG6WWY6k.mjs} +4 -4
  52. package/dist/{create-BSvTs-EV.mjs → create-D2Shlb7t.mjs} +3 -3
  53. package/dist/{create-DMVw9nrZ.mjs → create-DVEqry26.mjs} +4 -4
  54. package/dist/{create-B48rmY8v.mjs → create-D_pNX7d0.mjs} +3 -3
  55. package/dist/{create-D4Y69cDF.mjs → create-R0Q-nRlq.mjs} +4 -4
  56. package/dist/{create-CUHpxANR.mjs → create-SqmOf6WQ.mjs} +6 -6
  57. package/dist/{create-branch-Cw-uXows.mjs → create-branch-Cb3CWojg.mjs} +4 -4
  58. package/dist/{create-CnJKj9Nl.mjs → create-c2zR9y4J.mjs} +4 -4
  59. package/dist/{create-va8bByVt.mjs → create-xt4ff6fP.mjs} +3 -3
  60. package/dist/{create-B7S5fCkD.mjs → create-zpJIRn9j.mjs} +5 -5
  61. package/dist/{csv-CaKx1oFZ.mjs → csv-CRNOhy4X.mjs} +4 -4
  62. package/dist/{current-task-lGh69Z1i.mjs → current-task-DFo1ZJ51.mjs} +4 -4
  63. package/dist/dashboard-D11YAa7I.mjs +35 -0
  64. package/dist/{dashboard-D0hwTC-f.mjs → dashboard-Phz3XpRM.mjs} +2 -1
  65. package/dist/{dashboard-DgK81azj.mjs → dashboard-XSTr9QCr.mjs} +6 -2
  66. package/dist/data-action-BiHjjVjc.mjs +24 -0
  67. package/dist/data-action-DZxVB_hD.mjs +85 -0
  68. package/dist/data-action-R9qxJDPA.mjs +40 -0
  69. package/dist/database-BT7DVgSr.mjs +45 -0
  70. package/dist/{database-C3E9PZSx.mjs → database-Kq2AL5jH.mjs} +1 -1
  71. package/dist/dataset-BmvCxGoE.mjs +66 -0
  72. package/dist/{db-BRHPjshe.mjs → db-C8lj73Dz.mjs} +7 -7
  73. package/dist/delete-09O7BTNw.mjs +44 -0
  74. package/dist/{delete-Ci0aDYpf.mjs → delete-CYgNpHl7.mjs} +4 -4
  75. package/dist/{delete-G6EiGn2Q.mjs → delete-D_ZNoYVv.mjs} +4 -4
  76. package/dist/{delete-BxBadE3q.mjs → delete-HWeQtc4M.mjs} +4 -4
  77. package/dist/delete-I4eFpsed.mjs +44 -0
  78. package/dist/{delete-DMETa-37.mjs → delete-My8TX-B2.mjs} +4 -4
  79. package/dist/{delete-CQWCfqHf.mjs → delete-qwdN0N7e.mjs} +4 -4
  80. package/dist/delete-runtime-BbmRg_in.mjs +55 -0
  81. package/dist/{delete-table-N4rZtt1T.mjs → delete-table-BCvjX7bh.mjs} +4 -4
  82. package/dist/{dependencies-edN0P1SS.mjs → dependencies-BAE4YPXX.mjs} +5 -5
  83. package/dist/dependency-CIam7zmr.mjs +15 -0
  84. package/dist/dependency-DzLH3J8P.mjs +165 -0
  85. package/dist/dependency-zElFM-os.mjs +111 -0
  86. package/dist/dependents-Dv6tLdSs.mjs +52 -0
  87. package/dist/{dirty-U51bMoCP.mjs → dirty-CZORg0i0.mjs} +5 -5
  88. package/dist/discard-values-DKnP-JHr.mjs +55 -0
  89. package/dist/{document-CA0Q6lqu.mjs → document-C18b5rM6.mjs} +1 -1
  90. package/dist/{document-BHpLJbKU.mjs → document-DFCj1Az_.mjs} +2 -1
  91. package/dist/document-uxz96Lah.mjs +20 -0
  92. package/dist/{download-BJA6k-e6.mjs → download-BImtTll0.mjs} +2 -2
  93. package/dist/{eid-BtlRU1E0.mjs → eid-D0FxhT9H.mjs} +11 -10
  94. package/dist/entity-DWp9WJbU.mjs +20 -0
  95. package/dist/entry-flags-3sDWwa90.mjs +42 -0
  96. package/dist/{events-B5rnOo-L.mjs → events-BzCjVA3-.mjs} +4 -4
  97. package/dist/execute-BhHbkBqf.mjs +45 -0
  98. package/dist/export-CjqjDnaZ.mjs +74 -0
  99. package/dist/export-flags-BETJHNcw.mjs +81 -0
  100. package/dist/export-preflight-DzvIP6TB.mjs +35 -0
  101. package/dist/{field-CcN4oZy6.mjs → field-5nivEfd6.mjs} +33 -3
  102. package/dist/field-fBpiGiqr.mjs +21 -0
  103. package/dist/field-wmN6raOG.mjs +128 -0
  104. package/dist/{fields-zQ6O_W_H.mjs → fields-C-au1eLO.mjs} +6 -6
  105. package/dist/filter-flags-BIFcA2TT.mjs +72 -0
  106. package/dist/fks-83QIm8xb.mjs +36 -0
  107. package/dist/{get-93wuhTn2.mjs → get-BMHbEGbr.mjs} +4 -4
  108. package/dist/{get-DXwlZjw0.mjs → get-BTCOzSkl.mjs} +3 -3
  109. package/dist/{get-CekXFP3x.mjs → get-BawLhSwW.mjs} +3 -3
  110. package/dist/{get-BLjcCXp8.mjs → get-BjqqFG2m.mjs} +3 -3
  111. package/dist/{get-is8x5f2n.mjs → get-C-R_Fdsi.mjs} +3 -3
  112. package/dist/{get-DC_huYD8.mjs → get-C73V2KsB.mjs} +5 -5
  113. package/dist/{get-CG6G-mzV.mjs → get-C9sq2boy.mjs} +5 -5
  114. package/dist/{get-Cf6a4fFN.mjs → get-Cggv6yLC.mjs} +4 -4
  115. package/dist/{get-xPv7e5Ez.mjs → get-CkXc0Xld.mjs} +5 -5
  116. package/dist/{get-BLcS4il2.mjs → get-CqNEVAX_2.mjs} +3 -3
  117. package/dist/{get-DhpMuTSt.mjs → get-D7h7uH4k.mjs} +5 -5
  118. package/dist/get-DGmE5fmp.mjs +31 -0
  119. package/dist/{get-EFsmL4le.mjs → get-DTTsPd-c.mjs} +5 -5
  120. package/dist/{get-CeSQptdl.mjs → get-DXBXhPrU.mjs} +5 -5
  121. package/dist/{get-CTp5l7aU.mjs → get-D_v1IAL1.mjs} +3 -3
  122. package/dist/{get-BDrmBZ1z.mjs → get-DkzO3G5p.mjs} +5 -5
  123. package/dist/{get-Dg-S07ri.mjs → get-Dvr_69L7.mjs} +3 -3
  124. package/dist/get-NOMvMvYJ.mjs +36 -0
  125. package/dist/{get-BSoMWp4t2.mjs → get-YPDWhgm_2.mjs} +4 -4
  126. package/dist/{get-CwiJWeH4.mjs → get-Z36_0HX_.mjs} +4 -4
  127. package/dist/{get-run-DwY4sFGy.mjs → get-run-v1QHn-Mx.mjs} +4 -4
  128. package/dist/{git-sync-BwBRmEhE.mjs → git-sync-COokpYgc.mjs} +12 -3
  129. package/dist/git-sync-DspFahwV.mjs +165 -0
  130. package/dist/git-sync-VAqASCQ5.mjs +29 -0
  131. package/dist/glossary-BlNCrYbw.mjs +30 -0
  132. package/dist/glossary-Brnk2PBi.mjs +14 -0
  133. package/dist/glossary-LmZWwCNP.mjs +21 -0
  134. package/dist/graph-B6OliqnW.mjs +34 -0
  135. package/dist/{group-YQQ5GIcP.mjs → group-bpD_KcjA.mjs} +1 -1
  136. package/dist/{has-remote-changes-DE2_14FK.mjs → has-remote-changes-iTRCU9j0.mjs} +4 -4
  137. package/dist/{import-Cs7wk058.mjs → import-CdSs5CtT.mjs} +19 -8
  138. package/dist/{input-DEvkIjGr.mjs → input-D8qW-KtR.mjs} +6 -2
  139. package/dist/{is-dirty-XqDfqXGi.mjs → is-dirty-B5fj9NeS.mjs} +2 -2
  140. package/dist/{items-BloAjPwA.mjs → items-BxWnNEh7.mjs} +8 -8
  141. package/dist/{key-PYetuQ13.mjs → key-BynJSK9u.mjs} +1 -1
  142. package/dist/{library-Dgq_5BFh.mjs → library-BHHgurW0.mjs} +5 -5
  143. package/dist/{library-PGCfm0UA.mjs → library-BOv5SY24.mjs} +1 -1
  144. package/dist/{library-BPIzb3K_.mjs → library-Ck0EK5bi.mjs} +4 -2
  145. package/dist/{list-D9d5ocYi.mjs → list-BPMOLrwn.mjs} +5 -5
  146. package/dist/{list-D04uiS3F.mjs → list-BTcEm4td.mjs} +3 -3
  147. package/dist/{list-CghNKfYJ.mjs → list-BTgAbqeS.mjs} +4 -4
  148. package/dist/{list-3ErmGdY0.mjs → list-Bop1NTbU.mjs} +6 -6
  149. package/dist/{list-yV6CyPzn.mjs → list-By9XJRiv.mjs} +3 -3
  150. package/dist/list-CNC-XHbN.mjs +35 -0
  151. package/dist/{list-CUJ1wem9.mjs → list-CPWgBkPa.mjs} +4 -4
  152. package/dist/{list-sdCIS2Df.mjs → list-Cpa0Se7M.mjs} +5 -5
  153. package/dist/list-DA9KsA0o.mjs +101 -0
  154. package/dist/{list-VzrtA9lt.mjs → list-DE9gYY3I.mjs} +3 -3
  155. package/dist/{list-CUXlZiS1.mjs → list-DFJt2-fY.mjs} +4 -4
  156. package/dist/{list-BZnf3RmA.mjs → list-DUcnAb1h.mjs} +3 -3
  157. package/dist/{list-vsXIMssK.mjs → list-DW4-u7eO.mjs} +5 -5
  158. package/dist/{list-f8Csdjyc.mjs → list-DbXnSL2x.mjs} +5 -5
  159. package/dist/list-DgsM9YQX.mjs +28 -0
  160. package/dist/{list-BfLo1xI8.mjs → list-Dzzt6Yee.mjs} +3 -3
  161. package/dist/{list-CZCaqPoo.mjs → list-ZHLsjxXg.mjs} +6 -6
  162. package/dist/{list-Bzm5mXRo.mjs → list-e7yvJYMw.mjs} +3 -3
  163. package/dist/{list-DboUvg-Y.mjs → list-hN_Tu2T6.mjs} +6 -6
  164. package/dist/{list-DuJezLm_.mjs → list-zyKxxNvn.mjs} +3 -3
  165. package/dist/{login-Vw51Gts5.mjs → login-B7nGQDZK.mjs} +6 -6
  166. package/dist/{logout-BDIqoVhv.mjs → logout-pZffAh1G.mjs} +2 -2
  167. package/dist/{measure-LY9Tp9QZ.mjs → measure-AtnrCTCC.mjs} +6 -6
  168. package/dist/moderation-review-BdqEH6N1.mjs +31 -0
  169. package/dist/{notification-DVrLkjFT.mjs → notification-DOYdl0ao.mjs} +1 -1
  170. package/dist/{parameter-values-DWjmO7Ai.mjs → parameter-values-CxTkEjCs.mjs} +3 -3
  171. package/dist/{parse-enum-Dc0dMZ3P.mjs → parse-enum-CLIXMsd8.mjs} +1 -1
  172. package/dist/parse-id-7ja3HUdB.mjs +13 -0
  173. package/dist/{parse-ref-DTDld_LJ.mjs → parse-ref-Cw5fa4FI.mjs} +1 -1
  174. package/dist/parse-text-T0lTXzTZ.mjs +11 -0
  175. package/dist/{path-BUUAGYO5.mjs → path-DM4vyihl.mjs} +4 -4
  176. package/dist/{poll-CZeXepUQ.mjs → poll-Dz4tUm2f.mjs} +2 -2
  177. package/dist/{preflight-DcULqq8E.mjs → preflight-DaZ2z2C1.mjs} +3 -3
  178. package/dist/{process-CTrfxxaC.mjs → process-D0HdqZ3r.mjs} +1 -1
  179. package/dist/{publish-qVFmJQ1E.mjs → publish-C0HCL04a.mjs} +4 -4
  180. package/dist/{pulse-x0gFxWfG.mjs → pulse-D1uh8UIU.mjs} +1 -1
  181. package/dist/{query-Cq1lmqL5.mjs → query-BC-C6efK.mjs} +14 -33
  182. package/dist/query-BKtMP5eH.mjs +13 -0
  183. package/dist/query-CAFPlqfi.mjs +329 -0
  184. package/dist/remapping-CgA6UJGU.mjs +53 -0
  185. package/dist/{remove-collection-DBqh2Lqm.mjs → remove-collection-DoctJa9g.mjs} +5 -5
  186. package/dist/{render-Gx1hR7IF.mjs → render-Bvm9mta6.mjs} +2 -2
  187. package/dist/{replace-CujInVY9.mjs → replace-CaFJd9fO.mjs} +4 -4
  188. package/dist/rescan-values-7VOGCLMe.mjs +32 -0
  189. package/dist/{rescan-values-HypqBCSK.mjs → rescan-values-sJRwcHsk.mjs} +5 -5
  190. package/dist/{run-DEkQSOQa.mjs → run-COHDQ5J4.mjs} +3 -3
  191. package/dist/{run-b3jyF29q.mjs → run-RXpFlDAB.mjs} +4 -4
  192. package/dist/{runs-GHqHLGy4.mjs → runs-CUYdCKiE.mjs} +5 -5
  193. package/dist/{runtime-nCPku2nN.mjs → runtime-B8RtMb4B.mjs} +21 -82
  194. package/dist/{schema-tables-B5L05Y1L.mjs → schema-tables-CO5qyZBe.mjs} +6 -6
  195. package/dist/{schemas-Clx26p_4.mjs → schemas-CzHHgDdF.mjs} +4 -4
  196. package/dist/search-BWb052_b.mjs +131 -0
  197. package/dist/search-Cc9vHNae.mjs +85 -0
  198. package/dist/{segment-DiRJcbam.mjs → segment-C_rsUkHK.mjs} +6 -6
  199. package/dist/{send-DIHkDNBN.mjs → send-C-3bkpni.mjs} +3 -3
  200. package/dist/{set-D77qUZML.mjs → set-BDkT37OT.mjs} +4 -4
  201. package/dist/{set-active-DCdFgD0O.mjs → set-active-CDJTfQEc.mjs} +3 -3
  202. package/dist/set-sensitivity-DVrINHde.mjs +57 -0
  203. package/dist/{setting-DR9bj232.mjs → setting-CoLzd08x.mjs} +4 -4
  204. package/dist/{setup-DGa2LLEp.mjs → setup-C4F4XYbU.mjs} +3 -3
  205. package/dist/{signal-k7cm5N6h.mjs → signal-CxWeLszu.mjs} +1 -1
  206. package/dist/{skill-list-DAvGGHzS.mjs → skill-list-BgihWuPf.mjs} +2 -2
  207. package/dist/{skills-CqtNuSXM.mjs → skills-4qDjKRSk.mjs} +2 -2
  208. package/dist/{skills-CCn7cyMP.mjs → skills-BWEFRpUj.mjs} +3 -3
  209. package/dist/snippet-CYd8D9SK.mjs +19 -0
  210. package/dist/{stash-BTtsV0AG.mjs → stash-CZ1x0rox.mjs} +6 -6
  211. package/dist/{status-XgSS3StV.mjs → status-BM6eYW7I.mjs} +3 -3
  212. package/dist/{status-CW7Dt-nV.mjs → status-gqpPZvue.mjs} +7 -7
  213. package/dist/{subscription-CofRU47d.mjs → subscription-pSuO241O.mjs} +6 -6
  214. package/dist/{subscriptions-DCuuPF6U.mjs → subscriptions-n5zJ9rYZ.mjs} +6 -6
  215. package/dist/{summary-uGlgKE3C.mjs → summary-DvIf2EiO.mjs} +5 -5
  216. package/dist/sync-schema-Cc21crxQ.mjs +32 -0
  217. package/dist/{sync-schema-Cu9rD3eH.mjs → sync-schema-D1t8rhdQ.mjs} +6 -6
  218. package/dist/sync-task-CXFoqlpF.mjs +53 -0
  219. package/dist/{table-DfuY0N8e.mjs → table-Ci6bhZkb.mjs} +35 -12
  220. package/dist/table-CxvaDiIZ.mjs +155 -0
  221. package/dist/table-Dc0dLfyg.mjs +26 -0
  222. package/dist/table-selector-flags-BVZvnhUa.mjs +42 -0
  223. package/dist/text-DaNkPRwt.mjs +6 -0
  224. package/dist/timeline-BqU5sOb6.mjs +21 -0
  225. package/dist/{timeline-event-D-h0A_oh.mjs → timeline-event-jn1SOKd4.mjs} +6 -6
  226. package/dist/transform-BUIlFqpv.mjs +28 -0
  227. package/dist/{transform-CtqB1WYo.mjs → transform-CNBIV7No.mjs} +1 -1
  228. package/dist/transform-job-DsbY9mme.mjs +22 -0
  229. package/dist/{transform-tag-BLp_p9J-.mjs → transform-tag-C0jzV6Dk.mjs} +5 -5
  230. package/dist/{transforms-n2IwEcbU.mjs → transforms-DwTy_Quh.mjs} +5 -5
  231. package/dist/tree-p2j6IVy-.mjs +34 -0
  232. package/dist/{unpublish-DVQCAa3g.mjs → unpublish-B-961jX1.mjs} +3 -3
  233. package/dist/unreferenced-Dxy-aYI7.mjs +36 -0
  234. package/dist/{update-CnkPYL2i.mjs → update-BFYRBbRu.mjs} +6 -6
  235. package/dist/{update-ChpOukqq.mjs → update-BGeaPntx.mjs} +5 -5
  236. package/dist/{update-NGq0yXZk.mjs → update-BnIEN390.mjs} +5 -5
  237. package/dist/{update-DffrdV4b.mjs → update-CALlEgIC.mjs} +4 -4
  238. package/dist/{update-DFdBeJwc.mjs → update-CHkVN69L.mjs} +13 -8
  239. package/dist/{update-oQeQyqKO.mjs → update-CKqL9PmU.mjs} +5 -5
  240. package/dist/{update-rFRPLlb6.mjs → update-CYGYUCFQ.mjs} +4 -4
  241. package/dist/update-CuQy2g51.mjs +52 -0
  242. package/dist/{update-B7CikkI0.mjs → update-D4TGE6FS.mjs} +7 -7
  243. package/dist/{update-D9H6Lh5U.mjs → update-D7xi-0bU.mjs} +4 -4
  244. package/dist/{update-DKO9HF1f.mjs → update-DK77vtFF.mjs} +6 -6
  245. package/dist/{update-CKDRuduL.mjs → update-DKDQTlnV.mjs} +5 -5
  246. package/dist/update-DXxJHC8y.mjs +41 -0
  247. package/dist/update-DiJK0uRG.mjs +181 -0
  248. package/dist/{update-CAsqNhDC.mjs → update-MD1Kwq1P.mjs} +4 -4
  249. package/dist/{update-dashcard-DvPqLJ3N.mjs → update-dashcard-DuTjOh14.mjs} +6 -6
  250. package/dist/{update-DScUzKLI.mjs → update-hvO4VpfZ.mjs} +7 -7
  251. package/dist/{update-D4ggtuG4.mjs → update-qDZvnwvf.mjs} +7 -7
  252. package/dist/{update-C05J2nZ2.mjs → update-tltXCUwR.mjs} +4 -4
  253. package/dist/{upgrade-BRgw0fvn.mjs → upgrade-Ca-Ss5jb.mjs} +4 -4
  254. package/dist/{upload-Do2PBSeH.mjs → upload-C2fhpKkP.mjs} +2 -2
  255. package/dist/upload-Dw7mVr9u.mjs +13 -0
  256. package/dist/{upload-BrfbcbBW.mjs → upload-t6dkccqn.mjs} +3 -3
  257. package/dist/{uuid-B4eij1d7.mjs → uuid-BMlJZT8z.mjs} +2 -2
  258. package/dist/{validate-xR_MHBNR.mjs → validate-D7e110oU.mjs} +1 -1
  259. package/dist/{validate-query-D6_ad-Gi.mjs → validate-query-BzbZmenf.mjs} +7 -3
  260. package/dist/{values-xgOftPq5.mjs → values-CXN4xTTh.mjs} +5 -5
  261. package/dist/verify-CPVfwKSu.mjs +38 -0
  262. package/dist/verify-flags-CMpRkMPa.mjs +58 -0
  263. package/dist/verify-k-JB-k3D.mjs +38 -0
  264. package/dist/{verify-DTOA_wVM.mjs → verify-t-CEmvoG.mjs} +3 -3
  265. package/dist/{wait-BjeFgR13.mjs → wait-KSkq7kKW.mjs} +6 -6
  266. package/dist/{wait-flags-BCeCnaz3.mjs → wait-flags-KX7NHdj4.mjs} +2 -2
  267. package/dist/{window-DSb1tqSe.mjs → window-CI_QD04s.mjs} +1 -1
  268. package/package.json +1 -1
  269. package/skill-data/core/SKILL.md +18 -11
  270. package/skill-data/dashboard/SKILL.md +1 -1
  271. package/skill-data/data-action/SKILL.md +125 -0
  272. package/skill-data/document/SKILL.md +12 -1
  273. package/skill-data/git-sync/SKILL.md +61 -9
  274. package/skill-data/mbql/SKILL.md +5 -0
  275. package/skill-data/metadata/SKILL.md +36 -6
  276. package/skill-data/native-sql/SKILL.md +1 -1
  277. package/dist/body-Cu94pH4P.mjs +0 -17
  278. package/dist/card-ByOzVxpI.mjs +0 -24
  279. package/dist/collection-BGbW7u_Q.mjs +0 -20
  280. package/dist/dashboard-Bzjz2v6u.mjs +0 -33
  281. package/dist/database-JtHTqSpq.mjs +0 -26
  282. package/dist/delete-runtime-BKEzJn22.mjs +0 -49
  283. package/dist/document-DqJ7Cysa.mjs +0 -19
  284. package/dist/export-DO2josC0.mjs +0 -63
  285. package/dist/field-CHZByaXa.mjs +0 -18
  286. package/dist/field-fDtIrY6D.mjs +0 -80
  287. package/dist/get-yHIEezeG.mjs +0 -31
  288. package/dist/git-sync-NhfLSZA6.mjs +0 -28
  289. package/dist/git-sync-TjX1r_wF.mjs +0 -136
  290. package/dist/list-DgteFn01.mjs +0 -34
  291. package/dist/parse-id-whJX4DAb.mjs +0 -10
  292. package/dist/query-BPtIy79s.mjs +0 -114
  293. package/dist/query-result-E4Q-Gra6.mjs +0 -15
  294. package/dist/search-DxiuY5EV.mjs +0 -97
  295. package/dist/selectors-rEFuyXPZ.mjs +0 -35
  296. package/dist/snippet-g9JTDxqu.mjs +0 -19
  297. package/dist/sync-task-BXeWuARG.mjs +0 -37
  298. package/dist/table-C6h4tIRw.mjs +0 -37
  299. package/dist/table-Di-EY7pg.mjs +0 -18
  300. package/dist/timeline-D7EsWZm6.mjs +0 -21
  301. package/dist/transform-8XK1LIgC.mjs +0 -28
  302. package/dist/transform-job-CTizQkWy.mjs +0 -22
  303. package/dist/tree-cqxiDh2b.mjs +0 -26
  304. package/dist/upload-VXBFKzLT.mjs +0 -13
@@ -1,22 +1,28 @@
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-B8RtMb4B.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 { r as PivotExportFormat, t as DatasetQuery } from "./query-BKtMP5eH.mjs";
8
+ import { a as CardQueryResult, t as Card } from "./card-P5mBknsl.mjs";
9
+ import { b as TableVisibilityType, p as TableQueryMetadata, s as TableDataLayerTier, t as Table, u as TableForeignKey, v as TableSelectors } from "./table-Ci6bhZkb.mjs";
10
+ import { t as Database } from "./database-BT7DVgSr.mjs";
10
11
  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";
12
+ import { o as compiledQuerySchema, r as QueryMetadata } from "./dataset-BmvCxGoE.mjs";
13
+ import { c as CollectionItem, m as CollectionTreeNode, r as Collection } from "./collection-D3KXhvnc.mjs";
12
14
  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";
15
+ import { l as Dashcard, o as DashboardDetail, r as DashboardCopy, t as Dashboard } from "./dashboard-Phz3XpRM.mjs";
16
+ import { a as DataActionExecuteResult, s as dataActionSchema } from "./data-action-DZxVB_hD.mjs";
17
+ import { r as pollUntil } from "./poll-Dz4tUm2f.mjs";
18
+ import { i as DependencyEntity, s as DependencyGraph, t as BreakingSource, u as DependencyNode } from "./dependency-DzLH3J8P.mjs";
19
+ import { t as Document } from "./document-DFCj1Az_.mjs";
16
20
  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";
21
+ 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";
22
+ import { t as Glossary } from "./glossary-BlNCrYbw.mjs";
23
+ import { a as libraryWireSchema, i as LibraryPublishTablesInput, n as LibraryCollectionInfo, o as toLibrary } from "./library-Ck0EK5bi.mjs";
19
24
  import { t as Measure } from "./measure-CtfjqJFP.mjs";
25
+ import { r as ModerationReviewCreateInput, t as ModerationReview } from "./moderation-review-BdqEH6N1.mjs";
20
26
  import { t as Pulse } from "./pulse-Dz0ocv0l.mjs";
21
27
  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
28
  import { r as SearchResult } from "./search-BAXg-EJw.mjs";
@@ -349,43 +355,16 @@ async function readBodyForError(response) {
349
355
  }
350
356
  }
351
357
  //#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();
358
+ //#region ../client/src/resources/pivot-export.ts
359
+ const PivotedExportsSetting = z.object({ "enable-pivoted-exports": z.boolean() });
360
+ /**
361
+ * Refuse a pivoted export the server would answer with plain rows: a JSON export keeps only the
362
+ * ungrouped rows, and an admin can turn pivoted CSV and XLSX exports off.
363
+ */
364
+ async function assertPivotedExport(transport, format, options) {
365
+ if (!PivotExportFormat.safeParse(format).success) throw new ConfigError(`a ${format} export cannot be pivoted; only ${PivotExportFormat.options.join(" and ")} can`);
366
+ 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");
367
+ }
389
368
  //#endregion
390
369
  //#region ../client/src/resources/card.ts
391
370
  const CardApiList = z.array(Card);
@@ -442,15 +421,22 @@ function cardResource(transport) {
442
421
  });
443
422
  }
444
423
  /**
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.
424
+ * Run the query associated with a Card, and return its results as a file in the specified
425
+ * format. Unlike `query`, this endpoint takes a form-encoded body and answers bytes, so a caller
426
+ * consumes the stream rather than a value. A pivot the server would answer with plain rows (a
427
+ * JSON export, or pivoted exports turned off) is refused. `csv_include_bom` opens a CSV with a
428
+ * UTF-8 byte order mark; a server without it drops the key silently, so asking for one is refused
429
+ * there before the wire.
447
430
  */
448
431
  async function exportQuery(id, format, params, options = {}) {
449
432
  await transport.require("card.exportQuery", options);
433
+ await transport.requireFeatures(params.csv_include_bom ? ["exportCsvByteOrderMark"] : [], options);
434
+ if (params.pivot_results) await assertPivotedExport(transport, format, options);
450
435
  const body = new URLSearchParams({
451
436
  parameters: JSON.stringify(params.parameters),
452
437
  format_rows: String(params.format_rows),
453
- pivot_results: String(params.pivot_results)
438
+ pivot_results: String(params.pivot_results),
439
+ csv_include_bom: String(params.csv_include_bom)
454
440
  });
455
441
  return transport.requestStream(`/api/card/${id}/query/${format}`, {
456
442
  ...options,
@@ -534,20 +520,20 @@ function refPath(ref) {
534
520
  return encodeURIComponent(ref);
535
521
  }
536
522
  /**
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.
523
+ * List every collection the caller can read, the Library and its children among them, parsing each
524
+ * through the caller's own projection. `Collection` pins `type`, `namespace` and `authority_level`
525
+ * to closed enums, so a consumer reading a few fields off every collection on the instance narrows
526
+ * here: one collection carrying a server value outside those sets then costs nothing to a caller
527
+ * that never reads the field.
542
528
  */
543
- async function listCollectionsWithLibrary(transport, schema, options = {}) {
544
- return transport.requestParsed(z.array(schema), "/api/collection", {
545
- ...options,
546
- query: { "include-library": true }
547
- });
529
+ async function listCollectionsAs(transport, schema, options = {}) {
530
+ return transport.requestParsed(z.array(schema), "/api/collection", { ...options });
548
531
  }
549
532
  function collectionResource(transport) {
550
- /** List collections. `filter` picks a server-side preset: everything, archived, or personal. */
533
+ /**
534
+ * List collections. `filter` picks a server-side preset: everything, archived, or personal. Every
535
+ * preset includes the Library collections that match it.
536
+ */
551
537
  async function list(params = {}, options = {}) {
552
538
  await transport.require("collection.list", options);
553
539
  return {
@@ -558,18 +544,6 @@ function collectionResource(transport) {
558
544
  total: null
559
545
  };
560
546
  }
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
547
  /** Get one collection by id, entity id, or the `root`/`trash` alias. */
574
548
  async function get(ref, options = {}) {
575
549
  await transport.require("collection.get", options);
@@ -584,7 +558,11 @@ function collectionResource(transport) {
584
558
  body: params
585
559
  });
586
560
  }
587
- /** Update a collection, patching only the fields the body carries. */
561
+ /**
562
+ * Update a collection, patching the fields the body carries. The server reads an absent
563
+ * `archived` as `false`, so a patch without it restores an archived collection, and a patch that
564
+ * moves a collection into the trash ignores `parent_id`.
565
+ */
588
566
  async function update(ref, params, options = {}) {
589
567
  await transport.require("collection.update", options);
590
568
  return transport.requestParsed(Collection, `/api/collection/${refPath(ref)}`, {
@@ -617,16 +595,18 @@ function collectionResource(transport) {
617
595
  });
618
596
  }
619
597
  /** Fetch the collection hierarchy as a forest of nested nodes. */
620
- async function tree(options = {}) {
598
+ async function tree(params = {}, options = {}) {
621
599
  await transport.require("collection.tree", options);
622
600
  return {
623
- data: await transport.requestParsed(CollectionTreeApiList, "/api/collection/tree", { ...options }),
601
+ data: await transport.requestParsed(CollectionTreeApiList, "/api/collection/tree", {
602
+ ...options,
603
+ query: { "include-library": params["include-library"] }
604
+ }),
624
605
  total: null
625
606
  };
626
607
  }
627
608
  return {
628
609
  list,
629
- listWithLibrary,
630
610
  get,
631
611
  create,
632
612
  update,
@@ -715,9 +695,13 @@ function dashboardResource(transport) {
715
695
  }
716
696
  /**
717
697
  * 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`.
698
+ * copy duplicates its questions and metrics and references its models. With `is_deep_copy`
699
+ * false or absent the copy references every card, and a dashboard holding unarchived dashboard
700
+ * questions is refused. Archived cards, cards the caller cannot read, and every card on a
701
+ * dashcard whose main card the caller cannot read are left out and reported as `uncopied`, once
702
+ * per dashcard they sat on. A left-out main card takes its dashcard with it; a left-out series
703
+ * card stays on a dashcard whose main card is referenced and is dropped from one whose main card
704
+ * is duplicated. Action, link and placeholder dashcards are not copied.
721
705
  */
722
706
  async function copy(id, params = {}, options = {}) {
723
707
  await transport.require("dashboard.copy", options);
@@ -856,6 +840,81 @@ function stripEntityId(dashcard) {
856
840
  };
857
841
  }
858
842
  //#endregion
843
+ //#region ../client/src/resources/data-action.ts
844
+ function dataActionResource(transport) {
845
+ async function readSchema(options) {
846
+ const { features } = await transport.server(options);
847
+ return dataActionSchema(features);
848
+ }
849
+ /** List the unarchived data actions the caller can see. `GET /api/action` answers a bare array. */
850
+ async function list(options = {}) {
851
+ await transport.require("dataAction.list", options);
852
+ const schema = await readSchema(options);
853
+ return {
854
+ data: await transport.requestParsed(z.array(schema), "/api/action", { ...options }),
855
+ total: null
856
+ };
857
+ }
858
+ /** Get one unarchived data action by id. */
859
+ async function get(id, options = {}) {
860
+ await transport.require("dataAction.get", options);
861
+ const schema = await readSchema(options);
862
+ return transport.requestParsed(schema, `/api/action/${id}`, { ...options });
863
+ }
864
+ /** Create a data action — a parameterized native query that writes to a database — in a collection. */
865
+ async function create(params, options = {}) {
866
+ await transport.require("dataAction.create", options);
867
+ const schema = await readSchema(options);
868
+ return transport.requestParsed(schema, "/api/action", {
869
+ ...options,
870
+ method: "POST",
871
+ body: params
872
+ });
873
+ }
874
+ /** Update a data action by id, patching only the fields the body carries. */
875
+ async function update(id, params, options = {}) {
876
+ await transport.require("dataAction.update", options);
877
+ const schema = await readSchema(options);
878
+ return transport.requestParsed(schema, `/api/action/${id}`, {
879
+ ...options,
880
+ method: "PUT",
881
+ body: params
882
+ });
883
+ }
884
+ /** Archive (soft-delete) a data action by id. Metabase models this as an update, not its own endpoint. */
885
+ async function archive(id, options = {}) {
886
+ await transport.require("dataAction.archive", options);
887
+ return update(id, { archived: true }, options);
888
+ }
889
+ /** Delete a data action by id, removing it and the dashboard buttons that run it. */
890
+ async function remove(id, options = {}) {
891
+ await transport.require("dataAction.delete", options);
892
+ await transport.requestRaw(`/api/action/${id}`, {
893
+ ...options,
894
+ method: "DELETE",
895
+ expectContentType: "binary"
896
+ });
897
+ }
898
+ /** Execute a data action by id with parameter values keyed by parameter id. */
899
+ async function execute(id, params, options = {}) {
900
+ await transport.require("dataAction.execute", options);
901
+ return transport.requestParsed(DataActionExecuteResult, `/api/action/${id}/execute`, {
902
+ ...options,
903
+ method: "POST",
904
+ body: params
905
+ });
906
+ }
907
+ return {
908
+ list,
909
+ get,
910
+ create,
911
+ update,
912
+ archive,
913
+ delete: remove,
914
+ execute
915
+ };
916
+ }
917
+ //#endregion
859
918
  //#region ../client/src/resources/database.ts
860
919
  const DatabaseApiList = z.object({
861
920
  data: z.array(Database),
@@ -971,7 +1030,8 @@ function datasetResource(transport) {
971
1030
  */
972
1031
  async function native(datasetQuery, params = {}, options = {}) {
973
1032
  await transport.require("dataset.native", options);
974
- return transport.requestParsed(CompiledQuery, "/api/dataset/native", {
1033
+ const { features } = await transport.server(options);
1034
+ return transport.requestParsed(compiledQuerySchema(features), "/api/dataset/native", {
975
1035
  ...options,
976
1036
  method: "POST",
977
1037
  body: {
@@ -994,18 +1054,33 @@ function datasetResource(transport) {
994
1054
  });
995
1055
  }
996
1056
  /**
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.
1057
+ * Execute a query and download the result data as a file in the specified format. Unlike
1058
+ * `query`, this endpoint answers bytes, so a caller consumes the stream rather than a value.
1059
+ * `visualization_settings` drive `format_rows` column formatting and, through
1060
+ * `pivot_table.column_split`, the layout `pivot_results` lays the rows out in. The server only
1061
+ * computes that layout for a query it runs as a pivot, which it reads from the query's own
1062
+ * `was-pivot`, so `pivot_results` sets it. A pivot the server would answer with plain rows (a
1063
+ * JSON export, or pivoted exports turned off) is refused. `csv_include_bom` opens a CSV with a
1064
+ * UTF-8 byte order mark; a server without it drops the key silently, so asking for one is refused
1065
+ * there before the wire.
999
1066
  */
1000
1067
  async function exportQuery(format, params, options = {}) {
1001
1068
  await transport.require("dataset.exportQuery", options);
1069
+ await transport.requireFeatures(params.csv_include_bom ? ["exportCsvByteOrderMark"] : [], options);
1070
+ if (params.pivot_results) await assertPivotedExport(transport, format, options);
1071
+ const exported = params.pivot_results ? {
1072
+ ...params.query,
1073
+ "was-pivot": true
1074
+ } : params.query;
1002
1075
  return transport.requestStream(`/api/dataset/${format}`, {
1003
1076
  ...options,
1004
1077
  method: "POST",
1005
1078
  body: {
1006
- query: params.query,
1079
+ query: exported,
1080
+ visualization_settings: params.visualization_settings,
1007
1081
  format_rows: params.format_rows,
1008
- pivot_results: params.pivot_results
1082
+ pivot_results: params.pivot_results,
1083
+ csv_include_bom: params.csv_include_bom
1009
1084
  }
1010
1085
  });
1011
1086
  }
@@ -1017,133 +1092,18 @@ function datasetResource(transport) {
1017
1092
  };
1018
1093
  }
1019
1094
  //#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
1095
  //#region ../client/src/resources/dependency.ts
1126
1096
  const DependencyNodeApiList = z.array(DependencyNode);
1127
1097
  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
1098
  function dependencyResource(transport) {
1140
1099
  /**
1141
1100
  * The upstream dependency graph of one entity. `nodes` holds the starting entity plus every
1142
1101
  * entity it depends on, directly or transitively; each edge runs from the dependent to what it
1143
- * depends on.
1102
+ * depends on. A measure starts a graph only on a server with `measureDependencyGraph`.
1144
1103
  */
1145
1104
  async function graph(type, id, options = {}) {
1146
1105
  await transport.require("dependency.graph", options);
1106
+ if (type === "measure") await transport.requireFeatures(["measureDependencyGraph"], options);
1147
1107
  return transport.requestParsed(DependencyGraph, "/api/ee/dependencies/graph", {
1148
1108
  ...options,
1149
1109
  query: {
@@ -1160,7 +1120,6 @@ function dependencyResource(transport) {
1160
1120
  */
1161
1121
  async function dependents(type, id, params = {}, options = {}) {
1162
1122
  await transport.require("dependency.dependents", options);
1163
- await transport.requireFeatures(filterFeatures(params), options);
1164
1123
  return {
1165
1124
  data: await transport.requestParsed(DependencyNodeApiList, "/api/ee/dependencies/graph/dependents", {
1166
1125
  ...options,
@@ -1187,7 +1146,6 @@ function dependencyResource(transport) {
1187
1146
  */
1188
1147
  async function broken(type, id, params = {}, options = {}) {
1189
1148
  await transport.require("dependency.broken", options);
1190
- await transport.requireFeatures(filterFeatures(params), options);
1191
1149
  return {
1192
1150
  data: await transport.requestParsed(DependencyEntityApiList, "/api/ee/dependencies/graph/broken", {
1193
1151
  ...options,
@@ -1205,15 +1163,23 @@ function dependencyResource(transport) {
1205
1163
  };
1206
1164
  }
1207
1165
  /**
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,
1166
+ * Walk the entities that no readable, unarchived dependent depends on, one page at a time: an
1167
+ * entity used only by archived content, or by content the caller cannot read, is listed. `types`
1168
+ * and `card-types` narrow which kinds are listed, `query` matches against names and locations,
1210
1169
  * `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.
1170
+ * `sort-direction` order the result. A `query` leaves sandboxes out, since they have no name or
1171
+ * location to match, so sandboxes alone with a `query` answer one empty page without a request.
1172
+ * This endpoint pages on the server, so the caller consumes pages and decides how far to pull.
1213
1173
  */
1214
1174
  async function* unreferencedPages(params = {}, options = {}) {
1215
1175
  await transport.require("dependency.unreferencedPages", options);
1216
- await transport.requireFeatures(filterFeatures(params), options);
1176
+ if (queryLeavesNoKind(params)) {
1177
+ yield {
1178
+ items: [],
1179
+ total: 0
1180
+ };
1181
+ return;
1182
+ }
1217
1183
  yield* paginatePages(transport, "/api/ee/dependencies/graph/unreferenced", DependencyNode, {
1218
1184
  query: itemListQuery(params),
1219
1185
  ...options.offset !== void 0 && { offset: options.offset },
@@ -1231,7 +1197,13 @@ function dependencyResource(transport) {
1231
1197
  */
1232
1198
  async function* breakingPages(params = {}, options = {}) {
1233
1199
  await transport.require("dependency.breakingPages", options);
1234
- await transport.requireFeatures(filterFeatures(params), options);
1200
+ if (queryLeavesNoKind(params)) {
1201
+ yield {
1202
+ items: [],
1203
+ total: 0
1204
+ };
1205
+ return;
1206
+ }
1235
1207
  yield* paginatePages(transport, "/api/ee/dependencies/graph/breaking", BreakingSource, {
1236
1208
  query: itemListQuery(params),
1237
1209
  ...options.offset !== void 0 && { offset: options.offset },
@@ -1248,9 +1220,14 @@ function dependencyResource(transport) {
1248
1220
  breakingPages
1249
1221
  };
1250
1222
  }
1223
+ function queryLeavesNoKind(params) {
1224
+ const { query, types } = params;
1225
+ if (query === void 0 || types === void 0 || types.length === 0) return false;
1226
+ return types.every((type) => type === "sandbox");
1227
+ }
1251
1228
  function itemListQuery(params) {
1252
1229
  return {
1253
- types: params.types,
1230
+ types: params.types === void 0 ? void 0 : [...new Set(params.types)],
1254
1231
  "card-types": params["card-types"],
1255
1232
  query: params.query,
1256
1233
  "include-personal-collections": params["include-personal-collections"],
@@ -1417,21 +1394,39 @@ async function fetchOptionalParsed(client, path, schema, options = {}) {
1417
1394
  //#region ../client/src/resources/field.ts
1418
1395
  const FieldApiSummary = z.tuple([z.tuple([z.literal("count"), z.number().int()]), z.tuple([z.literal("distincts"), z.number().int()])]);
1419
1396
  function fieldResource(transport) {
1420
- /** Get one field by id. */
1397
+ /**
1398
+ * Get one field by id. A server that labels data sensitivity answers `data_sensitivity`, `null`
1399
+ * for an unlabelled field; any other answers the field without the key (`hasDataSensitivity`).
1400
+ */
1421
1401
  async function get(id, options = {}) {
1422
1402
  await transport.require("field.get", options);
1423
- return transport.requestParsed(Field, `/api/field/${id}`, { ...options });
1403
+ const { features } = await transport.server(options);
1404
+ return transport.requestParsed(fieldDetailSchema(features), `/api/field/${id}`, { ...options });
1424
1405
  }
1425
1406
  /**
1426
1407
  * Update a field by id, patching only the fields the body carries. A `data_sensitivity` label is
1427
1408
  * a person's call the server's classifier never overwrites, and `null` withdraws it so the
1428
1409
  * 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.
1410
+ * the label is refused there before the wire. Answers the field the way `get` does.
1430
1411
  */
1431
1412
  async function update(id, params, options = {}) {
1432
1413
  await transport.require("field.update", options);
1433
1414
  await transport.requireFeatures(params.data_sensitivity === void 0 ? [] : ["fieldDataSensitivity"], options);
1434
- return transport.requestParsed(Field, `/api/field/${id}`, {
1415
+ const { features } = await transport.server(options);
1416
+ return transport.requestParsed(fieldDetailSchema(features), `/api/field/${id}`, {
1417
+ ...options,
1418
+ method: "PUT",
1419
+ body: params
1420
+ });
1421
+ }
1422
+ /**
1423
+ * Label a field's data sensitivity by hand. A person's label is never overwritten by the server's
1424
+ * classifier; `null` withdraws it, so whatever label the classifier wrote shows again. Answers
1425
+ * the field with the label it now carries.
1426
+ */
1427
+ async function setDataSensitivity(id, params, options = {}) {
1428
+ await transport.require("field.setDataSensitivity", options);
1429
+ return transport.requestParsed(FieldWithDataSensitivity, `/api/field/${id}`, {
1435
1430
  ...options,
1436
1431
  method: "PUT",
1437
1432
  body: params
@@ -1439,8 +1434,11 @@ function fieldResource(transport) {
1439
1434
  }
1440
1435
  /**
1441
1436
  * 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.
1437
+ * matching values of `id` paired with them, ordered by value, at most `limit` of them. An FK on
1438
+ * either side is followed to the PK it points at, and a field that resolves to the same field as
1439
+ * `searchId` answers each value alone. Without `value`, the first `limit` values. A field with
1440
+ * custom display values answers every mapped value with its display value instead, matching
1441
+ * `value` against the display value, ignoring both `searchId` and `limit`.
1444
1442
  */
1445
1443
  async function search(id, searchId, params, options = {}) {
1446
1444
  await transport.require("field.search", options);
@@ -1454,11 +1452,13 @@ function fieldResource(transport) {
1454
1452
  }
1455
1453
  /**
1456
1454
  * 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.
1455
+ * or `null` when no row matches. For a numeric field the server reads the leading number of
1456
+ * `value` and ignores any text after it, refusing only a `value` that has none.
1458
1457
  */
1459
1458
  async function remapping(id, remappedId, params, options = {}) {
1460
1459
  await transport.require("field.remapping", options);
1461
- return fetchOptionalParsed(transport, `/api/field/${id}/remapping/${remappedId}`, FieldRemappedValue, {
1460
+ const { features } = await transport.server(options);
1461
+ return fetchOptionalParsed(transport, `/api/field/${id}/remapping/${remappedId}`, fieldRemappedValueSchema(features, id === remappedId), {
1462
1462
  ...options,
1463
1463
  query: { value: params.value }
1464
1464
  });
@@ -1481,6 +1481,7 @@ function fieldResource(transport) {
1481
1481
  return {
1482
1482
  get,
1483
1483
  update,
1484
+ setDataSensitivity,
1484
1485
  search,
1485
1486
  remapping,
1486
1487
  summary,
@@ -1512,6 +1513,7 @@ const SyncStashStarted = z.object({
1512
1513
  task_id: z.number().int().positive()
1513
1514
  });
1514
1515
  const RemoteSyncSetting = z.string().nullable();
1516
+ const RemoteSyncBranchProperty = z.object({ "remote-sync-branch": z.string().nullable().optional() });
1515
1517
  const FORBIDDEN_STATUS = 403;
1516
1518
  const UNREGISTERED_STATUS = 404;
1517
1519
  function isRemoteUnreadable(error) {
@@ -1559,16 +1561,24 @@ function gitSyncResource(transport) {
1559
1561
  /**
1560
1562
  * Import content from the remote into Metabase. The endpoint queues a task and returns at once;
1561
1563
  * 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.
1564
+ * answers no task id, and there is then nothing to poll. A server that guards the tracked branch
1565
+ * refuses with 409 when `expected_branch` disagrees with the setting; left out, it is the tracked
1566
+ * branch as read just before the request. `merge` folds the remote's changes into local content
1567
+ * by a three-way merge and keeps un-pushed local changes, where a plain import refuses on a dirty
1568
+ * instance.
1563
1569
  */
1564
1570
  async function importFromRemote(params = {}, options = {}) {
1565
1571
  await transport.require("gitSync.import", options);
1572
+ await requireMerge(params.merge, options);
1573
+ const expectedBranch = await guardedBranch(params.expected_branch, options);
1566
1574
  const started = await transport.requestParsed(SyncImportStarted, "/api/ee/remote-sync/import", {
1567
1575
  ...options,
1568
1576
  method: "POST",
1569
1577
  body: {
1570
1578
  branch: params.branch,
1571
- force: params.force
1579
+ force: params.force,
1580
+ merge: params.merge,
1581
+ expected_branch: expectedBranch
1572
1582
  }
1573
1583
  });
1574
1584
  const message = started.message ?? null;
@@ -1582,19 +1592,36 @@ function gitSyncResource(transport) {
1582
1592
  final: await settle(params.wait, options)
1583
1593
  };
1584
1594
  }
1595
+ async function requireMerge(merge, options) {
1596
+ if (merge === true) await transport.requireFeatures(["remoteSyncMerge"], options);
1597
+ }
1598
+ async function guardedBranch(given, options) {
1599
+ if (given !== void 0) return given;
1600
+ const { features } = await transport.server(options);
1601
+ if (!features.remoteSyncBranchGuard) return;
1602
+ return trackedBranch(options);
1603
+ }
1585
1604
  /**
1586
1605
  * 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.
1606
+ * `wait` to poll that task until it reaches a terminal status. A server that guards the tracked
1607
+ * branch refuses with 409 when `branch` is not the tracked one; left out, it is the tracked branch
1608
+ * as read just before the request there, and the server's own default elsewhere. When the remote
1609
+ * has moved past the last sync, a plain export ends in a `conflict` task where `merge` is
1610
+ * available, and is refused with 400 before any task elsewhere; `merge` folds the remote's changes
1611
+ * in by a three-way merge instead, and `force` overwrites them.
1588
1612
  */
1589
1613
  async function exportToRemote(params = {}, options = {}) {
1590
1614
  await transport.require("gitSync.export", options);
1615
+ await requireMerge(params.merge, options);
1616
+ const branchName = await guardedBranch(params.branch, options);
1591
1617
  const started = await transport.requestParsed(SyncExportStarted, "/api/ee/remote-sync/export", {
1592
1618
  ...options,
1593
1619
  method: "POST",
1594
1620
  body: {
1595
- branch: params.branch,
1621
+ branch: branchName,
1596
1622
  message: params.message,
1597
- force: params.force
1623
+ force: params.force,
1624
+ merge: params.merge
1598
1625
  }
1599
1626
  });
1600
1627
  if (params.wait === void 0) return {
@@ -1679,7 +1706,7 @@ function gitSyncResource(transport) {
1679
1706
  async function syncedCollections(options = {}) {
1680
1707
  await transport.require("gitSync.syncedCollections", options);
1681
1708
  return {
1682
- data: (await listCollectionsWithLibrary(transport, SyncScopeCollection, options)).filter((entry) => entry.is_remote_synced === true),
1709
+ data: (await listCollectionsAs(transport, SyncScopeCollection, options)).filter((entry) => entry.is_remote_synced === true),
1683
1710
  total: null
1684
1711
  };
1685
1712
  }
@@ -1695,17 +1722,22 @@ function gitSyncResource(transport) {
1695
1722
  }
1696
1723
  }
1697
1724
  /**
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.
1725
+ * The branch git-sync tracks, or null when none is configured. Refuses when the caller may not
1726
+ * read the setting (it is admin-only) or the server has no remote-sync module, rather than
1727
+ * reading either as unset.
1700
1728
  */
1701
1729
  async function branch(options = {}) {
1702
1730
  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
- }
1731
+ const tracked = (await transport.requestParsed(RemoteSyncBranchProperty, PROBE_PATH, { ...options }))["remote-sync-branch"];
1732
+ 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");
1733
+ return tracked;
1734
+ }
1735
+ /** The branch git-sync tracks, refused when none is configured or the caller may not read it. */
1736
+ async function trackedBranch(options = {}) {
1737
+ await transport.require("gitSync.trackedBranch", options);
1738
+ const tracked = await branch(options);
1739
+ if (tracked === null) throw new ConfigError("git-sync tracks no branch: the remote-sync-branch setting is unset");
1740
+ return tracked;
1709
1741
  }
1710
1742
  /**
1711
1743
  * Poll the current task until it reaches a terminal status. A server with no task at all
@@ -1737,36 +1769,11 @@ function gitSyncResource(transport) {
1737
1769
  syncedCollections,
1738
1770
  remoteUrl,
1739
1771
  branch,
1772
+ trackedBranch,
1740
1773
  waitForTask
1741
1774
  };
1742
1775
  }
1743
1776
  //#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
1777
  //#region ../client/src/resources/glossary.ts
1771
1778
  const GlossaryApiList = z.object({ data: z.array(Glossary) }).loose();
1772
1779
  function glossaryResource(transport) {
@@ -1819,6 +1826,17 @@ function glossaryResource(transport) {
1819
1826
  };
1820
1827
  }
1821
1828
  //#endregion
1829
+ //#region ../client/src/resources/request-body.ts
1830
+ /**
1831
+ * Parse the body a caller hands a method, refusing one that does not match `schema` before any
1832
+ * request. `what` names the body in the refusal.
1833
+ */
1834
+ function parseRequestBody(schema, value, what) {
1835
+ const parsed = schema.safeParse(value);
1836
+ if (!parsed.success) throw new ConfigError(`invalid ${what}: ${parsed.error.issues.map(formatZodIssue).join("; ")}`);
1837
+ return parsed.data;
1838
+ }
1839
+ //#endregion
1822
1840
  //#region ../client/src/resources/library.ts
1823
1841
  const LIBRARY_ROOT_PATH = "/api/ee/library/";
1824
1842
  const PUBLISH_TABLES_PATH = "/api/ee/data-studio/table/publish-tables";
@@ -1835,7 +1853,7 @@ function libraryResource(transport) {
1835
1853
  return toLibrary(wire, await libraryListing(options));
1836
1854
  }
1837
1855
  async function libraryListing(options) {
1838
- const data = await listCollectionsWithLibrary(transport, LibraryCollectionInfo, options);
1856
+ const data = await listCollectionsAs(transport, LibraryCollectionInfo, options);
1839
1857
  const byId = /* @__PURE__ */ new Map();
1840
1858
  for (const collection of data) if (typeof collection.id === "number") byId.set(collection.id, collection);
1841
1859
  return byId;
@@ -1868,26 +1886,31 @@ function libraryResource(transport) {
1868
1886
  }
1869
1887
  /**
1870
1888
  * 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.
1889
+ * data pickers and rank up in search. Answers the collection they landed in. The endpoint
1890
+ * answers the same whether or not the selectors matched a table, so a body that does not match
1891
+ * `LibraryPublishTablesInput` is refused before any request.
1872
1892
  */
1873
1893
  async function publishTables(params, options = {}) {
1874
1894
  await transport.require("library.publishTables", options);
1895
+ const body = parseRequestBody(LibraryPublishTablesInput, params, "tables to publish");
1875
1896
  return (await transport.requestParsed(PublishTablesResponse, PUBLISH_TABLES_PATH, {
1876
1897
  ...options,
1877
1898
  method: "POST",
1878
- body: params
1899
+ body
1879
1900
  })).target_collection;
1880
1901
  }
1881
1902
  /**
1882
1903
  * Clear the Library collection from tables, and recursively from every downstream table that
1883
- * depends on them. The endpoint answers no JSON body.
1904
+ * depends on them. The endpoint answers no JSON body, whether or not the selectors matched a
1905
+ * table, so selectors that do not match `TableSelectors` are refused before any request.
1884
1906
  */
1885
1907
  async function unpublishTables(params, options = {}) {
1886
1908
  await transport.require("library.unpublishTables", options);
1909
+ const body = parseRequestBody(TableSelectors, params, "table selectors");
1887
1910
  await transport.requestRaw(UNPUBLISH_TABLES_PATH, {
1888
1911
  ...options,
1889
1912
  method: "POST",
1890
- body: params,
1913
+ body,
1891
1914
  expectContentType: "binary"
1892
1915
  });
1893
1916
  }
@@ -2140,48 +2163,21 @@ function metricResource(transport) {
2140
2163
  };
2141
2164
  }
2142
2165
  //#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
2166
  //#region ../client/src/resources/moderation-review.ts
2173
2167
  function moderationReviewResource(transport) {
2174
2168
  /**
2175
2169
  * Create a moderation review on a card or dashboard. `status: "verified"` marks the item
2176
2170
  * verified, `null` or an absent status records a note that leaves it unverified. The new review
2177
2171
  * becomes the item's most recent one; the server keeps the ten newest per item. Admins only.
2172
+ * A body that does not match `ModerationReviewCreateInput` is refused before any request.
2178
2173
  */
2179
2174
  async function create(params, options = {}) {
2180
2175
  await transport.require("moderationReview.create", options);
2176
+ const body = parseRequestBody(ModerationReviewCreateInput, params, "moderation review");
2181
2177
  return transport.requestParsed(ModerationReview, "/api/moderation-review", {
2182
2178
  ...options,
2183
2179
  method: "POST",
2184
- body: params
2180
+ body
2185
2181
  });
2186
2182
  }
2187
2183
  return { create };
@@ -2702,8 +2698,10 @@ function searchResource(transport) {
2702
2698
  * may match, `archived` swaps the active set for the archived one, `table_db_id` restricts to
2703
2699
  * items on one database, `verified` to verified content, `collection` to one collection and its
2704
2700
  * 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.
2701
+ * matches native query text but narrows to the models that carry one (cards, models, metrics,
2702
+ * actions, transforms), `include_metadata` attaches each card's `result_metadata`,
2703
+ * `include_dashboard_questions` also matches questions saved into a dashboard (excluded by
2704
+ * default), and `limit`/`offset` are the window the server applies before ranking hydration.
2707
2705
  */
2708
2706
  async function query(params = {}, options = {}) {
2709
2707
  await transport.require("search.query", options);
@@ -2720,7 +2718,8 @@ function searchResource(transport) {
2720
2718
  collection: params.collection,
2721
2719
  created_by: params.created_by,
2722
2720
  search_native_query: params.search_native_query,
2723
- include_metadata: params.include_metadata
2721
+ include_metadata: params.include_metadata,
2722
+ include_dashboard_questions: params.include_dashboard_questions
2724
2723
  }
2725
2724
  });
2726
2725
  return {
@@ -2904,14 +2903,18 @@ function snippetResource(transport) {
2904
2903
  const TableApiList = z.array(Table);
2905
2904
  const TableApiFks = z.array(TableForeignKey);
2906
2905
  const SyncSchemaResponse = z.object({ status: z.literal("ok") });
2907
- const RescanValuesResponse = z.object({ status: z.literal("success") });
2906
+ const FieldValuesResponse = z.object({ status: z.literal("success") });
2908
2907
  const BulkEditResponse = z.object({});
2909
2908
  const BULK_EDIT_PATH = "/api/data-studio/table/edit";
2909
+ const BULK_SYNC_SCHEMA_PATH = "/api/data-studio/table/sync-schema";
2910
+ const BULK_RESCAN_VALUES_PATH = "/api/data-studio/table/rescan-values";
2911
+ const BULK_DISCARD_VALUES_PATH = "/api/data-studio/table/discard-values";
2910
2912
  const LIST_PARAM_FEATURES = [
2911
2913
  ["can-query", "tableListAccessFilters"],
2912
2914
  ["can-write", "tableListAccessFilters"],
2913
2915
  ["include-transform-targets", "tableListTransformTargets"],
2914
- ["unused-only", "tableUnusedFilter"]
2916
+ ["unused-only", "tableUnusedFilter"],
2917
+ ["published-only", "tableListPublishedFilter"]
2915
2918
  ];
2916
2919
  function listParamFeatures(params) {
2917
2920
  return LIST_PARAM_FEATURES.filter(([param]) => params[param] !== void 0).map(([, feature]) => feature);
@@ -2925,7 +2928,7 @@ function tableResource(transport) {
2925
2928
  * List every table the caller can see, across all databases. `term` matches names and display
2926
2929
  * names; `can-query` and `can-write` keep only the tables the caller may query or edit the
2927
2930
  * metadata of; `include-transform-targets` adds tables a transform writes to; `unused-only` keeps
2928
- * tables nothing depends on.
2931
+ * tables nothing depends on; `published-only` keeps tables published to the library.
2929
2932
  */
2930
2933
  async function list(params = {}, options = {}) {
2931
2934
  await transport.require("table.list", options);
@@ -2943,6 +2946,7 @@ function tableResource(transport) {
2943
2946
  "owner-email": params["owner-email"],
2944
2947
  "orphan-only": params["orphan-only"],
2945
2948
  "unused-only": params["unused-only"],
2949
+ "published-only": params["published-only"],
2946
2950
  "can-query": params["can-query"],
2947
2951
  "can-write": params["can-write"],
2948
2952
  "include-transform-targets": params["include-transform-targets"]
@@ -2992,38 +2996,107 @@ function tableResource(transport) {
2992
2996
  };
2993
2997
  }
2994
2998
  /**
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.
2999
+ * Trigger a sync of this table: its columns, their fingerprints and its cached field values. It
3000
+ * never discovers new tables. The sync runs after the call returns; a warehouse the server cannot
3001
+ * connect to is a 422.
2997
3002
  */
2998
3003
  async function syncSchema(id, options = {}) {
2999
3004
  await transport.require("table.syncSchema", options);
3000
- await transport.requestParsed(SyncSchemaResponse, `/api/table/${id}/sync_schema`, {
3001
- ...options,
3002
- method: "POST"
3003
- });
3005
+ return {
3006
+ id,
3007
+ status: (await transport.requestParsed(SyncSchemaResponse, `/api/table/${id}/sync_schema`, {
3008
+ ...options,
3009
+ method: "POST"
3010
+ })).status
3011
+ };
3004
3012
  }
3005
3013
  /**
3006
- * Trigger an update of the field values of every eligible field of this table. The scan runs
3007
- * after the call returns.
3014
+ * Trigger an update of the field values of every eligible field of this table that already has a
3015
+ * cached set. The scan runs after the call returns.
3008
3016
  */
3009
3017
  async function rescanValues(id, options = {}) {
3010
3018
  await transport.require("table.rescanValues", options);
3011
- await transport.requestParsed(RescanValuesResponse, `/api/table/${id}/rescan_values`, {
3012
- ...options,
3013
- method: "POST"
3014
- });
3019
+ return {
3020
+ id,
3021
+ status: (await transport.requestParsed(FieldValuesResponse, `/api/table/${id}/rescan_values`, {
3022
+ ...options,
3023
+ method: "POST"
3024
+ })).status
3025
+ };
3026
+ }
3027
+ /**
3028
+ * Discard the cached field values of every field of this table, custom display values included.
3029
+ * No scan recreates a discarded set; the server rebuilds it, without the display values, the next
3030
+ * time the field's values are read.
3031
+ */
3032
+ async function discardValues(id, options = {}) {
3033
+ await transport.require("table.discardValues", options);
3034
+ return {
3035
+ id,
3036
+ status: (await transport.requestParsed(FieldValuesResponse, `/api/table/${id}/discard_values`, {
3037
+ ...options,
3038
+ method: "POST"
3039
+ })).status
3040
+ };
3015
3041
  }
3016
3042
  /**
3017
3043
  * 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.
3044
+ * layer is re-synced after the call returns. The server answers the same whether or not the
3045
+ * selectors matched a table.
3019
3046
  */
3020
3047
  async function bulkEdit(params, options = {}) {
3021
3048
  await transport.require("table.bulkEdit", options);
3049
+ await requireDataAuthorityNull(params.data_authority, options);
3022
3050
  await transport.requestParsed(BulkEditResponse, BULK_EDIT_PATH, {
3023
3051
  ...options,
3024
3052
  method: "POST",
3025
3053
  body: params
3026
3054
  });
3055
+ return {
3056
+ accepted: true,
3057
+ ...params
3058
+ };
3059
+ }
3060
+ async function requireDataAuthorityNull(value, options) {
3061
+ if (value === null) await transport.requireFeatures(["tableUserValueWithdrawal"], options);
3062
+ }
3063
+ async function postSelection(path, selectors, options) {
3064
+ const body = parseRequestBody(TableSelectors, selectors, "table selectors");
3065
+ await transport.requestRaw(path, {
3066
+ ...options,
3067
+ method: "POST",
3068
+ body,
3069
+ expectContentType: "binary"
3070
+ });
3071
+ return {
3072
+ accepted: true,
3073
+ ...body
3074
+ };
3075
+ }
3076
+ /**
3077
+ * Trigger a sync of every table the selectors pick out: its columns, their fingerprints and its
3078
+ * cached field values. Every database behind them must answer a connection test first, or the
3079
+ * call is a 422; the syncs run after it returns.
3080
+ */
3081
+ async function bulkSyncSchema(selectors, options = {}) {
3082
+ await transport.require("table.bulkSyncSchema", options);
3083
+ return postSelection(BULK_SYNC_SCHEMA_PATH, selectors, options);
3084
+ }
3085
+ /**
3086
+ * Trigger a field-values rescan of every table the selectors pick out, refreshing the sets that
3087
+ * are already cached. The scans run after the call returns.
3088
+ */
3089
+ async function bulkRescanValues(selectors, options = {}) {
3090
+ await transport.require("table.bulkRescanValues", options);
3091
+ return postSelection(BULK_RESCAN_VALUES_PATH, selectors, options);
3092
+ }
3093
+ /**
3094
+ * Discard the cached field values of every table the selectors pick out, custom display values
3095
+ * included. No scan recreates a discarded set.
3096
+ */
3097
+ async function bulkDiscardValues(selectors, options = {}) {
3098
+ await transport.require("table.bulkDiscardValues", options);
3099
+ return postSelection(BULK_DISCARD_VALUES_PATH, selectors, options);
3027
3100
  }
3028
3101
  async function updateFromCsv(id, action, file, options) {
3029
3102
  await transport.requestRaw(`/api/table/${id}/${UPLOAD_UPDATE_PATHS[action]}`, {
@@ -3065,7 +3138,11 @@ function tableResource(transport) {
3065
3138
  fks,
3066
3139
  syncSchema,
3067
3140
  rescanValues,
3141
+ discardValues,
3068
3142
  bulkEdit,
3143
+ bulkSyncSchema,
3144
+ bulkRescanValues,
3145
+ bulkDiscardValues,
3069
3146
  appendCsv,
3070
3147
  replaceCsv
3071
3148
  };
@@ -4207,6 +4284,7 @@ function createClient(config, options) {
4207
4284
  collection: collectionResource(transport),
4208
4285
  contentTranslation: contentTranslationResource(transport),
4209
4286
  dashboard: dashboardResource(transport),
4287
+ dataAction: dataActionResource(transport),
4210
4288
  database: databaseResource(transport),
4211
4289
  dataset: datasetResource(transport),
4212
4290
  dependency: dependencyResource(transport),