@metabase/cli 0.1.8-alpha.drop-workspaces.75fe1d5 → 0.1.9
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 +24 -12
- package/dist/{add-collection-CLLtJ4hp.mjs → add-collection-CoP-6FZR.mjs} +5 -5
- package/dist/add-collection-EPp89tcs.mjs +10 -0
- package/dist/{archive-BiAxoJ1m.mjs → archive-BY8nrgnq.mjs} +4 -4
- package/dist/{archive-Dzug49jS.mjs → archive-BeslLaal.mjs} +5 -5
- package/dist/{archive-CXZ1Mg97.mjs → archive-Blt0TxxA.mjs} +4 -4
- package/dist/{archive-CcXT7XDi.mjs → archive-BxwGVDpd.mjs} +5 -5
- package/dist/{archive-BLySelYN.mjs → archive-C17qIvFW.mjs} +4 -4
- package/dist/{archive-BxvnYXN2.mjs → archive-CPLXsrzD.mjs} +4 -4
- package/dist/auth-CCUDM9Sv.mjs +19 -0
- package/dist/{body-CibAG3Gn.mjs → body-2jl-YSxT.mjs} +1 -1
- package/dist/{branches-CqYNkMew.mjs → branches-Vlu44J51.mjs} +5 -5
- package/dist/{cancel-PLvMQNzN.mjs → cancel-D0aBPUhs.mjs} +4 -4
- package/dist/{cancel-task-dnxyQrhZ.mjs → cancel-task-DoL2bqs1.mjs} +5 -5
- package/dist/{capabilities-Dj3NgPHg.mjs → capabilities-7L9GVMd_.mjs} +17 -2
- package/dist/{card-BtPiKjbB.mjs → card-DnIeMmUn.mjs} +17 -1
- package/dist/card-UwczcLjq.mjs +20 -0
- package/dist/{cards-DUCwTT1X.mjs → cards-6MTreYAo.mjs} +4 -4
- package/dist/cli.mjs +23 -33
- package/dist/{collection-B3sPXRLs.mjs → collection-BPTlcFw5.mjs} +8 -2
- package/dist/collection-Cexywhlj.mjs +20 -0
- package/dist/collection-namespace-BdqQJb7j.mjs +12 -0
- package/dist/{create-VB2v6CFw.mjs → create-BWD8H6yw.mjs} +10 -7
- package/dist/{create-BGtmOc5Z.mjs → create-BZRA7nPu.mjs} +4 -4
- package/dist/{create-Btltf94v.mjs → create-BsOdn1Q1.mjs} +7 -7
- package/dist/{create-CrEv9lPi.mjs → create-C_Z3IDrW.mjs} +6 -6
- package/dist/{create-Di0_His2.mjs → create-DNYFXAsy.mjs} +4 -4
- package/dist/{create-CJ7GFRnZ.mjs → create-DcoF52Kx.mjs} +7 -7
- package/dist/{create-branch-DbD4Mr3v.mjs → create-branch-40Xm4DN7.mjs} +5 -5
- package/dist/create-dVmIemXi.mjs +52 -0
- package/dist/{create-DbD1wgnN.mjs → create-k59K2qf1.mjs} +6 -6
- package/dist/{current-task-C8gML78R.mjs → current-task-BN_XEFSX.mjs} +5 -5
- package/dist/dashboard-B_CuVbMX.mjs +21 -0
- package/dist/{database-_Td7rG4o.mjs → database-Dsv4QBs0.mjs} +19 -9
- package/dist/db-DULi5MOr.mjs +22 -0
- package/dist/{delete-DnorVsnc.mjs → delete-DEFgs5LE.mjs} +5 -5
- package/dist/{delete-runtime-Bo7v-0au.mjs → delete-runtime-DVb-Pkzp.mjs} +1 -1
- package/dist/{delete-C_H6NNKT.mjs → delete-tPjicYO4.mjs} +5 -5
- package/dist/{delete-table-B-UwOkQ8.mjs → delete-table-CDj19Qn6.mjs} +5 -5
- package/dist/{dirty-Q8VNL_QG.mjs → dirty-DGCa6W1F.mjs} +5 -5
- package/dist/{eid-CQO-WWqZ.mjs → eid-3v5MAKNA.mjs} +4 -4
- package/dist/{error-BYn4eqJH.mjs → error-BndUmcwS.mjs} +1 -1
- package/dist/{export-DaTZ6gvj.mjs → export-BIZ-UR_M.mjs} +7 -7
- package/dist/field-CfrrLetM.mjs +18 -0
- package/dist/{fields-CrFLg4ED.mjs → fields-9lOrO8UH.mjs} +4 -4
- package/dist/{get-yM_8b0OQ.mjs → get-6Cj360cH.mjs} +4 -4
- package/dist/{get-DljOZz2K.mjs → get-BIH72g0v.mjs} +5 -5
- package/dist/{get-DzK1a7SS.mjs → get-BSJN5TwW.mjs} +4 -4
- package/dist/{get-C1sugXm_.mjs → get-BYSj7tMP.mjs} +3 -3
- package/dist/{get-BSIQndJI.mjs → get-Bk81meka.mjs} +4 -4
- package/dist/{get-rQxZzRkA.mjs → get-BpWjLkKT.mjs} +3 -3
- package/dist/{get-D188icmF.mjs → get-BuM6QPjZ.mjs} +4 -4
- package/dist/{get-BeFkBriz.mjs → get-CHaIVT6Y.mjs} +4 -4
- package/dist/{get-Cgdc7hCr.mjs → get-CRa-h69C.mjs} +4 -4
- package/dist/{get-C03uSHdF.mjs → get-DFe2WoJ2.mjs} +5 -5
- package/dist/{get-BzHRPRpv.mjs → get-DlGlnciR.mjs} +4 -4
- package/dist/{get-QoJ4HbKQ.mjs → get-LI2xsRoT.mjs} +4 -4
- package/dist/{get-run-Dzu_f6Hi.mjs → get-run-hCZaw8-h.mjs} +5 -5
- package/dist/{get-FqlK_kjE.mjs → get-w-WqpjKy.mjs} +5 -5
- package/dist/git-sync-BpRstrZo.mjs +28 -0
- package/dist/{has-remote-changes-CH6m9DG_.mjs → has-remote-changes-DcpW1_KX.mjs} +5 -5
- package/dist/{import-Ct_wFwN3.mjs → import-CTQT1atq.mjs} +7 -7
- package/dist/{is-dirty-BZZx74du.mjs → is-dirty-DGrmt1ss.mjs} +4 -4
- package/dist/is-dirty-DuWCgrz2.mjs +9 -0
- package/dist/{items-DZwlhSEL.mjs → items-Kr0oN2V7.mjs} +5 -5
- package/dist/{list-CY2snf4x.mjs → list-Bz2ej0Cl.mjs} +3 -3
- package/dist/{list-CgQVYt5R.mjs → list-CCtYVgPN.mjs} +3 -3
- package/dist/{list-CQpckqCa.mjs → list-CLvlEVQo.mjs} +4 -4
- package/dist/{list-BmaG3xeR.mjs → list-Ccj8-vb5.mjs} +3 -3
- package/dist/{list-BYmhSHzh.mjs → list-Cj3v4Lgv.mjs} +4 -4
- package/dist/{list-D81pxMKm.mjs → list-Cl_O4_U4.mjs} +4 -4
- package/dist/{list-seY6unmL.mjs → list-D2D5Mw1E.mjs} +4 -4
- package/dist/{list-B3Ovx70Y.mjs → list-DNmekF2B.mjs} +3 -3
- package/dist/{list-CnFLhMYE.mjs → list-DaESiI72.mjs} +3 -3
- package/dist/{list-9XlzunAC.mjs → list-DzKKdfCI.mjs} +4 -4
- package/dist/{list-DoqLo7A0.mjs → list-jcgK0thu.mjs} +4 -4
- package/dist/{list-BGGAF_6C.mjs → list-tklIxo38.mjs} +4 -4
- package/dist/{list-BIhaOrA5.mjs → list-zRQsvrH6.mjs} +3 -3
- package/dist/{login-DYTNx7yh.mjs → login-BMKBmgeQ.mjs} +4 -4
- package/dist/{logout-DZ8y8HOD.mjs → logout-C5pod937.mjs} +3 -3
- package/dist/{manifest-B_OfG-Ss.mjs → manifest-Cmu--CG5.mjs} +1 -1
- package/dist/measure-BkwFsP44.mjs +19 -0
- package/dist/{metadata-HFNA8q0S.mjs → metadata-CG4VZ5NW.mjs} +4 -4
- package/dist/{metadata-9C7IqqPO.mjs → metadata-DIEbyQeS.mjs} +5 -5
- package/dist/{parse-id-sz7USsM2.mjs → parse-id-Boqc4wn4.mjs} +1 -1
- package/dist/{path-CQtJFQoD.mjs → path-ur3NsMFr.mjs} +3 -3
- package/dist/{poll-DO11tBiL.mjs → poll-BMjCkDaj.mjs} +1 -1
- package/dist/{poll-task-DnzX7GX_.mjs → poll-task-CiRA0ER9.mjs} +2 -2
- package/dist/{preflight-B-LRcq3c.mjs → preflight-CSqcIlbX.mjs} +3 -3
- package/dist/{query-77r-viQY.mjs → query-B8JzsQ_I.mjs} +6 -6
- package/dist/{query-CsN3tsch.mjs → query-CG0rEMS-.mjs} +8 -8
- package/dist/{query-result-PoQE05Pe.mjs → query-result-B4kTRid7.mjs} +1 -1
- package/dist/{remove-collection-DoUP8olH.mjs → remove-collection-Clwz3EHQ.mjs} +7 -7
- package/dist/{rescan-values-B0Aubnud.mjs → rescan-values-DuHBnFjK.mjs} +6 -8
- package/dist/run-JXRivkfH.mjs +136 -0
- package/dist/{runs-C3t03bls.mjs → runs-FxgbXvax.mjs} +5 -5
- package/dist/{runtime-DHJQOqZu.mjs → runtime-Ck8KKQe-.mjs} +3 -3
- package/dist/{schema-tables-D7df6z1V.mjs → schema-tables-izDPI4f5.mjs} +4 -4
- package/dist/{schemas-DT3v9JRw.mjs → schemas-CyzplnXl.mjs} +4 -4
- package/dist/{search-B3EvSZce.mjs → search-BeuoOEQV.mjs} +4 -4
- package/dist/segment-ChYmSM0p.mjs +19 -0
- package/dist/{set-zEPevfIf.mjs → set-ClzB_5Jk.mjs} +4 -4
- package/dist/{setting-fWAwsQKm.mjs → setting-CBJVEx7_.mjs} +3 -3
- package/dist/{setup-SjStGgMi.mjs → setup-vKXEUMM7.mjs} +4 -4
- package/dist/skills-1Z5Wj7Kp.mjs +18 -0
- package/dist/snippet-De70ayL1.mjs +19 -0
- package/dist/{stash-CLN-okHt.mjs → stash-DLtVf4_D.mjs} +7 -7
- package/dist/{status-CIyVMUXh.mjs → status-AnPzI1f7.mjs} +3 -3
- package/dist/{status-B0YQmlXV.mjs → status-DHFYn9kO.mjs} +6 -6
- package/dist/{summary-DBhVgNU4.mjs → summary-DDed1LOz.mjs} +4 -4
- package/dist/sync-schema-BGQVq2JA.mjs +55 -0
- package/dist/table-C_bP2ao-.mjs +19 -0
- package/dist/transform-B4RZfm6A.mjs +24 -0
- package/dist/{transform-DyJb0bV0.mjs → transform-DyWCoiO-.mjs} +1 -0
- package/dist/transform-job-C4pZcrIF.mjs +19 -0
- package/dist/{tree-2qvtbIdj.mjs → tree-BlYgJOn9.mjs} +4 -4
- package/dist/{update-Cw0oHpsm.mjs → update-B0z-2zqC.mjs} +8 -8
- package/dist/{update-B93L5MJR.mjs → update-BHtliIr_.mjs} +5 -5
- package/dist/{update-CiIYqtRb.mjs → update-CdfAogO2.mjs} +5 -5
- package/dist/{update-CWgm0WZQ.mjs → update-CgOPxKXK.mjs} +11 -8
- package/dist/{update-YxMDkgY6.mjs → update-CilTW98H.mjs} +7 -7
- package/dist/{update-BA0wgxkx.mjs → update-CoVvsU-I.mjs} +5 -5
- package/dist/{update-DWwBv7XP.mjs → update-DBN7yfAk.mjs} +5 -5
- package/dist/{update-D5fs9raK.mjs → update-DqSG5_Ie.mjs} +7 -7
- package/dist/{update-DdI9epnQ.mjs → update-DykqQLfo.mjs} +8 -8
- package/dist/{update-dashcard-BA65Gjah.mjs → update-dashcard-DZ8oV8up.mjs} +5 -5
- package/dist/{upgrade-82Zo6-n6.mjs → upgrade-B8sEEQdQ.mjs} +3 -3
- package/dist/{uuid-B2xU0Ibp.mjs → uuid-lLVnEoBN.mjs} +3 -3
- package/dist/{validate-CqVB_3_p.mjs → validate-B62TRDGV.mjs} +1 -1
- package/dist/{validate-query-BUTNK00f.mjs → validate-query-BpiN1CFu.mjs} +2 -2
- package/dist/{values-Cs6sJEid.mjs → values-oD72EtRq.mjs} +4 -4
- package/dist/{verify-D8wLpHse.mjs → verify-Bg6F0oFN.mjs} +1 -1
- package/dist/{wait-CW6jJWmY.mjs → wait-BtzuqQC3.mjs} +6 -6
- package/dist/{wait-flags-Dl-xi5yx.mjs → wait-flags-DyFfZeav.mjs} +2 -2
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +5 -5
- package/skill-data/mbql/SKILL.md +94 -29
- package/skill-data/mbql/references/operators.md +13 -13
- package/skill-data/transform/SKILL.md +9 -8
- package/dist/add-collection-CRm-ILtk.mjs +0 -10
- package/dist/auth-9zbMAJJT.mjs +0 -19
- package/dist/card-pT87DhqA.mjs +0 -20
- package/dist/collection-DR2bXpGN.mjs +0 -20
- package/dist/create-C9GnQVhD.mjs +0 -44
- package/dist/dashboard-D4uKuH7K.mjs +0 -21
- package/dist/db-UVZmfVwk.mjs +0 -22
- package/dist/field-BYKXbj6M.mjs +0 -18
- package/dist/git-sync-CbvqlHaK.mjs +0 -28
- package/dist/is-dirty-B2h2xG28.mjs +0 -9
- package/dist/measure-RIucuF-O.mjs +0 -19
- package/dist/run-CBuzp0Oj.mjs +0 -95
- package/dist/segment-CvxcX3iJ.mjs +0 -19
- package/dist/skills-zSDzVgBI.mjs +0 -18
- package/dist/snippet-DTwXkIqY.mjs +0 -19
- package/dist/sync-schema-CvRI0jtk.mjs +0 -43
- package/dist/table-CTTjXzo3.mjs +0 -19
- package/dist/transform-CWNrL2gg.mjs +0 -24
- package/dist/transform-job-C--GBO9Q.mjs +0 -19
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import "./input-xewHccej.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
7
|
+
import { readBody } from "./body-2jl-YSxT.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D78h_-Ua.mjs";
|
|
9
|
-
import "./validate-
|
|
10
|
-
import { MEASURE_DEFINITION_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-
|
|
9
|
+
import "./validate-B62TRDGV.mjs";
|
|
10
|
+
import { MEASURE_DEFINITION_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-BpiN1CFu.mjs";
|
|
11
11
|
import { Measure, MeasureUpdateInput, measureView } from "./measure-ClESGxIb.mjs";
|
|
12
12
|
|
|
13
13
|
//#region src/commands/measure/update.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import "./input-xewHccej.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
7
|
+
import { readBody } from "./body-2jl-YSxT.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D78h_-Ua.mjs";
|
|
9
9
|
import { TransformJob, TransformJobUpdateInput, transformJobView } from "./transform-job-DpDGoqQt.mjs";
|
|
10
10
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import "./input-xewHccej.mjs";
|
|
6
6
|
import "./field-MGxpNQUH.mjs";
|
|
7
|
-
import { parseId } from "./parse-id-
|
|
8
|
-
import { readBody } from "./body-
|
|
7
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
8
|
+
import { readBody } from "./body-2jl-YSxT.mjs";
|
|
9
9
|
import { bodyInputFlags } from "./body-flags-D78h_-Ua.mjs";
|
|
10
10
|
import { Table, TableUpdateInput, tableView } from "./table-CkWja2UH.mjs";
|
|
11
11
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import "./input-xewHccej.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
7
|
+
import { readBody } from "./body-2jl-YSxT.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D78h_-Ua.mjs";
|
|
9
|
-
import "./validate-
|
|
10
|
-
import { SEGMENT_DEFINITION_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-
|
|
9
|
+
import "./validate-B62TRDGV.mjs";
|
|
10
|
+
import { SEGMENT_DEFINITION_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-BpiN1CFu.mjs";
|
|
11
11
|
import { Segment, SegmentUpdateInput, segmentView } from "./segment-Be2v4ilr.mjs";
|
|
12
12
|
|
|
13
13
|
//#region src/commands/segment/update.ts
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import "./input-xewHccej.mjs";
|
|
6
6
|
import "./field-MGxpNQUH.mjs";
|
|
7
|
-
import { Card, CardUpdateInput, cardView } from "./card-
|
|
8
|
-
import { parseId } from "./parse-id-
|
|
9
|
-
import { readBody } from "./body-
|
|
7
|
+
import { Card, CardUpdateInput, cardView } from "./card-DnIeMmUn.mjs";
|
|
8
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
9
|
+
import { readBody } from "./body-2jl-YSxT.mjs";
|
|
10
10
|
import { bodyInputFlags } from "./body-flags-D78h_-Ua.mjs";
|
|
11
|
-
import "./validate-
|
|
12
|
-
import { CARD_DATASET_QUERY_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-
|
|
11
|
+
import "./validate-B62TRDGV.mjs";
|
|
12
|
+
import { CARD_DATASET_QUERY_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-BpiN1CFu.mjs";
|
|
13
13
|
|
|
14
14
|
//#region src/commands/card/update.ts
|
|
15
15
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import "./input-xewHccej.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
7
|
+
import { readBody } from "./body-2jl-YSxT.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D78h_-Ua.mjs";
|
|
9
9
|
import { DashboardDetail, Dashcard, DashcardPatchInput, dashcardView } from "./dashboard-FY5UzJ_Z.mjs";
|
|
10
10
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AbortError, NetworkError, TimeoutError, UnknownError, errorMessage, isNotFoundError } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { outputFlags, package_default } from "./error-
|
|
3
|
-
import { HttpError, USER_AGENT, combineAborts, defineMetabaseCommand, parseJson, throwIfAborted } from "./runtime-
|
|
4
|
-
import { renderItem, writeText } from "./capabilities-
|
|
2
|
+
import { outputFlags, package_default } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { HttpError, USER_AGENT, combineAborts, defineMetabaseCommand, parseJson, throwIfAborted } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderItem, writeText } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import { promptConfirm } from "./prompt-u4WhE4T5.mjs";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { realpathSync } from "node:fs";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { outputFlags } from "./error-
|
|
3
|
-
import { defineMetabaseCommand, parseInteger } from "./runtime-
|
|
4
|
-
import { writeJson, writeText } from "./capabilities-
|
|
2
|
+
import { outputFlags } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand, parseInteger } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { writeJson, writeText } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConfigError, escapeJsonPointerSegment } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { isPlainObject } from "./capabilities-
|
|
2
|
+
import { isPlainObject } from "./capabilities-7L9GVMd_.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
5
5
|
import addFormats from "ajv-formats";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { writeJson } from "./capabilities-
|
|
3
|
-
import { assertNotLegacyEnvelopeWrappingMbql5, isMbql5Query, validateQuery } from "./validate-
|
|
2
|
+
import { writeJson } from "./capabilities-7L9GVMd_.mjs";
|
|
3
|
+
import { assertNotLegacyEnvelopeWrappingMbql5, isMbql5Query, validateQuery } from "./validate-B62TRDGV.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/commands/validate-query.ts
|
|
6
6
|
const skipValidateFlag = { "skip-validate": {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { formatScalar, renderSummary } from "./capabilities-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { formatScalar, renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
5
|
import { FieldValues, fieldValuesView } from "./field-MGxpNQUH.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
6
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
7
7
|
|
|
8
8
|
//#region src/commands/field/values.ts
|
|
9
9
|
var values_default = defineMetabaseCommand({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MetabaseError, NetworkError, TimeoutError, errorMessage } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { HttpError, createClient, probeServer } from "./runtime-
|
|
2
|
+
import { HttpError, createClient, probeServer } from "./runtime-Ck8KKQe-.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
//#region src/domain/user.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import { renderSummary } from "./capabilities-
|
|
5
|
-
import { parseId } from "./parse-id-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-BndUmcwS.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-Ck8KKQe-.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-7L9GVMd_.mjs";
|
|
5
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
6
|
+
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-BMjCkDaj.mjs";
|
|
7
|
+
import { SyncTaskOrIdle, formatSyncTask, pollSyncTask, syncTaskIdleView, syncTaskView, throwIfFailedTask } from "./poll-task-CiRA0ER9.mjs";
|
|
8
8
|
|
|
9
9
|
//#region src/commands/git-sync/wait.ts
|
|
10
10
|
const WaitResult = SyncTaskOrIdle;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseId } from "./parse-id-
|
|
2
|
-
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-
|
|
1
|
+
import { parseId } from "./parse-id-Boqc4wn4.mjs";
|
|
2
|
+
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-BMjCkDaj.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/wait-flags.ts
|
|
5
5
|
const waitScheduleFlags = {
|
package/package.json
CHANGED
package/skill-data/core/SKILL.md
CHANGED
|
@@ -15,7 +15,7 @@ auth | db | table | field | query | card | dashboard | snippet | segment | measu
|
|
|
15
15
|
transform | transform-job | setting | search | git-sync | setup | eid | uuid | upgrade | skills
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
The patterns below — auth, flag conventions, output flags, body input — apply across **every** group. Per-command flags, examples, and output schemas live in `mb __manifest` (see below). A few flows have their own specialized skills; load them on demand (see "Specialized skills"). Authoring any query body (cards, transforms, measures, segments, ad-hoc `mb query`) is one — load `mbql` whenever you build MBQL by hand.
|
|
18
|
+
The patterns below — auth, flag conventions, output flags, body input — apply across **every** group. Per-command flags, examples, and output schemas live in `mb __manifest` (see below). A few flows have their own specialized skills; load them on demand (see "Specialized skills"). Authoring any query body (cards, transforms, measures, segments, ad-hoc `mb query`) is one — load `mbql` whenever you build MBQL by hand. When a **question** (card) needs a query, prefer MBQL over native SQL — it's portable across warehouse engines and the CLI pre-flight-validates it. Try it first, but don't force it: fall back to native SQL when MBQL can't express the query, or when an MBQL body keeps failing server-side and you can't resolve it.
|
|
19
19
|
|
|
20
20
|
## Auth & profiles
|
|
21
21
|
|
|
@@ -128,19 +128,19 @@ Use it to (a) enumerate verbs, (b) validate flag names before constructing a com
|
|
|
128
128
|
|
|
129
129
|
Routine verb shapes (list / get / create / update), every flag, and output JSON Schemas live in `mb __manifest` — pull them on demand. Below is only what the manifest does _not_ tell you: the footguns and non-obvious behaviors.
|
|
130
130
|
|
|
131
|
-
- **db traversal vs. rollup.** Default to granular: `database list` → `database schemas <db-id>` → `database schema-tables <db-id> <schema>` → `table get <table-id> --include fields`. The rollup endpoints (`database get --include tables.fields`, `database metadata <db-id>`) pull megabytes and blow the context window on any real warehouse — use them only on a small/dev db. `sync-schema` / `rescan-values` queue async work and return `{status:"ok"}` immediately
|
|
131
|
+
- **db traversal vs. rollup.** Default to granular: `database list` → `database schemas <db-id>` → `database schema-tables <db-id> <schema>` → `table get <table-id> --include fields`. The rollup endpoints (`database get --include tables.fields`, `database metadata <db-id>`) pull megabytes and blow the context window on any real warehouse — use them only on a small/dev db. `sync-schema` / `rescan-values` queue async work and return `{status:"ok"}` immediately; `sync-schema --wait` blocks until `initial_sync_status: complete`.
|
|
132
132
|
- **table fields.** `table get` never returns fields on its own — pass `--include fields` (compact) or use `table fields <id>` (list envelope). `table metadata <id>` adds FKs + dimensions (heavier). `table update` patches table-level metadata only; physical columns aren't editable here.
|
|
133
133
|
- **field has no `list`.** Fields are per-table — get them via `table get <id> --include fields`. Never enumerate fields across a whole db (context blow-up). `field summary` is live cardinality `{field_id, count, distincts}`; `field values` is the cached distinct set (`has_more_values: true` ⇒ truncated cache). `field update` patches metadata only; `base_type` isn't editable.
|
|
134
134
|
- **card.** `dataset_query` is the **flat** `mbql/query` value, not a legacy `{type:"query",query:…}` envelope (→ `mbql` skill). `--export-format csv|xlsx` streams the raw export (pipe to a file), bypassing the JSON envelope. `archive` is the only delete; unarchive with `update --body '{"archived":false}'`. `visualization_settings` keys are scoped by `display` and aren't pre-flighted — see the `viz` skill.
|
|
135
|
-
- **dashboard.** Dashcards round-trip through `PUT /api/dashboard/:id` (no per-dashcard endpoint): `update-dashcard <dash-id> <dashcard-id>` patches one safely; `update --body '{"dashcards":[…]}'` replaces the whole set (omitted ids are deleted server-side; use negative ids for new cards). `create` accepts the **same** `dashcards` array in its initial body, so you can lay out the whole dashboard in one call — negative ids for new cards, and `card_id:null` plus a `visualization_settings.virtual_card` block (`{display:"text"|"heading"|"link"|…}`) for non-question cards. `create`/`update` pre-flight every positive `card_id` against live server state and exit **2** with `{ok:false,errors:[…]}` on a bad ref — non-bypassable (no `--skip-validate`). `dashboard get <id>` (or `--full`) hydrates dashcards/tabs; `list` omits them.
|
|
135
|
+
- **dashboard.** Dashcards round-trip through `PUT /api/dashboard/:id` (no per-dashcard endpoint): `update-dashcard <dash-id> <dashcard-id>` patches one safely; `update --body '{"dashcards":[…]}'` replaces the whole set (omitted ids are deleted server-side; use negative ids for new cards). `create` accepts the **same** `dashcards` array in its initial body, so you can lay out the whole dashboard in one call — negative ids for new cards, and `card_id:null` plus a `visualization_settings.virtual_card` block (`{display:"text"|"heading"|"link"|…}`) for non-question cards. `create`/`update` pre-flight every positive `card_id` against live server state and exit **2** with `{ok:false,errors:[…]}` on a bad ref — non-bypassable (no `--skip-validate`). `dashboard get <id>` (or `--full`) hydrates dashcards/tabs; `list` omits them. **Dashcard geometry: the grid is 24 columns wide.** Each dashcard's `{col, row, size_x, size_y}` is in grid units — `col` (0-indexed, left edge) and `size_x` are columns, `row`/`size_y` are rows; **full-width is `size_x: 24`** (`size_x: 12` is half a row — the usual cause of a card that only fills half the width, since it's a common per-chart default). Keep `col + size_x ≤ 24`, start each card's `col` at 0 for a full-width stack, and don't overlap cards (the server stores whatever you send — it won't auto-fix collisions).
|
|
136
136
|
- **snippet `--archived` is a swap, not a union** — list returns _either_ active _or_ archived rows, never both. (Same shape for `--filter archived` on dashboard/collection.)
|
|
137
137
|
- **segment / measure** `update` and `archive` require a non-blank `revision_message` (audit-logged); the CLI does not synthesize it on `update`. `archive` defaults to `"Archived via mb CLI"` — override with `--revision-message`. `definition` is a flat MBQL clause (→ `mbql` skill): segment = a filter, measure = exactly one aggregation.
|
|
138
138
|
- **collection `<ref>`** accepts four forms only — positive int, `root`, `trash`, or a 21-char entity_id — anything else is a client-side `ConfigError`. `collection items` auto-paginates (cap with `--limit`, which then omits `total`). `collection tree` is **JSON-only** — `--format text` is rejected.
|
|
139
139
|
- **setting set** parses the value as **strict JSON**: a string is `'"value"'` (inner quotes), booleans `true`/`false`, numbers bare. Wrong quoting silently errors — confirm with `setting get <key>` after. `setting get --json` works on every value type (it wraps bare-text responses into `{key, value}`).
|
|
140
140
|
- **search vs. list.** For plain enumeration of cards/dashboards/collections use the dedicated `… list` verbs; reach for `search --models <kind>` only for ranking against a query string or a cross-resource lookup.
|
|
141
|
-
- **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 you get only `{run_id, final:null}`. (→ `transform` skill.)
|
|
141
|
+
- **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 run's output table to register and returns `target_table_id`) or you get only `{run_id, final:null}`. (→ `transform` skill.)
|
|
142
142
|
- **setup is one-shot.** `mb setup` walks `/api/setup` for a **fresh** instance only — it errors against an already-configured one. Mostly for bootstrapping local / e2e instances.
|
|
143
|
-
- **eid** translates a string entity id → numeric id: `mb eid --model <model> <eid1,eid2> --json` (EIDs are a positional used with `--model`; or pass `--body '{"entity_ids":{"card":["…"]}}'`). Useful when an external system hands you an entity id and a verb needs the numeric one.
|
|
143
|
+
- **eid** translates a string entity id → numeric id: `mb eid --model <model> <eid1,eid2> --json` (EIDs are a positional used with `--model`; or pass `--body '{"entity_ids":{"card":["…"]}}'`). Entity ids are NanoIDs that can start with `-`, which the positional form misreads as a flag (shell quotes don't help — the `-` survives into argv). For an id that may start with `-`, use `--body` — the id is a JSON string value, immune to flag parsing: `mb eid --body '{"entity_ids":{"card":["-…"]}}'`. Useful when an external system hands you an entity id and a verb needs the numeric one.
|
|
144
144
|
- **query / uuid.** `mb query` is the ad-hoc MBQL surface (`--print-schema` → `--dry-run` → run); `mb uuid --count <n>` mints the `lib/uuid` values every MBQL 5 clause needs. Both workflows live in the `mbql` skill.
|
|
145
145
|
|
|
146
146
|
## Specialized skills (load on demand)
|
package/skill-data/mbql/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mbql
|
|
3
|
-
description: Author Metabase MBQL 5 query bodies for the `mb` CLI — the only hand-authorable query format. Covers the JSON shape (lib/type mbql/query, flat stages, numeric ids), the "options object always second" clause rule, lib/uuid
|
|
3
|
+
description: Author Metabase MBQL 5 query bodies for the `mb` CLI — the only hand-authorable query format. Covers the JSON shape (lib/type mbql/query, flat stages, numeric ids), the "options object always second" clause rule, when lib/uuid is needed (it's optional — only to reference a clause), the print-schema → dry-run → run validation loop, where MBQL 5 is consumed (mb query, card dataset_query, transform source.query, measure/segment definition), the flat-vs-legacy-envelope footgun, joins and FK traversal, multi-stage pipelines, and naming aggregation output columns. Load whenever building or fixing an MBQL query by hand — "write an MBQL query", "create a card from MBQL", "the dataset_query is wrong", "fix the validation errors", "aggregate and group by", "order by the count", "join two tables", "month-over-month", or any `--dry-run` / `mb query` work.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
|
8
8
|
|
|
9
9
|
MBQL 5 is the **only query format you can author by hand** with confidence — it has a bundled JSON Schema, so the CLI pre-flight-validates it before sending. Legacy MBQL 4 and native SQL are accepted but **not** schema-validated (see "Other formats" below).
|
|
10
10
|
|
|
11
|
-
Prefer MBQL over native SQL:
|
|
11
|
+
Prefer MBQL over native SQL: it's portable across warehouse engines and the CLI pre-flight-validates it. Try it first, but don't force it — fall back to native SQL when MBQL can't express what you need, or when an MBQL body keeps failing server-side and you can't resolve it.
|
|
12
12
|
|
|
13
13
|
The general flag conventions, body-input precedence, and output flags live in the `core` skill (`mb skills get core`).
|
|
14
14
|
|
|
@@ -24,8 +24,8 @@ A query is a flat object — `lib/type`, a numeric `database` id, and an ordered
|
|
|
24
24
|
{
|
|
25
25
|
"lib/type": "mbql.stage/mbql",
|
|
26
26
|
"source-table": 7,
|
|
27
|
-
"aggregation": [["count", {
|
|
28
|
-
"breakout": [["field", { "temporal-unit": "month"
|
|
27
|
+
"aggregation": [["count", {}]],
|
|
28
|
+
"breakout": [["field", { "temporal-unit": "month" }, 22]]
|
|
29
29
|
}
|
|
30
30
|
]
|
|
31
31
|
}
|
|
@@ -33,43 +33,42 @@ A query is a flat object — `lib/type`, a numeric `database` id, and an ordered
|
|
|
33
33
|
|
|
34
34
|
- **Numeric ids only.** `database`, `source-table`, and field ids are integers from `mb database list` / `mb table get <id> --include fields`. (The portable YAML representation under git-sync uses _names_ like `[Sample Database, PUBLIC, ORDERS]`; the CLI's `/api/dataset` form uses numeric ids — don't mix them.)
|
|
35
35
|
- **First stage** carries `source-table` (a table id) or `source-card` (a saved card). Later stages omit both and read the previous stage's output columns by name.
|
|
36
|
-
- `source-card` references a saved card by entity id; downstream fields are referenced by column name (string), not a field id.
|
|
36
|
+
- `source-card` references a saved card by its **numeric id** (from `mb card list`), not its string entity id; downstream fields are referenced by column name (string), not a field id.
|
|
37
37
|
|
|
38
38
|
## The one rule that trips everyone: options object is **second**
|
|
39
39
|
|
|
40
40
|
Every clause is `[op, {options}, ...args]`. The options object is element **1**, args follow.
|
|
41
41
|
|
|
42
42
|
```json
|
|
43
|
-
["field", { "base-type": "type/Text"
|
|
44
|
-
["count", {
|
|
45
|
-
["sum", {
|
|
46
|
-
["=", {
|
|
47
|
-
["asc", {
|
|
43
|
+
["field", { "base-type": "type/Text" }, 1779] // field id is THIRD; options may be empty {}
|
|
44
|
+
["count", {}] // no args
|
|
45
|
+
["sum", {}, ["field", {}, 42]]
|
|
46
|
+
["=", {}, ["field", {}, 1779], "delivered"]
|
|
47
|
+
["asc", {}, ["field", {}, 42]]
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
The legacy MBQL 4 field shape `["field", id, opts]` (id second) is **rejected** here. A slot-1 violation surfaces from `--dry-run` as `must be the field options object` / `must be the clause options object` at `/stages/0/<verb>/<n>/1`.
|
|
51
51
|
|
|
52
52
|
The same `[op, {options}, …]` rule holds for `aggregation`, `breakout` (a list of field refs), `filters` (implicitly ANDed; nest an explicit `["or", {}, …]` for OR), `order-by`, `expressions`, and join `conditions`.
|
|
53
53
|
|
|
54
|
-
## UUIDs: mint
|
|
54
|
+
## UUIDs: optional — mint only to reference a clause
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
`lib/uuid` is **optional — leave it out whenever you can.** Omit it and the server generates a unique one for every clause as the query comes in; an empty options object `{}` is the normal, preferred case. Don't add a UUID per clause: it's needless work, and the more UUIDs you hand-manage the easier it is to trip the server's "all `lib/uuid`s must be unique" check — a duplicated UUID passes pre-flight, then fails server-side.
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
mb uuid --count 5 --json # → ["…","…","…","…","…"] — mint exactly what you need, in one call
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Workflow: count the slots (one per clause options object), `mb uuid --count <N> --json`, substitute each minted value as you build the JSON. Never copy a UUID from docs, a prior query, or another session.
|
|
63
|
-
|
|
64
|
-
**Aggregation/expression refs are the only legitimate reuse.** To reference an aggregation downstream (in `order-by` or a later stage), use `["aggregation", {options}, "<uuid>"]` where the third arg is the **string** `lib/uuid` of the target aggregation — the same minted value, by string equality. A numeric position fails with `must be the target aggregation's lib/uuid (string), not a numeric position`. Expression refs work the same way but key off the expression's name string.
|
|
58
|
+
Set an explicit `lib/uuid` only when you must **reference a clause from elsewhere in the query** — the one thing the server can't do for you, since you have to know the value to point at. The case that needs it: **ordering by (or otherwise reusing) an aggregation.** `["aggregation", {…}, "<uuid>"]`'s third arg is the **string** `lib/uuid` of the target aggregation, so give that aggregation an explicit `lib/uuid` and point the ref at the same string. A numeric position fails with `must be the target aggregation's lib/uuid (string), not a numeric position`.
|
|
65
59
|
|
|
66
60
|
```json
|
|
67
61
|
"aggregation": [["count", { "lib/uuid": "AGG_UUID" }]],
|
|
68
|
-
"order-by": [["desc", { "
|
|
69
|
-
["aggregation", { "lib/uuid": "REF_UUID" }, "AGG_UUID"]]]
|
|
62
|
+
"order-by": [["desc", {}, ["aggregation", {}, "AGG_UUID"]]]
|
|
70
63
|
```
|
|
71
64
|
|
|
72
|
-
(`AGG_UUID`
|
|
65
|
+
(`AGG_UUID` is both the aggregation's own `lib/uuid` and the string the ref points at — one value, by string equality. Every other clause omits its UUID. Expression refs work the same way but key off the expression's `lib/expression-name` string, so expressions rarely need an explicit `lib/uuid`.)
|
|
66
|
+
|
|
67
|
+
On the rare occasion you do need one, **always mint it with `mb uuid` — never write, guess, or copy a UUID yourself.** A hand-authored value is either rejected pre-flight as not-a-v4 (`"a1"`, `"uuid-1"`, `"agg-uuid-001"` → `must be a UUID v4 (RFC 4122) — run \`mb uuid\``) or, if it happens to look valid, risks colliding with another clause. Only `mb uuid`gives you genuine, unique v4s — mint just the few you reference (this also covers native template-tag ids and any other`format: "uuid"` slot):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
mb uuid --count 2 --json # mint only the clauses you actually reference
|
|
71
|
+
```
|
|
73
72
|
|
|
74
73
|
## Authoring loop: print-schema → dry-run → run
|
|
75
74
|
|
|
@@ -87,7 +86,14 @@ mb query --file q.json --profile <n> --json # 3. validate +
|
|
|
87
86
|
|
|
88
87
|
`path` is a JSON Pointer into the body (`/stages/0/aggregation/0`); `message` is the validator error. Exit codes: `0` valid + ran, `2` validation failed / malformed body, `1` server-side error after a valid pre-flight.
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
**Pre-flight is a lightweight shape check, not the full backend validator.** It checks JSON shape, `lib/uuid` format, and enum values — not operator names, the first-stage source rule, or whether a reference resolves. A clean `--dry-run` is necessary but not sufficient: a body can pass pre-flight and still fail on the server (exit `1`). The Metabase server is the authority — when a run fails, read its error and fix the body. The common ones and what they mean:
|
|
90
|
+
|
|
91
|
+
- `not a known MBQL clause` → a misspelled or unsupported **operator**. Check the vocabulary in `operators.md` (`mb skills get mbql --full`).
|
|
92
|
+
- `Initial MBQL stage must have either :source-table or :source-card` → the **first stage** is missing its source (a numeric table or card id); only the first stage takes one, later stages read the previous stage's columns.
|
|
93
|
+
- `Invalid :expression reference: no expression named "X"` (or an invalid `:aggregation` reference) → a **ref** points to an expression name / aggregation `lib/uuid` that isn't defined in the query; fix the target string.
|
|
94
|
+
- `Duplicate :lib/uuid` → you reused a `lib/uuid`. Omit them (the server mints unique ones) or give each clause a distinct value.
|
|
95
|
+
|
|
96
|
+
A successful run emits the compact envelope by default: `data.rows` + slim `data.cols` (`name`, `display_name`, `base_type`, `semantic_type`). Pass `--full` for the raw `/api/dataset` envelope (`results_metadata`, `native_form`, per-column fingerprints/`field_ref`) only when you need that metadata; `--fields data.rows` narrows to rows alone. `mb query` also runs a **native** body — `{database, type:"native", native:{query:"SELECT …"}}` — which skips pre-flight; the quickest way to eyeball warehouse data.
|
|
91
97
|
|
|
92
98
|
`--skip-validate` bypasses the pre-flight and sends as-is — use only when the bundled schema disagrees with what the server actually accepts (drift / false negative). Mutually exclusive with `--dry-run`. The same flag exists on `card create/update` and `transform create/update`.
|
|
93
99
|
|
|
@@ -112,7 +118,7 @@ The most common mistake. The legacy MBQL 4 shape `{ "type": "query", "database":
|
|
|
112
118
|
"lib/type": "mbql/query",
|
|
113
119
|
"database": 2,
|
|
114
120
|
"stages": [{ "lib/type": "mbql.stage/mbql", "source-table": 190,
|
|
115
|
-
"aggregation": [["count", {
|
|
121
|
+
"aggregation": [["count", {}]] }]
|
|
116
122
|
}
|
|
117
123
|
```
|
|
118
124
|
|
|
@@ -127,15 +133,74 @@ Anything that is not `lib/type: "mbql/query"` is sent as-is and normalized serve
|
|
|
127
133
|
|
|
128
134
|
`mb query --file probe.json` runs these directly; `--dry-run` on them returns `{ ok: true, errors: [] }`. Don't author MBQL 4 by hand — if you need a legacy or complex query, build it in the Metabase UI and pull the body with `mb card get <id> --full --json` / `mb transform get <id> --full --json`.
|
|
129
135
|
|
|
136
|
+
## Joins and FK traversal
|
|
137
|
+
|
|
138
|
+
Two ways to read columns from a related table.
|
|
139
|
+
|
|
140
|
+
**Explicit join.** A stage's `joins` array holds join objects, each with three required keys: `stages` (the joined source as its own one-stage array carrying `source-table`/`source-card`), `conditions` (the ON clause — `[op, {}, leftRef, rightRef]`, slot-1 rule and all), and `alias` (the string name you address joined columns by). Optional `strategy` (`left-join` default; also `right-join` / `inner-join` / `full-join`) and `fields` (`"all"` | `"none"` | an array of refs — which joined columns to select). Reference a joined column anywhere downstream by putting **`join-alias`** in the field options:
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
"joins": [
|
|
144
|
+
{
|
|
145
|
+
"alias": "Customers",
|
|
146
|
+
"strategy": "left-join",
|
|
147
|
+
"stages": [{ "lib/type": "mbql.stage/mbql", "source-table": 170 }],
|
|
148
|
+
"conditions": [
|
|
149
|
+
["=", {}, ["field", {}, 1711], ["field", { "join-alias": "Customers" }, 1684]]
|
|
150
|
+
],
|
|
151
|
+
"fields": "none"
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"breakout": [["field", { "join-alias": "Customers" }, 1682]]
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The condition's left ref is a column of the stage's own source (`1711` = orders.customer_id); the right ref carries `join-alias` and points at the joined table's key (`1684` = customers.id). Every later reference to a joined column (`1682` = customers.plan) needs that same `join-alias`. Stack multiple objects in `joins` for multiple joins, each with its own `alias`.
|
|
158
|
+
|
|
159
|
+
**Implicit FK join via `source-field`.** For a single-hop FK lookup, skip the join — put the FK column's id in the target field's `source-field` option and Metabase traverses the relationship:
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
["field", { "source-field": 1711 }, 1682] // orders.customer_id → customers.plan
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`source-field` is the **FK field id** (orders.customer_id); the third element is the **target field id** in the related table (customers.plan). Use it for "show a column from the table this FK points at"; reach for an explicit join when you need a non-FK condition, a non-default strategy, or control over which joined columns return.
|
|
166
|
+
|
|
167
|
+
## Multi-stage pipelines
|
|
168
|
+
|
|
169
|
+
Stages run in order; each reads the **previous stage's output columns** — the breakouts and aggregations it produced — referenced by **string name + `base-type`**, not a numeric field id. Only the first stage takes a `source-table`/`source-card`. The reason to add a stage is to operate on an aggregate (you can't filter or order by an aggregation within the stage that computes it): aggregate, then filter the aggregate, then order + limit.
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
"stages": [
|
|
173
|
+
{ "lib/type": "mbql.stage/mbql", "source-table": 175,
|
|
174
|
+
"aggregation": [["sum", { "name": "total" }, ["field", {}, 1715]]],
|
|
175
|
+
"breakout": [["field", {}, 1711]] },
|
|
176
|
+
{ "lib/type": "mbql.stage/mbql",
|
|
177
|
+
"filters": [[">", {}, ["field", { "base-type": "type/BigInteger" }, "total"], 0]] },
|
|
178
|
+
{ "lib/type": "mbql.stage/mbql",
|
|
179
|
+
"order-by": [["desc", {}, ["field", { "base-type": "type/BigInteger" }, "total"]]],
|
|
180
|
+
"limit": 3 }
|
|
181
|
+
]
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Later stages address the first stage's aggregation by the `name` you gave it (`"total"`) — set that `name`, or the column lands as the default `sum` / `count` / … and you reference that string instead.
|
|
185
|
+
|
|
186
|
+
**Window functions** sit in `aggregation` next to ordinary aggregates. `offset` reads a value from another breakout row — month-over-month is `offset` of a sum by `-1` against a monthly breakout:
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
"aggregation": [
|
|
190
|
+
["sum", { "name": "revenue" }, ["field", {}, 1715]],
|
|
191
|
+
["offset", { "name": "prev_month" }, ["sum", {}, ["field", {}, 1715]], -1]
|
|
192
|
+
],
|
|
193
|
+
"breakout": [["field", { "temporal-unit": "month" }, 1717]]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Binning** is a breakout-level field option — bucket a numeric column into ranges with `["field", { "binning": { "strategy": "num-bins", "num-bins": 5 } }, 1715]`, the numeric counterpart to the `temporal-unit` bucket. Strategies (`num-bins` / `bin-width` / `default`) are in the operator reference.
|
|
197
|
+
|
|
130
198
|
## Naming aggregation output columns
|
|
131
199
|
|
|
132
200
|
Default MBQL 5 aggregations materialize as `count`, `count_where`, `avg`, `avg_2`, `sum`, … — fine for an ad-hoc run, ugly when the output is a transform target table or a card column. Set `name` (becomes the warehouse column name) and `display-name` (the UI header) in the aggregation's options:
|
|
133
201
|
|
|
134
202
|
```json
|
|
135
|
-
[
|
|
136
|
-
"count",
|
|
137
|
-
{ "lib/uuid": "<mint>", "name": "shipments_shipped", "display-name": "Shipments shipped" }
|
|
138
|
-
]
|
|
203
|
+
["count", { "name": "shipments_shipped", "display-name": "Shipments shipped" }]
|
|
139
204
|
```
|
|
140
205
|
|
|
141
206
|
## Operator reference
|
|
@@ -151,7 +216,7 @@ mb skills path mbql # → the skill dir; then Read references/operator
|
|
|
151
216
|
|
|
152
217
|
## Don't
|
|
153
218
|
|
|
154
|
-
- Don't
|
|
219
|
+
- Don't mint a `lib/uuid` for every clause — they're optional; omit them and the server fills them in. Mint (with `mb uuid`) only the clause you need to reference; never invent, hard-code, or copy a UUID (duplicates are rejected server-side).
|
|
155
220
|
- Don't put the options object anywhere but slot 1, and don't use the legacy `["field", id, opts]` order.
|
|
156
221
|
- Don't wrap an MBQL 5 body in `{type:"query", query:…}` — `dataset_query` / `source.query` / `definition` is the flat `mbql/query`.
|
|
157
222
|
- Don't author MBQL 4 by hand — build it in the UI and pull it with `… get <id> --full --json`.
|
|
@@ -5,15 +5,15 @@ form. The clause _structure_ and the slot-1-options rule are in the SKILL.md bod
|
|
|
5
5
|
this file is the catalog of which operators exist and their arguments.
|
|
6
6
|
|
|
7
7
|
**Reading the tables.** Every clause is `[op, {options}, ...args]`. Below, `{…}`
|
|
8
|
-
abbreviates the slot-1 options object
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
abbreviates the slot-1 options object — usually empty (`{}`), since `lib/uuid` is
|
|
9
|
+
optional and the server generates it (see the SKILL body). It carries a value only
|
|
10
|
+
when noted: an operator-specific option named in the row, or an explicit `lib/uuid`
|
|
11
|
+
you mint to reference the clause. Field refs are numeric: `["field", {…}, <field-id>]`.
|
|
12
|
+
Everything here passes `mb query --dry-run`; when in doubt, that loop is the authority.
|
|
12
13
|
|
|
13
|
-
>
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
> those — send it with `--skip-validate` rather than rewriting it.
|
|
14
|
+
> For relative date filters, prefer **`time-interval`** / **`relative-time-interval`**
|
|
15
|
+
> (below). `relative-datetime` / `absolute-datetime` literals (e.g. from a UI-built
|
|
16
|
+
> query) also work.
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -67,7 +67,7 @@ options object.
|
|
|
67
67
|
| `ends-with` | field, 1+ strings |
|
|
68
68
|
|
|
69
69
|
```json
|
|
70
|
-
["contains", { "
|
|
70
|
+
["contains", { "case-sensitive": false }, ["field", {…}, 9], "widget"]
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
### Temporal
|
|
@@ -120,7 +120,7 @@ A stage's `aggregation` is a list of aggregation clauses.
|
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
**Naming** — set `name` (warehouse column) and/or `display-name` (UI header) in the
|
|
123
|
-
options object: `["sum", { "
|
|
123
|
+
options object: `["sum", { "name": "revenue", "display-name": "Revenue" }, …]`.
|
|
124
124
|
|
|
125
125
|
**Window function** — `offset` is only valid inside `aggregation`:
|
|
126
126
|
|
|
@@ -205,7 +205,7 @@ Add/subtract/interval units: `year`, `quarter`, `month`, `week`, `day`, `hour`,
|
|
|
205
205
|
| `coalesce` | 2+ expressions | first non-null |
|
|
206
206
|
|
|
207
207
|
```json
|
|
208
|
-
["case", { "lib/
|
|
208
|
+
["case", { "lib/expression-name": "Tier" },
|
|
209
209
|
[[[">", {…}, ["field", {…}, 14], 100], "Premium"],
|
|
210
210
|
[["<=", {…}, ["field", {…}, 14], 20], "Budget"]],
|
|
211
211
|
"Standard"]
|
|
@@ -235,7 +235,7 @@ positional arg is the default.)
|
|
|
235
235
|
`month-of-year`, `quarter-of-year`, `year-of-era`, `second-of-minute`.
|
|
236
236
|
|
|
237
237
|
```json
|
|
238
|
-
["field", { "
|
|
238
|
+
["field", { "temporal-unit": "month" }, 22]
|
|
239
239
|
```
|
|
240
240
|
|
|
241
241
|
## Field option: binning
|
|
@@ -249,5 +249,5 @@ positional arg is the default.)
|
|
|
249
249
|
| `default` | — | Metabase chooses |
|
|
250
250
|
|
|
251
251
|
```json
|
|
252
|
-
["field", { "
|
|
252
|
+
["field", { "binning": { "strategy": "num-bins", "num-bins": 10 } }, 14]
|
|
253
253
|
```
|