@metabase/cli 0.5.8 → 0.5.10

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 (302) hide show
  1. package/dist/{add-collection-DIrpeq9O.mjs → add-collection-B6_b7Z0h.mjs} +3 -3
  2. package/dist/{alert-DuUreVMq.mjs → alert-CaOd6Sye.mjs} +7 -7
  3. package/dist/{alerts-C7vJ-NAI.mjs → alerts-B4XDd_EG.mjs} +6 -6
  4. package/dist/api-key-BEyGzjhr.mjs +13 -0
  5. package/dist/{append-v3fakJOd.mjs → append-D4yRU3nt.mjs} +4 -4
  6. package/dist/{archive-TBPRGm7s.mjs → archive-B0wPQhnH.mjs} +3 -3
  7. package/dist/{archive-DwVbn3FG.mjs → archive-B4KdkRj1.mjs} +3 -3
  8. package/dist/{archive-BrGj2yoP.mjs → archive-BTpXIs7W.mjs} +3 -3
  9. package/dist/{archive-Cy6RUJaD.mjs → archive-BTsVi373.mjs} +3 -3
  10. package/dist/{archive-5pjvTser.mjs → archive-BkCFPiWS.mjs} +3 -3
  11. package/dist/{archive-Bt8fwInI.mjs → archive-BxN7gbKa.mjs} +4 -4
  12. package/dist/{archive-CuygjxgQ.mjs → archive-CSt4KxhB.mjs} +3 -3
  13. package/dist/{archive-D299FxXt.mjs → archive-DJT5Du9l.mjs} +3 -3
  14. package/dist/{archive-DdPaXaJo.mjs → archive-DoZ8HBxg.mjs} +4 -4
  15. package/dist/{archive-CyhH-395.mjs → archive-btZAAdMv.mjs} +3 -3
  16. package/dist/{archive-CmhV_hlP.mjs → archive-jtNM7hhn.mjs} +3 -3
  17. package/dist/{archive-BEhhmkTO.mjs → archive-pMSD0Cou.mjs} +3 -3
  18. package/dist/{auth-B63Hfuwg.mjs → auth-BtrN725t.mjs} +5 -5
  19. package/dist/{branches-BM0L124r.mjs → branches-D4Lwau0h.mjs} +3 -3
  20. package/dist/{breaking-VMUrgVVE.mjs → breaking-DH9tr0ug.mjs} +5 -5
  21. package/dist/{broken-BbpNq5WG.mjs → broken-DiT2Ww1u.mjs} +6 -6
  22. package/dist/{bulk-discard-values-Cohox-Zb.mjs → bulk-discard-values-D7jD6GjV.mjs} +5 -5
  23. package/dist/{bulk-edit-B9-XH592.mjs → bulk-edit-DsetARSf.mjs} +3 -3
  24. package/dist/{bulk-rescan-values-CsWKirZw.mjs → bulk-rescan-values-DSUVmXSh.mjs} +4 -4
  25. package/dist/{bulk-sync-schema-CorpcAjz.mjs → bulk-sync-schema-n5Qe7UnU.mjs} +4 -4
  26. package/dist/{cancel-iGUVm1h2.mjs → cancel-oFccoFiE.mjs} +3 -3
  27. package/dist/{cancel-task-DWiicb_t.mjs → cancel-task-kpJZ4G2I.mjs} +2 -2
  28. package/dist/card-Bnkg5z4G.mjs +25 -0
  29. package/dist/{cards-D6jWz0N9.mjs → cards-BCU56A8s.mjs} +4 -4
  30. package/dist/{ci-BQKTyiRi.mjs → ci-DfbKRU5x.mjs} +2 -2
  31. package/dist/cli.mjs +52 -47
  32. package/dist/{client-Ba61gEcn.mjs → client-BvjSFQ8P.mjs} +27 -42
  33. package/dist/collection-CXYDfvsX.mjs +21 -0
  34. package/dist/{collection-namespace-D0_-6eWp.mjs → collection-namespace-lQLOPUbc.mjs} +1 -1
  35. package/dist/{content-translation-B57aHSuc.mjs → content-translation-CsRsYA5Q.mjs} +3 -3
  36. package/dist/{copy-D-VIVVB1.mjs → copy-7kyXaQVn.mjs} +4 -4
  37. package/dist/{copy-BeD_fk5J.mjs → copy-CR8wSNpp.mjs} +4 -4
  38. package/dist/{copy-flags-BcW9weVX.mjs → copy-flags-Bgy3sSFg.mjs} +1 -1
  39. package/dist/{create-CP9lrYE4.mjs → create-BAxf_Wqm.mjs} +2 -2
  40. package/dist/{create-BlmRvuQg.mjs → create-BIgILG1P.mjs} +3 -3
  41. package/dist/{create-HNchuWpj.mjs → create-BMe3ZtQi.mjs} +3 -3
  42. package/dist/{create-DybrZHV-.mjs → create-BZ9x1_Dm.mjs} +2 -2
  43. package/dist/{create-zALsdMhF.mjs → create-BZ_tLyVg.mjs} +2 -2
  44. package/dist/{create-DcDyXL4g.mjs → create-BewmenPL.mjs} +2 -2
  45. package/dist/{create-C6c-clLK.mjs → create-BhHZBIc4.mjs} +3 -3
  46. package/dist/{create-BURh8kHp.mjs → create-BrFgRgjY.mjs} +3 -3
  47. package/dist/{create-MmZVmRsH.mjs → create-C1CwTQjk.mjs} +2 -2
  48. package/dist/{create-CGiSOtIR.mjs → create-Cx47jTQ9.mjs} +3 -3
  49. package/dist/{create-Bw9DAq_x2.mjs → create-CxZe8ghH2.mjs} +5 -5
  50. package/dist/{create-B--aPIbp.mjs → create-D6FGsFnV.mjs} +2 -2
  51. package/dist/{create-DF7nC9qW.mjs → create-DG9NIdWy.mjs} +2 -2
  52. package/dist/{create-_wex54m1.mjs → create-DHJ75ufg.mjs} +2 -2
  53. package/dist/{create-lHqpAdxg.mjs → create-DVYRfN1s.mjs} +3 -3
  54. package/dist/{create-DQOapeeI.mjs → create-DYf1fYsW.mjs} +3 -3
  55. package/dist/{create-DMtlDzrE.mjs → create-DaspEGaN.mjs} +3 -3
  56. package/dist/{create-Dm8BvbsU.mjs → create-Ddt8jkGe.mjs} +2 -2
  57. package/dist/{create-branch-C8arQT4M.mjs → create-branch-CSqKpG-X.mjs} +2 -2
  58. package/dist/{create-D44fg_iT.mjs → create-gD1BKkjH.mjs} +2 -2
  59. package/dist/{csv-CFabsH6l.mjs → csv-CEQ5iHiR.mjs} +4 -4
  60. package/dist/{current-task-GG6JqfGp.mjs → current-task-Cwn-A02w.mjs} +2 -2
  61. package/dist/dashboard-BQMAwgQv.mjs +35 -0
  62. package/dist/data-action-BOyBN50C.mjs +24 -0
  63. package/dist/data-app-CTxlD3Sa.mjs +39 -0
  64. package/dist/{data-app-Blz61mG5.mjs → data-app-Cglgbj_E.mjs} +1 -1
  65. package/dist/{data-app-BUW-HlUo.mjs → data-app-bl88oUla.mjs} +27 -14
  66. package/dist/data-app-project-C1V4_8k5.mjs +155 -0
  67. package/dist/{db-DSj2I1X9.mjs → db-DjrLLqDW.mjs} +8 -8
  68. package/dist/{delete-Dkwk2mZH.mjs → delete-B3zIJHbp.mjs} +4 -4
  69. package/dist/{delete-YKX2HilI.mjs → delete-B8wPN6Mi.mjs} +4 -4
  70. package/dist/{delete-CsgkbmBy.mjs → delete-BecCd6_I.mjs} +4 -4
  71. package/dist/{delete-Cx75BsN6.mjs → delete-CA8N6OSh.mjs} +4 -4
  72. package/dist/{delete-AF64p0xG.mjs → delete-CYPidCqb.mjs} +4 -4
  73. package/dist/{delete-CnGb4QIm.mjs → delete-Crc2lguC.mjs} +4 -4
  74. package/dist/{delete-CxL5okLN.mjs → delete-DvHo5Dau.mjs} +4 -4
  75. package/dist/{delete-C6N_Aj78.mjs → delete-auLsOacz.mjs} +4 -4
  76. package/dist/{delete-D_l7FRE6.mjs → delete-rBkGuteA.mjs} +4 -4
  77. package/dist/{delete-runtime-BUbOQx5I.mjs → delete-runtime-Bxy6qAqZ.mjs} +2 -2
  78. package/dist/{delete-table-CubRk-5H.mjs → delete-table-CWo5Azjp.mjs} +4 -4
  79. package/dist/{dependencies-W2dxsCpF.mjs → dependencies-B5rZybIE.mjs} +5 -5
  80. package/dist/dependency-BCvsKkvF.mjs +15 -0
  81. package/dist/{dependency-BPCRTBKd.mjs → dependency-DdeyH8m5.mjs} +1 -1
  82. package/dist/{dependents-B4V8pDYq.mjs → dependents-DTokHohZ.mjs} +6 -6
  83. package/dist/{dirty-DKj4ScBN.mjs → dirty-DJzqGN8R.mjs} +3 -3
  84. package/dist/{discard-values-5l91z3Dy.mjs → discard-values-Z0Aaau-z.mjs} +5 -5
  85. package/dist/document-DaQNhYhh.mjs +20 -0
  86. package/dist/{download-DRxR3yGi.mjs → download-CUNQkaWC.mjs} +2 -2
  87. package/dist/{eid-B6JYogNC.mjs → eid-CA9nIsPk.mjs} +2 -2
  88. package/dist/{entry-flags-6Y0fdYbG.mjs → entry-flags-CsbT7fHf.mjs} +1 -1
  89. package/dist/{events-CE80dTib.mjs → events-CtMOLbVW.mjs} +4 -4
  90. package/dist/{execute-C9foK2IU.mjs → execute-BFKWsB4U.mjs} +3 -3
  91. package/dist/{export-B8QyoPWP.mjs → export-DsbEWoLo.mjs} +3 -3
  92. package/dist/{export-flags-DvdxpRMt.mjs → export-flags-DkbYlWlE.mjs} +1 -1
  93. package/dist/{export-preflight-BQbwxyoJ.mjs → export-preflight-TRzdLXI_.mjs} +2 -2
  94. package/dist/field-BnSUwI5l.mjs +21 -0
  95. package/dist/{fields-TE3PnmwW.mjs → fields-Cf-yzUqO.mjs} +4 -4
  96. package/dist/{filter-flags-DAUmdUwa.mjs → filter-flags-B5jGUuHb.mjs} +1 -1
  97. package/dist/{fks-B41Re5dt.mjs → fks-BL7aqSz3.mjs} +5 -5
  98. package/dist/generate-actions-D8iT2Vx_.mjs +38 -0
  99. package/dist/generate-queries-Cmo2IFAd.mjs +41 -0
  100. package/dist/generate-schema-Hubesglp.mjs +34 -0
  101. package/dist/{get-DguRhloC.mjs → get-10d6M3WX.mjs} +2 -2
  102. package/dist/{get-DvPgnqAA.mjs → get-45g97RD0.mjs} +2 -2
  103. package/dist/{get-DJeeXbwj.mjs → get-B0AwjMgu.mjs} +3 -3
  104. package/dist/{get-CtRJUybv.mjs → get-B6uK0K5I.mjs} +3 -3
  105. package/dist/{get-DeiC05Lm.mjs → get-B7I96VF7.mjs} +3 -3
  106. package/dist/{get-BcWr6U0n.mjs → get-BPrKH_VC.mjs} +2 -2
  107. package/dist/{get-BJgBsiEK.mjs → get-BRfgDBX1.mjs} +5 -5
  108. package/dist/{get-uWk0JKvF.mjs → get-B_1SDjVE.mjs} +4 -4
  109. package/dist/{get-BscyItLF.mjs → get-BsLJ6NN4.mjs} +3 -3
  110. package/dist/{get-PLIbg3Vy.mjs → get-C1d4sGGj.mjs} +3 -3
  111. package/dist/{get-sjhoDJyB.mjs → get-C4TSvV8x.mjs} +5 -5
  112. package/dist/{get-Cjk-A9dQ.mjs → get-CHmUuPoY.mjs} +3 -3
  113. package/dist/{get-BAGQ-bvt.mjs → get-CNwSqJ34.mjs} +3 -3
  114. package/dist/{get-CCTRO18v.mjs → get-CORcDYjE.mjs} +4 -4
  115. package/dist/{get-DG5fPl-S.mjs → get-CQx83tws.mjs} +4 -4
  116. package/dist/{get-m-vpr7GN.mjs → get-CkiiPNoS.mjs} +3 -3
  117. package/dist/{get-CU6AWbqL.mjs → get-Cvl3jefC.mjs} +3 -3
  118. package/dist/{get-CefCrGWy.mjs → get-DAsNzVI7.mjs} +3 -3
  119. package/dist/{get-DbZDp2ve.mjs → get-DIYDn-tm.mjs} +3 -3
  120. package/dist/{get-Ck0cRNyr.mjs → get-DUvEGkvw.mjs} +4 -4
  121. package/dist/{get-3XwqrjxC.mjs → get-O81o3nAv.mjs} +3 -3
  122. package/dist/{get-run-DnKCnvUa.mjs → get-run-uEQGMjmi.mjs} +4 -4
  123. package/dist/{get-BrhIHZYg.mjs → get-xMWLwAHj.mjs} +3 -3
  124. package/dist/git-sync-CswhluG_.mjs +29 -0
  125. package/dist/glossary-Cb37yiw3.mjs +14 -0
  126. package/dist/{graph-B2YkV2oX.mjs → graph-BKuSPVVZ.mjs} +4 -4
  127. package/dist/{group-D1nGaEXW.mjs → group-DxaqX3Gg.mjs} +1 -1
  128. package/dist/{has-remote-changes-ChMSjhmC.mjs → has-remote-changes-BUCHJZqQ.mjs} +2 -2
  129. package/dist/{import-CNpN9iS0.mjs → import-B-ekaPHP.mjs} +3 -3
  130. package/dist/{is-dirty-Bud2wuxQ.mjs → is-dirty-BGcu7D5c.mjs} +2 -2
  131. package/dist/{items-B1DXzdwg.mjs → items-vDPpkZUK.mjs} +3 -3
  132. package/dist/{library-8G0s5VLO.mjs → library-n-3eu6WW.mjs} +5 -5
  133. package/dist/{list-z4iqffgl.mjs → list-BIOCkt1A.mjs} +4 -4
  134. package/dist/{list-CAAvhl9h.mjs → list-BSQPBkVu.mjs} +3 -3
  135. package/dist/{list-tHzgEkzv.mjs → list-BiXIUvBg.mjs} +5 -5
  136. package/dist/{list-BVz0N0g_.mjs → list-BoOFUEYh.mjs} +3 -3
  137. package/dist/{list-Dk3upD11.mjs → list-BtENqZIq.mjs} +5 -5
  138. package/dist/{list-DAdWd8gn.mjs → list-C8a6WeMs.mjs} +3 -3
  139. package/dist/{list-BeaA7gQ7.mjs → list-CADlvzKj.mjs} +3 -3
  140. package/dist/{list-DjfY80vj.mjs → list-Ci8Y9AdJ.mjs} +3 -3
  141. package/dist/{list-Ckqu41Zx.mjs → list-CoM1L7ZK.mjs} +3 -3
  142. package/dist/{list-CAZHyhd5.mjs → list-D-zjbHfR.mjs} +3 -3
  143. package/dist/{list-BSvQ0AT_.mjs → list-D5yxCOsl.mjs} +3 -3
  144. package/dist/{list-0aX638ov.mjs → list-DJAlAVuS.mjs} +5 -5
  145. package/dist/{list-B2PbnXp4.mjs → list-DMdRy6Cx.mjs} +4 -4
  146. package/dist/{list-DpyIV41y.mjs → list-DU2dKd2T.mjs} +4 -4
  147. package/dist/{list-CcfGHN19.mjs → list-J5FxC72O.mjs} +3 -3
  148. package/dist/{list-BJasizCe.mjs → list-JWWHtIMj.mjs} +3 -3
  149. package/dist/{list-CO62N1eD.mjs → list-PvFvPn0p.mjs} +3 -3
  150. package/dist/{list-D1WO7lxP.mjs → list-Qy-5LvDC.mjs} +4 -4
  151. package/dist/{list-DX5SmBCQ.mjs → list-UJ3nPrrD.mjs} +3 -3
  152. package/dist/{list-mRSKPKoO.mjs → list-e8h2S-3y.mjs} +3 -3
  153. package/dist/{list-DZLGnsAK.mjs → list-jfxTNTSm.mjs} +3 -3
  154. package/dist/{list-CPwy-AEn.mjs → list-mkXqkfck.mjs} +8 -12
  155. package/dist/{list-JqIFAXpw.mjs → list-nd6-vgOU.mjs} +3 -3
  156. package/dist/{login-muOdP15h.mjs → login-DcneUyj9.mjs} +4 -4
  157. package/dist/{logout-Z0_gSSM4.mjs → logout-wA2-ebUy.mjs} +2 -2
  158. package/dist/{measure-CTF4qqiE.mjs → measure-BICKq4Ud.mjs} +6 -6
  159. package/dist/nano-id-qEgGloYk.mjs +55 -0
  160. package/dist/{notification-Bj45MgWm.mjs → notification-Ec1Jo0Oc.mjs} +1 -1
  161. package/dist/{parameter-values-to5u_-2n.mjs → parameter-values-d_zi14dw.mjs} +3 -3
  162. package/dist/{parse-id-CbF7zxGv.mjs → parse-id-DKKwr4c8.mjs} +1 -1
  163. package/dist/{path-B-0S-9i2.mjs → path-Cn1xCJb_.mjs} +4 -4
  164. package/dist/{poll-zB3cX0Kq.mjs → poll-BGWVry_U.mjs} +1 -1
  165. package/dist/{preflight-Dgj2yyY_.mjs → preflight-Beuxqhhf.mjs} +1 -1
  166. package/dist/{publish-tKh9tJeh.mjs → publish-C89wo-cw.mjs} +3 -3
  167. package/dist/{pulse-DhddeMMG.mjs → pulse-BWs9tqVG.mjs} +1 -1
  168. package/dist/{query-o1Z2dgtw.mjs → query-L29u5CEu.mjs} +4 -4
  169. package/dist/{query-B4xK9j0u.mjs → query-ja91JN10.mjs} +4 -4
  170. package/dist/{remapping-DT305P-k.mjs → remapping-B8aqlkSk.mjs} +3 -3
  171. package/dist/{remove-collection-Bsme1OBA.mjs → remove-collection-LbKh838S.mjs} +3 -3
  172. package/dist/{render-Df56xOPJ.mjs → render-C96TStlT.mjs} +1 -1
  173. package/dist/{replace-C3PQwvfl.mjs → replace-B9Cyb9q2.mjs} +4 -4
  174. package/dist/{requirement-check-qqRkRGcN.mjs → requirement-check-XJCPOfWw.mjs} +2 -2
  175. package/dist/{rescan-values-C0P0upEB.mjs → rescan-values-Ca4FVr2Q.mjs} +4 -4
  176. package/dist/{rescan-values-CGN4bjyB.mjs → rescan-values-uxZ22Z0c.mjs} +3 -3
  177. package/dist/{run-C_IZfmQ7.mjs → run-B4zwhVuB.mjs} +404 -85
  178. package/dist/{run-bVD66LrU.mjs → run-BQvsDYzx.mjs} +3 -3
  179. package/dist/{run-ZRY5wy4x.mjs → run-CtGMVO3W.mjs} +4 -4
  180. package/dist/{run-BaEBHum8.mjs → run-DskhDpUQ.mjs} +4 -4
  181. package/dist/{runs-DWm1pIdP.mjs → runs-C0s-CfQE.mjs} +5 -5
  182. package/dist/{runtime-Dd2uBKqN.mjs → runtime-B8leBJ1G.mjs} +6 -5
  183. package/dist/scaffold-BdrbFYhc.mjs +54 -0
  184. package/dist/{schema-DoELV3FT.mjs → schema-8tGj8t5W.mjs} +2 -2
  185. package/dist/{schema-tables-DGyHJnJX.mjs → schema-tables-DZRvTRLf.mjs} +5 -5
  186. package/dist/{schemas-7w9MPZcZ.mjs → schemas-yiE-cMoI.mjs} +4 -4
  187. package/dist/{search-BZh0BwZ9.mjs → search-1-5z-NQO.mjs} +4 -4
  188. package/dist/{search-CyyySVTz.mjs → search-Cdd2cDNA.mjs} +4 -4
  189. package/dist/{segment--JCnZCgL.mjs → segment-DcLtYcgq.mjs} +6 -6
  190. package/dist/{send-c4FpapMf.mjs → send-I5nk7MpB.mjs} +3 -3
  191. package/dist/{set-active-BexM75_s.mjs → set-active-DrgsPOnr.mjs} +2 -2
  192. package/dist/{set-data-actions-BnrX6ARh.mjs → set-data-actions-C-TNEnTJ.mjs} +3 -3
  193. package/dist/{set-enabled-Np4xqFA_.mjs → set-enabled-Co0jIMn0.mjs} +5 -5
  194. package/dist/{set-sensitivity-DDzrkjdv.mjs → set-sensitivity-DCOxoynX.mjs} +3 -3
  195. package/dist/{set-_puxfyaP.mjs → set-vigeEoz9.mjs} +2 -2
  196. package/dist/{setting-BGK1uRxm.mjs → setting-DqHsywkM.mjs} +4 -4
  197. package/dist/{setup-BCliYRAt.mjs → setup-2EJT5aTc.mjs} +2 -2
  198. package/dist/{skill-list-4LagdTq5.mjs → skill-list-Duqt2jXs.mjs} +1 -1
  199. package/dist/{skills-CoXIflBw.mjs → skills-n1IpS3pA.mjs} +3 -3
  200. package/dist/{skills-PULUh2VV.mjs → skills-xJsQWYll.mjs} +3 -3
  201. package/dist/{slug-COdwq63O.mjs → slug-9m4PXe-s.mjs} +1 -1
  202. package/dist/snippet-CDLpUxOv.mjs +19 -0
  203. package/dist/{stash-d3FtnE2F.mjs → stash-C7VstG6F.mjs} +3 -3
  204. package/dist/{status-BJTdBEN4.mjs → status-BclmIIUO.mjs} +3 -3
  205. package/dist/{status-CJLd6Uk6.mjs → status-DZh35kON.mjs} +2 -2
  206. package/dist/{subscription-Dpq45fMP.mjs → subscription-DaEZk3Am.mjs} +6 -6
  207. package/dist/{subscriptions-Cu4km2CN.mjs → subscriptions-DcOtdHen.mjs} +6 -6
  208. package/dist/{summary-3Av5251t.mjs → summary-yoqD8lKK.mjs} +3 -3
  209. package/dist/{sync-schema-BYJuUBsG.mjs → sync-schema-C7mvw4JY.mjs} +4 -4
  210. package/dist/{sync-schema-BNHt8S3P.mjs → sync-schema-QcmZUpbc.mjs} +4 -4
  211. package/dist/table-CSv2nzuP.mjs +26 -0
  212. package/dist/{table-DFbkLSgK.mjs → table-CcUdjp8F.mjs} +1 -1
  213. package/dist/{table-selector-flags-BiA8p56s.mjs → table-selector-flags-FNPxRc9B.mjs} +2 -2
  214. package/dist/{timeline-event-BLBqSAjH.mjs → timeline-event-B3bnxvSU.mjs} +6 -6
  215. package/dist/timeline-xSDfBYEA.mjs +21 -0
  216. package/dist/transform-D5ugnljj.mjs +28 -0
  217. package/dist/{transform-CKeLIqoc.mjs → transform-drjCAqQs.mjs} +1 -1
  218. package/dist/transform-job-C3uL7HVt.mjs +22 -0
  219. package/dist/{transform-tag-CETHXuAi.mjs → transform-tag-Dh_xkEHJ.mjs} +5 -5
  220. package/dist/transform-test-DO4J2dGZ.mjs +16 -0
  221. package/dist/{transforms-CstSQgQ-.mjs → transforms-BhycY9Dy.mjs} +5 -5
  222. package/dist/{transport-D74axlBJ.mjs → transport-B4wfgpqB.mjs} +3 -3
  223. package/dist/{tree-BDhm4E_W.mjs → tree-C0Jqbvr7.mjs} +2 -2
  224. package/dist/{unpublish-BNBSxZFl.mjs → unpublish-0erfDFu-.mjs} +3 -3
  225. package/dist/{unreferenced-B2nDcQ7m.mjs → unreferenced-CHJuU079.mjs} +5 -5
  226. package/dist/{update-BkFy2BV_.mjs → update-BAl0aZsq.mjs} +4 -4
  227. package/dist/{update-BGFGng3a.mjs → update-BGCKUTtV.mjs} +4 -4
  228. package/dist/{update-pzu78yZB.mjs → update-BHz5uxTe.mjs} +3 -3
  229. package/dist/{update-DRw_610p.mjs → update-BPaXLS7J.mjs} +4 -4
  230. package/dist/{update-Cpd1tKqr.mjs → update-BYfjNqm0.mjs} +3 -3
  231. package/dist/{update-BMHPp3nt.mjs → update-Bzbst6T5.mjs} +3 -3
  232. package/dist/{update-ByBqo1if.mjs → update-C7_YQxNg.mjs} +4 -4
  233. package/dist/{update-CWzmrGS_.mjs → update-C8Ec4fCx.mjs} +3 -3
  234. package/dist/{update-BS-E7QLh.mjs → update-CBcKfzne.mjs} +4 -4
  235. package/dist/{update-BenGrugz.mjs → update-CR1zzVES.mjs} +4 -4
  236. package/dist/{update-BA0NxInb.mjs → update-CZkKz3PD.mjs} +4 -4
  237. package/dist/{update-DU3jpGps.mjs → update-CjKfz61h.mjs} +3 -3
  238. package/dist/{update-B6xWuJqk.mjs → update-DAl3J-6n.mjs} +3 -3
  239. package/dist/{update-CFLJWHOT.mjs → update-DSlAN-t5.mjs} +3 -3
  240. package/dist/{update-DrvDC_0m2.mjs → update-Dh1X_b9e2.mjs} +3 -3
  241. package/dist/{update-DxLypq9G.mjs → update-DnGjFqwP.mjs} +6 -6
  242. package/dist/{update-B9iHHoJB.mjs → update-DqN3ikiq.mjs} +4 -4
  243. package/dist/{update-DT8KwBxO.mjs → update-Is5yboYO.mjs} +4 -4
  244. package/dist/{update-dashcard-BU3Wqcnf.mjs → update-dashcard-B8s5t0jG.mjs} +3 -3
  245. package/dist/{update-DKcPzoG9.mjs → update-ujP9d00H.mjs} +3 -3
  246. package/dist/{upgrade-Cq89D4Oe.mjs → upgrade-Dc43HJun.mjs} +2 -2
  247. package/dist/upload-DIiiLP23.mjs +13 -0
  248. package/dist/{upload-INQHve86.mjs → upload-DWwwFANs.mjs} +3 -3
  249. package/dist/{upload-CmwO6anj.mjs → upload-xXTXZQsW.mjs} +1 -1
  250. package/dist/{uuid-BNJKaQGB.mjs → uuid-BNZQ6Dyb.mjs} +2 -2
  251. package/dist/{validate-query-CQ4UPpZX.mjs → validate-query-37KgmRbb.mjs} +1 -1
  252. package/dist/{values-BVtqwRlR.mjs → values-thjqrbtC.mjs} +3 -3
  253. package/dist/{verify-BSlj7S_E.mjs → verify-CLObQxZk.mjs} +3 -3
  254. package/dist/{verify-Bp9ZyPgX.mjs → verify-CqJPc-DW.mjs} +3 -3
  255. package/dist/{verify-BwodYH0C.mjs → verify-DNhhRy4T.mjs} +3 -3
  256. package/dist/{wait-DZclBI3D.mjs → wait-DxeRAukN.mjs} +4 -4
  257. package/dist/{wait-flags-CmIfm6_U.mjs → wait-flags-P5MIy4fp.mjs} +2 -2
  258. package/dist/{window-BoW2xWwm.mjs → window-CI_QD04s.mjs} +1 -1
  259. package/dist/{yaml-BthVUNj3.mjs → yaml-BtI8iDba.mjs} +16 -7
  260. package/package.json +1 -1
  261. package/skill-data/core/SKILL.md +1 -1
  262. package/skill-data/data-action/SKILL.md +2 -3
  263. package/skill-data/data-app/SKILL.md +64 -45
  264. package/skill-data/data-app/template/.env.local.example +1 -0
  265. package/skill-data/data-app/template/README.md +16 -7
  266. package/skill-data/data-app/template/gitignore +0 -1
  267. package/skill-data/data-app/template/package.json +1 -2
  268. package/skill-data/data-app/template/src/metabase.actions.ts +3 -0
  269. package/skill-data/data-app/template/src/metabase.queries.ts +3 -0
  270. package/skill-data/data-app/template/src/metabase.schema.ts +3 -0
  271. package/skill-data/data-app/template/src/theme.ts +3 -1
  272. package/skill-data/data-app-actions/SKILL.md +43 -23
  273. package/skill-data/data-app-data/SKILL.md +86 -64
  274. package/skill-data/data-app-filters/SKILL.md +3 -3
  275. package/skill-data/data-app-ui/SKILL.md +12 -4
  276. package/skill-data/git-sync/SKILL.md +4 -6
  277. package/skill-data/transform/SKILL.md +1 -1
  278. package/dist/api-key-Cia6SHQ9.mjs +0 -13
  279. package/dist/card-C-KsmoJW.mjs +0 -25
  280. package/dist/collection-DsNRlVcN.mjs +0 -21
  281. package/dist/create-D-Eu1nBe.mjs +0 -37
  282. package/dist/dashboard-BRQtw_1e.mjs +0 -35
  283. package/dist/data-action-Bm6QMyV0.mjs +0 -24
  284. package/dist/data-app-DtW2i2SD.mjs +0 -41
  285. package/dist/data-app-project-CHYcJRrU.mjs +0 -58
  286. package/dist/delete-ClT1ROrM.mjs +0 -40
  287. package/dist/dependency-B0KmVz2u.mjs +0 -15
  288. package/dist/document--zYZP-u3.mjs +0 -20
  289. package/dist/field-Bk09crKC.mjs +0 -21
  290. package/dist/git-sync-DMyH3Y85.mjs +0 -29
  291. package/dist/glossary-CcRGJaVi.mjs +0 -14
  292. package/dist/scaffold-BnT99dhY.mjs +0 -50
  293. package/dist/set-bundle-B-qAvkDo.mjs +0 -40
  294. package/dist/snippet-Czzma-M2.mjs +0 -19
  295. package/dist/table-CwfF6ZTZ.mjs +0 -26
  296. package/dist/timeline-C4WCMzDX.mjs +0 -21
  297. package/dist/transform-job-SQ57QOlQ.mjs +0 -22
  298. package/dist/transform-jxF8cjNA.mjs +0 -28
  299. package/dist/transform-test-MlVjTlKo.mjs +0 -16
  300. package/dist/typed-schema-BZkv_z2f.mjs +0 -45
  301. package/dist/update-DrfAOlkf.mjs +0 -36
  302. package/dist/upload-DbDFl9qT.mjs +0 -13
