@metabase/cli 0.5.2 → 0.5.4
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.
- package/README.md +1 -1
- package/dist/{add-collection-C0BQHjJd.mjs → add-collection-D2x34KVO.mjs} +3 -3
- package/dist/{alert-mXHOt00T.mjs → alert-B-w0c61D.mjs} +7 -7
- package/dist/{alerts-CyB1Z7AU.mjs → alerts-nnrpqD-U.mjs} +6 -6
- package/dist/api-key-9jVV67hF.mjs +38 -0
- package/dist/api-key-CTyXuYui.mjs +13 -0
- package/dist/api-key-DbsqHlN6.mjs +31 -0
- package/dist/{append-DeHhUAeY.mjs → append-BPrVW4RB.mjs} +4 -4
- package/dist/{archive-DRMXvkiI.mjs → archive-BYo35OGC.mjs} +5 -5
- package/dist/{archive-Bi-Sfq5T.mjs → archive-BZVRJYTT.mjs} +5 -5
- package/dist/{archive-CCKxZEuq.mjs → archive-Bw_cvk_4.mjs} +3 -3
- package/dist/{archive-qy0CFo1s2.mjs → archive-CJFUFozc.mjs} +5 -5
- package/dist/{archive-CfNLlebd.mjs → archive-CTZs6Hl6.mjs} +5 -5
- package/dist/{archive-CDSAXKKB.mjs → archive-Ccf6Qqrf.mjs} +3 -3
- package/dist/{archive-DfDqPgtk.mjs → archive-Cwetg5kK.mjs} +5 -5
- package/dist/{archive-CjVd1fJ5.mjs → archive-DBQnauVo.mjs} +5 -5
- package/dist/{archive-CpvpGZlz.mjs → archive-F5hoWW7f.mjs} +5 -5
- package/dist/{archive-DpgtAdEa.mjs → archive-OZQaaQkK.mjs} +5 -5
- package/dist/{archive-B1MA5MZp.mjs → archive-p7gGwh0n.mjs} +5 -5
- package/dist/{archive-HCVTRXI2.mjs → archive-tmrsG41w.mjs} +3 -3
- package/dist/{auth-_cdypXeX.mjs → auth-eogOlU4X.mjs} +5 -5
- package/dist/{branch-flag-CPTQ4wXp.mjs → branch-flag-BvIdNB5z.mjs} +1 -1
- package/dist/{branches-C7mNYAky.mjs → branches-CERgKqFq.mjs} +3 -3
- package/dist/{breaking-BindR3ZW.mjs → breaking-B8f_vl0i.mjs} +6 -6
- package/dist/{broken-SoXfkx7d.mjs → broken-mrkOdV4j.mjs} +8 -8
- package/dist/{bulk-discard-values-D_d5_1w5.mjs → bulk-discard-values-BQ3z6nJb.mjs} +5 -5
- package/dist/{bulk-edit-Cce05vb_.mjs → bulk-edit-CJxoxDGQ.mjs} +7 -7
- package/dist/{bulk-rescan-values-DIQN4VT_.mjs → bulk-rescan-values-DflzyxEj.mjs} +5 -5
- package/dist/{bulk-sync-schema-DLWf5dCl.mjs → bulk-sync-schema-CBIs4yHs.mjs} +5 -5
- package/dist/{cancel-rnd6UI-6.mjs → cancel-CyTRWSOr.mjs} +3 -3
- package/dist/{cancel-task-acq1GT6Z.mjs → cancel-task-BuZsQuLp.mjs} +2 -2
- package/dist/{card-QR3zEu6E.mjs → card-BJRZ5D5Q.mjs} +2 -2
- package/dist/card-DA1W3Axw.mjs +25 -0
- package/dist/{card-3NmUiU5F.mjs → card-VipF12MJ.mjs} +1 -1
- package/dist/{cards-DmzPtx81.mjs → cards-BEeFNiCt.mjs} +6 -6
- package/dist/cli.mjs +142 -292
- package/dist/{client-D-Aw6JLk.mjs → client-DvWllzKd.mjs} +401 -189
- package/dist/{collection-D5vt2IJ_.mjs → collection-Bf3lv-zo.mjs} +1 -1
- package/dist/collection-C98jgufi.mjs +21 -0
- package/dist/{collection-DNmFKALA.mjs → collection-Cz2qLX2m.mjs} +1 -1
- package/dist/{collection-namespace-Dl8_7xII.mjs → collection-namespace-C0JcSEwN.mjs} +2 -1
- package/dist/{content-translation-DxT1OMnP.mjs → content-translation-1coWME1P.mjs} +3 -3
- package/dist/{copy-BTdTiDQo.mjs → copy-DVe4rcLK.mjs} +6 -6
- package/dist/{copy-flags-CTM91pxH.mjs → copy-flags-DZ5Cy-Gk.mjs} +2 -2
- package/dist/{copy-CyFf3e2Y.mjs → copy-hE6SaHfb.mjs} +6 -6
- package/dist/{create-CuJJd7Rh.mjs → create-B3P62NaN.mjs} +4 -5
- package/dist/{create-BH6zpwKD.mjs → create-B3kz_fHg.mjs} +4 -5
- package/dist/{create-Dn8V5siS.mjs → create-BPRuU7Mv.mjs} +7 -8
- package/dist/{create-DeCPAYJi.mjs → create-BjH0i2BC.mjs} +9 -10
- package/dist/{create-Ch-NbeMr.mjs → create-Btwnm6D2.mjs} +9 -10
- package/dist/{create-Ce5YVusp.mjs → create-CCb2_Kcc.mjs} +6 -7
- package/dist/{create-DeiBnRRz.mjs → create-D271V9Cf.mjs} +9 -9
- package/dist/create-D6Xm2b2D.mjs +37 -0
- package/dist/{create-roJbQOmm.mjs → create-DCoo3sI2.mjs} +4 -4
- package/dist/{create-B6dABrs7.mjs → create-DEIIUohY2.mjs} +10 -11
- package/dist/{create-qtTB8rIE.mjs → create-DJg0Ohj5.mjs} +9 -10
- package/dist/{create-C3rabvE_.mjs → create-DR5tpMUA.mjs} +4 -5
- package/dist/{create-BwIOlpLc.mjs → create-DR8g_rEL.mjs} +6 -7
- package/dist/{create-GU8_GNbN.mjs → create-DXivfl69.mjs} +4 -5
- package/dist/create-DdfFgF-w.mjs +33 -0
- package/dist/{create-DsCydgm22.mjs → create-DkFCjBp3.mjs} +6 -7
- package/dist/{create-B3QZpifA.mjs → create-Dz4c8E33.mjs} +9 -10
- package/dist/{create-Bg3WTMMU.mjs → create-LpdQKxUt.mjs} +7 -7
- package/dist/{create-D6NLpIzV.mjs → create-XCzUuT42.mjs} +4 -5
- package/dist/{create-DiG165B2.mjs → create-XVjr8IDS.mjs} +6 -7
- package/dist/{create-branch-C4Ql9G2g.mjs → create-branch-D_nbKxDS.mjs} +3 -2
- package/dist/{csv-DmuyyLdz.mjs → csv-LP7sE-CS.mjs} +4 -4
- package/dist/{current-task-C2PPBVVv.mjs → current-task-DhgwtGN3.mjs} +3 -3
- package/dist/{dashboard-D5E3fMKh.mjs → dashboard-Bx2sYijR.mjs} +1 -1
- package/dist/dashboard-CR97_zXn.mjs +35 -0
- package/dist/{dashboard-Chjy5GKR.mjs → dashboard-Cwsf-e9T.mjs} +23 -6
- package/dist/data-action-C4jE-RLb.mjs +24 -0
- package/dist/{data-action-DZxVB_hD.mjs → data-action-CuvI17XF.mjs} +8 -2
- package/dist/{data-action-R9qxJDPA.mjs → data-action-DLj9cgpu.mjs} +1 -1
- package/dist/data-app-BUW-HlUo.mjs +52 -0
- package/dist/data-app-BlBvvRzC.mjs +41 -0
- package/dist/data-app-Blz61mG5.mjs +29 -0
- package/dist/data-app-project-DjDDWgUF.mjs +58 -0
- package/dist/{database-CxykzTAA.mjs → database-C5ucihp3.mjs} +2 -2
- package/dist/{database-D8XzgJEz.mjs → database-u_spHEa0.mjs} +1 -1
- package/dist/{dataset-DIQLAp2P.mjs → dataset-LJxNN6p5.mjs} +3 -3
- package/dist/{db-BgKKN1-4.mjs → db-D8mPRqZc.mjs} +8 -8
- package/dist/{delete-DiZg2wit.mjs → delete-8k7oYDFr.mjs} +4 -4
- package/dist/{delete-_XC6R-Jn.mjs → delete-B1SbEVIc.mjs} +4 -4
- package/dist/{delete-CS6hsBnd.mjs → delete-CaaPrNOf.mjs} +4 -4
- package/dist/{delete-5ZOvFr-7.mjs → delete-CqyBkMCd.mjs} +4 -4
- package/dist/{delete-DeqGTuwO.mjs → delete-CuyGTe0i.mjs} +4 -4
- package/dist/delete-DC-DEYSq.mjs +44 -0
- package/dist/{delete-B3aylPHD.mjs → delete-DWTqIlbr.mjs} +4 -4
- package/dist/delete-DaqzPLcG.mjs +40 -0
- package/dist/{delete-DtIbkF42.mjs → delete-DuaJ8PUI.mjs} +4 -4
- package/dist/{delete-CH32Ew4m.mjs → delete-ZjLpkwgx.mjs} +4 -4
- package/dist/delete-runtime-DOOy3gzH.mjs +73 -0
- package/dist/{delete-table-BEuMlqw1.mjs → delete-table-CnGv1gx9.mjs} +4 -4
- package/dist/{dependencies-DD48u9i3.mjs → dependencies-D6SNdLW8.mjs} +6 -6
- package/dist/dependency-Bbg9x1V9.mjs +15 -0
- package/dist/{dependency-CaC6XuTY.mjs → dependency-C1DExO6k.mjs} +8 -5
- package/dist/{dependency-Dxvb2Znu.mjs → dependency-DcM96XJ-.mjs} +4 -3
- package/dist/{dependents-ByfHs8pO.mjs → dependents-BizQb14Q.mjs} +9 -9
- package/dist/{dirty-DsrGfLit.mjs → dirty-BHwdHOEj.mjs} +3 -3
- package/dist/{discard-values-BfpwwC62.mjs → discard-values-BWlh2ce8.mjs} +5 -5
- package/dist/document-B6254tue.mjs +20 -0
- package/dist/{document-UMG6me2P.mjs → document-BHOQq2T_.mjs} +2 -2
- package/dist/{document-DVIu3Vj4.mjs → document-lS1XZEF3.mjs} +1 -1
- package/dist/{download-kpgGtfpw.mjs → download-D2wEAgi_.mjs} +2 -2
- package/dist/{eid-Tp-ACZ4O.mjs → eid-KtWIPUCC.mjs} +5 -5
- package/dist/{entity-DjDkaMkB.mjs → entity-DICgy4Bl.mjs} +2 -2
- package/dist/{entry-flags-nhBrUS6p.mjs → entry-flags-DLS6r8Vf.mjs} +5 -6
- package/dist/{events-Dm9-ofXu.mjs → events-B8yMqrrD.mjs} +4 -4
- package/dist/{execute-BL0dAlrp.mjs → execute-Bebvab7D.mjs} +7 -8
- package/dist/{export-CIW-dHft.mjs → export-BNj3RvAl.mjs} +6 -5
- package/dist/{export-flags-CpukgETM.mjs → export-flags-iXfEILf7.mjs} +3 -2
- package/dist/{export-preflight-BMlz3Hp9.mjs → export-preflight-F3OapAD5.mjs} +3 -3
- package/dist/{field-DoWQUl7V.mjs → field-C2qOViFZ.mjs} +8 -2
- package/dist/{field-BVz4AS3f.mjs → field-CT4r6b92.mjs} +1 -1
- package/dist/field-DQAcCjXr.mjs +21 -0
- package/dist/{fields-CcerFaiu.mjs → fields-BkAS_wIA.mjs} +6 -6
- package/dist/{filter-flags-DhE4olyf.mjs → filter-flags-ezqqsOQL.mjs} +4 -4
- package/dist/{fks-CYfBesHV.mjs → fks--SaqvPw1.mjs} +6 -6
- package/dist/{get-DKbGKa6F.mjs → get-B1S1kW2N.mjs} +5 -5
- package/dist/{get-Be7yjY9v.mjs → get-B1uiZyyi.mjs} +5 -5
- package/dist/{get-BaiyMem3.mjs → get-B2nBYYCw.mjs} +4 -4
- package/dist/{get-CmxYFUuR.mjs → get-BSKpQJVB.mjs} +5 -5
- package/dist/{get-BFloqjrN.mjs → get-BjgB5l7X.mjs} +5 -5
- package/dist/{get-RCDF-hEq.mjs → get-Boql3_0n.mjs} +5 -5
- package/dist/{get-CEJE9Rmp.mjs → get-BseHija1.mjs} +5 -5
- package/dist/{get-eNRULmE5.mjs → get-C9VumVZ3.mjs} +6 -5
- package/dist/{get--E7UvR-v.mjs → get-CGPxAoow.mjs} +3 -3
- package/dist/{get-HzDQViDP2.mjs → get-CM9IOr82.mjs} +3 -3
- package/dist/{get-CRfrkxqc.mjs → get-CTTKQDr7.mjs} +5 -5
- package/dist/{get-DHSuVxrH.mjs → get-CU1zKfBS.mjs} +5 -5
- package/dist/{get-Dp45rXRS.mjs → get-CWDz6eV2.mjs} +3 -3
- package/dist/{get-p2sZvp7v.mjs → get-C_hatP_z.mjs} +3 -3
- package/dist/get-Cdcj1c9U.mjs +28 -0
- package/dist/{get-BLnQ2aut.mjs → get-CiLYhFjU.mjs} +5 -5
- package/dist/{get-LRTRu85E.mjs → get-De6qpuzO.mjs} +5 -5
- package/dist/{get-CZgAr8rM.mjs → get-VpGfaL7c.mjs} +5 -5
- package/dist/{get-BvEHWLGL.mjs → get-f2km9wsq.mjs} +3 -3
- package/dist/{get-Cj3-w_Nu.mjs → get-gGSl7Se4.mjs} +5 -5
- package/dist/{get-B0RQPTV-2.mjs → get-iOs1ci6x.mjs} +5 -5
- package/dist/{get-run-C3AHKn3-.mjs → get-run-CHup8cMl.mjs} +5 -5
- package/dist/{get-DRhcS76J.mjs → get-uHs9Ve-4.mjs} +5 -5
- package/dist/git-sync-Czena0TW.mjs +29 -0
- package/dist/glossary-BVxRpD7o.mjs +14 -0
- package/dist/{glossary-BkGmCI4X.mjs → glossary-CQRW3Z4d.mjs} +1 -1
- package/dist/{glossary-QN-hHfOT.mjs → glossary-iPIWrEbP.mjs} +1 -1
- package/dist/{graph-BGOYocJc.mjs → graph-B7SlzpkC.mjs} +6 -6
- package/dist/{group-81zoQcEP.mjs → group--6adAsqG.mjs} +2 -2
- package/dist/{has-remote-changes-DxsRvZsw.mjs → has-remote-changes-DZq7q2Wk.mjs} +2 -2
- package/dist/{import-izn2_OsW.mjs → import-DKZF0kMU.mjs} +6 -5
- package/dist/input-gate-registry-Dh8QjKgW.mjs +14 -0
- package/dist/{is-dirty-DHYYRl6Y.mjs → is-dirty-haRLODo1.mjs} +2 -2
- package/dist/{items-mIoZBqUc.mjs → items-BGWE5hLl.mjs} +7 -6
- package/dist/{key-BYEv4Wgq.mjs → key-DLrpCgdZ.mjs} +1 -1
- package/dist/{library-wUiD2jbw.mjs → library-BprxuqZl.mjs} +1 -1
- package/dist/{library-DKIqzyUk.mjs → library-C4g9pdiS.mjs} +8 -3
- package/dist/{library-5I0TlXmf.mjs → library-e3aiJ1Yb.mjs} +5 -5
- package/dist/{list-BKhJfFyB.mjs → list-B9yhUzCc.mjs} +5 -5
- package/dist/{list-CpxEOoqw.mjs → list-BNel4hYs.mjs} +6 -6
- package/dist/{list-D8jiz8YP.mjs → list-Bbc8VYDi.mjs} +3 -3
- package/dist/{list-CT7AOXTS.mjs → list-BiIZdUoN.mjs} +5 -5
- package/dist/list-C-AnwSRP.mjs +33 -0
- package/dist/list-CNiCM1NL.mjs +29 -0
- package/dist/{list-DV4wojtv.mjs → list-COPGHkWL.mjs} +5 -5
- package/dist/{list-CTlIVHeG.mjs → list-CsXdnNyp.mjs} +5 -5
- package/dist/{list-DVnPzc5m.mjs → list-D0ASRA_6.mjs} +6 -6
- package/dist/{list-B6TYzXyW.mjs → list-DAa4EWlv.mjs} +5 -5
- package/dist/{list-CmOTwt_z.mjs → list-DDt1iLXj.mjs} +4 -4
- package/dist/{list-C6roDyBd.mjs → list-DFuydMdV.mjs} +6 -6
- package/dist/{list-C1dEh2yq.mjs → list-DFxfpa4W.mjs} +6 -6
- package/dist/{list-OWPg67JC.mjs → list-DJyIkrY1.mjs} +5 -5
- package/dist/{list-CuEPFHrk.mjs → list-DUCxqhtn.mjs} +5 -5
- package/dist/{list-B8FPpgct.mjs → list-D_8GeDG-.mjs} +3 -3
- package/dist/{list-NeImhwLD.mjs → list-DcXqKZyg.mjs} +5 -5
- package/dist/{list-C3CXHKTW.mjs → list-DednUvr3.mjs} +3 -3
- package/dist/{list-O_nmgwSj.mjs → list-Dvf1iB8r.mjs} +3 -3
- package/dist/{list-jT5ndEGr.mjs → list-HI7Mpoy-.mjs} +5 -5
- package/dist/{list-BEBAq1xc.mjs → list-OUSeeuXb.mjs} +5 -5
- package/dist/{list-BxIulkp3.mjs → list-P7FnSsbZ.mjs} +6 -6
- package/dist/{list-C-f-G-cC.mjs → list-gcDxZ7Th.mjs} +5 -5
- package/dist/{login-DOW1mr40.mjs → login-APHXId1p.mjs} +6 -5
- package/dist/{logout-BQ8wywf7.mjs → logout-V0pxj6AM.mjs} +3 -2
- package/dist/{measure-CtfjqJFP.mjs → measure-BMWrX1ca.mjs} +3 -1
- package/dist/{measure-Bz-bGn-Z.mjs → measure-DnGWkKyx.mjs} +6 -6
- package/dist/{measure-4P0bOlZ3.mjs → measure-DqZG65of.mjs} +1 -1
- package/dist/{notification-DaA4bBHW.mjs → notification-B5yMuPmo.mjs} +6 -1
- package/dist/{notification-W2SVssyY.mjs → notification-BEJaEZS2.mjs} +2 -2
- package/dist/{parameter-DvRQMKd2.mjs → parameter-Bucz3cLJ.mjs} +1 -1
- package/dist/{parameter-values-B7rr6fcy.mjs → parameter-values-DfZSEK3O.mjs} +6 -5
- package/dist/{parse-enum-DAcTzG1q.mjs → parse-enum-CEXPuN9H.mjs} +1 -1
- package/dist/{parse-id-5BZGQ9Vd.mjs → parse-id-EXZan40V.mjs} +1 -1
- package/dist/{parse-ref-ByXc-pls.mjs → parse-ref-D28NvwpR.mjs} +1 -1
- package/dist/{parse-text-FgX60vIg.mjs → parse-text-C4LYzIFa.mjs} +1 -1
- package/dist/{path-CHQguAPa.mjs → path-Bni-pnKS.mjs} +4 -4
- package/dist/{poll-CgtcJopL.mjs → poll-vxN__4cz.mjs} +2 -2
- package/dist/predicates-0C0TsWcJ.mjs +219 -0
- package/dist/{preflight-ChTKhB8Y.mjs → preflight-4iy2qzsh.mjs} +3 -2
- package/dist/{process-aqXm5QgC.mjs → process-BQC3mK2k.mjs} +1 -1
- package/dist/{publish-CaoFOucS.mjs → publish-DkYn86ak.mjs} +5 -4
- package/dist/{pulse-CC81N2_0.mjs → pulse-B2AmIWsO.mjs} +11 -4
- package/dist/{pulse-JPrq6NFP.mjs → pulse-CPSpum5U.mjs} +2 -2
- package/dist/{query-0u1WR1bV.mjs → query-CZbI4Rlv.mjs} +17 -29
- package/dist/{query-CzDBwAZD.mjs → query-gHeYfWj_.mjs} +7 -6
- package/dist/{remapping-CodmT28F.mjs → remapping-hcWkFQsx.mjs} +5 -5
- package/dist/{remove-collection-DfUsf6Dd.mjs → remove-collection-Qne5ww6M.mjs} +3 -3
- package/dist/{render-DP6UoZNT.mjs → render-d1-sCPn_.mjs} +3 -2
- package/dist/{replace-qWiUOgmn.mjs → replace-DoU0IFGd.mjs} +4 -4
- package/dist/{requirement-check-sfmyH2PH.mjs → requirement-check-BoVSK1uK.mjs} +2 -2
- package/dist/{rescan-values-BuDmeda3.mjs → rescan-values-COzM86P5.mjs} +5 -5
- package/dist/{rescan-values-BcrhdSj_.mjs → rescan-values-s82n_You.mjs} +5 -5
- package/dist/{run-BG_5lR0x.mjs → run-Bwj4Uuxk.mjs} +4 -4
- package/dist/{run-BBRnFayr.mjs → run-JYNbEO_V.mjs} +6 -5
- package/dist/{run-DXXD-CnS.mjs → run-Q7fHux1F.mjs} +5 -4
- package/dist/{runs-CovgMSwy.mjs → runs-GQD6FO2k.mjs} +6 -6
- package/dist/{runtime-Cmes70jO.mjs → runtime-iIsqiOwO.mjs} +51 -9
- package/dist/scaffold-CJo9l-2p.mjs +50 -0
- package/dist/schema-2JhmK8FM.mjs +283 -0
- package/dist/{schema-tables-CjKl8jr5.mjs → schema-tables-CarGLayY.mjs} +6 -6
- package/dist/{schemas-CAGvBAD_.mjs → schemas-oSjtuQ4G.mjs} +4 -4
- package/dist/{search-DFU6FHRd.mjs → search-Ca0sIr28.mjs} +7 -6
- package/dist/{search-OpYS2Ub4.mjs → search-CvGEL2h-.mjs} +6 -5
- package/dist/{segment-D-SKpFzF.mjs → segment-BJCEJwNY.mjs} +6 -6
- package/dist/{segment-C_gl5ag6.mjs → segment-CWVASaM1.mjs} +1 -1
- package/dist/{segment-OsrbUDzw.mjs → segment-Cf-DrdjE.mjs} +3 -1
- package/dist/{send-DNu83_3E.mjs → send-B4nZI6CU.mjs} +3 -3
- package/dist/{set-CGYZcLVo.mjs → set-BjMZCdN8.mjs} +5 -6
- package/dist/{set-active-32IaLx1O.mjs → set-active-CWDdv3kN.mjs} +4 -4
- package/dist/set-bundle-C2uk4jdt.mjs +40 -0
- package/dist/{set-data-actions-DRhgAfhE.mjs → set-data-actions-lWl05ekf.mjs} +6 -6
- package/dist/set-enabled-CPhw1AX4.mjs +41 -0
- package/dist/{set-sensitivity-D_i3XEe8.mjs → set-sensitivity-B7WI5BJC.mjs} +6 -6
- package/dist/{setting-BBn9Lv9J.mjs → setting-BvPpFjJT.mjs} +4 -4
- package/dist/{setup-CO7QV-ao.mjs → setup-BnczkG96.mjs} +1 -1
- package/dist/{setup-8d7Uplhy.mjs → setup-DPRa8Uxm.mjs} +5 -6
- package/dist/{signal-D8MH3LMN.mjs → signal-BNUlQjpc.mjs} +1 -1
- package/dist/{skill-list-D2FhhYS3.mjs → skill-list-BoJITnw8.mjs} +1 -1
- package/dist/{skills-BeIDC-_H.mjs → skills-BCivFuuZ.mjs} +3 -3
- package/dist/{skills-BZGd_9d3.mjs → skills-BY3MCR8i.mjs} +3 -2
- package/dist/slug-COdwq63O.mjs +15 -0
- package/dist/snippet-BcN1UwoS.mjs +19 -0
- package/dist/{stash-Dyc1xZ8u.mjs → stash-leoW1fby.mjs} +5 -4
- package/dist/{status-CQZwl1PX.mjs → status-AA4APlwZ.mjs} +3 -3
- package/dist/{status-lCN8unWe.mjs → status-BezD_K-g.mjs} +4 -4
- package/dist/{subscription-CEFxmtGH.mjs → subscription-BDukZFlC.mjs} +6 -6
- package/dist/{subscriptions-AU14uznL.mjs → subscriptions-CU4E_p7B.mjs} +6 -6
- package/dist/{summary-Do9IBOQM.mjs → summary-BFspP71W.mjs} +5 -5
- package/dist/{sync-schema-_gw9RQyF.mjs → sync-schema-BhRhsm8Y.mjs} +6 -6
- package/dist/{sync-schema-B3nyoKZl.mjs → sync-schema-BtjC-PNY.mjs} +5 -5
- package/dist/{sync-task-DNKG9Bk4.mjs → sync-task-Gf86CU9l.mjs} +1 -1
- package/dist/{table-BDsqRU7a.mjs → table-BNA9Or05.mjs} +3 -3
- package/dist/table-Dzp1uANs.mjs +26 -0
- package/dist/{table-CF7zW9cI.mjs → table-hgrX1i-R.mjs} +36 -5
- package/dist/{table-selector-flags-CHfrVpYQ.mjs → table-selector-flags-BpFFoSaT.mjs} +4 -3
- package/dist/{text-C2VwKF9D.mjs → text-8nOxfC17.mjs} +1 -1
- package/dist/timeline-Cr5d4Oer.mjs +21 -0
- package/dist/{timeline-event-B-nGnoVL.mjs → timeline-event-BiYDbW3r.mjs} +6 -6
- package/dist/{transform-DiW7bREn.mjs → transform-B62craFM.mjs} +76 -7
- package/dist/transform-C-0nV5Et.mjs +28 -0
- package/dist/{transform-CWGJB8N_.mjs → transform-DKPtUV54.mjs} +2 -2
- package/dist/transform-job-B9MPk7S5.mjs +22 -0
- package/dist/{transform-job-ClX8e5iO.mjs → transform-job-CDIb3B9o.mjs} +6 -1
- package/dist/{transform-job-BBZ5L46v.mjs → transform-job-D18XRLBK.mjs} +1 -1
- package/dist/{transform-tag-dKCqQPTd.mjs → transform-tag-DQXOPhmt.mjs} +5 -5
- package/dist/transform-test-wmAjyaka.mjs +16 -0
- package/dist/{transforms-DRAws1f4.mjs → transforms-DcXL4Dox.mjs} +6 -6
- package/dist/{transport-Ck4anhoc.mjs → transport-DZSxmmtY.mjs} +5 -4
- package/dist/{tree-Ddsj298M.mjs → tree-DrYYCdXP.mjs} +4 -3
- package/dist/typed-schema-DEzmTY3J.mjs +45 -0
- package/dist/{unpublish-BMfjQ8UV.mjs → unpublish-D8hmulCx.mjs} +3 -3
- package/dist/{unreferenced-DRQrvH5r.mjs → unreferenced-C3CqO3tu.mjs} +6 -6
- package/dist/{update-C1VwtJWu.mjs → update-3lRE8G9k.mjs} +10 -11
- package/dist/{update-BCC1Igr2.mjs → update-4TDRNrV-.mjs} +7 -8
- package/dist/{update-0AoF6QJ_.mjs → update-4sOfpwpv.mjs} +5 -6
- package/dist/{update-BQLTaw3z.mjs → update-552UGPAG.mjs} +7 -8
- package/dist/{update-DpP1EEC0.mjs → update-7iXRB23T2.mjs} +7 -8
- package/dist/{update-Bpsdi6kM.mjs → update-B21GAnzT.mjs} +7 -8
- package/dist/{update-6sfqiInZ.mjs → update-BVz0oIwS.mjs} +10 -11
- package/dist/{update-CGpiLu7N.mjs → update-BxRFktpB.mjs} +8 -9
- package/dist/{update-CnxzmPRG.mjs → update-CEDMvgJI.mjs} +11 -12
- package/dist/{update-BIL0JPqm.mjs → update-CcNYCalv.mjs} +5 -6
- package/dist/{update-DlFHoUxe.mjs → update-CctMr2T1.mjs} +8 -8
- package/dist/{update-DrT10fxQ.mjs → update-Ch6AAOeh.mjs} +5 -6
- package/dist/{update-_hHnM1Hx.mjs → update-CtuLA42g.mjs} +11 -11
- package/dist/{update-C19B1Sry.mjs → update-DVD77mVR.mjs} +5 -6
- package/dist/{update-C1x90FSH.mjs → update-DmMHHn75.mjs} +10 -11
- package/dist/{update-D1aKeWfo.mjs → update-DvGIaZdl.mjs} +5 -6
- package/dist/{update-BtfUX9CN.mjs → update-LlJM4tUd.mjs} +10 -11
- package/dist/{update-8eXJso_l.mjs → update-Zv7PP8nl.mjs} +7 -8
- package/dist/{update-dashcard-CDI0Tnxy.mjs → update-dashcard-BijqiYQd.mjs} +7 -8
- package/dist/{update-pXVhyiFo.mjs → update-l4WRN6Jh.mjs} +7 -8
- package/dist/update-sma1ZRm2.mjs +36 -0
- package/dist/{upgrade-Cfouv1Ii.mjs → upgrade-TzILOkiM.mjs} +5 -4
- package/dist/upload-B37bUVl_.mjs +13 -0
- package/dist/{upload-DnLXgUA-.mjs → upload-CdiDKe69.mjs} +2 -2
- package/dist/{upload-DIEcI5iM.mjs → upload-Do-kOGtc.mjs} +3 -3
- package/dist/{uuid-D0sH5txV.mjs → uuid-Dqq2WfAT.mjs} +3 -2
- package/dist/{validate-BQ7vI8_x.mjs → validate-moGYlHxB.mjs} +8 -18
- package/dist/validate-query-Bf5FhhMI.mjs +72 -0
- package/dist/{values-BFPO6y5o.mjs → values-CtY5zv0m.mjs} +5 -5
- package/dist/{verify-C-StvB4f.mjs → verify-BiB8jzXB.mjs} +3 -3
- package/dist/{verify-CuGs0X3C.mjs → verify-DBTlWx-S.mjs} +3 -3
- package/dist/{verify-7fW020r_.mjs → verify-DJ7fGyLL.mjs} +4 -3
- package/dist/{wait-Cvt8xO0h.mjs → wait-DEYagfq4.mjs} +5 -5
- package/dist/{wait-flags-BnZ-dfE2.mjs → wait-flags-C3cu_O0w.mjs} +2 -2
- package/dist/{window-CfK_j6m1.mjs → window-D1w7B0vh.mjs} +1 -1
- package/package.json +2 -2
- package/skill-data/core/SKILL.md +14 -13
- package/skill-data/data-action/SKILL.md +1 -1
- package/skill-data/data-app/SKILL.md +138 -0
- package/skill-data/data-app/template/.env.local.example +2 -0
- package/skill-data/data-app/template/LICENSE +21 -0
- package/skill-data/data-app/template/README.md +29 -0
- package/skill-data/data-app/template/gitignore +5 -0
- package/skill-data/data-app/template/package.json +25 -0
- package/skill-data/data-app/template/src/App.tsx +9 -0
- package/skill-data/data-app/template/src/index.tsx +14 -0
- package/skill-data/data-app/template/src/theme.ts +25 -0
- package/skill-data/data-app/template/tsconfig.json +25 -0
- package/skill-data/data-app/template/vite.config.ts +3 -0
- package/skill-data/data-app-actions/SKILL.md +96 -0
- package/skill-data/data-app-data/SKILL.md +158 -0
- package/skill-data/data-app-filters/SKILL.md +87 -0
- package/skill-data/data-app-ui/SKILL.md +120 -0
- package/skill-data/mbql/SKILL.md +3 -3
- package/skill-data/native-sql/SKILL.md +1 -1
- package/skill-data/native-sql/references/template-tags.md +1 -1
- package/dist/body-C0VnEiRV.mjs +0 -16
- package/dist/card-BnL92zoT.mjs +0 -25
- package/dist/collection-DRHGwFSL.mjs +0 -21
- package/dist/dashboard-Bq1pae4N.mjs +0 -35
- package/dist/data-action-BZ2PvlaP.mjs +0 -24
- package/dist/delete-runtime-DRGveT8H.mjs +0 -55
- package/dist/dependency-6kfpR8Ga.mjs +0 -15
- package/dist/document-C0mZEg5w.mjs +0 -20
- package/dist/field-BUkyWiWk.mjs +0 -21
- package/dist/git-sync-CNTB5jvI.mjs +0 -29
- package/dist/glossary-B9Eo4hXc.mjs +0 -14
- package/dist/snippet-CpZ5cJ_y.mjs +0 -19
- package/dist/table-Cb_Uvw8m.mjs +0 -26
- package/dist/timeline-x0s_3sfc.mjs +0 -21
- package/dist/transform-job-Dlx2c6II.mjs +0 -22
- package/dist/transform-kP11Mv9_.mjs +0 -28
- package/dist/transform-test-jFuzVhlT.mjs +0 -16
- package/dist/upload-Cqv-In6j.mjs +0 -13
- package/dist/validate-query-YtH3d5BP.mjs +0 -38
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as escapeJsonPointerSegment, o as ConfigError, r as isPlainObject } from "./predicates-0C0TsWcJ.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
4
4
|
import addFormats from "ajv-formats";
|
|
@@ -1012,8 +1012,11 @@ var query_default = {
|
|
|
1012
1012
|
"lib/type": { "const": "mbql.stage/native" },
|
|
1013
1013
|
"native": { "type": "string" },
|
|
1014
1014
|
"template-tags": {
|
|
1015
|
-
"
|
|
1016
|
-
"
|
|
1015
|
+
"description": "Template tag definitions. The current format is a list of template tags (order-preserving). The legacy map format (tag name -> tag) is also accepted.\n",
|
|
1016
|
+
"type": ["array", "object"],
|
|
1017
|
+
"if": { "type": "array" },
|
|
1018
|
+
"then": { "items": { "$ref": "#/$defs/template_tag" } },
|
|
1019
|
+
"else": { "additionalProperties": { "$ref": "#/$defs/template_tag" } }
|
|
1017
1020
|
}
|
|
1018
1021
|
}
|
|
1019
1022
|
},
|
|
@@ -1350,23 +1353,10 @@ const refSchemaWithIds = {
|
|
|
1350
1353
|
}
|
|
1351
1354
|
};
|
|
1352
1355
|
const templateTag = query_default.$defs.template_tag;
|
|
1353
|
-
const nativeStage = query_default.$defs.native_stage;
|
|
1354
|
-
const TEMPLATE_TAG_REF = { $ref: "#/$defs/template_tag" };
|
|
1355
1356
|
const querySchemaForApi = {
|
|
1356
1357
|
...query_default,
|
|
1357
1358
|
$defs: {
|
|
1358
1359
|
...query_default.$defs,
|
|
1359
|
-
native_stage: {
|
|
1360
|
-
...nativeStage,
|
|
1361
|
-
properties: {
|
|
1362
|
-
...nativeStage.properties,
|
|
1363
|
-
"template-tags": {
|
|
1364
|
-
type: ["object", "array"],
|
|
1365
|
-
additionalProperties: TEMPLATE_TAG_REF,
|
|
1366
|
-
items: TEMPLATE_TAG_REF
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
},
|
|
1370
1360
|
template_tag: {
|
|
1371
1361
|
...templateTag,
|
|
1372
1362
|
properties: {
|
|
@@ -1491,7 +1481,7 @@ function assertNotLegacyEnvelopeWrappingMbql5(value, options) {
|
|
|
1491
1481
|
if (!isLegacyEnvelopeWrappingMbql5(value)) return;
|
|
1492
1482
|
throw new ConfigError(`${options.contextLabel}: ${options.bodyNoun} is the query itself: {"lib/type": "mbql/query", "database": N, "stages": […]}.`);
|
|
1493
1483
|
}
|
|
1494
|
-
z.object({
|
|
1484
|
+
const QuerySchemaBundle = z.object({
|
|
1495
1485
|
schema: z.unknown(),
|
|
1496
1486
|
defs: z.object({
|
|
1497
1487
|
"id.yaml": z.unknown(),
|
|
@@ -1512,4 +1502,4 @@ function getQuerySchemaBundle() {
|
|
|
1512
1502
|
};
|
|
1513
1503
|
}
|
|
1514
1504
|
//#endregion
|
|
1515
|
-
export {
|
|
1505
|
+
export { isMbql5Query as a, getQuerySchemaBundle as i, ValidationOutcome as n, validateQuery as o, assertNotLegacyEnvelopeWrappingMbql5 as r, QuerySchemaBundle as t };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { o as ConfigError, r as isPlainObject } from "./predicates-0C0TsWcJ.mjs";
|
|
2
|
+
import { f as writeJson } from "./cli.mjs";
|
|
3
|
+
import { a as isMbql5Query, i as getQuerySchemaBundle, o as validateQuery, r as assertNotLegacyEnvelopeWrappingMbql5 } from "./validate-moGYlHxB.mjs";
|
|
4
|
+
//#region src/commands/validate-query.ts
|
|
5
|
+
const skipValidateFlag = { "skip-validate": {
|
|
6
|
+
type: "boolean",
|
|
7
|
+
description: "Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts."
|
|
8
|
+
} };
|
|
9
|
+
const QUERY_DOCUMENTS = {
|
|
10
|
+
title: "MBQL 5 query",
|
|
11
|
+
command: ["query"],
|
|
12
|
+
bundle: getQuerySchemaBundle()
|
|
13
|
+
};
|
|
14
|
+
function hasQuerySource(body) {
|
|
15
|
+
return valueAt(body, ["source", "type"]) === "query";
|
|
16
|
+
}
|
|
17
|
+
const CARD_DATASET_QUERY = {
|
|
18
|
+
resource: "card",
|
|
19
|
+
path: ["dataset_query"],
|
|
20
|
+
when: null,
|
|
21
|
+
documents: QUERY_DOCUMENTS
|
|
22
|
+
};
|
|
23
|
+
const DATA_ACTION_DATASET_QUERY = {
|
|
24
|
+
resource: "dataAction",
|
|
25
|
+
path: ["dataset_query"],
|
|
26
|
+
when: null,
|
|
27
|
+
documents: QUERY_DOCUMENTS
|
|
28
|
+
};
|
|
29
|
+
const TRANSFORM_SOURCE_QUERY = {
|
|
30
|
+
resource: "transform",
|
|
31
|
+
path: ["source", "query"],
|
|
32
|
+
when: hasQuerySource,
|
|
33
|
+
documents: QUERY_DOCUMENTS
|
|
34
|
+
};
|
|
35
|
+
const MEASURE_DEFINITION = {
|
|
36
|
+
resource: "measure",
|
|
37
|
+
path: ["definition"],
|
|
38
|
+
when: null,
|
|
39
|
+
documents: QUERY_DOCUMENTS
|
|
40
|
+
};
|
|
41
|
+
const SEGMENT_DEFINITION = {
|
|
42
|
+
resource: "segment",
|
|
43
|
+
path: ["definition"],
|
|
44
|
+
when: null,
|
|
45
|
+
documents: QUERY_DOCUMENTS
|
|
46
|
+
};
|
|
47
|
+
function preflightEmbeddedQuery(body, embedded, options) {
|
|
48
|
+
const holdsNoQuery = embedded.when !== null && !embedded.when(body);
|
|
49
|
+
if (options.skip || holdsNoQuery) return;
|
|
50
|
+
const query = valueAt(body, embedded.path);
|
|
51
|
+
const bodyNoun = embedded.path.join(".");
|
|
52
|
+
const contextLabel = `${embedded.resource}.${bodyNoun} validation failed`;
|
|
53
|
+
assertNotLegacyEnvelopeWrappingMbql5(query, {
|
|
54
|
+
contextLabel,
|
|
55
|
+
bodyNoun
|
|
56
|
+
});
|
|
57
|
+
if (!isMbql5Query(query)) return;
|
|
58
|
+
const outcome = validateQuery(query);
|
|
59
|
+
if (outcome.ok) return;
|
|
60
|
+
writeJson(outcome);
|
|
61
|
+
throw new ConfigError(`${contextLabel}: ${outcome.errors.length} error(s) — fix them, or pass --skip-validate to send anyway`);
|
|
62
|
+
}
|
|
63
|
+
function valueAt(body, path) {
|
|
64
|
+
let value = body;
|
|
65
|
+
for (const key of path) {
|
|
66
|
+
if (!isPlainObject(value)) return;
|
|
67
|
+
value = value[key];
|
|
68
|
+
}
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { CARD_DATASET_QUERY, DATA_ACTION_DATASET_QUERY, MEASURE_DEFINITION, QUERY_DOCUMENTS, SEGMENT_DEFINITION, TRANSFORM_SOURCE_QUERY, preflightEmbeddedQuery, skipValidateFlag };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as parseId } from "./parse-id-
|
|
3
|
-
import { t as defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import {
|
|
5
|
-
import { s as fieldValuesView } from "./field-
|
|
1
|
+
import { h as formatScalar, it as connectionFlags, l as renderSummary, lt as outputFlags, ut as profileFlag } from "./cli.mjs";
|
|
2
|
+
import { t as parseId } from "./parse-id-EXZan40V.mjs";
|
|
3
|
+
import { t as defineMetabaseCommand } from "./runtime-iIsqiOwO.mjs";
|
|
4
|
+
import { d as FieldValues } from "./field-C2qOViFZ.mjs";
|
|
5
|
+
import { s as fieldValuesView } from "./field-CT4r6b92.mjs";
|
|
6
6
|
//#region src/commands/field/values.ts
|
|
7
7
|
var values_default = defineMetabaseCommand({
|
|
8
8
|
meta: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as parseId } from "./parse-id-
|
|
3
|
-
import { t as defineMetabaseCommand } from "./runtime-
|
|
1
|
+
import { it as connectionFlags, l as renderSummary, lt as outputFlags, ut as profileFlag } from "./cli.mjs";
|
|
2
|
+
import { t as parseId } from "./parse-id-EXZan40V.mjs";
|
|
3
|
+
import { t as defineMetabaseCommand } from "./runtime-iIsqiOwO.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/card/verify.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as parseId } from "./parse-id-
|
|
3
|
-
import { t as defineMetabaseCommand } from "./runtime-
|
|
1
|
+
import { it as connectionFlags, l as renderSummary, lt as outputFlags, ut as profileFlag } from "./cli.mjs";
|
|
2
|
+
import { t as parseId } from "./parse-id-EXZan40V.mjs";
|
|
3
|
+
import { t as defineMetabaseCommand } from "./runtime-iIsqiOwO.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,6 +1,7 @@
|
|
|
1
|
-
import { n as createClient } from "./client-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { n as createClient } from "./client-DvWllzKd.mjs";
|
|
2
|
+
import { g as errorMessage, l as MetabaseError, p as TimeoutError, u as NetworkError } from "./predicates-0C0TsWcJ.mjs";
|
|
3
|
+
import { K as HttpError } from "./cli.mjs";
|
|
4
|
+
import { B as probeServer, E as USER_AGENT } from "./runtime-iIsqiOwO.mjs";
|
|
4
5
|
//#region src/core/auth/verify.ts
|
|
5
6
|
const VERIFY_TIMEOUT_MS = 15e3;
|
|
6
7
|
async function verifyAndProbe(url, credential, options = {}) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as defineMetabaseCommand } from "./runtime-
|
|
3
|
-
import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-
|
|
4
|
-
import { r as parseWaitSchedule } from "./wait-flags-
|
|
1
|
+
import { it as connectionFlags, l as renderSummary, lt as outputFlags, ut as profileFlag } from "./cli.mjs";
|
|
2
|
+
import { t as defineMetabaseCommand } from "./runtime-iIsqiOwO.mjs";
|
|
3
|
+
import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-vxN__4cz.mjs";
|
|
4
|
+
import { r as parseWaitSchedule } from "./wait-flags-C3cu_O0w.mjs";
|
|
5
5
|
import { u as syncTaskView } from "./git-sync-D1aKczo6.mjs";
|
|
6
|
-
import { a as throwIfFailedTask, i as taskPollOptions, n as formatSyncTask, r as syncTaskIdleView, t as SyncTaskOrIdle } from "./sync-task-
|
|
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
|
|
8
8
|
const WaitResult = SyncTaskOrIdle;
|
|
9
9
|
var wait_default = defineMetabaseCommand({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as interruptSignal } from "./cli.mjs";
|
|
2
|
-
import { t as parseId } from "./parse-id-
|
|
3
|
-
import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-
|
|
2
|
+
import { t as parseId } from "./parse-id-EXZan40V.mjs";
|
|
3
|
+
import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-vxN__4cz.mjs";
|
|
4
4
|
//#region src/commands/wait-flags.ts
|
|
5
5
|
const waitScheduleFlags = {
|
|
6
6
|
timeout: {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metabase/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Metabase CLI",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/metabase/
|
|
8
|
+
"url": "git+https://github.com/metabase/metabase-cli.git",
|
|
9
9
|
"directory": "packages/cli"
|
|
10
10
|
},
|
|
11
11
|
"bin": {
|
package/skill-data/core/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: core
|
|
3
|
-
description: Foundations for driving Metabase from the terminal with the `mb` CLI — authentication and named profiles, the flag/output/`--json` conventions every command shares, JSON body input, command discovery via `--help`
|
|
3
|
+
description: Foundations for driving Metabase from the terminal with the `mb` CLI — authentication and named profiles, the flag/output/`--json` conventions every command shares, JSON body input, command discovery via `--help` and `mb schema`, and the per-resource footguns (db, table, field, upload, content translation, card, dashboard, collection, segment, measure, timeline, alert, subscription, library, setting, search, eid). Load first for any `mb` task; it routes to the specialized skills for deeper work.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -13,10 +13,10 @@ 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 | setup | eid | uuid | upgrade | skills
|
|
16
|
+
search | dependency | git-sync | data-action | data-app | setup | eid | uuid | upgrade | skills | schema
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
The conventions below — auth, flags, output, body input — hold across **every** group.
|
|
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.
|
|
20
20
|
|
|
21
21
|
## Auth & profiles
|
|
22
22
|
|
|
@@ -28,13 +28,13 @@ mb auth status --json # → {profile, present, url} for the d
|
|
|
28
28
|
mb auth status --profile <name> --json # health probe for one profile
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
`auth list`
|
|
31
|
+
`auth list` returns every profile in one call, with sanitized URL, an `authenticated` flag, and a probe `status` (`ok` / `auth-failed` / `network-error` / `server-error` / `not-probed`). Use it before asking which profile to pick.
|
|
32
32
|
|
|
33
33
|
- One profile and intent doesn't disambiguate → use it.
|
|
34
34
|
- Several → ask via `AskUserQuestion`, presenting the names from `auth list`.
|
|
35
35
|
- Empty `data: []` → ask the user to run `mb auth login` themselves and tell you the profile name.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Profile names are arbitrary local labels (`prod`, `staging`).
|
|
38
38
|
|
|
39
39
|
## Flag conventions
|
|
40
40
|
|
|
@@ -46,7 +46,7 @@ Once a name is established, pass `--profile <name>` to **every** subsequent comm
|
|
|
46
46
|
❌ mb table --profile prod list # → unknown command: prod
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
**`--wait` for async operations.** `transform run`, `git-sync import`, and similar verbs return immediately
|
|
49
|
+
**`--wait` for async operations.** `transform run`, `git-sync import`, and similar verbs return immediately; pass `--wait` whenever the next step depends on completion — without it you race the operation and see "not ready" / transient connection refusals.
|
|
50
50
|
|
|
51
51
|
**Some "lookup" verbs return JSON envelopes, not bare values.** `mb setting get <key>` returns `{"key": "...", "value": ...}`. Extract before reusing:
|
|
52
52
|
|
|
@@ -94,7 +94,7 @@ Verbs that take a payload accept it from one of four sources, **first non-empty
|
|
|
94
94
|
3. stdin (auto-detected when piped; `--file -` names it explicitly)
|
|
95
95
|
4. positional argument
|
|
96
96
|
|
|
97
|
-
Exactly one
|
|
97
|
+
Exactly one; more than one of `--body` / `--file` / a positional argument is a `ConfigError`.
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
100
|
cat > ./.scratch/body.json <<'EOF'
|
|
@@ -105,7 +105,7 @@ mb <noun> create --file ./.scratch/body.json --profile <n> --json
|
|
|
105
105
|
|
|
106
106
|
Single-quoted `'EOF'` stops the shell interpolating `$vars` inside the JSON.
|
|
107
107
|
|
|
108
|
-
Write working files to **`./.scratch`** in the current directory (`mkdir -p ./.scratch` first), never `/tmp
|
|
108
|
+
Write working files to **`./.scratch`** in the current directory (`mkdir -p ./.scratch` first), never `/tmp`: better permissions, kept for the session, reviewable by the user.
|
|
109
109
|
|
|
110
110
|
## Discovering commands and schemas
|
|
111
111
|
|
|
@@ -113,12 +113,13 @@ Cheapest source that answers the question wins:
|
|
|
113
113
|
|
|
114
114
|
- What groups/verbs exist? → `mb --help`, then `mb <group> --help`. Add `--json` for a machine-readable `{command, description}` index (`mb --help --json` lists every command).
|
|
115
115
|
- What flags does a command take? → `mb <command> --help` — flags with enums and defaults, examples, ~1 KB.
|
|
116
|
-
-
|
|
116
|
+
- Body shape before authoring, output before parsing? → `mb schema <command>`: the body's JSON Schema, a feature a field needs in its `description`; `--output` for output.
|
|
117
|
+
- Flags, arg types, needed features? → `mb <command> --help --json`.
|
|
117
118
|
|
|
118
119
|
```bash
|
|
119
120
|
mb card query --help # flags, enums, defaults, examples
|
|
120
|
-
mb card
|
|
121
|
-
mb card
|
|
121
|
+
mb schema card create # body schema before authoring
|
|
122
|
+
mb schema card list --output # output schema before parsing
|
|
122
123
|
mb transform --help --json | jq -r '.commands[].command' # verbs under "transform"
|
|
123
124
|
```
|
|
124
125
|
|
|
@@ -152,7 +153,7 @@ What `--help` doesn't say: footguns and non-obvious behaviors.
|
|
|
152
153
|
<!-- requires: transforms -->
|
|
153
154
|
- **transform.** Iterate with `transform update <id>`, never `delete` + `create` (keeps the row, `entity_id`, materialized table, and YAML filename — avoids `_2` suffixes and noisy git history). `transform run` needs `--wait` (or `--sync`, which also waits for the output table to register and returns `target_table_id`) or you get only `{run_id, final:null}`. (→ `transform`.)
|
|
154
155
|
<!-- /requires -->
|
|
155
|
-
- **setup is one-shot.** `mb setup` walks `/api/setup` for a **fresh** instance only
|
|
156
|
+
- **setup is one-shot.** `mb setup` walks `/api/setup` for a **fresh** instance only and errors on a configured one; mostly for bootstrapping local / e2e instances.
|
|
156
157
|
- **eid** translates a string entity id → numeric id: `mb eid --model <model> <eid1,eid2> --json`. Entity ids are NanoIDs that can start with `-`, which the positional form misreads as a flag (shell quotes don't help) — for those, use `--body '{"entity_ids":{"card":["-…"]}}'` (the id is a JSON string value, immune to flag parsing).
|
|
157
158
|
<!-- requires: library -->
|
|
158
159
|
- **library.** The Library is a curated subtree (`library-data` "Data" + `library-metrics` "Metrics" under a `library` root): tables in **Data** lead data pickers and rank up in search; metrics in **Metrics** lead nav, search, and the query builder. `library get` shows its Data/Metrics collection ids; `library create` provisions it (idempotent). `library publish --table-ids/--db-ids/--schemas` publishes tables into Data, **resolving the Data collection and creating the Library if absent**; each `--schemas` entry is `<db-id>:<schema>` (`1:public`), not a bare name. `publish` cascades to upstream FK dependencies, `unpublish` to downstream dependents; both need **admin or data-analyst** (Curate alone won't publish) and exit **403** without write **and** query permission on every affected table. `table get`/`table list` carry `is_published` (`collection_id` under `--full`). Publishing leaves the Data collection out of git-sync scope: on a remote-sync instance, `mb git-sync add-collection <data-collection-id>` makes exports carry published tables' metadata (see `git-sync`).
|
|
@@ -164,7 +165,7 @@ What `--help` doesn't say: footguns and non-obvious behaviors.
|
|
|
164
165
|
|
|
165
166
|
## Specialized skills (load on demand)
|
|
166
167
|
|
|
167
|
-
This file is enough for any single-command task. For anything deeper, load the relevant skill **proactively** — don't wing an MBQL body, a transform body, or the git-sync workflow from this overview.
|
|
168
|
+
This file is enough for any single-command task. For anything deeper, load the relevant skill **proactively** with `mb skills get <name>` — don't wing an MBQL body, a transform body, or the git-sync workflow from this overview.
|
|
168
169
|
|
|
169
170
|
- **`mbql`** — authoring/fixing any MBQL query body (`mb query`, card `dataset_query`, transform `source.query`, measure/segment `definition`); reading `--dry-run` errors. The query-body reference.
|
|
170
171
|
- **`native-sql`** — authoring a native SQL `dataset_query` with parameters: template tags, field filters vs. raw variables, snippets, card references, and wiring a tag to a dashboard filter. The SQL fallback when MBQL can't express it (`mbql` first).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: data-action
|
|
3
|
-
description: Author and run Metabase data actions with the `mb` CLI — saved, parameterized native SQL writes (INSERT, UPDATE, DELETE) filed in a collection and run with values. Covers enabling them on a database, the collection they go in, the body, mapping template tags to parameters, running, and the lifecycle. Triggers — "add a data action", "let users update a row", "a button that inserts a record", "run a write query", "a form that saves to the database", "delete rows from Metabase".
|
|
3
|
+
description: Author and run Metabase data actions with the `mb` CLI — saved, parameterized native SQL writes (INSERT, UPDATE, DELETE) filed in a collection and run with values. Covers enabling them on a database, the collection they go in, the body, mapping template tags to parameters, running, and the lifecycle. Triggers — "add a data action", "let users update a row", "a button that inserts a record", "run a write query", "a form that saves to the database", "delete rows from Metabase". Inside a data app, start with `data-app-actions`.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
requires: [dataActionsWithoutModel]
|
|
6
6
|
---
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
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 on or 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
|
+
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
|
+
requires: [dataApps]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Data apps
|
|
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`.
|
|
11
|
+
|
|
12
|
+
The work, in order:
|
|
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_).
|
|
19
|
+
|
|
20
|
+
For every later change: regenerate `src/metabase.ts` if the app's collection changed, then build and set the bundle. Metabase receives only the built bundle; the source stays in the project directory, under git if the user keeps one.
|
|
21
|
+
|
|
22
|
+
## Before you start
|
|
23
|
+
|
|
24
|
+
- Use an **admin** profile — only admins create apps and write the app's collection. `mb auth status --json | jq .user.isAdmin` prints `true` for one; 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.
|
|
27
|
+
|
|
28
|
+
## Create the app
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
mb data-app create --body '{"name":"sales-overview","display_name":"Sales overview"}' --json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`name` is the slug; `display_name` and `description` are optional. The app starts disabled, with an empty bundle. 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.
|
|
35
|
+
|
|
36
|
+
## Scaffold and install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
mb data-app scaffold sales-overview && cd sales-overview
|
|
40
|
+
```
|
|
41
|
+
|
|
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. Then install the SDK, then the rest:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install @metabase/embedding-sdk-react@<major>-beta # <major>: 66 for a version tag v1.66.x (`mb auth status --json | jq -r .version.tag`)
|
|
46
|
+
npm install && npm run typecheck && npm run build
|
|
47
|
+
```
|
|
48
|
+
|
|
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".
|
|
50
|
+
|
|
51
|
+
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
|
+
|
|
53
|
+
**An existing project.** Before changing an app you didn't scaffold in this session, check both: `vite.config.ts` is `export default dataAppConfig()` from `@metabase/embedding-sdk-react/data-app-dev/config`, with no local `config/` directory; and `src/index.tsx` default-exports a `DataAppFactory` that takes no arguments and returns `{ component, providerProps? }`. If either 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.
|
|
54
|
+
|
|
55
|
+
## Dev preview
|
|
56
|
+
|
|
57
|
+
`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:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
( umask 077
|
|
61
|
+
URL=$(mb auth status --json | jq -r .url)
|
|
62
|
+
KEY=$(mb api-key create --body '{"name":"data-app <slug> dev","group_id":2}' --json | jq -r .unmasked_key)
|
|
63
|
+
[ -n "$KEY" ] && [ "$KEY" != null ] && printf 'DATA_APP_MB_URL=%s\nDATA_APP_MB_API_KEY=%s\n' "$URL" "$KEY" > .env.local && echo written )
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Group `2` is Administrators. Never print `.env.local`. Delete the key at handoff (`mb api-key list`, then `mb api-key delete <id> --yes`); the next session writes a new one. A CORS error means the instance doesn't allow the preview's origin: ask the user to add `http://localhost:5174` under Admin → Embedding → Embedded analytics SDK → CORS.
|
|
67
|
+
|
|
68
|
+
### The diagnostics feed
|
|
69
|
+
|
|
70
|
+
Sandbox blocks, failed queries and uncaught errors never reach the terminal. With a preview tab open, read them from the feed:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
curl -s "http://localhost:5174/__data-app/diagnostics?startEventId=0"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```jsonc
|
|
77
|
+
{
|
|
78
|
+
"entries": [
|
|
79
|
+
{
|
|
80
|
+
"eventId": 31,
|
|
81
|
+
"kind": "blocked-network",
|
|
82
|
+
"alert": true,
|
|
83
|
+
"summary": "Blocked fetch to api.example.com (not in allowed_hosts)",
|
|
84
|
+
"detail": null,
|
|
85
|
+
"hint": "…",
|
|
86
|
+
"buildId": 7,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
"clients": 1, // open preview tabs; 0 means nothing ran
|
|
90
|
+
"buildId": 7, // the bundle running now
|
|
91
|
+
"staleEntries": 164, // withheld: reported by a build already replaced
|
|
92
|
+
"nextEventId": 32, // pass back as ?startEventId=
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- `clients: 0` means no tab is open, so empty `entries` prove nothing.
|
|
97
|
+
- Before an edit, note `nextEventId`; after it, read again with that value as `startEventId`.
|
|
98
|
+
- 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.
|
|
99
|
+
- 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`. The feed keeps the last 200 entries; `curl -X DELETE …/__data-app/diagnostics` clears it.
|
|
100
|
+
|
|
101
|
+
| `kind` | Fix |
|
|
102
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
103
|
+
| `blocked-network`, `csp-violation` | An external API: `data-app-ui`, _External APIs_. A `script-src` or `style-src` violation: bundle the asset instead. |
|
|
104
|
+
| `blocked-api` | Blocked in Metabase too: use the replacement in `data-app-ui`. |
|
|
105
|
+
| `sdk-call` with `alert: true` | A Metabase request failed; `summary` names it. |
|
|
106
|
+
| `error` | A bug; `detail` has the stack. |
|
|
107
|
+
|
|
108
|
+
## Build and publish
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm run typecheck && npm run build
|
|
112
|
+
mb data-app set-bundle sales-overview
|
|
113
|
+
mb data-app set-enabled sales-overview true # the first time
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`set-bundle` uploads `dist/index.js` (`--bundle` for another path) and replaces the app's bundle, live at once. A new app is disabled until `set-enabled` turns it on. Give the user `<metabase-url>/apps/<slug>`.
|
|
117
|
+
|
|
118
|
+
Admins open every app, enabled or not. Anyone else needs the app enabled (otherwise "not found") and one of their groups assigned to it (otherwise "You don't have access"), which only the user can do (Admin → Settings → Data apps → the app → Groups). A group reaches the app's collection and nothing more, so a viewer also needs data access to the tables its questions read.
|
|
119
|
+
|
|
120
|
+
## Pitfalls
|
|
121
|
+
|
|
122
|
+
| Symptom | Fix |
|
|
123
|
+
| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
124
|
+
| `set-bundle`: bundle not found | Run `npm run build` in the project directory first. |
|
|
125
|
+
| 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. |
|
|
126
|
+
| "Failed to fetch the user, the session might be invalid." | A bad key in `.env.local`, or CORS (_Dev preview_). |
|
|
127
|
+
| A bundle of several MB | `vite.config.ts` no longer uses `dataAppConfig()`, or the SDK isn't the `<major>-beta` tag. |
|
|
128
|
+
| "Invalid hook call" | A second React got bundled: nothing may add another `react` or `react-dom`. |
|
|
129
|
+
| Drill-through popups don't open | The app renders its own `<MetabaseProvider>`: remove it. |
|
|
130
|
+
| A rebuilt or reinstalled SDK still behaves like the old one | Vite caches it: stop `npm run dev`, delete `node_modules/.vite`, start again. |
|
|
131
|
+
| 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. |
|
|
132
|
+
|
|
133
|
+
## Change, move, delete
|
|
134
|
+
|
|
135
|
+
- **Turn off:** `mb data-app set-enabled <slug> false`. **Rename:** `mb data-app update <slug> --body '{"display_name":"…"}'` (also `description`, `allowed_hosts`).
|
|
136
|
+
- **Outdated:** an app Metabase lists as _Outdated_ targets an older data-app contract: it won't open for anyone, and only admins see it listed, until it's migrated. Tell the user; don't change its code ad hoc.
|
|
137
|
+
- **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` and bundle work there. On a read-only instance the app's collection can't be edited: change it where it was built and export again.
|
|
138
|
+
- **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.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Metabase
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Data app
|
|
2
|
+
|
|
3
|
+
A Metabase data app: a single-bundle React app, built with the Embedding SDK,
|
|
4
|
+
that Metabase serves at `/apps/<slug>`. Build and change it with a coding agent
|
|
5
|
+
and the `mb` data-app skills.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Install the SDK tag matching the Metabase instance first, then the rest.
|
|
10
|
+
`<major>` is 66 for a version tag v1.66.x (`mb auth status --json | jq -r .version.tag`);
|
|
11
|
+
`package.json` asks for any version, which would install `latest`.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @metabase/embedding-sdk-react@<major>-beta
|
|
15
|
+
npm install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Commands
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm run dev # preview at http://localhost:5174, in the sandbox Metabase runs apps in
|
|
22
|
+
npm run typecheck # type-checks src/ and vite.config.ts
|
|
23
|
+
npm run build # builds dist/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 dist/index.js the app's bundle
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`npm run dev` reads `DATA_APP_MB_URL` and `DATA_APP_MB_API_KEY` from
|
|
29
|
+
`.env.local`; `.env.local.example` lists them.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "data-app-template",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"typecheck": "tsc --noEmit"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@metabase/embedding-sdk-react": "*",
|
|
13
|
+
"react": "^18.3.1",
|
|
14
|
+
"react-dom": "^18.3.1"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/react": "^18.3.12",
|
|
18
|
+
"@types/react-dom": "^18.3.1",
|
|
19
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
20
|
+
"typescript": "^6.0.3",
|
|
21
|
+
"vite": "^8.0.16",
|
|
22
|
+
"vite-plugin-css-injected-by-js": "^3.5.2",
|
|
23
|
+
"vite-plugin-svgr": "^5.2.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DataAppFactory } from "@metabase/embedding-sdk-react/data-app";
|
|
2
|
+
|
|
3
|
+
import App from "./App";
|
|
4
|
+
import { sdkTheme } from "./theme";
|
|
5
|
+
|
|
6
|
+
// The data app's entry point. Return the root component plus any `providerProps`
|
|
7
|
+
// the host should apply to `MetabaseProvider` (e.g. `theme`,
|
|
8
|
+
// `allowedCustomVisualizations`).
|
|
9
|
+
const factory: DataAppFactory = () => ({
|
|
10
|
+
component: App,
|
|
11
|
+
providerProps: { theme: sdkTheme },
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export default factory;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MetabaseTheme } from "@metabase/embedding-sdk-react";
|
|
2
|
+
|
|
3
|
+
export const sdkTheme: MetabaseTheme = {
|
|
4
|
+
colors: {
|
|
5
|
+
brand: "#4D96FF",
|
|
6
|
+
"brand-hover": "#EAF4FF",
|
|
7
|
+
positive: "#4D96FF",
|
|
8
|
+
charts: [
|
|
9
|
+
"#4D96FF",
|
|
10
|
+
"#E8743B",
|
|
11
|
+
"#2BA672",
|
|
12
|
+
"#9461D9",
|
|
13
|
+
"#E0475B",
|
|
14
|
+
"#1C9FB8",
|
|
15
|
+
"#C99A1E",
|
|
16
|
+
"#5468D4",
|
|
17
|
+
],
|
|
18
|
+
background: "white",
|
|
19
|
+
"background-secondary": "white",
|
|
20
|
+
"text-primary": "#1f2937",
|
|
21
|
+
"text-secondary": "#4b5563",
|
|
22
|
+
"text-tertiary": "#6b7280",
|
|
23
|
+
},
|
|
24
|
+
fontFamily: "system-ui, -apple-system, Segoe UI, sans-serif",
|
|
25
|
+
};
|