@metabase/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +972 -57
  2. package/dist/add-collection-DwxQDXzL.mjs +54 -0
  3. package/dist/add-collection-SL08iMub.mjs +11 -0
  4. package/dist/api-key-BktzvPb7.mjs +13 -0
  5. package/dist/{archive-CsWeHXle.mjs → archive-C1mF-9Kj.mjs} +7 -4
  6. package/dist/archive-CLWtbvvH.mjs +44 -0
  7. package/dist/archive-Cq4WKmJt.mjs +44 -0
  8. package/dist/archive-kYoy5LK5.mjs +39 -0
  9. package/dist/auth-DfYkakP3.mjs +19 -0
  10. package/dist/{body-Dv9hQ0Qk.mjs → body-rDrR-C1c.mjs} +3 -2
  11. package/dist/{branches-BujtceGr.mjs → branches-CH2UcCpX.mjs} +8 -6
  12. package/dist/cancel-CgLZcItQ.mjs +56 -0
  13. package/dist/{cancel-task-CT2xUMRg.mjs → cancel-task-DcYrFsM6.mjs} +9 -7
  14. package/dist/{card-CsXk8T6A.mjs → card-CQxvHeyP.mjs} +34 -15
  15. package/dist/card-ZCGU2JEh.mjs +20 -0
  16. package/dist/cards-C4NIaERo.mjs +37 -0
  17. package/dist/cli.mjs +33 -14
  18. package/dist/collection-B3sPXRLs.mjs +163 -0
  19. package/dist/collection-D_uFLIAS.mjs +19 -0
  20. package/dist/create-BUCLNqiN.mjs +48 -0
  21. package/dist/create-CB0Yp__0.mjs +66 -0
  22. package/dist/create-CNvd5T8h.mjs +48 -0
  23. package/dist/create-Cbh1cGj9.mjs +48 -0
  24. package/dist/create-CzfNOhOF.mjs +48 -0
  25. package/dist/create-DU0ZhnZu.mjs +44 -0
  26. package/dist/create-Dh0p-c2Y.mjs +44 -0
  27. package/dist/create-DvrVZ2hS.mjs +125 -0
  28. package/dist/create-QgN369N5.mjs +50 -0
  29. package/dist/{create-B8ektf-R.mjs → create-bqc_rmix.mjs} +8 -6
  30. package/dist/{create-branch-goZBTNnr.mjs → create-branch-BJFH9Hda.mjs} +9 -7
  31. package/dist/credentials-DTP1xuKz.mjs +85 -0
  32. package/dist/{current-task-DBjRNCFq.mjs → current-task-z_TiJ0kt.mjs} +9 -7
  33. package/dist/dashboard-CnMD04PQ.mjs +163 -0
  34. package/dist/dashboard-G1-dGLUR.mjs +20 -0
  35. package/dist/database-DQkUxTLd.mjs +17 -0
  36. package/dist/database-vvig8k4x.mjs +51 -0
  37. package/dist/db-CBaEfumR.mjs +22 -0
  38. package/dist/{delete-8vGU35r3.mjs → delete-CVYII8mq.mjs} +7 -5
  39. package/dist/{delete-B27KLF5X.mjs → delete-DeZQ1r9w.mjs} +7 -5
  40. package/dist/{delete-runtime-Byr60cR3.mjs → delete-runtime-BMzvfj_B.mjs} +4 -4
  41. package/dist/{delete-table-BNaJ_gA4.mjs → delete-table-ZiR9-ndv.mjs} +7 -5
  42. package/dist/deprovision-BhD3J-Am.mjs +61 -0
  43. package/dist/{dirty-aNUuph4I.mjs → dirty-D9agt7Os.mjs} +8 -6
  44. package/dist/docker-CHpV8PRz.mjs +612 -0
  45. package/dist/eid-B5wawMmO.mjs +13 -0
  46. package/dist/{export-QDkuuzSE.mjs → export-Bfk7JAlR.mjs} +30 -23
  47. package/dist/field-B3gvaqpK.mjs +278 -0
  48. package/dist/field-BDJ1pEgr.mjs +18 -0
  49. package/dist/fields-7ByLsxLg.mjs +38 -0
  50. package/dist/flag-pair-DtR1AiBQ.mjs +17 -0
  51. package/dist/get-BE6Izpus.mjs +36 -0
  52. package/dist/get-C3CcAJGg.mjs +49 -0
  53. package/dist/{get-DI_IJvgk.mjs → get-CQGeF-eP.mjs} +6 -4
  54. package/dist/get-D2m4jhwT.mjs +53 -0
  55. package/dist/{get-BGBIzMKY.mjs → get-DKy3DAJX.mjs} +6 -4
  56. package/dist/{get-COXHplHP.mjs → get-DUSR5i99.mjs} +7 -5
  57. package/dist/get-DikegGzi.mjs +36 -0
  58. package/dist/get-StkjKuh0.mjs +40 -0
  59. package/dist/get-bYc7eGYe.mjs +36 -0
  60. package/dist/{get-Cl8-IauC.mjs → get-cuHp9-6U.mjs} +7 -4
  61. package/dist/{get-i6LWOByV.mjs → get-gOT_RarI.mjs} +6 -4
  62. package/dist/get-run-D59Yqaoh.mjs +36 -0
  63. package/dist/get-tISo-cmg.mjs +41 -0
  64. package/dist/git-sync-BiTWfLgY.mjs +28 -0
  65. package/dist/{has-remote-changes-hjKoQuRy.mjs → has-remote-changes-B1TciDVD.mjs} +8 -6
  66. package/dist/{import-HJsSKRYx.mjs → import-DnnmmJbp.mjs} +11 -9
  67. package/dist/{input-Dojr-RTw.mjs → input-ikCiip6x.mjs} +2 -1
  68. package/dist/is-dirty-DClGFOGV.mjs +10 -0
  69. package/dist/{is-dirty-1Qy7hiHB.mjs → is-dirty-DlfX7e39.mjs} +5 -4
  70. package/dist/items-DQFQSpjF.mjs +77 -0
  71. package/dist/{key-DBxPSFwi.mjs → key-NDEARu2L.mjs} +1 -1
  72. package/dist/{license-MoWse3ZI.mjs → license-DBh13sc8.mjs} +3 -3
  73. package/dist/list-4kYCGv01.mjs +32 -0
  74. package/dist/list-9AOWhxqp.mjs +61 -0
  75. package/dist/{list-Bk6RsbJl.mjs → list-BwjqQ6pp.mjs} +5 -3
  76. package/dist/{list-C_PRdL5e.mjs → list-CP5RNjO6.mjs} +7 -5
  77. package/dist/{list-C8tdLOH5.mjs → list-Cy0VhXQs.mjs} +5 -3
  78. package/dist/list-D067ZSE5.mjs +47 -0
  79. package/dist/list-DAZP-IM5.mjs +32 -0
  80. package/dist/list-DJN-OvTZ.mjs +52 -0
  81. package/dist/list-DQj-QJAs.mjs +40 -0
  82. package/dist/list-Di529OJD.mjs +55 -0
  83. package/dist/{list-C4Ajrw8f.mjs → list-DlKzgnqo.mjs} +6 -3
  84. package/dist/list-GFfR9SuT.mjs +32 -0
  85. package/dist/{list-CWt3fqrZ.mjs → list-iFVEdi2J.mjs} +5 -3
  86. package/dist/{login-C9WTwNn6.mjs → login-DxgkosGx.mjs} +30 -9
  87. package/dist/{logout-oLszGCOg.mjs → logout-BlVwqBog.mjs} +7 -6
  88. package/dist/logs-CudNEkT4.mjs +58 -0
  89. package/dist/{manifest-CAdjQYH8.mjs → manifest-Dv5B9Blc.mjs} +3 -7
  90. package/dist/measure-BEQfnLdN.mjs +67 -0
  91. package/dist/measure-C7SbdYQk.mjs +19 -0
  92. package/dist/metadata-B2Td415K.mjs +38 -0
  93. package/dist/metadata-BTJAFVvZ.mjs +37 -0
  94. package/dist/{package-BGfw4ZWJ.mjs → package-DV6Asqim.mjs} +7 -1
  95. package/dist/paginate-CTSfuYiF.mjs +49 -0
  96. package/dist/parse-id-B38zTlYs.mjs +12 -0
  97. package/dist/parse-ref-DGvh4aDn.mjs +17 -0
  98. package/dist/parse-schemas-Ds-cVE-O.mjs +12 -0
  99. package/dist/{poll-ILanYysl.mjs → poll-Bh6oAifO.mjs} +2 -1
  100. package/dist/{poll-task-DbpsiQhl.mjs → poll-task-vPwV31Fs.mjs} +8 -7
  101. package/dist/predicates-DiIiS3k7.mjs +153 -0
  102. package/dist/preflight-DxJb-hUV.mjs +91 -0
  103. package/dist/{prompt-DpT8yAVy.mjs → prompt-Bf3DQ-qE.mjs} +1 -1
  104. package/dist/provision-B-I0zuDe.mjs +77 -0
  105. package/dist/ps-BmYQYC7t.mjs +10 -0
  106. package/dist/ps-CaiOFCv2.mjs +78 -0
  107. package/dist/query-BtF1yWZZ.mjs +90 -0
  108. package/dist/{query-PihYi-UZ.mjs → query-jmfqaXRP.mjs} +38 -13
  109. package/dist/remove-C2iv0g03.mjs +98 -0
  110. package/dist/remove-collection-DhZghaZy.mjs +38 -0
  111. package/dist/{remove-B2hVYn1v.mjs → remove-xskleeru.mjs} +6 -5
  112. package/dist/render-DXv-D6fU.mjs +182 -0
  113. package/dist/rescan-values-DW6u90ep.mjs +43 -0
  114. package/dist/revision-message-flag-CWQbKhdl.mjs +11 -0
  115. package/dist/{run-C2so6Qp6.mjs → run-DxVzhcF3.mjs} +27 -36
  116. package/dist/runs-BOHk1XnM.mjs +54 -0
  117. package/dist/{runtime-C9CEZhcn.mjs → runtime-cwBS8wwK.mjs} +428 -442
  118. package/dist/schema-tables-CcFbY_jN.mjs +45 -0
  119. package/dist/schemas-DZmv_V62.mjs +47 -0
  120. package/dist/{search-CopOytXY.mjs → search-CYMuc7Fg.mjs} +6 -19
  121. package/dist/segment-BMrUBz94.mjs +70 -0
  122. package/dist/segment-Df4pfjco.mjs +19 -0
  123. package/dist/{set-BcF7M1GQ.mjs → set-B_rrVwU4.mjs} +6 -4
  124. package/dist/{set-CbibegpA.mjs → set-CbGfQ7Ye.mjs} +8 -6
  125. package/dist/{setting-U3NtBMFo.mjs → setting-DqZY9NXP.mjs} +3 -3
  126. package/dist/setup-DxmcAorA.mjs +71 -0
  127. package/dist/snippet-CwSHjQyn.mjs +19 -0
  128. package/dist/snippet-Dw0Sjzkr.mjs +64 -0
  129. package/dist/start-Cn0epTks.mjs +380 -0
  130. package/dist/{stash-DOBbYozC.mjs → stash-BFZIl9F4.mjs} +9 -7
  131. package/dist/{status-Buf1ZbNR.mjs → status-BjCeJNLp.mjs} +10 -8
  132. package/dist/{status-CUcs8XBH.mjs → status-FDIDmqvM.mjs} +4 -2
  133. package/dist/{status-D1F5XHae.mjs → status-UALK3OJl.mjs} +4 -2
  134. package/dist/stop-DUwrDWw8.mjs +81 -0
  135. package/dist/summary-CS4UGiFJ.mjs +41 -0
  136. package/dist/sync-schema-IrHdJxmX.mjs +43 -0
  137. package/dist/{table-Cfk7oSvw.mjs → table-B-PYcgGb.mjs} +22 -9
  138. package/dist/table-Cdr5bKp1.mjs +19 -0
  139. package/dist/transform-CeZusR_w.mjs +24 -0
  140. package/dist/{transform-B5uRpg1G.mjs → transform-IEX4Mx3X.mjs} +56 -2
  141. package/dist/transform-job-BOn9-CGa.mjs +19 -0
  142. package/dist/{transform-job-C7QXWTVE.mjs → transform-job-Csr86muI.mjs} +7 -0
  143. package/dist/translate-B__zbDKm.mjs +111 -0
  144. package/dist/tree-Mh0uQ_Wy.mjs +32 -0
  145. package/dist/update-1Di9hbPo.mjs +56 -0
  146. package/dist/update-B5_pp6Jj.mjs +56 -0
  147. package/dist/update-B9DBMo30.mjs +52 -0
  148. package/dist/update-BfBsM_y1.mjs +56 -0
  149. package/dist/update-Bw0WZix_.mjs +73 -0
  150. package/dist/update-Cp1789qq.mjs +52 -0
  151. package/dist/update-D2VI_5cy.mjs +57 -0
  152. package/dist/update-D8GwQTcL.mjs +59 -0
  153. package/dist/{update-CL8tRbxr.mjs → update-Masp5WeT.mjs} +9 -7
  154. package/dist/update-dashcard-CNiQw1MD.mjs +71 -0
  155. package/dist/update-j9vgemKR.mjs +51 -0
  156. package/dist/url-GFM76VIK.mjs +54 -0
  157. package/dist/uuid-Uif0lNk8.mjs +47 -0
  158. package/dist/validate-DCYx6jdL.mjs +1496 -0
  159. package/dist/validate-query-B07oGG4K.mjs +37 -0
  160. package/dist/values-DrwNHUAI.mjs +36 -0
  161. package/dist/{wait-Bugr9eXD.mjs → wait-BoKk8CJy.mjs} +10 -8
  162. package/dist/wait-DO7tS7NI.mjs +19 -0
  163. package/dist/wait-flags-CjX2sEGm.mjs +35 -0
  164. package/dist/workspace-CyEX40D-.mjs +24 -0
  165. package/dist/workspace-DVuqKJGG.mjs +72 -0
  166. package/dist/workspace-credentials-B6BL-X0d.mjs +139 -0
  167. package/package.json +7 -1
  168. package/dist/auth-BF7IjZIH.mjs +0 -18
  169. package/dist/card-_Ta7zdYe.mjs +0 -19
  170. package/dist/create-CI2Cunq5.mjs +0 -38
  171. package/dist/create-DdbU3TLX.mjs +0 -42
  172. package/dist/database-PA9Goi25.mjs +0 -33
  173. package/dist/db-DMghzgb6.mjs +0 -17
  174. package/dist/field-C8IVs6rp.mjs +0 -76
  175. package/dist/field-DaYo_90x.mjs +0 -13
  176. package/dist/get-Cwpj7lDe.mjs +0 -35
  177. package/dist/get-Dh_acl8q.mjs +0 -34
  178. package/dist/is-dirty-DpKn9HJp.mjs +0 -8
  179. package/dist/list-CBSBHtK-.mjs +0 -38
  180. package/dist/parse-id-BhmmfyCP.mjs +0 -14
  181. package/dist/sync-BPyGXfUk.mjs +0 -26
  182. package/dist/table-D7nJt7JO.mjs +0 -16
  183. package/dist/transform-UbyewMxY.mjs +0 -21
  184. package/dist/transform-job-CrYkr-Ma.mjs +0 -19
  185. package/dist/update-DU2oU2j-.mjs +0 -49
  186. /package/dist/{body-flags-BUA9XV1u.mjs → body-flags-BK7J6Daz.mjs} +0 -0
  187. /package/dist/{setting-26ckqHAP.mjs → setting-CTaAeMci.mjs} +0 -0