@@ -1,7 +1,7 @@
1
- import { n as createClient } from "./client-Ba61gEcn.mjs";
1
+ import { n as createClient } from "./client-BvjSFQ8P.mjs";
2
2
  import { g as errorMessage, l as MetabaseError, p as TimeoutError, u as NetworkError } from "./predicates-0C0TsWcJ.mjs";
3
- import { q as HttpError } from "./cli.mjs";
4
- import { B as probeServer, E as USER_AGENT } from "./runtime-Dd2uBKqN.mjs";
3
+ import { Y as HttpError } from "./cli.mjs";
4
+ import { D as USER_AGENT, V as probeServer } from "./runtime-B8leBJ1G.mjs";
5
5
  //#region src/core/auth/verify.ts
6
6
  const VERIFY_TIMEOUT_MS = 15e3;
7
7
  async function verifyAndProbe(url, credential, options = {}) {
@@ -1,6 +1,6 @@
1
- import { dt as outputFlags, ft as profileFlag, ot as connectionFlags, u as renderSummary } from "./cli.mjs";
2
- import { t as parseId } from "./parse-id-CbF7zxGv.mjs";
3
- import { t as defineMetabaseCommand } from "./runtime-Dd2uBKqN.mjs";
1
+ import { ct as connectionFlags, f as renderSummary, mt as profileFlag, pt as outputFlags } from "./cli.mjs";
2
+ import { t as parseId } from "./parse-id-DKKwr4c8.mjs";
3
+ import { t as defineMetabaseCommand } from "./runtime-B8leBJ1G.mjs";
4
4
  import { t as ModerationReview } from "./moderation-review-Bf9bPNQI.mjs";
5
5
  import { i as moderationReviewView, n as verifyFlags, r as describeReview, t as reviewInput } from "./verify-flags-DEVMB9w0.mjs";
6
6
  //#region src/commands/dashboard/verify.ts
@@ -1,7 +1,7 @@
1
- import { dt as outputFlags, ft as profileFlag, ot as connectionFlags, u as renderSummary } from "./cli.mjs";
2
- import { t as defineMetabaseCommand } from "./runtime-Dd2uBKqN.mjs";
3
- import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-zB3cX0Kq.mjs";
4
- import { r as parseWaitSchedule } from "./wait-flags-CmIfm6_U.mjs";
1
+ import { ct as connectionFlags, f as renderSummary, mt as profileFlag, pt as outputFlags } from "./cli.mjs";
2
+ import { t as defineMetabaseCommand } from "./runtime-B8leBJ1G.mjs";
3
+ import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-BGWVry_U.mjs";
4
+ import { r as parseWaitSchedule } from "./wait-flags-P5MIy4fp.mjs";
5
5
  import { u as syncTaskView } from "./git-sync-D1aKczo6.mjs";
6
6
  import { a as throwIfFailedTask, i as taskPollOptions, n as formatSyncTask, r as syncTaskIdleView, t as SyncTaskOrIdle } from "./sync-task-Gf86CU9l.mjs";
7
7
  //#region src/commands/git-sync/wait.ts
@@ -1,6 +1,6 @@
1
1
  import { t as interruptSignal } from "./cli.mjs";
2
- import { t as parseId } from "./parse-id-CbF7zxGv.mjs";
3
- import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-zB3cX0Kq.mjs";
2
+ import { t as parseId } from "./parse-id-DKKwr4c8.mjs";
3
+ import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-BGWVry_U.mjs";
4
4
  //#region src/commands/wait-flags.ts
5
5
  const waitScheduleFlags = {
6
6
  timeout: {
@@ -1,4 +1,4 @@
1
- import { v as projectForList } from "./cli.mjs";
1
+ import { b as projectForList } from "./cli.mjs";
2
2
  //#region src/output/window.ts
3
3
  const MAX_REQUEST_PAGE_SIZE = 200;
4
4
  function windowList(items, range, serverTotal) {
@@ -35,13 +35,12 @@ function parseYamlResult(input, schema, opts = {}) {
35
35
  };
36
36
  }
37
37
  const YAML_1_1_LINE_BREAKS = /[\u0085\u2028\u2029]/;
38
- function parseMetabaseYaml(input, source) {
39
- if (YAML_1_1_LINE_BREAKS.test(input)) throw new ValidationError(`${source}: holds U+0085, U+2028 or U+2029, which Metabase reads as a line break and this check does not; remove the character`, {
40
- source,
41
- zodIssues: []
42
- });
38
+ function parseAs(input, source, version) {
43
39
  try {
44
- return parse(input, { merge: true });
40
+ return parse(input, {
41
+ merge: true,
42
+ version
43
+ });
45
44
  } catch (error) {
46
45
  throw new ValidationError(`${source}: invalid YAML: ${errorMessage(error)}`, {
47
46
  source,
@@ -49,5 +48,15 @@ function parseMetabaseYaml(input, source) {
49
48
  });
50
49
  }
51
50
  }
51
+ function parseMetabaseYaml(input, source) {
52
+ if (YAML_1_1_LINE_BREAKS.test(input)) throw new ValidationError(`${source}: holds U+0085, U+2028 or U+2029, which Metabase reads as a line break and this check does not; remove the character`, {
53
+ source,
54
+ zodIssues: []
55
+ });
56
+ return {
57
+ yaml12: parseAs(input, source, "1.2"),
58
+ yaml11: parseAs(input, source, "1.1")
59
+ };
60
+ }
52
61
  //#endregion
53
- export { parseYaml as n, parseMetabaseYaml as t };
62
+ export { parseYaml as n, parseYamlResult as r, parseMetabaseYaml as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metabase/cli",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "description": "Metabase CLI",
5
5
  "license": "AGPL-3.0",
6
6
  "repository": {
@@ -13,7 +13,7 @@ Top-level command groups (run `mb <group> --help` to discover verbs):
13
13
  ```
14
14
  auth | db | table | field | upload | content-translation | query | card | dashboard | snippet | segment | measure | collection | library
15
15
  document | glossary | timeline | timeline-event | transform | transform-job | transform-tag | transform-test | alert | subscription | setting
16
- search | dependency | git-sync | data-action | data-app | setup | eid | uuid | upgrade | skills | schema
16
+ search | dependency | git-sync | data-action | data-app | api-key | nano-id | setup | eid | uuid | upgrade | skills | schema
17
17
  ```
18
18
 
19
19
  The conventions below — auth, flags, output, body input — hold across **every** group. A few flows have their own skills (see "Specialized skills"). When a card needs a query, prefer MBQL over native SQL (portable, pre-flight-validated — load `mbql`); fall back to SQL when MBQL can't express it.
@@ -29,7 +29,7 @@ mb db get <id> --full --json
29
29
 
30
30
  ## Pick the collection
31
31
 
32
- A data action goes in a data actions collection, a data app collection, or the data actions root (omit `collection_id`). A regular collection is refused with `An action without a model can only go in a data actions or data app collection.` Make one with:
32
+ A data action goes in a data actions collection or the data actions root (omit `collection_id`); a data app defines its own (`data-app-actions`). A regular collection is refused with `An action without a model can only go in a data actions or data app collection.` Make one with:
33
33
 
34
34
  ```bash
35
35
  mb collection create --namespace data-actions --body '{"name":"Order actions"}' --json
@@ -125,7 +125,6 @@ Each `{{name}}` needs a `template-tags` entry and a `parameters` entry, all usin
125
125
  ```
126
126
 
127
127
  - `kind` is `row/create`, `row/update` or `row/delete`; `table_id` comes from `mb table list --db-id <id>`. The table needs exactly one primary key, or create answers `An implicit action needs a table with exactly one primary key.`
128
- - In a data app's collection the table must also be published to the Library (`mb library publish`), or create answers `An implicit action in a data app's collection can write only to a table published to the Library.`
129
128
  - The body has no `dataset_query` or `parameters`: Metabase derives the parameters from the table's columns, without sensitive and retired ones. Each parameter `id` is its column name, slugified; `mb data-action get <id> --full --json` lists them.
130
129
 
131
130
  | `kind` | Parameters | Answers |
@@ -136,7 +135,7 @@ Each `{{name}}` needs a `template-tags` entry and a `parameters` entry, all usin
136
135
 
137
136
  - `required` marks each `NOT NULL` column without a default, and the key of an update or delete. Execution itself checks only that an update or delete has the key; an insert without a `NOT NULL` column fails in the database.
138
137
  - An update writes only the columns given a value. A `null` value is dropped, so an update can't clear a column. A key that matches no row is refused: `Sorry, the row you're trying to update doesn't exist` (or `delete`).
139
- - `visualization_settings.fields.<parameter id>.hidden: true` hides a parameter: execution refuses a value for it, and a data app's `src/metabase.ts` leaves it out. Hide a column an insert needs only when the same field has a `defaultValue`.
138
+ - `visualization_settings.fields.<parameter id>.hidden: true` hides a parameter: execution refuses a value for it. Hide a column an insert needs only when the same field has a `defaultValue`.
140
139
  - A patch (_Lifecycle_) changes a query action's `dataset_query` or a table action's `kind` and `table_id`, never both.
141
140
 
142
141
  ## Run it
@@ -1,52 +1,57 @@
1
1
  ---
2
2
  name: data-app
3
- description: Create, preview, publish and manage a Metabase data app — a React app Metabase serves at /apps/<slug> — create it, scaffold its project, run the dev preview and read its diagnostics feed, build and publish the bundle, turn it off, move it to another instance, delete it. Triggers — "build a data app", "make an internal tool in Metabase", "scaffold a data app", "publish my data app", "update the app", "the app is blank". Start here; the UI is in `data-app-ui`, questions and charts in `data-app-data`, filter controls in `data-app-filters`, writes in `data-app-actions`.
3
+ description: Create, preview, release and manage a Metabase data app — a React app Metabase serves at /apps/<slug> from the synced git repository — scaffold it in the repository, run the dev preview and read its diagnostics feed, generate its questions and actions, build, push and import it, turn it off, move it to another instance, delete it. Triggers — "build a data app", "make an internal tool in Metabase", "scaffold a data app", "publish my data app", "update the app", "the app is blank". Start here; the UI is in `data-app-ui`, questions and charts in `data-app-data`, filter controls in `data-app-filters`, writes in `data-app-actions`.
4
4
  allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
5
5
  requires: [dataApps]
6
6
  ---
7
7
 
8
8
  # Data apps
9
9
 
10
- A **data app** is a React app built into one JavaScript bundle, which Metabase runs in a sandbox at `/apps/<slug>`. Each app has its own collection — **the app's collection** — and the questions and actions in it are everything the app can run. Flag conventions are in `core`.
10
+ A **data app** is a React app built into one JavaScript bundle, which Metabase runs in a sandbox at `/apps/<slug>`. An app lives in the instance's synced git repository: `data_apps/<slug>/` holds its source, its `data_app.yaml` and its bundle `dist/index.js`, and `collections/data_apps/` its collection, with the questions and actions it runs. The app defines those in its source, as `defineQuery` exports in `src/metabase.queries.ts` and `defineAction` exports in `src/metabase.actions.ts`; `mb data-app generate-queries` and `mb data-app generate-actions` write them as the collection's files. Nothing about an app is created or changed in Metabase through the API: the app, its collection, its questions and actions exist on an instance once the repository is imported (`mb git-sync import`). Flag conventions are in `core`.
11
11
 
12
12
  The work, in order:
13
13
 
14
- 1. Create the app on the instance.
15
- 2. Scaffold the project and install the SDK.
16
- 3. Give it data: questions over the Library's published tables and metrics in the app's collection, then `src/metabase.ts` (`data-app-data`); writes are `data-app-actions`.
17
- 4. Start the dev preview (_Dev preview_), then write the UI under `src/` (`data-app-ui`; filter controls in `data-app-filters`).
18
- 5. Build and publish (_Build and publish_).
14
+ 1. Scaffold the app in the synced repository and install the SDK.
15
+ 2. Give it data: fetch `src/metabase.schema.ts`, then define questions over the Library's published tables and metrics (`data-app-data`); writes are `data-app-actions`.
16
+ 3. Start the dev preview (_Dev preview_), then write the UI under `src/` (`data-app-ui`; filter controls in `data-app-filters`).
17
+ 4. Generate the collection, build, push and import (_Release_).
19
18
 
20
- For every later change: first pass the checks in _An existing project_ (_Scaffold and install_), then regenerate `src/metabase.ts` if the app's collection changed, then build and set the bundle; in a synced repository, then export and commit the source as in _Move to another instance_. Metabase receives only the built bundle; the source stays in the project directory, which is the app's folder in the synced git repository when there is one (_Scaffold and install_).
19
+ For every later change: first pass the checks in _An existing project_ (_Scaffold and install_), then change the source, then release (_Release_). The live app changes only through the import.
21
20
 
22
21
  ## Before you start
23
22
 
24
- - Use an **admin** profile — only admins create apps and write the app's collection. `mb auth status --profile <name> --json | jq .user.isAdmin` prints `true` for one, and every command below takes that `--profile`; otherwise ask the user for an admin profile (`mb auth list`).
25
- - Run `mb data-app list`. A failure means the instance has no data apps: stop and tell the user.
26
- - Settle the **slug**, the `/apps/<slug>` URL: lowercase letters, digits and single dashes (`sales-overview`), at most 100 characters. If the app's purpose is unclear, ask "what's this app for?" and propose one.
23
+ The app reaches Metabase only through the instance's synced git repository, so settle that first. If any check below fails, stop and tell the user which one, changing nothing:
27
24
 
28
- ## Create the app
25
+ 1. **The instance syncs with git.** `mb git-sync status --profile <name> --json` reports `remote_configured: true`. A read-only instance is fine: the app is pushed to the repository and pulled in by an import.
26
+ 2. **The working folder is that repository.** `git rev-parse --show-toplevel` succeeds, and one of `git remote -v` names the same repository as `mb setting get remote-sync-url --profile <name>`, however each spells it. That top level is `<repo>` below, checked out on the branch the instance tracks (`mb setting get remote-sync-branch --profile <name>`) and pulled (`git pull --ff-only`).
27
+ 3. **You can push to it.** `git push --dry-run` from `<repo>` succeeds. Without a push the app never reaches the instance.
29
28
 
30
- ```bash
31
- mb data-app create --body '{"name":"sales-overview","display_name":"Sales overview"}' --json
32
- ```
29
+ Then:
30
+
31
+ - Use an **admin** profile. `mb auth status --profile <name> --json | jq .user.isAdmin` prints `true` for one, and every command in the data-app skills that reaches Metabase takes that `--profile` (`scaffold` and `nano-id` take none); otherwise ask the user for an admin profile (`mb auth list`).
32
+ - Run `mb data-app list --profile <name>`. A failure means the instance has no data apps: stop and tell the user.
33
+ - **Only when the request needs the app to add, change or delete rows**, settle data actions on the database it writes to now, before designing anything (`data-app-actions`, _Data actions on the database_): the user may turn them on, or choose an app without writes. An app that only reads skips this, and never asks about data actions.
34
+ - Settle the **slug**, the `/apps/<slug>` URL: lowercase letters, digits and single dashes (`sales-overview`), at most 100 characters, and neither in `mb data-app list` nor under `<repo>/data_apps/`. If the app's purpose is unclear, ask "what's this app for?" and propose one.
33
35
 
34
- `name` is the slug; `display_name` and `description` are optional. The app starts enabled, with an empty bundle, open to admins until a group is assigned. The answer's `resource_collection_id` is the id of the app's collection — note it. A `409` means the slug is taken: `mb data-app list` shows that app; reuse it or pick another slug.
36
+ The app's questions and actions refer to the Library's tables and metrics by their portable IDs, which resolve on this instance as they are: the Library needn't be in the repository to release here, only to move the app to another instance (_Change, move, delete_).
35
37
 
36
38
  ## Scaffold and install
37
39
 
38
40
  ```bash
39
- mb data-app scaffold <repo>/data_apps/sales-overview && cd <repo>/data_apps/sales-overview
41
+ cd <repo> && mb data-app scaffold sales-overview
40
42
  ```
41
43
 
42
- `scaffold [dir]` takes a **directory**, not the slug: it copies the Vite + React + TypeScript template into a new or empty directory (the current one when omitted) and needs no server. When the instance syncs with a git repository (`mb git-sync status`), the directory is `data_apps/<slug>/` in a local clone of that repository (ask the user for its path, or clone the remote), where an export writes the app's `data_app.yaml` and bundle: an export leaves the source alone and an import ignores it, so the repository keeps the source with the app. `scaffold` needs an empty directory, so scaffold before the app's first export; for an app already in the repository, scaffold into a new directory and copy its files, dotfiles included (`cp -R <dir>/. data_apps/<slug>/`), in beside `data_app.yaml` and `dist/`; check `.gitignore` is there before `npm install`. Without a repository, use any new directory, and once remote sync is set up, move the project (without `node_modules/`, `build/`, `dist/`, `.env.local` and a hand-written `data_app.yaml`) into `data_apps/<slug>/` before committing its source. Then install the SDK, then the rest:
44
+ From the repository root, `scaffold <slug>` copies the Vite + React + TypeScript template into `data_apps/<slug>/`, which must be missing or empty, and writes the app's `data_app.yaml` and its collection's file `collections/data_apps/data_app__<slug>.yaml`, with fresh entity IDs, and adds `.env.local` to `<repo>/.gitignore`. It needs no server. An app already in the repository is never scaffolded again: its entity IDs stay as they are.
45
+
46
+ `data_app.yaml` is the app's manifest. Edit `name` (the title Metabase shows: the one the user gave the app, or a short one that says what it's for), `description` and `allowed_hosts` (a YAML list of origins, `data-app-ui`, _External APIs_) in it directly; never change `entity_id`, `slug`, `path`, `version` or `collection`. Then install the SDK, then the rest:
43
47
 
44
48
  ```bash
49
+ cd data_apps/sales-overview
45
50
  npm install @metabase/embedding-sdk-react@<major>-beta # <major>: 66 for a version tag v1.66.x (`mb auth status --profile <name> --json | jq -r .version.tag`)
46
- npm install && npm run typecheck && npm run build
51
+ npm install && npm run typecheck
47
52
  ```
48
53
 
49
- Skip the SDK line when `package.json` already points it at a local build (`file:` or `link:`), and never install `latest`. A tag without a version number, such as `vLOCAL_DEV`, is a development build: ask the user which SDK build to install. The starter renders "Hello, data app".
54
+ Install the SDK before the first `npm install`, which would otherwise install `latest` for the template's `*`. The starter renders "Hello, data app".
50
55
 
51
56
  The template is the bundle contract. Don't edit `package.json` by hand, and never rewrite `vite.config.ts`, `tsconfig.json` or `src/index.tsx`: `vite.config.ts` stays `export default dataAppConfig()` (its only option is `port`), and `src/index.tsx` default-exports the `DataAppFactory` — change it only to add a `providerProps` key. Metabase and the dev preview each wrap the app in a `<MetabaseProvider>`, so the app never renders one.
52
57
 
@@ -56,20 +61,22 @@ The template is the bundle contract. Don't edit `package.json` by hand, and neve
56
61
  - `src/index.tsx` default-exports a `DataAppFactory` that takes no arguments and returns `{ component, providerProps? }`.
57
62
  - `npm ls react react-dom` exits 0 and reports 19.x. A 19.x it marks `invalid` fails. This check applies whatever the instance or SDK version; to skip it, ask the user first.
58
63
 
59
- Fix a failed React check yourself, before any other change: upgrade `react`, `react-dom`, `@types/react` and `@types/react-dom` to 19 until `npm run typecheck && npm run build` passes and the diagnostics feed is clean (_Dev preview_); then publish (_Build and publish_). If either other check fails, stop: tell the user the project differs from the template, and ask whether to scaffold a fresh project and port the code over, or go on at their own risk.
64
+ Fix a failed React check yourself, before any other change: upgrade `react`, `react-dom`, `@types/react` and `@types/react-dom` to 19 until `npm run typecheck` passes and the diagnostics feed is clean (_Dev preview_); then release (_Release_). If either other check fails, stop: tell the user the project differs from the template, and ask whether to scaffold a fresh project and port the code over, or go on at their own risk.
60
65
 
61
66
  ## Dev preview
62
67
 
63
- `npm run dev` serves the app at `http://localhost:5174` — or the next free port, in Vite's `Local:` line — through the same sandbox Metabase uses. An edit under `src/` rebuilds the bundle and remounts the app, resetting component state. The preview reads `DATA_APP_MB_URL` and an admin `DATA_APP_MB_API_KEY` from `.env.local` beside `package.json`. Write a new key straight into that file, never into the chat or the terminal:
68
+ `npm run dev` serves the app at `http://localhost:5174` — or the next free port, in Vite's `Local:` line — under the restrictions Metabase puts on a data app (its CSP and blocked APIs), in the page itself rather than in an iframe. An edit under `src/` rebuilds the bundle and remounts the app, resetting component state. The preview runs each question from its definition and each action without saving it, against the instance whose IDs `src/metabase.schema.ts` holds, so that instance needs nothing of the app.
69
+
70
+ The preview reads `DATA_APP_MB_URL` and an admin `DATA_APP_MB_API_KEY` from `<repo>/.env.local`, which `<repo>/.gitignore` lists once the app is scaffolded: check the line is there before writing the file, and add it when it isn't. Create that key only on the user's yes: ask with `AskUserQuestion` ("Create an admin API key `data-app <slug> dev` for the preview? It goes in `.env.local` and is deleted at handoff."). On a no, the user fills in `<repo>/.env.local` from the app's `.env.local.example`. Write a new key straight into that file, never into the chat or the terminal:
64
71
 
65
72
  ```bash
66
73
  ( umask 077
67
74
  URL=$(mb auth status --profile <name> --json | jq -r .url)
68
75
  KEY=$(mb api-key create --profile <name> --body '{"name":"data-app <slug> dev","group_id":2}' --json | jq -r .unmasked_key)
69
- [ -n "$KEY" ] && [ "$KEY" != null ] && printf 'DATA_APP_MB_URL=%s\nDATA_APP_MB_API_KEY=%s\n' "$URL" "$KEY" > .env.local && echo written )
76
+ [ -n "$KEY" ] && [ "$KEY" != null ] && printf 'DATA_APP_MB_URL=%s\nDATA_APP_MB_API_KEY=%s\n' "$URL" "$KEY" > <repo>/.env.local && echo written )
70
77
  ```
71
78
 
72
- Group `2` is Administrators. Never print `.env.local`. Delete the key at handoff (`mb api-key list --profile <name>`, then `mb api-key delete <id> --yes --profile <name>`); the next session writes a new one. Metabase allows any localhost origin unless `MB_DISABLE_CORS_ON_LOCALHOST` is set, so a CORS error from the preview means it is: ask the user to unset it on this instance. Otherwise check `DATA_APP_MB_URL`.
79
+ Group `2` is Administrators. Never print `.env.local`. Delete the key at handoff, when you finish and give the app back to the user (`mb api-key list --profile <name>`, then `mb api-key delete <id> --yes --profile <name>`), and stop `npm run dev` with it: the preview can't reach Metabase once the key is gone. The next session writes a new one. Metabase allows any localhost origin unless `MB_DISABLE_CORS_ON_LOCALHOST` is set, so a CORS error from the preview means it is: ask the user to unset it on this instance. Otherwise check `DATA_APP_MB_URL`.
73
80
 
74
81
  ### The diagnostics feed
75
82
 
@@ -92,17 +99,20 @@ curl -s "http://localhost:5174/__data-app/diagnostics?startEventId=0"
92
99
  "buildId": 7,
93
100
  },
94
101
  ],
102
+ "manifest": { "errors": [], "warnings": [], "restartRequired": false }, // checks of data_app.yaml
95
103
  "clients": 1, // open preview tabs; 0 means nothing ran
96
104
  "buildId": 7, // the bundle running now
97
105
  "staleEntries": 164, // withheld: reported by a build already replaced
98
106
  "nextEventId": 32, // pass back as ?startEventId=
107
+ // also connection, sessionId, lastReportAt and lastRebuildAt, for diagnosing the feed itself
99
108
  }
100
109
  ```
101
110
 
102
- - `clients: 0` means no tab is open, so empty `entries` prove nothing.
111
+ - `clients: 0` means no tab is open, so empty `entries` prove nothing. The preview page's Diagnostics button shows the same entries; its being there doesn't mean anything is wrong. Open the preview URL in your browser tool; without one, ask the user to open it and keep the tab open while you read the feed. The preview serves its page only to a browser (`Accept: text/html`), so a bare `curl` of it answers 404: probe the feed instead.
112
+ - `manifest` checks `data_app.yaml`: its `errors` need fixing like entries, and `restartRequired: true` means restart `npm run dev`. Its `warnings` too, except that a missing `dist/index.js` is expected until you build at release.
103
113
  - Before an edit, note `nextEventId`; after it, read again with that value as `startEventId`.
104
114
  - The feed answers for the running bundle: entries from replaced builds are counted in `staleEntries`, and anything still broken reports again under the new `buildId` (`?includeStale=true` shows the withheld ones). A failed build doesn't advance `buildId` and doesn't reach the feed — read the `npm run dev` terminal.
105
- - Quote `summary` as it is when you report it, and follow `hint` when there is one — except that you never add the Metabase URL to `allowed_hosts`, and in a synced repository you set `allowed_hosts` with `mb data-app update`, export, and pull the export branch (_Move to another instance_) instead of editing `data_app.yaml`. A `frame-src` or `form-action` block can't be lifted in the preview (`data-app-ui`). The feed keeps the last 200 entries; `curl -X DELETE …/__data-app/diagnostics` clears it.
115
+ - Quote `summary` as it is when you report it, and follow `hint` when there is one — except that you never add the Metabase URL to `allowed_hosts`. An origin goes in `allowed_hosts` in `data_app.yaml`, then restart `npm run dev`. A `frame-src` or `form-action` block can't be lifted in the preview (`data-app-ui`). The feed keeps the last 200 entries; `curl -X DELETE …/__data-app/diagnostics` clears it.
106
116
 
107
117
  | `kind` | Fix |
108
118
  | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
@@ -111,33 +121,42 @@ curl -s "http://localhost:5174/__data-app/diagnostics?startEventId=0"
111
121
  | `sdk-call` with `alert: true` | A Metabase request failed; `summary` names it. |
112
122
  | `error` | A bug; `detail` has the stack. |
113
123
 
114
- ## Build and publish
124
+ ## Release
115
125
 
116
- ```bash
117
- npm run typecheck && npm run build
118
- mb data-app set-bundle sales-overview
119
- ```
126
+ Build the bundle last, test it in the dev preview, then push it with the source and the collection in one commit:
127
+
128
+ 1. On a read-write instance, `mb git-sync is-dirty --profile <name> --json`: when it reports unexported changes (a table just published to the Library, say), export them first (`git-sync`, its branch guard included), or the import refuses; then `git pull --ff-only` in `<repo>`.
129
+ 2. In `<repo>`, `mb data-app generate-queries <slug> --profile <name>` and `mb data-app generate-actions <slug> --profile <name>`. They load the exports of `src/metabase.queries.ts` and of `src/metabase.actions.ts` with the app's Vite, so `npm install` runs in the app first, and each replaces its kind of file in `collections/data_apps/data_app__<slug>/`: one YAML file per question or action, named after its export in lowercase and carrying its `entityId`. A generated question shows as a table in Metabase whatever the app makes of it. Nothing changes in Metabase.
130
+ 3. In the app, `npm run typecheck && npm run build`, which writes `dist/index.js`.
131
+ 4. With `npm run dev` running and a preview tab open, read the diagnostics feed (_Dev preview_) with every page mounted; fix what it reports, then generate and build again.
132
+ 5. Commit `data_apps/<slug>/` — the source, `package.json`, `package-lock.json`, `data_app.yaml` and `dist/index.js` — and `collections/data_apps/` together, and push.
133
+ 6. `mb git-sync import --profile <name>`, whatever a cached `has-remote-changes` says. The bundle, questions and actions are live at once.
120
134
 
121
- `set-bundle` uploads `build/index.js`, the file `npm run build` writes (`--bundle` for another path), and replaces the app's bundle, live at once. A new app is on from the start; `mb data-app set-enabled <slug> false` turns it off, which only the user decides. An app turned off opens only in Data Studio → Data apps → the app → Overview; `/apps/<slug>` says "not found", for admins too. Give the user `<metabase-url>/apps/<slug>`.
135
+ A production build runs the question or action each `entityId` names, so a bundle pushed without its collection's files fails where they're missing.
136
+
137
+ The first import creates the app on, open to admins until a group is assigned; later imports keep its on/off state. `mb data-app set-enabled <slug> false` turns it off, which only the user decides. An app turned off opens only in Data Studio → Data apps → the app → Overview; `/apps/<slug>` says "not found", for admins too. Give the user `<metabase-url>/apps/<slug>`.
122
138
 
123
139
  A viewer needs one of their groups assigned to the app (otherwise "You don't have access"), which only the user can do (Data Studio → Data apps → the app → Permissions). A group reaches the app's collection and nothing more, so a viewer also needs data access to the tables its questions read.
124
140
 
125
141
  ## Pitfalls
126
142
 
127
- | Symptom | Fix |
128
- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
129
- | `set-bundle`: bundle not found | Run `npm run build` in the project directory first. |
130
- | Blank app, `Bundle did not assign a function to __dataAppFactory__` | `src/index.tsx` must `export default` the factory and nothing else; otherwise the diagnostics feed has the real error. |
131
- | "Failed to fetch the user, the session might be invalid." | A bad key in `.env.local`, or CORS (_Dev preview_). |
132
- | A bundle of several MB | `vite.config.ts` no longer uses `dataAppConfig()`, or the SDK isn't the `<major>-beta` tag. |
133
- | "Invalid hook call" | A second React got bundled: nothing may add another `react` or `react-dom`. |
134
- | Drill-through popups don't open | The app renders its own `<MetabaseProvider>`: remove it. |
135
- | A rebuilt or reinstalled SDK still behaves like the old one | Vite caches it: stop `npm run dev`, delete `node_modules/.vite`, start again. |
136
- | A viewer's query or action fails with 403 | It reads something outside the app's collection, or the viewer lacks data access to its tables. |
143
+ | Symptom | Fix |
144
+ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
145
+ | The app still runs the old bundle | `dist/index.js` isn't in the pushed commit, or the push wasn't imported: build, commit, push, import. |
146
+ | Works in the preview, a question or action fails in Metabase | `generate-queries` or `generate-actions` didn't run after the last change, or the files weren't committed with the bundle: _Release_. |
147
+ | Blank app, `Bundle did not assign a function to __dataAppFactory__` | `src/index.tsx` must `export default` the factory and nothing else; otherwise the diagnostics feed has the real error. |
148
+ | "Failed to fetch the user, the session might be invalid." | A bad key in `<repo>/.env.local`, or CORS (_Dev preview_). |
149
+ | A bundle of several MB | `vite.config.ts` no longer uses `dataAppConfig()`, or the SDK isn't the `<major>-beta` tag. |
150
+ | "Invalid hook call" | A second React got bundled: nothing may add another `react` or `react-dom`. |
151
+ | Drill-through popups don't open | The app renders its own `<MetabaseProvider>`: remove it. |
152
+ | An upgraded SDK still behaves like the old one | Vite caches it: stop `npm run dev`, delete `node_modules/.vite`, start again. |
153
+ | A viewer's query or action fails with 403 | It reads a table not published to the Library on that instance, or the viewer lacks data access to its tables. |
137
154
 
138
155
  ## Change, move, delete
139
156
 
140
- - **Turn off:** `mb data-app set-enabled <slug> false`. **Rename:** `mb data-app update <slug> --body '{"display_name":"…"}'` (also `description`, `allowed_hosts`).
157
+ Every change below is a commit to `<repo>`, pushed and imported (_Release_).
158
+
159
+ - **Turn off:** `mb data-app set-enabled <slug> false`. **Rename:** `name` in `data_app.yaml` (also `description`, `allowed_hosts`); the app's collection keeps its name, `Data App: <slug>`.
141
160
  - **Outdated:** an app Data Studio lists as _Outdated_ targets an older data-app contract: it won't open for anyone, and only admins see it, until it's migrated. Tell the user; don't change its code ad hoc.
142
- - **Move to another instance:** the app, its collection and what the collection holds are git-synced content. `mb git-sync export` (`git-sync`) writes `data_apps/<slug>/` with the bundle, and the collection under `collections/data_apps/`; importing the repository on the other instance recreates them with the same entity IDs, so the same `src/metabase.ts` works there. The first import there creates the app on, like `create`, open to admins until the user assigns groups; later imports keep its on/off state. The import doesn't check that the questions' tables are published on that instance, so the Library content they read goes in the same export: flag the Library root once (`mb git-sync add-collection <library-id>`, `git-sync`), or its metrics, measures and segments stay out of the repository; a data action needs its database's toggle on there too. Once the app is done, commit its source in `data_apps/<slug>/` on the branch you exported to, after the export. Pull the export branch: `git fetch`, `git switch <branch>`, `git pull --ff-only`. Then `git add data_apps/<slug>`, commit and push, and `mb git-sync import` whatever a cached `has-remote-changes` says, or the next export ends in `conflict`. The export writes `data_app.yaml` and `dist/index.js`, the bundle you uploaded; never edit those two, and leave them out of your commits unless the bundle ships through git (below). The template's `.gitignore` keeps `node_modules/`, `build/` and `.env.local` out. A bundle can instead ship through git, from CI say: `npm run build:ci` writes `dist/index.js`, and once that is committed and pushed, the next import loads it. On a read-only synced instance only `set-enabled` works: creating, bundling, updating and deleting an app answer 403, and so does editing its collection; change it where it was built and export again.
143
- - **Delete:** confirm with the user, then `mb data-app delete <slug> --yes` — it removes the app, its bundle, its collection and the questions and actions in it. The project directory stays: in a synced repository, the next export removes the app's `data_app.yaml`, bundle and collection files; after that export, switch and pull the same way, delete the source in `data_apps/<slug>/` in a commit of your own, push, and import.
161
+ - **Move to another instance:** import the repository there. The app, its collection, questions and actions keep their entity IDs, so the same bundle runs there. The import doesn't check that the questions' tables are published on that instance, so the Library content they read goes in the same repository: flag the Library root once (`mb git-sync add-collection <library-id>`, `git-sync`), or its metrics, measures and segments stay out of it; an action needs its database's actions toggle on there too. `dist/index.js` changes only through `npm run build`. The app's `.gitignore` keeps `node_modules/` out, and `<repo>/.gitignore` keeps `.env.local` out.
162
+ - **Delete:** confirm with the user, then delete `data_apps/<slug>/`, `collections/data_apps/data_app__<slug>.yaml` and `collections/data_apps/data_app__<slug>/` in a commit of your own, push, and import.
@@ -1,2 +1,3 @@
1
+ # The dev preview reads these from .env.local at the repository root, not from this folder.
1
2
  DATA_APP_MB_URL=http://localhost:3000
2
3
  DATA_APP_MB_API_KEY=mb_replace_me
@@ -17,17 +17,26 @@ npm install
17
17
 
18
18
  ## Commands
19
19
 
20
+ In the app:
21
+
20
22
  ```bash
21
23
  npm run dev # preview at http://localhost:5174, in the sandbox Metabase runs apps in
22
24
  npm run typecheck # type-checks src/ and vite.config.ts
23
- npm run build # builds build/index.js
24
- mb data-app typed-schema <slug> --out src/metabase.ts # the app's queries and actions
25
- mb data-app set-bundle <slug> # makes build/index.js the app's bundle
25
+ npm run build # builds dist/index.js, the app's bundle
26
+ ```
27
+
28
+ From the repository root:
29
+
30
+ ```bash
31
+ mb data-app generate-schema <slug> --profile <name> # src/metabase.schema.ts: the Library's tables and metrics
32
+ mb data-app generate-queries <slug> --profile <name> # the questions of src/metabase.queries.ts, as collection files
33
+ mb data-app generate-actions <slug> --profile <name> # the actions of src/metabase.actions.ts, as collection files
34
+ mb nano-id --count <n> # entity IDs for new questions and actions
26
35
  ```
27
36
 
28
- To ship the bundle through git instead, for example from CI, run
29
- `npm run build:ci` and commit `dist/index.js`, the file the app's
30
- `data_app.yaml` names; the next git-sync import loads it.
37
+ The app ships through git: commit `data_apps/<slug>/`, `dist/index.js`
38
+ included, with the files `generate-queries` and `generate-actions` write under
39
+ `collections/data_apps/`, and push; the next git-sync import loads them.
31
40
 
32
41
  `npm run dev` reads `DATA_APP_MB_URL` and `DATA_APP_MB_API_KEY` from
33
- `.env.local`; `.env.local.example` lists them.
42
+ `.env.local` at the repository root; `.env.local.example` lists them.
@@ -1,5 +1,4 @@
1
1
  node_modules
2
- build
3
2
  .env.local
4
3
  .vite
5
4
  .idea
@@ -5,8 +5,7 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
- "build": "vite build",
9
- "build:ci": "vite build --outDir dist",
8
+ "build": "vite build --outDir dist",
10
9
  "typecheck": "tsc --noEmit"
11
10
  },
12
11
  "dependencies": {
@@ -0,0 +1,3 @@
1
+ import { defineAction } from "@metabase/embedding-sdk-react/data-app";
2
+
3
+ import { schema } from "./metabase.schema";
@@ -0,0 +1,3 @@
1
+ import { defineQuery } from "@metabase/embedding-sdk-react/data-app";
2
+
3
+ import { schema } from "./metabase.schema";
@@ -0,0 +1,3 @@
1
+ const schema = { tables: {}, metrics: {} } as const;
2
+
3
+ export { schema };
@@ -4,7 +4,9 @@ export const sdkTheme: MetabaseTheme = {
4
4
  colors: {
5
5
  brand: "#4D96FF",
6
6
  "brand-hover": "#EAF4FF",
7
- positive: "#4D96FF",
7
+ "brand-hover-light": "#F5FAFF",
8
+ positive: "#2BA672",
9
+ negative: "#E5484D",
8
10
  charts: [
9
11
  "#4D96FF",
10
12
  "#E8743B",