@@ -1,8 +1,11 @@
1
- import "./package-BGfw4ZWJ.mjs";
1
+ import "./package-DV6Asqim.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { ConfigError, connectionFlags, defineMetabaseCommand, outputFlags, parseJson, profileFlag, renderItem } from "./runtime-C9CEZhcn.mjs";
4
- import { CardQueryResult, cardQueryView } from "./card-CsXk8T6A.mjs";
5
- import { parseId } from "./parse-id-BhmmfyCP.mjs";
3
+ import { renderItem } from "./render-DXv-D6fU.mjs";
4
+ import { ConfigError } from "./predicates-DiIiS3k7.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, parseJson, profileFlag } from "./runtime-cwBS8wwK.mjs";
6
+ import { parseId } from "./parse-id-B38zTlYs.mjs";
7
+ import "./field-B3gvaqpK.mjs";
8
+ import { CardQueryResult, cardQueryView } from "./card-CQxvHeyP.mjs";
6
9
  import { z } from "zod";
7
10
  import { Writable } from "node:stream";
8
11
 
@@ -13,12 +16,16 @@ async function pipeToStdout(stream) {
13
16
 
14
17
  //#endregion
15
18
  //#region src/commands/card/query.ts
16
- const ExportFormat = z.enum(["csv", "xlsx"]);
19
+ const ExportFormat = z.enum([
20
+ "csv",
21
+ "json",
22
+ "xlsx"
23
+ ]);
17
24
  const QueryParameters = z.array(z.unknown());
18
25
  var query_default = defineMetabaseCommand({
19
26
  meta: {
20
27
  name: "query",
21
- description: "Run a saved card and return results (json envelope, CSV, or XLSX)"
28
+ description: "Run a saved card and return results (json envelope, or stream CSV/JSON/XLSX via --export-format)"
22
29
  },
23
30
  args: {
24
31
  ...outputFlags,
@@ -39,7 +46,17 @@ var query_default = defineMetabaseCommand({
39
46
  },
40
47
  limit: {
41
48
  type: "string",
42
- description: "Cap rows kept in the JSON envelope (no effect on csv/xlsx exports)"
49
+ description: "Cap rows kept in the JSON envelope (no effect on streamed exports)"
50
+ },
51
+ "format-rows": {
52
+ type: "boolean",
53
+ description: "Streamed exports only: apply visualization-settings formatting to values (default false)",
54
+ default: false
55
+ },
56
+ "pivot-results": {
57
+ type: "boolean",
58
+ description: "Streamed exports only: emit the pivoted output for pivot questions (default false)",
59
+ default: false
43
60
  }
44
61
  },
45
62
  outputSchema: CardQueryResult,
@@ -55,8 +72,12 @@ var query_default = defineMetabaseCommand({
55
72
  const client = await getClient();
56
73
  const exportFormatRaw = args["export-format"];
57
74
  if (exportFormatRaw !== void 0 && exportFormatRaw !== "") {
58
- const exportFormat = parseExportFormat(exportFormatRaw);
59
- await streamExport(client, id, exportFormat, parameters);
75
+ await streamExport(client, id, {
76
+ format: parseExportFormat(exportFormatRaw),
77
+ parameters,
78
+ formatRows: args["format-rows"],
79
+ pivotResults: args["pivot-results"]
80
+ });
60
81
  return;
61
82
  }
62
83
  const result = await client.requestParsed(CardQueryResult, `/api/card/${id}/query`, {
@@ -77,7 +98,7 @@ function parseExportFormat(raw) {
77
98
  return result.data;
78
99
  }
79
100
  function applyLimit(result, limit) {
80
- if (limit === null || result.status !== "completed" || result.data.rows.length <= limit) return result;
101
+ if (limit === null || result.data === void 0 || result.data.rows.length <= limit) return result;
81
102
  return {
82
103
  ...result,
83
104
  data: {
@@ -86,9 +107,13 @@ function applyLimit(result, limit) {
86
107
  }
87
108
  };
88
109
  }
89
- async function streamExport(client, id, format, parameters) {
90
- const body = new URLSearchParams({ parameters: JSON.stringify(parameters) });
91
- const stream = await client.requestStream(`/api/card/${id}/query/${format}`, {
110
+ async function streamExport(client, id, options) {
111
+ const body = new URLSearchParams({
112
+ parameters: JSON.stringify(options.parameters),
113
+ format_rows: String(options.formatRows),
114
+ pivot_results: String(options.pivotResults)
115
+ });
116
+ const stream = await client.requestStream(`/api/card/${id}/query/${options.format}`, {
92
117
  method: "POST",
93
118
  body
94
119
  });
@@ -0,0 +1,98 @@
1
+ import "./package-DV6Asqim.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem } from "./render-DXv-D6fU.mjs";
4
+ import "./predicates-DiIiS3k7.mjs";
5
+ import { defineMetabaseCommand, outputFlags } from "./runtime-cwBS8wwK.mjs";
6
+ import { parseId } from "./parse-id-B38zTlYs.mjs";
7
+ import { promptConfirm } from "./prompt-Bf3DQ-qE.mjs";
8
+ import "./poll-Bh6oAifO.mjs";
9
+ import { checkDockerReady, containerNameFor, removeContainer, removeVolume, volumeNameFor } from "./docker-CHpV8PRz.mjs";
10
+ import { z } from "zod";
11
+
12
+ //#region src/commands/workspace/remove.ts
13
+ const RemoveResult = z.object({
14
+ workspace_id: z.number().int().positive(),
15
+ container_name: z.string(),
16
+ volume_name: z.string(),
17
+ removed_container: z.boolean(),
18
+ removed_volume: z.boolean()
19
+ });
20
+ const removeResultView = {
21
+ compactPick: RemoveResult.pick({
22
+ workspace_id: true,
23
+ removed_container: true,
24
+ removed_volume: true
25
+ }).strip(),
26
+ tableColumns: [
27
+ {
28
+ key: "workspace_id",
29
+ label: "ID"
30
+ },
31
+ {
32
+ key: "container_name",
33
+ label: "Container"
34
+ },
35
+ {
36
+ key: "volume_name",
37
+ label: "Volume"
38
+ },
39
+ {
40
+ key: "removed_container",
41
+ label: "Removed Container"
42
+ },
43
+ {
44
+ key: "removed_volume",
45
+ label: "Removed Volume"
46
+ }
47
+ ]
48
+ };
49
+ var remove_default = defineMetabaseCommand({
50
+ meta: {
51
+ name: "remove",
52
+ description: "Stop and remove the local container + app-db volume (does not affect remote)"
53
+ },
54
+ args: {
55
+ ...outputFlags,
56
+ id: {
57
+ type: "positional",
58
+ description: "Workspace id",
59
+ required: true
60
+ },
61
+ "keep-volume": {
62
+ type: "boolean",
63
+ description: "Keep the workspace's app-db volume (faster restart, app-db survives)",
64
+ default: false
65
+ },
66
+ yes: {
67
+ type: "boolean",
68
+ description: "Skip the confirmation prompt",
69
+ default: false
70
+ }
71
+ },
72
+ outputSchema: RemoveResult,
73
+ examples: ["metabase workspace remove 1 --yes", "metabase workspace remove 1 --keep-volume --yes"],
74
+ async run({ args, ctx }) {
75
+ const workspaceId = parseId(args.id);
76
+ const containerName = containerNameFor(workspaceId);
77
+ const volumeName = volumeNameFor(workspaceId);
78
+ const shouldRemoveVolume = args["keep-volume"] !== true;
79
+ await checkDockerReady();
80
+ if (!args.yes && process.stdin.isTTY === true) {
81
+ const confirmed = await promptConfirm({ message: shouldRemoveVolume ? `Remove container ${containerName} and its app-db volume ${volumeName}?` : `Remove container ${containerName}? (volume ${volumeName} will be kept)` });
82
+ if (!confirmed) return;
83
+ }
84
+ const removedContainer = await removeContainer(containerName);
85
+ const removedVolume = shouldRemoveVolume ? await removeVolume(volumeName) : false;
86
+ const result = {
87
+ workspace_id: workspaceId,
88
+ container_name: containerName,
89
+ volume_name: volumeName,
90
+ removed_container: removedContainer,
91
+ removed_volume: removedVolume
92
+ };
93
+ renderItem(result, removeResultView, ctx);
94
+ }
95
+ });
96
+
97
+ //#endregion
98
+ export { remove_default as default };
@@ -0,0 +1,38 @@
1
+ import "./package-DV6Asqim.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem } from "./render-DXv-D6fU.mjs";
4
+ import "./predicates-DiIiS3k7.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-cwBS8wwK.mjs";
6
+ import { parseId } from "./parse-id-B38zTlYs.mjs";
7
+ import "./poll-task-vPwV31Fs.mjs";
8
+ import "./poll-Bh6oAifO.mjs";
9
+ import { SyncSettingsUpdateResult, setCollectionRemoteSynced, syncSettingsUpdateView } from "./add-collection-DwxQDXzL.mjs";
10
+
11
+ //#region src/commands/git-sync/remove-collection.ts
12
+ var remove_collection_default = defineMetabaseCommand({
13
+ meta: {
14
+ name: "remove-collection",
15
+ description: "Unmark a collection as git-synced; cascades to descendants by location prefix"
16
+ },
17
+ args: {
18
+ ...outputFlags,
19
+ ...profileFlag,
20
+ ...connectionFlags,
21
+ id: {
22
+ type: "positional",
23
+ description: "Collection id (positive integer)",
24
+ required: true
25
+ }
26
+ },
27
+ outputSchema: SyncSettingsUpdateResult,
28
+ examples: ["metabase git-sync remove-collection 12", "metabase git-sync remove-collection 12 --json --profile prod"],
29
+ async run({ args, ctx, getClient }) {
30
+ const collectionId = parseId(args.id, "id");
31
+ const client = await getClient();
32
+ const result = await setCollectionRemoteSynced(client, collectionId, false);
33
+ renderItem(result, syncSettingsUpdateView, ctx);
34
+ }
35
+ });
36
+
37
+ //#endregion
38
+ export { remove_collection_default as default };
@@ -1,7 +1,9 @@
1
- import "./package-BGfw4ZWJ.mjs";
1
+ import "./package-DV6Asqim.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { ConfigError, clearLicense, defineMetabaseCommand, outputFlags, renderItem } from "./runtime-C9CEZhcn.mjs";
4
- import { promptConfirm } from "./prompt-DpT8yAVy.mjs";
3
+ import { renderItem } from "./render-DXv-D6fU.mjs";
4
+ import "./predicates-DiIiS3k7.mjs";
5
+ import { clearLicense, defineMetabaseCommand, outputFlags } from "./runtime-cwBS8wwK.mjs";
6
+ import { promptConfirm } from "./prompt-Bf3DQ-qE.mjs";
5
7
  import { z } from "zod";
6
8
 
7
9
  //#region src/commands/license/remove.ts
@@ -35,8 +37,7 @@ var remove_default = defineMetabaseCommand({
35
37
  outputSchema: LicenseRemoveResult,
36
38
  examples: ["metabase license remove --yes"],
37
39
  async run({ args, ctx }) {
38
- if (!args.yes) {
39
- if (!process.stdin.isTTY) throw new ConfigError("--yes required to remove license non-interactively");
40
+ if (!args.yes && process.stdin.isTTY === true) {
40
41
  const ok = await promptConfirm({
41
42
  message: "Remove stored license token?",
42
43
  initialValue: false
@@ -0,0 +1,182 @@
1
+ import { ConfigError, isPlainObject } from "./predicates-DiIiS3k7.mjs";
2
+ import Table from "cli-table3";
3
+
4
+ //#region src/output/cap.ts
5
+ function capListEnvelope(envelope, maxBytes) {
6
+ if (maxBytes <= 0) return envelope;
7
+ const fullBytes = jsonByteLength(envelope);
8
+ if (fullBytes <= maxBytes) return envelope;
9
+ let lo = 0;
10
+ let hi = envelope.data.length;
11
+ while (lo < hi) {
12
+ const mid = Math.ceil((lo + hi) / 2);
13
+ if (jsonByteLength(truncate(envelope, mid, fullBytes)) <= maxBytes) lo = mid;
14
+ else hi = mid - 1;
15
+ }
16
+ return truncate(envelope, lo, fullBytes);
17
+ }
18
+ function truncate(envelope, count, originalBytes) {
19
+ return {
20
+ ...envelope,
21
+ data: envelope.data.slice(0, count),
22
+ returned: count,
23
+ truncated: {
24
+ reason: "max_bytes",
25
+ bytes: originalBytes
26
+ }
27
+ };
28
+ }
29
+ function jsonByteLength(value) {
30
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
31
+ }
32
+
33
+ //#endregion
34
+ //#region src/output/notice.ts
35
+ function warn(message) {
36
+ process.stderr.write(message + "\n");
37
+ }
38
+ function listTruncationNotice(bytes) {
39
+ return `… cut at ${bytes} bytes; rerun with --max-bytes 0`;
40
+ }
41
+ function itemOversizeNotice(bytes) {
42
+ return `… item is ${bytes} bytes (exceeds --max-bytes); narrow with --fields, or pass --max-bytes 0`;
43
+ }
44
+
45
+ //#endregion
46
+ //#region src/output/projection.ts
47
+ function applyProjection(value, view, full, fields) {
48
+ if (fields !== void 0) {
49
+ if (fields.length === 0) throw new ConfigError("--fields requires at least one path");
50
+ return projectFields(value, fields);
51
+ }
52
+ if (full) return value;
53
+ const parsed = view.compactPick.safeParse(value);
54
+ if (parsed.success) return parsed.data;
55
+ throw new ConfigError(`compact projection failed: ${parsed.error.message}`);
56
+ }
57
+ function projectFields(value, fields) {
58
+ const out = {};
59
+ for (const path of fields) {
60
+ if (path.length === 0) throw new ConfigError(`empty field path`);
61
+ const parts = path.split(".");
62
+ if (parts.some((part) => part.length === 0)) throw new ConfigError(`invalid field path: "${path}"`);
63
+ setPath(out, parts, pickPath(value, parts));
64
+ }
65
+ return out;
66
+ }
67
+ function pickPath(value, parts) {
68
+ let cursor = value;
69
+ for (const part of parts) {
70
+ if (!isPlainObject(cursor) || !Object.hasOwn(cursor, part)) throw new ConfigError(`unknown field path: "${parts.join(".")}"`);
71
+ cursor = Reflect.get(cursor, part);
72
+ }
73
+ return cursor;
74
+ }
75
+ function setPath(target, parts, value) {
76
+ let cursor = target;
77
+ const lastIndex = parts.length - 1;
78
+ for (const [index, part] of parts.entries()) {
79
+ if (index === lastIndex) {
80
+ cursor[part] = value;
81
+ return;
82
+ }
83
+ const existing = cursor[part];
84
+ if (isPlainObject(existing)) cursor = existing;
85
+ else {
86
+ const next = {};
87
+ cursor[part] = next;
88
+ cursor = next;
89
+ }
90
+ }
91
+ }
92
+
93
+ //#endregion
94
+ //#region src/output/table.ts
95
+ function renderTable(rows, columns) {
96
+ const head = columns.map((column) => column.label ?? column.key);
97
+ const widths = columns.map((column) => column.width ?? null);
98
+ const hasWidth = widths.some((width) => width !== null);
99
+ const table = new Table(hasWidth ? {
100
+ head,
101
+ colWidths: widths
102
+ } : { head });
103
+ for (const row of rows) table.push(columns.map((column) => formatCell(row, column)));
104
+ return table.toString();
105
+ }
106
+ function formatCell(row, column) {
107
+ const value = row[column.key];
108
+ if (column.format !== void 0) return column.format(value);
109
+ return formatScalar(value);
110
+ }
111
+ function formatScalar(value) {
112
+ if (value === null || value === void 0) return "";
113
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
114
+ return JSON.stringify(value);
115
+ }
116
+
117
+ //#endregion
118
+ //#region src/output/render.ts
119
+ function writeJson(value) {
120
+ process.stdout.write(JSON.stringify(value, null, 2) + "\n");
121
+ }
122
+ function writeText(text) {
123
+ process.stdout.write(text + "\n");
124
+ }
125
+ function renderItem(item, view, opts) {
126
+ const projected = applyProjection(item, view, opts.full, opts.fields);
127
+ const body = renderItemBody(item, view, projected, opts) + "\n";
128
+ process.stdout.write(body);
129
+ emitItemOversizeNotice(body, opts.maxBytes);
130
+ }
131
+ function renderList(envelope, view, opts) {
132
+ if (opts.format === "json" || opts.fields !== void 0) {
133
+ renderJsonEnvelope(envelope, view, opts);
134
+ return;
135
+ }
136
+ if (envelope.data.length === 0) {
137
+ process.stdout.write("(no results)\n");
138
+ return;
139
+ }
140
+ const capped = capListEnvelope(envelope, opts.maxBytes);
141
+ process.stdout.write(renderTable(capped.data, view.tableColumns) + "\n");
142
+ if (capped.truncated !== void 0) warn(listTruncationNotice(capped.truncated.bytes));
143
+ }
144
+ function renderJsonEnvelope(envelope, view, opts) {
145
+ const projectedItems = envelope.data.map((item) => applyProjection(item, view, opts.full, opts.fields));
146
+ const projectedEnvelope = {
147
+ ...envelope,
148
+ data: projectedItems
149
+ };
150
+ const capped = capListEnvelope(projectedEnvelope, opts.maxBytes);
151
+ process.stdout.write(JSON.stringify(capped, null, 2) + "\n");
152
+ if (capped.truncated !== void 0) warn(listTruncationNotice(capped.truncated.bytes));
153
+ }
154
+ function renderItemBody(item, view, projected, opts) {
155
+ if (opts.format === "json" || opts.fields !== void 0) return JSON.stringify(projected, null, 2);
156
+ if (!opts.full) return renderKeyValueLines(columnPairs(item, view.tableColumns));
157
+ return renderKeyValueLines(objectPairs(projected));
158
+ }
159
+ function columnPairs(item, columns) {
160
+ return columns.map((column) => [column.label ?? column.key, formatCell(item, column)]);
161
+ }
162
+ function objectPairs(value) {
163
+ if (!isPlainObject(value)) {
164
+ const scalar = formatScalar(value);
165
+ return scalar === "" ? [] : [["", scalar]];
166
+ }
167
+ return Object.entries(value).map(([key, raw]) => [key, formatScalar(raw)]);
168
+ }
169
+ function renderKeyValueLines(pairs) {
170
+ if (pairs.length === 0) return "";
171
+ const padding = Math.max(...pairs.map(([label]) => label.length));
172
+ return pairs.map(([label, value]) => `${label.padEnd(padding)} ${value}`).join("\n");
173
+ }
174
+ function emitItemOversizeNotice(body, maxBytes) {
175
+ if (maxBytes <= 0) return;
176
+ const bytes = Buffer.byteLength(body, "utf8");
177
+ if (bytes <= maxBytes) return;
178
+ warn(itemOversizeNotice(bytes));
179
+ }
180
+
181
+ //#endregion
182
+ export { renderItem, renderList, warn, writeJson, writeText };
@@ -0,0 +1,43 @@
1
+ import "./package-DV6Asqim.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem } from "./render-DXv-D6fU.mjs";
4
+ import "./predicates-DiIiS3k7.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-cwBS8wwK.mjs";
6
+ import { parseId } from "./parse-id-B38zTlYs.mjs";
7
+ import "./field-B3gvaqpK.mjs";
8
+ import "./table-B-PYcgGb.mjs";
9
+ import { DatabaseSyncResult, databaseSyncResultView } from "./database-vvig8k4x.mjs";
10
+ import { z } from "zod";
11
+
12
+ //#region src/commands/db/rescan-values.ts
13
+ const RescanValuesApiResponse = z.object({ status: z.literal("ok") });
14
+ var rescan_values_default = defineMetabaseCommand({
15
+ meta: {
16
+ name: "rescan-values",
17
+ description: "Trigger a rescan of cached field values for a database"
18
+ },
19
+ args: {
20
+ ...outputFlags,
21
+ ...profileFlag,
22
+ ...connectionFlags,
23
+ id: {
24
+ type: "positional",
25
+ description: "Database id",
26
+ required: true
27
+ }
28
+ },
29
+ outputSchema: DatabaseSyncResult,
30
+ examples: ["metabase db rescan-values 1", "metabase db rescan-values 1 --json"],
31
+ async run({ args, ctx, getClient }) {
32
+ const id = parseId(args.id);
33
+ const client = await getClient();
34
+ const response = await client.requestParsed(RescanValuesApiResponse, `/api/database/${id}/rescan_values`, { method: "POST" });
35
+ renderItem({
36
+ id,
37
+ status: response.status
38
+ }, databaseSyncResultView, ctx);
39
+ }
40
+ });
41
+
42
+ //#endregion
43
+ export { rescan_values_default as default };
@@ -0,0 +1,11 @@
1
+ //#region src/commands/revision-message-flag.ts
2
+ const DEFAULT_ARCHIVE_REVISION_MESSAGE = "Archived via metabase CLI";
3
+ const revisionMessageFlag = { revisionMessage: {
4
+ type: "string",
5
+ description: "Audit-log message recorded with the change",
6
+ alias: "revision-message",
7
+ default: DEFAULT_ARCHIVE_REVISION_MESSAGE
8
+ } };
9
+
10
+ //#endregion
11
+ export { revisionMessageFlag };
@@ -1,9 +1,12 @@
1
- import "./package-BGfw4ZWJ.mjs";
1
+ import "./package-DV6Asqim.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag, renderItem } from "./runtime-C9CEZhcn.mjs";
4
- import { parseId } from "./parse-id-BhmmfyCP.mjs";
5
- import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS, pollUntil } from "./poll-ILanYysl.mjs";
6
- import { TransformRun } from "./transform-B5uRpg1G.mjs";
3
+ import { renderItem } from "./render-DXv-D6fU.mjs";
4
+ import "./predicates-DiIiS3k7.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-cwBS8wwK.mjs";
6
+ import { parseId } from "./parse-id-B38zTlYs.mjs";
7
+ import { pollUntil } from "./poll-Bh6oAifO.mjs";
8
+ import { TransformRun } from "./transform-IEX4Mx3X.mjs";
9
+ import { parseWaitFlags, waitFlags } from "./wait-flags-CjX2sEGm.mjs";
7
10
  import { z } from "zod";
8
11
 
9
12
  //#region src/commands/transform/run.ts
@@ -25,9 +28,9 @@ const TransformRunKickoff = z.object({
25
28
  const TransformRunResult = z.object({
26
29
  message: z.string(),
27
30
  run_id: z.number().int().positive().nullable(),
28
- final: TransformRun.nullable().optional()
31
+ final: TransformRun.nullable()
29
32
  });
30
- const transformRunView = {
33
+ const transformRunResultView = {
31
34
  compactPick: TransformRunResult,
32
35
  tableColumns: [{
33
36
  key: "run_id",
@@ -46,21 +49,7 @@ var run_default = defineMetabaseCommand({
46
49
  ...outputFlags,
47
50
  ...profileFlag,
48
51
  ...connectionFlags,
49
- wait: {
50
- type: "boolean",
51
- description: "Poll until the run reaches a terminal status",
52
- default: false
53
- },
54
- timeout: {
55
- type: "string",
56
- description: "Polling timeout in ms (used with --wait)",
57
- default: String(DEFAULT_TIMEOUT_MS)
58
- },
59
- interval: {
60
- type: "string",
61
- description: "Polling interval in ms (used with --wait)",
62
- default: String(DEFAULT_INTERVAL_MS)
63
- },
52
+ ...waitFlags,
64
53
  id: {
65
54
  type: "positional",
66
55
  description: "Transform id",
@@ -71,31 +60,33 @@ var run_default = defineMetabaseCommand({
71
60
  examples: ["metabase transform run 1", "metabase transform run 1 --wait --json"],
72
61
  async run({ args, ctx, getClient }) {
73
62
  const id = parseId(args.id);
63
+ const wait = parseWaitFlags(args);
74
64
  const client = await getClient();
75
65
  const kickoff = await client.requestParsed(TransformRunKickoff, `/api/transform/${id}/run`, { method: "POST" });
76
- if (!args.wait || kickoff.run_id === null) {
66
+ if (!wait.enabled) {
77
67
  renderItem({
78
68
  message: kickoff.message,
79
- run_id: kickoff.run_id
80
- }, transformRunView, ctx);
69
+ run_id: kickoff.run_id,
70
+ final: null
71
+ }, transformRunResultView, ctx);
81
72
  return;
82
73
  }
83
- const intervalMs = parseId(args.interval, "interval");
84
- const timeoutMs = parseId(args.timeout, "timeout");
74
+ if (kickoff.run_id === null) {
75
+ renderItem({
76
+ message: kickoff.message,
77
+ run_id: null,
78
+ final: null
79
+ }, transformRunResultView, ctx);
80
+ throw new Error(`transform run did not start: ${kickoff.message}`);
81
+ }
85
82
  const runId = kickoff.run_id;
86
- const final = await pollUntil(async () => client.requestParsed(TransformRun, `/api/transform/run/${runId}`), (run) => RUN_TERMINAL_STATUSES.has(run.status), {
87
- intervalMs,
88
- timeoutMs
89
- });
83
+ const final = await pollUntil(async () => client.requestParsed(TransformRun, `/api/transform/run/${runId}`), (run) => RUN_TERMINAL_STATUSES.has(run.status), wait.schedule);
90
84
  renderItem({
91
85
  message: kickoff.message,
92
86
  run_id: runId,
93
87
  final
94
- }, transformRunView, ctx);
95
- if (RUN_FAILURE_STATUSES.has(final.status)) {
96
- const detail = final.message ? `: ${final.message}` : "";
97
- throw new Error(`transform run ${runId} ${final.status}${detail}`);
98
- }
88
+ }, transformRunResultView, ctx);
89
+ if (RUN_FAILURE_STATUSES.has(final.status)) throw new Error(`transform run ${runId} ${final.status}`);
99
90
  }
100
91
  });
101
92
 
@@ -0,0 +1,54 @@
1
+ import "./package-DV6Asqim.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderList } from "./render-DXv-D6fU.mjs";
4
+ import "./predicates-DiIiS3k7.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, listEnvelopeSchema, outputFlags, profileFlag } from "./runtime-cwBS8wwK.mjs";
6
+ import { parseId } from "./parse-id-B38zTlYs.mjs";
7
+ import { collectPaginated } from "./paginate-CTSfuYiF.mjs";
8
+ import { TransformRun, TransformRunCompact, transformRunView } from "./transform-IEX4Mx3X.mjs";
9
+
10
+ //#region src/commands/transform/runs.ts
11
+ const TransformRunListEnvelope = listEnvelopeSchema(TransformRunCompact);
12
+ var runs_default = defineMetabaseCommand({
13
+ meta: {
14
+ name: "runs",
15
+ description: "List recent transform runs"
16
+ },
17
+ args: {
18
+ ...outputFlags,
19
+ ...profileFlag,
20
+ ...connectionFlags,
21
+ "transform-id": {
22
+ type: "string",
23
+ description: "Filter to runs of a single transform id"
24
+ },
25
+ limit: {
26
+ type: "string",
27
+ description: "Cap total runs returned (default: drain all pages)"
28
+ }
29
+ },
30
+ outputSchema: TransformRunListEnvelope,
31
+ examples: [
32
+ "metabase transform runs",
33
+ "metabase transform runs --transform-id 1 --json",
34
+ "metabase transform runs --limit 10 --json"
35
+ ],
36
+ async run({ args, ctx, getClient }) {
37
+ const transformId = args["transform-id"] === void 0 ? void 0 : parseId(args["transform-id"], "--transform-id");
38
+ const max = args.limit === void 0 ? void 0 : parseId(args.limit, "--limit");
39
+ const client = await getClient();
40
+ const items = await collectPaginated(client, "/api/transform/run", TransformRun, {
41
+ query: { "transform-ids": transformId },
42
+ ...max !== void 0 && { max }
43
+ });
44
+ const envelope = {
45
+ data: items,
46
+ returned: items.length,
47
+ ...max === void 0 ? { total: items.length } : { limit: max }
48
+ };
49
+ renderList(envelope, transformRunView, ctx);
50
+ }
51
+ });
52
+
53
+ //#endregion
54
+ export { runs_default as default };