@metabase/cli 0.1.6 → 0.1.8-alpha.drop-workspaces.a42f32e

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 (197) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +16 -238
  3. package/dist/{add-collection-BU8r3r2M.mjs → add-collection-CuLyFlrE.mjs} +8 -6
  4. package/dist/add-collection-DkucDB2N.mjs +10 -0
  5. package/dist/{archive-DMPS8Kih.mjs → archive-C1lk1rR7.mjs} +5 -6
  6. package/dist/{archive-C1enZgKV.mjs → archive-C2AfP9G_.mjs} +6 -7
  7. package/dist/{archive-lWgqiFAt.mjs → archive-COAWrOVp.mjs} +5 -6
  8. package/dist/{archive-BNinrUak.mjs → archive-DNVqPMhp.mjs} +7 -8
  9. package/dist/{archive-CRhiBpPJ.mjs → archive-Dt1qDaIF.mjs} +5 -6
  10. package/dist/{archive-CDA0KxL8.mjs → archive-mdSqCzVw.mjs} +5 -6
  11. package/dist/auth-WILFa6Xf.mjs +19 -0
  12. package/dist/{body-DjdFxjpg.mjs → body-b76dLVpL.mjs} +2 -2
  13. package/dist/{branches-B1WRfG7-.mjs → branches-DwV1q-4h.mjs} +5 -6
  14. package/dist/{cancel-Dl_Ho056.mjs → cancel-DDKstWQM.mjs} +6 -7
  15. package/dist/{cancel-task-CdigdCaO.mjs → cancel-task-DX_OdGan.mjs} +6 -7
  16. package/dist/{render-CfznwleY.mjs → capabilities-Dj3NgPHg.mjs} +66 -10
  17. package/dist/card-Bd8jLmZW.mjs +20 -0
  18. package/dist/{card-DlCAaAPq.mjs → card-BtPiKjbB.mjs} +1 -1
  19. package/dist/{cards-BGiJS675.mjs → cards-CYKPNOp3.mjs} +4 -5
  20. package/dist/cli.mjs +23 -24
  21. package/dist/collection-gz4k8jWl.mjs +20 -0
  22. package/dist/{create-Be_0Vier.mjs → create-B4aKAWaQ.mjs} +8 -9
  23. package/dist/{create-dhxPxfF3.mjs → create-BfRIHlHk.mjs} +12 -13
  24. package/dist/{create-CzzrbL0u.mjs → create-BfseKO3F.mjs} +8 -9
  25. package/dist/{create-BTcpaop_.mjs → create-BqiR1kvi.mjs} +7 -8
  26. package/dist/{create-BYlIju0b.mjs → create-BscN4jFB.mjs} +10 -11
  27. package/dist/{create-CwGtmwqm.mjs → create-CE1WZ4du.mjs} +9 -10
  28. package/dist/{create-DGth_uOp.mjs → create-CQxJpVXk.mjs} +9 -10
  29. package/dist/{create-BNiva__H.mjs → create-DRhRPfD-.mjs} +11 -12
  30. package/dist/{create-branch-DKZkoQ64.mjs → create-branch-2yEa7-9x.mjs} +6 -7
  31. package/dist/{current-task-CCRzm0_7.mjs → current-task-5buIatuG.mjs} +7 -8
  32. package/dist/dashboard-BL8_Ysst.mjs +21 -0
  33. package/dist/{database-lH-B3G1I.mjs → database-_Td7rG4o.mjs} +1 -1
  34. package/dist/db-Bw8m4M2J.mjs +22 -0
  35. package/dist/{delete-Dimc-2y8.mjs → delete-C3i5dE4s.mjs} +8 -7
  36. package/dist/{delete-ZjnV35OJ.mjs → delete-CF8in6gw.mjs} +8 -7
  37. package/dist/{delete-runtime-B6RQo_pw.mjs → delete-runtime-Bo7v-0au.mjs} +6 -6
  38. package/dist/{delete-table-agZJpivt.mjs → delete-table-m-6cOPnX.mjs} +8 -7
  39. package/dist/{dirty-D4d0yHqj.mjs → dirty-hGWiemB-.mjs} +5 -6
  40. package/dist/{eid-BXzaQh0o.mjs → eid-BP0H-LTl.mjs} +12 -8
  41. package/dist/{error-C9S6PN3-.mjs → error-BLukG0Vf.mjs} +3 -2
  42. package/dist/{export-DTygoXBP.mjs → export-wh9l0s7F.mjs} +10 -10
  43. package/dist/field-GgVH-HUD.mjs +18 -0
  44. package/dist/{field-yomXlkvl.mjs → field-MGxpNQUH.mjs} +12 -3
  45. package/dist/{fields-CoQi99gv.mjs → fields-BD52yx5k.mjs} +6 -7
  46. package/dist/{get-C2p383Qc.mjs → get-436DayeX.mjs} +5 -6
  47. package/dist/{get-D3SbEQSE.mjs → get-B1jyFBkg.mjs} +4 -5
  48. package/dist/{get-C3HdQ91a.mjs → get-BLUldOxi.mjs} +5 -6
  49. package/dist/{get-CP3Z3NiH.mjs → get-BVMyLnhh.mjs} +6 -7
  50. package/dist/{get-Bzys7vgp.mjs → get-BhFiIyyH.mjs} +4 -5
  51. package/dist/{get-lb7q3JYs.mjs → get-C5PKCCzj.mjs} +3 -4
  52. package/dist/{get-DQTZG_NP.mjs → get-C_LAPJ7J.mjs} +4 -5
  53. package/dist/{get-CzuzeKSe.mjs → get-CgdzDOTX.mjs} +7 -8
  54. package/dist/{get-C_w1kvN3.mjs → get-Cu7Om0g2.mjs} +6 -7
  55. package/dist/{get-Ddr0XLh7.mjs → get-DETcYP1F.mjs} +5 -6
  56. package/dist/{get-DFxZXaKz.mjs → get-DSmnRBrw.mjs} +5 -7
  57. package/dist/{get-Hc93A0Yz.mjs → get-EJOWmpkC.mjs} +5 -6
  58. package/dist/{get-run-B7sKdaDU.mjs → get-run-BEvwTmr7.mjs} +5 -6
  59. package/dist/{get-DSWFjy7O.mjs → get-z9XIWbVG.mjs} +4 -5
  60. package/dist/git-sync-oYYp_Z6v.mjs +28 -0
  61. package/dist/{has-remote-changes-BY10-nnE.mjs → has-remote-changes-BNjTil7k.mjs} +7 -7
  62. package/dist/{import-CiMz4Wz-.mjs → import-C0iBM0UR.mjs} +11 -10
  63. package/dist/is-dirty-C_RyVkc1.mjs +9 -0
  64. package/dist/{is-dirty-BZOaryxT.mjs → is-dirty-D_e5Xoke.mjs} +5 -5
  65. package/dist/{items-BWfvkY-J.mjs → items-D6h0ejme.mjs} +4 -5
  66. package/dist/{list-BI4zr8LW.mjs → list-B3CgwSU4.mjs} +6 -7
  67. package/dist/{list-DZ8fNUoQ.mjs → list-BJxm0-6m.mjs} +6 -7
  68. package/dist/{list-sD5N3fGk.mjs → list-BZkOPBmK.mjs} +6 -7
  69. package/dist/{list-2j7GsXsl.mjs → list-CSX_xieo.mjs} +3 -4
  70. package/dist/{list-D4sFiqX8.mjs → list-CWItVq2v.mjs} +5 -6
  71. package/dist/{list-Brgh-Z2v.mjs → list-CkCgkJFh.mjs} +4 -5
  72. package/dist/{list-d58BprgJ.mjs → list-CmVbbX3f.mjs} +4 -5
  73. package/dist/{list--OYdUTtu.mjs → list-D0ZVA1e1.mjs} +4 -5
  74. package/dist/{list-CL7eCOQE.mjs → list-DLC82gFo.mjs} +3 -4
  75. package/dist/{list-SOG0whQ-.mjs → list-DcV2bfg8.mjs} +3 -4
  76. package/dist/{list-Clz5igWg.mjs → list-ZX3ooQ9h.mjs} +4 -6
  77. package/dist/{list-C3hfovHv.mjs → list-pXgd_HTy.mjs} +4 -5
  78. package/dist/{list-DXH7TlkU.mjs → list-r3gm10tz.mjs} +4 -5
  79. package/dist/{login-Bm2AnCez.mjs → login-DSS8QywX.mjs} +17 -14
  80. package/dist/{logout-BlyRJODO.mjs → logout-B6acbVng.mjs} +9 -9
  81. package/dist/{manifest-BBR46KFM.mjs → manifest-B_OfG-Ss.mjs} +1 -2
  82. package/dist/measure-DDn0jAB8.mjs +19 -0
  83. package/dist/{metadata-DqiI2q9q.mjs → metadata-C-bcafH-.mjs} +6 -7
  84. package/dist/{metadata-B8ZSF9LA.mjs → metadata-D_wFDaCb.mjs} +7 -8
  85. package/dist/{parse-id-lk_K-CEF.mjs → parse-id-BapRoz4R.mjs} +1 -1
  86. package/dist/{path-AEtZ3mBq.mjs → path-DmYXSF59.mjs} +4 -6
  87. package/dist/{poll-DHKDpCiq.mjs → poll-CYFFYOiB.mjs} +1 -1
  88. package/dist/{poll-task-Cooi0lQV.mjs → poll-task-Dalt24ov.mjs} +19 -3
  89. package/dist/{preflight-aXV5LyDs.mjs → preflight-G7NUAKod.mjs} +3 -3
  90. package/dist/{query-BlsVNZpD.mjs → query-COWTai5j.mjs} +12 -12
  91. package/dist/{query-AaKzYnTY.mjs → query-DRosi9Ha.mjs} +9 -8
  92. package/dist/query-result-PoQE05Pe.mjs +19 -0
  93. package/dist/{remove-collection-CoCmrrQs.mjs → remove-collection-CLWw-48s.mjs} +10 -9
  94. package/dist/{render-OQn3iRsI.mjs → render-BQHJhSP1.mjs} +1 -1
  95. package/dist/{rescan-values-C0FDsjT7.mjs → rescan-values-C3L03Crf.mjs} +9 -10
  96. package/dist/{run-B4Wn43zm.mjs → run-PL8TRDGx.mjs} +14 -14
  97. package/dist/{runs-Bbaszr18.mjs → runs-B86YP36a.mjs} +5 -6
  98. package/dist/{runtime-Dmv5VtUK.mjs → runtime-C2EDX9E7.mjs} +16 -87
  99. package/dist/{schema-tables-CaWinbuK.mjs → schema-tables-CZr0QT1g.mjs} +6 -7
  100. package/dist/{schemas-DUgGpAyB.mjs → schemas-DnGJlmQl.mjs} +4 -5
  101. package/dist/{search-BLrBXLUk.mjs → search-thFe-n3F.mjs} +4 -5
  102. package/dist/segment-ydERbF0L.mjs +19 -0
  103. package/dist/{set-DfGsta5O.mjs → set-CDQE4s8H.mjs} +7 -7
  104. package/dist/setting-BTMmbmKB.mjs +17 -0
  105. package/dist/{setup-C9ikBRw_.mjs → setup-mOHveOFI.mjs} +7 -8
  106. package/dist/{skills-CiN1OQ8W.mjs → skills-BDPVoBWU.mjs} +33 -2
  107. package/dist/{skills-CUHIcQS6.mjs → skills-d2iLclsk.mjs} +3 -3
  108. package/dist/snippet-i1Z8-yJQ.mjs +19 -0
  109. package/dist/{stash-EIDcSvpF.mjs → stash-B4RTStPo.mjs} +11 -10
  110. package/dist/{status-95ElRAu9.mjs → status-B7H0JH52.mjs} +10 -8
  111. package/dist/{status-B0_MiZEf.mjs → status-DoVvjifV.mjs} +4 -5
  112. package/dist/{summary-C12LiEuJ.mjs → summary-BsdiF7LZ.mjs} +5 -6
  113. package/dist/{sync-schema-Ba8M3DiX.mjs → sync-schema-CvXkT9Rg.mjs} +9 -10
  114. package/dist/{table-C7a5V6Zn.mjs → table-CkWja2UH.mjs} +1 -1
  115. package/dist/table-DoAu2iwB.mjs +19 -0
  116. package/dist/transform-JzFSQdFi.mjs +24 -0
  117. package/dist/transform-job-C8q3Fcf7.mjs +19 -0
  118. package/dist/{tree-Des2ZG9d.mjs → tree-CGBtDXfk.mjs} +3 -4
  119. package/dist/{update-DzAN4SPj.mjs → update-B89kI8l9.mjs} +10 -11
  120. package/dist/{update-_QfgNa53.mjs → update-BA48uHRd.mjs} +10 -11
  121. package/dist/{update-DBi5U8zb.mjs → update-BHit5RyS.mjs} +12 -13
  122. package/dist/{update-mYVnoYNV.mjs → update-BJhk_A4R.mjs} +11 -12
  123. package/dist/{update-Bx54nWEI.mjs → update-BJn9ZitD.mjs} +12 -13
  124. package/dist/{update-F6DmZncY.mjs → update-C44bumhM.mjs} +9 -10
  125. package/dist/{update-CyIZdbIQ.mjs → update-DqAKFmkw.mjs} +9 -10
  126. package/dist/{update-njHe3j-s.mjs → update-JpO3b8g3.mjs} +10 -11
  127. package/dist/{update-DSgceARZ.mjs → update-WMzbyUw2.mjs} +9 -10
  128. package/dist/{update-dashcard-wpSjv4M7.mjs → update-dashcard-C8BGZtY7.mjs} +8 -9
  129. package/dist/{upgrade-iAuvhX-W.mjs → upgrade-DeiR3fjf.mjs} +41 -28
  130. package/dist/{uuid-CMKnS8-z.mjs → uuid-BWvbC2Z8.mjs} +3 -4
  131. package/dist/{validate-dPEOnOf8.mjs → validate-CqVB_3_p.mjs} +1 -1
  132. package/dist/{validate-query-Cw6WE5Y8.mjs → validate-query-BUTNK00f.mjs} +2 -2
  133. package/dist/values-07BZxAK5.mjs +44 -0
  134. package/dist/{verify-D5YtTqqp.mjs → verify-D2q5RI4i.mjs} +1 -1
  135. package/dist/{wait-Bv3Tsnv4.mjs → wait-DWyuBO_X.mjs} +8 -9
  136. package/dist/{wait-flags-Dzq9BGQY.mjs → wait-flags-Crs-j7Z8.mjs} +2 -2
  137. package/package.json +1 -1
  138. package/skill-data/core/SKILL.md +13 -26
  139. package/skill-data/git-sync/SKILL.md +8 -63
  140. package/skill-data/transform/SKILL.md +3 -4
  141. package/skill-data/visualization/SKILL.md +158 -0
  142. package/skill-data/visualization/references/settings.md +414 -0
  143. package/skills/metabase-cli/SKILL.md +1 -1
  144. package/dist/add-collection-C0w6ACQF.mjs +0 -11
  145. package/dist/auth-CzXb_zB2.mjs +0 -19
  146. package/dist/capabilities-7e9MgquN.mjs +0 -29
  147. package/dist/card-DP4rfoOi.mjs +0 -21
  148. package/dist/collection-tY18ezvn.mjs +0 -21
  149. package/dist/create-CHF313Qg.mjs +0 -52
  150. package/dist/credentials-dzeq7ckm.mjs +0 -88
  151. package/dist/dashboard-ChM_Tu0l.mjs +0 -22
  152. package/dist/database-CIXwHKjK.mjs +0 -17
  153. package/dist/db-DrQn_i3W.mjs +0 -22
  154. package/dist/delete-CM3jnAeQ.mjs +0 -100
  155. package/dist/deprovision-CwxcIT3k.mjs +0 -65
  156. package/dist/docker-Oq80q3tu.mjs +0 -515
  157. package/dist/field-Z6Pcxf4n.mjs +0 -19
  158. package/dist/git-sync-CiGAad76.mjs +0 -28
  159. package/dist/is-dirty-Ume4oV0j.mjs +0 -10
  160. package/dist/license-Dxarh-gG.mjs +0 -17
  161. package/dist/list-zSO0DMw-.mjs +0 -36
  162. package/dist/logs-CywPikkL.mjs +0 -60
  163. package/dist/measure-C44EK_xt.mjs +0 -20
  164. package/dist/parse-schemas-BqUdWUwq.mjs +0 -12
  165. package/dist/process-C7V8LJ-j.mjs +0 -105
  166. package/dist/provision-UWcNDoDe.mjs +0 -82
  167. package/dist/ps-CJU0EbrC.mjs +0 -80
  168. package/dist/ps-DEroLgbI.mjs +0 -11
  169. package/dist/remove-BFWun0e8.mjs +0 -63
  170. package/dist/segment-B3Uwwcsm.mjs +0 -20
  171. package/dist/set-B8cUbRLD.mjs +0 -68
  172. package/dist/setting-D2p2MA7f.mjs +0 -18
  173. package/dist/snippet-B7D0uWlz.mjs +0 -20
  174. package/dist/start-3PX3ahjT.mjs +0 -413
  175. package/dist/status-CEplmC44.mjs +0 -34
  176. package/dist/stop-CQ0XGrN8.mjs +0 -83
  177. package/dist/table-e6h8SLVX.mjs +0 -20
  178. package/dist/transform-BMYh1lsC.mjs +0 -25
  179. package/dist/transform-job-Cm7z5TfH.mjs +0 -20
  180. package/dist/update-DHZubok3.mjs +0 -77
  181. package/dist/url-DWaT6WIZ.mjs +0 -56
  182. package/dist/values-BfSTAbzc.mjs +0 -37
  183. package/dist/wait-8yV9_WIo.mjs +0 -19
  184. package/dist/workspace-BBXJczJK.mjs +0 -72
  185. package/dist/workspace-CKLZrR7l.mjs +0 -26
  186. package/dist/workspace-credentials-BXpABsNZ.mjs +0 -100
  187. package/dist/yaml-YTQiYJ9s.mjs +0 -43
  188. package/skill-data/viz/SKILL.md +0 -137
  189. package/skill-data/viz/references/settings.md +0 -312
  190. package/skill-data/workspace/SKILL.md +0 -390
  191. /package/dist/{body-flags-D7q87Btw.mjs → body-flags-D78h_-Ua.mjs} +0 -0
  192. /package/dist/{input-cMSEqISy.mjs → input-xewHccej.mjs} +0 -0
  193. /package/dist/{parse-enum-CrEWOhuY.mjs → parse-enum-Dr7ACrTR.mjs} +0 -0
  194. /package/dist/{prompt-CFKoys7k.mjs → prompt-u4WhE4T5.mjs} +0 -0
  195. /package/dist/{snippet-COggaWxx.mjs → snippet-xh42tYly.mjs} +0 -0
  196. /package/dist/{transform-GTW3G-01.mjs → transform-DyJb0bV0.mjs} +0 -0
  197. /package/dist/{transform-job-DeTDPMxt.mjs → transform-job-DpDGoqQt.mjs} +0 -0
@@ -1,413 +0,0 @@
1
- import { ConfigError, errorMessage } from "./command-augment-BH9qgQ5u.mjs";
2
- import { connectionFlags, outputFlags, profileFlag } from "./error-C9S6PN3-.mjs";
3
- import { createClient, defineMetabaseCommand, localUrl, parseInteger, parseOptionalInteger, resolveLicenseToken } from "./runtime-Dmv5VtUK.mjs";
4
- import { warn } from "./capabilities-7e9MgquN.mjs";
5
- import { renderItem } from "./render-CfznwleY.mjs";
6
- import { parseId } from "./parse-id-lk_K-CEF.mjs";
7
- import { pollUntil } from "./poll-DHKDpCiq.mjs";
8
- import "./yaml-YTQiYJ9s.mjs";
9
- import { runProcess } from "./process-C7V8LJ-j.mjs";
10
- import { Workspace } from "./workspace-BBXJczJK.mjs";
11
- import { CONTAINER_REPO_DIR, checkDockerReady, containerLifecycleStatus, containerNameFor, pullImage, removeContainer, runWorkspaceContainer, scrubContainerConfig, waitForConfigConsumed } from "./docker-Oq80q3tu.mjs";
12
- import { REPO_SYNC_MODES, RepoSyncMode, buildCredentialsJson, generateWorkspaceCredentials, injectCredentialsIntoConfig, injectRepoSettingsIntoConfig } from "./workspace-credentials-BXpABsNZ.mjs";
13
- import { z } from "zod";
14
- import { resolve } from "node:path";
15
- import { stat } from "node:fs/promises";
16
- import { createServer } from "node:net";
17
-
18
- //#region src/core/http/probe.ts
19
- async function probeHealth(url, timeoutMs) {
20
- try {
21
- const response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
22
- return {
23
- ready: response.ok,
24
- status: response.status
25
- };
26
- } catch (error) {
27
- if (error instanceof Error) return {
28
- ready: false,
29
- status: null
30
- };
31
- throw error;
32
- }
33
- }
34
-
35
- //#endregion
36
- //#region src/runtime/port.ts
37
- const PORT_SCAN_LIMIT = 100;
38
- function isPortFree(port) {
39
- return new Promise((resolve$1) => {
40
- const server = createServer();
41
- server.unref();
42
- server.once("error", () => resolve$1(false));
43
- server.once("listening", () => {
44
- server.close(() => resolve$1(true));
45
- });
46
- server.listen(port, "0.0.0.0");
47
- });
48
- }
49
- async function findFreePort(start) {
50
- for (let port = start; port < start + PORT_SCAN_LIMIT; port++) if (await isPortFree(port)) return port;
51
- throw new ConfigError(`no free port in range ${start}..${start + PORT_SCAN_LIMIT - 1}`);
52
- }
53
-
54
- //#endregion
55
- //#region src/commands/workspace/start.ts
56
- const ENTERPRISE_IMAGE = "metabase/metabase-enterprise";
57
- const ENTERPRISE_HEAD_IMAGE = "metabase/metabase-enterprise-head";
58
- const LATEST_TAG = "latest";
59
- const WORKSPACES_MIN_VERSION = 62;
60
- const DEFAULT_HOST_PORT = 3e3;
61
- const DEFAULT_READY_TIMEOUT_MS = 24e4;
62
- const HEALTH_INTERVAL_MS = 2e3;
63
- const HEALTH_MAX_INTERVAL_MS = 1e4;
64
- const HEALTH_PROBE_TIMEOUT_MS = 4e3;
65
- const DEFAULT_REPO_MODE = "read-write";
66
- const REPO_FILE_URL = `file://${CONTAINER_REPO_DIR}`;
67
- const METADATA_IMPORT_TIMEOUT_MS = DEFAULT_READY_TIMEOUT_MS;
68
- const METADATA_POLL_INTERVAL_MS = 250;
69
- const METADATA_POLL_MAX_INTERVAL_MS = 5e3;
70
- const MetadataImportEnqueued = z.object({
71
- queued: z.literal(true),
72
- "import-id": z.string()
73
- });
74
- const MetadataImportStatus = z.object({
75
- id: z.string(),
76
- status: z.enum([
77
- "queued",
78
- "running",
79
- "ok",
80
- "error"
81
- ]),
82
- "enqueued-at": z.string(),
83
- "started-at": z.string().nullable(),
84
- "finished-at": z.string().nullable(),
85
- "wall-ms": z.number().nullable(),
86
- error: z.string().nullable()
87
- });
88
- const StartResult = z.object({
89
- workspace_id: z.number().int().positive(),
90
- workspace_name: z.string(),
91
- container_name: z.string(),
92
- state: z.enum(["running", "starting"]),
93
- host_port: z.number().int().positive(),
94
- url: z.string(),
95
- image: z.string()
96
- });
97
- const startResultView = {
98
- compactPick: StartResult.pick({
99
- workspace_id: true,
100
- workspace_name: true,
101
- state: true,
102
- url: true
103
- }).strip(),
104
- tableColumns: [
105
- {
106
- key: "workspace_id",
107
- label: "ID"
108
- },
109
- {
110
- key: "workspace_name",
111
- label: "Name"
112
- },
113
- {
114
- key: "state",
115
- label: "State"
116
- },
117
- {
118
- key: "url",
119
- label: "URL"
120
- }
121
- ]
122
- };
123
- var start_default = defineMetabaseCommand({
124
- meta: {
125
- name: "start",
126
- description: "Start a local Docker container that serves as the workspace's dev instance"
127
- },
128
- capabilities: {
129
- minVersion: WORKSPACES_MIN_VERSION,
130
- tokenFeature: "workspaces"
131
- },
132
- args: {
133
- ...outputFlags,
134
- ...profileFlag,
135
- ...connectionFlags,
136
- id: {
137
- type: "positional",
138
- description: "Workspace id",
139
- required: true
140
- },
141
- port: {
142
- type: "string",
143
- description: `Host port to bind (default: ${DEFAULT_HOST_PORT}; auto-shifts up when this flag is omitted, fails on collision when set explicitly)`
144
- },
145
- image: {
146
- type: "string",
147
- description: `Docker image to run. Default: ${ENTERPRISE_IMAGE}:${LATEST_TAG} once Metabase v${WORKSPACES_MIN_VERSION} is released, otherwise ${ENTERPRISE_HEAD_IMAGE}:${LATEST_TAG}.`
148
- },
149
- wait: {
150
- type: "boolean",
151
- description: "Block until /api/health is ready before returning. Default: return as soon as the container has consumed config.yml. (Implied when --metadata is on, since the import requires a live API.)",
152
- default: false
153
- },
154
- timeout: {
155
- type: "string",
156
- description: `Per-phase readiness deadline in ms — covers post-create config consumption, (with --wait) the /api/health probe, and (with --metadata) the metadata-import status poll. Default: ${DEFAULT_READY_TIMEOUT_MS}.`,
157
- default: String(DEFAULT_READY_TIMEOUT_MS)
158
- },
159
- pull: {
160
- type: "boolean",
161
- description: "Pull the image before starting",
162
- default: true
163
- },
164
- metadata: {
165
- type: "boolean",
166
- description: "Fetch the workspace's warehouse metadata from the parent and POST it to the child instance once it is healthy",
167
- default: true
168
- },
169
- force: {
170
- type: "boolean",
171
- description: "Remove and recreate the container even if it is running. Stopped containers (exited/created/dead) are recreated automatically without this flag.",
172
- default: false
173
- },
174
- repo: {
175
- type: "string",
176
- description: `Bind-mount a host directory (typically a remote-sync git repo) into the container at ${CONTAINER_REPO_DIR}. Sets remote-sync-url=${REPO_FILE_URL} in the workspace config.yml so the child boots already wired to the repo.`
177
- },
178
- "repo-branch": {
179
- type: "string",
180
- description: "Branch to set as remote-sync-branch (default: the current branch of the host repo, read from HEAD)"
181
- },
182
- "repo-mode": {
183
- type: "string",
184
- description: "remote-sync-type: 'read-write' (default) or 'read-only'",
185
- default: DEFAULT_REPO_MODE
186
- }
187
- },
188
- outputSchema: StartResult,
189
- examples: [
190
- "mb workspace start 1",
191
- "mb workspace start 1 --wait",
192
- "mb workspace start 1 --port 3100",
193
- "mb workspace start 1 --image metabase/metabase-enterprise:latest --no-pull",
194
- "mb workspace start 1 --force",
195
- "mb workspace start 1 --repo /path/to/sync-repo --wait",
196
- "mb workspace start 1 --repo /path/to/sync-repo --repo-branch dev --repo-mode read-only"
197
- ],
198
- async run({ args, ctx, getClient, getResolvedConfig, getServerInfo }) {
199
- const workspaceId = parseId(args.id);
200
- const containerName = containerNameFor(workspaceId);
201
- const requestedPort = parseOptionalInteger(args.port, {
202
- name: "--port",
203
- min: 1
204
- });
205
- const readyTimeoutMs = parseInteger(args.timeout ?? String(DEFAULT_READY_TIMEOUT_MS), {
206
- name: "--timeout",
207
- min: 1e3
208
- });
209
- const client = await getClient();
210
- const resolved = await getResolvedConfig();
211
- const licenseToken = await resolveLicenseToken({});
212
- const serverInfo = await getServerInfo();
213
- const image = args.image ?? resolveDefaultImage(serverInfo?.version ?? null);
214
- await checkDockerReady();
215
- await ensureNoExistingContainer(workspaceId, containerName, args.force);
216
- const pullPromise = args.pull ? pullImage(image) : Promise.resolve();
217
- const workspace = await client.requestParsed(Workspace, `/api/ee/workspace-manager/${workspaceId}`);
218
- assertAllDatabasesProvisioned(workspace);
219
- const hostPort = await resolveHostPort(requestedPort);
220
- const [parentConfigYaml, metadataJson, repoOptions] = await Promise.all([
221
- fetchConfigYaml(client, workspaceId),
222
- args.metadata ? fetchMetadataJson(client, workspaceId) : Promise.resolve(null),
223
- resolveRepoOptions({
224
- hostPath: args.repo,
225
- branch: args["repo-branch"],
226
- mode: args["repo-mode"]
227
- })
228
- ]);
229
- const bundle = assembleBootBundle(parentConfigYaml, workspaceId, repoOptions);
230
- await pullPromise;
231
- await runWorkspaceContainer({
232
- workspaceId,
233
- workspaceName: workspace.name,
234
- profile: resolved.profile,
235
- parentUrl: resolved.url,
236
- image,
237
- hostPort,
238
- configYaml: bundle.configYaml,
239
- credentialsJson: bundle.credentialsJson,
240
- licenseToken,
241
- bindMounts: repoOptions === null ? [] : [repoOptions.bindMount]
242
- });
243
- const state = await finalizeContainer({
244
- workspaceId,
245
- hostPort,
246
- credentials: bundle.credentials,
247
- metadataJson,
248
- wait: args.wait,
249
- timeoutMs: readyTimeoutMs
250
- });
251
- const result = {
252
- workspace_id: workspaceId,
253
- workspace_name: workspace.name,
254
- container_name: containerName,
255
- state,
256
- host_port: hostPort,
257
- url: localUrl(hostPort),
258
- image
259
- };
260
- renderItem(result, startResultView, ctx);
261
- }
262
- });
263
- function resolveDefaultImage(version) {
264
- const isReleased = version !== null && version.major >= WORKSPACES_MIN_VERSION;
265
- const repo = isReleased ? ENTERPRISE_IMAGE : ENTERPRISE_HEAD_IMAGE;
266
- return `${repo}:${LATEST_TAG}`;
267
- }
268
- function assertAllDatabasesProvisioned(workspace) {
269
- const databases = workspace.databases ?? [];
270
- if (databases.length === 0) throw new ConfigError(`workspace ${workspace.id} has no databases — provision at least one before starting`);
271
- const unready = databases.filter((entry) => entry.status !== "provisioned");
272
- if (unready.length > 0) {
273
- const summary = unready.map((entry) => `database ${entry.database_id}=${entry.status}`).join(", ");
274
- throw new ConfigError(`workspace ${workspace.id} is not ready: ${summary}. Wait for provisioning to finish.`);
275
- }
276
- }
277
- async function ensureNoExistingContainer(workspaceId, containerName, force) {
278
- if (force) {
279
- await removeContainer(containerName);
280
- return;
281
- }
282
- const status = await containerLifecycleStatus(containerName);
283
- if (status === "missing") return;
284
- if (status === "exited" || status === "created" || status === "dead") {
285
- await removeContainer(containerName);
286
- return;
287
- }
288
- throw new ConfigError(`container ${containerName} is currently ${status}. Run \`mb workspace stop ${workspaceId}\` first, or use --force to recreate it.`);
289
- }
290
- async function resolveHostPort(requested) {
291
- if (requested !== null) {
292
- if (!await isPortFree(requested)) throw new ConfigError(`port ${requested} is already in use`);
293
- return requested;
294
- }
295
- if (await isPortFree(DEFAULT_HOST_PORT)) return DEFAULT_HOST_PORT;
296
- return findFreePort(DEFAULT_HOST_PORT + 1);
297
- }
298
- async function fetchConfigYaml(client, workspaceId) {
299
- const response = await client.requestRaw(`/api/ee/workspace-manager/${workspaceId}/config`, { expectContentType: "binary" });
300
- return response.text();
301
- }
302
- async function fetchMetadataJson(client, workspaceId) {
303
- const response = await client.requestRaw(`/api/ee/workspace-manager/${workspaceId}/metadata/export`, {
304
- expectContentType: "binary",
305
- query: {
306
- "with-databases": true,
307
- "with-tables": true,
308
- "with-fields": true
309
- }
310
- });
311
- return new Uint8Array(await response.arrayBuffer());
312
- }
313
- function assembleBootBundle(parentConfigYaml, workspaceId, repoOptions) {
314
- const credentials = generateWorkspaceCredentials(workspaceId);
315
- const withCredentials = injectCredentialsIntoConfig(parentConfigYaml, credentials);
316
- const configYaml = repoOptions !== null ? injectRepoSettingsIntoConfig(withCredentials, repoOptions.repo) : withCredentials;
317
- return {
318
- configYaml,
319
- credentialsJson: buildCredentialsJson(credentials),
320
- credentials
321
- };
322
- }
323
- async function finalizeContainer(input) {
324
- await waitForConfigConsumed(input.workspaceId, input.timeoutMs);
325
- try {
326
- await scrubContainerConfig(input.workspaceId);
327
- } catch (error) {
328
- warn(`could not scrub in-container config.yml: ${errorMessage(error)}`);
329
- }
330
- const reachedHealth = input.wait || input.metadataJson !== null;
331
- if (reachedHealth) await waitForHealth(input.hostPort, input.timeoutMs);
332
- if (input.metadataJson !== null) await importMetadataIntoChild(input.hostPort, input.credentials, input.metadataJson, input.timeoutMs);
333
- return reachedHealth ? "running" : "starting";
334
- }
335
- async function waitForHealth(hostPort, timeoutMs) {
336
- const url = `${localUrl(hostPort)}/api/health`;
337
- await pollUntil(() => probeHealth(url, HEALTH_PROBE_TIMEOUT_MS), (probe) => probe.ready, {
338
- intervalMs: HEALTH_INTERVAL_MS,
339
- maxIntervalMs: HEALTH_MAX_INTERVAL_MS,
340
- backoff: "exponential",
341
- timeoutMs
342
- });
343
- }
344
- async function importMetadataIntoChild(hostPort, credentials, metadataJson, pollTimeoutMs) {
345
- const childClient = createClient({
346
- url: localUrl(hostPort),
347
- apiKey: credentials.api_key.key
348
- });
349
- const enqueued = await childClient.requestParsed(MetadataImportEnqueued, "/api/ee/serialization/metadata/import", {
350
- method: "POST",
351
- body: metadataJson,
352
- timeoutMs: METADATA_IMPORT_TIMEOUT_MS
353
- });
354
- const importId = enqueued["import-id"];
355
- const final = await pollUntil(() => childClient.requestParsed(MetadataImportStatus, `/api/ee/serialization/metadata/import/${importId}`), (status) => status.status === "ok" || status.status === "error", {
356
- intervalMs: METADATA_POLL_INTERVAL_MS,
357
- maxIntervalMs: METADATA_POLL_MAX_INTERVAL_MS,
358
- backoff: "exponential",
359
- timeoutMs: pollTimeoutMs
360
- });
361
- if (final.status === "error") {
362
- const detail = final.error !== null ? `: ${final.error}` : "";
363
- throw new Error(`metadata import failed (id=${importId})${detail}`);
364
- }
365
- }
366
- async function resolveRepoOptions(input) {
367
- if (input.hostPath === void 0 || input.hostPath === "") {
368
- const explicitBranch = input.branch !== void 0;
369
- const explicitNonDefaultMode = input.mode !== void 0 && input.mode !== DEFAULT_REPO_MODE;
370
- if (explicitBranch || explicitNonDefaultMode) throw new ConfigError("--repo-branch and --repo-mode require --repo to point at a host repo path");
371
- return null;
372
- }
373
- const hostPath = resolve(input.hostPath);
374
- const stats = await stat(hostPath).catch(() => null);
375
- if (stats === null || !stats.isDirectory()) throw new ConfigError(`--repo path does not exist or is not a directory: ${hostPath}`);
376
- const mode = parseRepoMode(input.mode);
377
- const branch = input.branch ?? await detectBranch(hostPath);
378
- return {
379
- bindMount: {
380
- hostPath,
381
- containerPath: CONTAINER_REPO_DIR,
382
- readOnly: mode === "read-only"
383
- },
384
- repo: {
385
- url: REPO_FILE_URL,
386
- branch,
387
- mode
388
- }
389
- };
390
- }
391
- function parseRepoMode(raw) {
392
- const result = RepoSyncMode.safeParse(raw ?? DEFAULT_REPO_MODE);
393
- if (!result.success) throw new ConfigError(`invalid --repo-mode: "${raw}" (expected one of: ${REPO_SYNC_MODES.join(", ")})`);
394
- return result.data;
395
- }
396
- async function detectBranch(hostPath) {
397
- const result = await runProcess("git", [
398
- "-C",
399
- hostPath,
400
- "symbolic-ref",
401
- "--short",
402
- "HEAD"
403
- ]).catch((error) => {
404
- throw new ConfigError(`--repo-branch not provided and could not detect a branch at ${hostPath}: ${errorMessage(error)}`);
405
- });
406
- if (result.exitCode !== 0) throw new ConfigError(`--repo-branch not provided and \`git symbolic-ref\` at ${hostPath} failed: ${result.stderr.trim() || "no output"}`);
407
- const branch = result.stdout.trim();
408
- if (branch === "") throw new ConfigError(`--repo-branch not provided and HEAD at ${hostPath} resolved to an empty branch name`);
409
- return branch;
410
- }
411
-
412
- //#endregion
413
- export { start_default as default };
@@ -1,34 +0,0 @@
1
- import "./command-augment-BH9qgQ5u.mjs";
2
- import { outputFlags } from "./error-C9S6PN3-.mjs";
3
- import { defineMetabaseCommand, readLicense } from "./runtime-Dmv5VtUK.mjs";
4
- import "./capabilities-7e9MgquN.mjs";
5
- import { renderScalar } from "./render-CfznwleY.mjs";
6
- import { z } from "zod";
7
-
8
- //#region src/commands/workspace/license/status.ts
9
- const LicenseStatus = z.object({ present: z.boolean() });
10
- const licenseStatusView = {
11
- compactPick: LicenseStatus,
12
- tableColumns: [{
13
- key: "present",
14
- label: "Present"
15
- }]
16
- };
17
- var status_default = defineMetabaseCommand({
18
- meta: {
19
- name: "status",
20
- description: "Show whether a license token is stored (does not reveal value)"
21
- },
22
- capabilities: null,
23
- args: { ...outputFlags },
24
- outputSchema: LicenseStatus,
25
- examples: ["mb workspace license status", "mb workspace license status --json"],
26
- async run({ ctx }) {
27
- const present = await readLicense() !== null;
28
- const summary = present ? "A license token is stored." : "No license token stored.";
29
- renderScalar({ present }, licenseStatusView, summary, ctx);
30
- }
31
- });
32
-
33
- //#endregion
34
- export { status_default as default };
@@ -1,83 +0,0 @@
1
- import "./command-augment-BH9qgQ5u.mjs";
2
- import { outputFlags } from "./error-C9S6PN3-.mjs";
3
- import { defineMetabaseCommand } from "./runtime-Dmv5VtUK.mjs";
4
- import "./capabilities-7e9MgquN.mjs";
5
- import { renderItem } from "./render-CfznwleY.mjs";
6
- import { parseId } from "./parse-id-lk_K-CEF.mjs";
7
- import "./poll-DHKDpCiq.mjs";
8
- import "./process-C7V8LJ-j.mjs";
9
- import { checkDockerReady, containerLifecycleStatus, containerNameFor, stopContainer } from "./docker-Oq80q3tu.mjs";
10
- import { LocalWorkspaceState } from "./ps-CJU0EbrC.mjs";
11
- import { z } from "zod";
12
-
13
- //#region src/commands/workspace/stop.ts
14
- const StopResult = z.object({
15
- workspace_id: z.number().int().positive(),
16
- container_name: z.string(),
17
- stopped: z.boolean(),
18
- prior_state: LocalWorkspaceState.nullable()
19
- });
20
- const stopResultView = {
21
- compactPick: StopResult.pick({
22
- workspace_id: true,
23
- stopped: true,
24
- prior_state: 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: "stopped",
37
- label: "Stopped"
38
- },
39
- {
40
- key: "prior_state",
41
- label: "Prior State"
42
- }
43
- ]
44
- };
45
- var stop_default = defineMetabaseCommand({
46
- meta: {
47
- name: "stop",
48
- description: "Stop the local Docker container for a workspace (does not remove it)"
49
- },
50
- capabilities: null,
51
- args: {
52
- ...outputFlags,
53
- id: {
54
- type: "positional",
55
- description: "Workspace id",
56
- required: true
57
- }
58
- },
59
- outputSchema: StopResult,
60
- examples: ["mb workspace stop 1", "mb workspace stop 1 --json"],
61
- async run({ args, ctx }) {
62
- const workspaceId = parseId(args.id);
63
- const containerName = containerNameFor(workspaceId);
64
- await checkDockerReady();
65
- const status = await containerLifecycleStatus(containerName);
66
- const priorState = status === "missing" ? null : status;
67
- let stopped = false;
68
- if (status === "running") {
69
- await stopContainer(containerName);
70
- stopped = true;
71
- }
72
- const result = {
73
- workspace_id: workspaceId,
74
- container_name: containerName,
75
- stopped,
76
- prior_state: priorState
77
- };
78
- renderItem(result, stopResultView, ctx);
79
- }
80
- });
81
-
82
- //#endregion
83
- export { stop_default as default };
@@ -1,20 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/table/index.ts
4
- var table_default = defineCommand({
5
- meta: {
6
- name: "table",
7
- alias: "tables",
8
- description: "Manage Metabase tables"
9
- },
10
- subCommands: {
11
- list: () => import("./list-sD5N3fGk.mjs").then((m) => m.default),
12
- get: () => import("./get-C_w1kvN3.mjs").then((m) => m.default),
13
- metadata: () => import("./metadata-DqiI2q9q.mjs").then((m) => m.default),
14
- fields: () => import("./fields-CoQi99gv.mjs").then((m) => m.default),
15
- update: () => import("./update-_QfgNa53.mjs").then((m) => m.default)
16
- }
17
- });
18
-
19
- //#endregion
20
- export { table_default as default };
@@ -1,25 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/transform/index.ts
4
- var transform_default = defineCommand({
5
- meta: {
6
- name: "transform",
7
- alias: "transforms",
8
- description: "Manage Metabase transforms"
9
- },
10
- subCommands: {
11
- list: () => import("./list-C3hfovHv.mjs").then((mod) => mod.default),
12
- get: () => import("./get-C2p383Qc.mjs").then((mod) => mod.default),
13
- create: () => import("./create-BYlIju0b.mjs").then((mod) => mod.default),
14
- update: () => import("./update-mYVnoYNV.mjs").then((mod) => mod.default),
15
- delete: () => import("./delete-ZjnV35OJ.mjs").then((mod) => mod.default),
16
- "delete-table": () => import("./delete-table-agZJpivt.mjs").then((mod) => mod.default),
17
- run: () => import("./run-B4Wn43zm.mjs").then((mod) => mod.default),
18
- cancel: () => import("./cancel-Dl_Ho056.mjs").then((mod) => mod.default),
19
- "get-run": () => import("./get-run-B7sKdaDU.mjs").then((mod) => mod.default),
20
- runs: () => import("./runs-Bbaszr18.mjs").then((mod) => mod.default)
21
- }
22
- });
23
-
24
- //#endregion
25
- export { transform_default as default };
@@ -1,20 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/transform-job/index.ts
4
- var transform_job_default = defineCommand({
5
- meta: {
6
- name: "transform-job",
7
- alias: "transform-jobs",
8
- description: "Manage Metabase transform jobs"
9
- },
10
- subCommands: {
11
- list: () => import("./list-d58BprgJ.mjs").then((mod) => mod.default),
12
- get: () => import("./get-Hc93A0Yz.mjs").then((mod) => mod.default),
13
- create: () => import("./create-CzzrbL0u.mjs").then((mod) => mod.default),
14
- update: () => import("./update-DSgceARZ.mjs").then((mod) => mod.default),
15
- delete: () => import("./delete-Dimc-2y8.mjs").then((mod) => mod.default)
16
- }
17
- });
18
-
19
- //#endregion
20
- export { transform_job_default as default };
@@ -1,77 +0,0 @@
1
- import "./command-augment-BH9qgQ5u.mjs";
2
- import { connectionFlags, outputFlags, profileFlag } from "./error-C9S6PN3-.mjs";
3
- import { defineMetabaseCommand } from "./runtime-Dmv5VtUK.mjs";
4
- import "./capabilities-7e9MgquN.mjs";
5
- import { renderItem } from "./render-CfznwleY.mjs";
6
- import "./input-cMSEqISy.mjs";
7
- import { parseId } from "./parse-id-lk_K-CEF.mjs";
8
- import { readBody } from "./body-DjdFxjpg.mjs";
9
- import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
10
- import "./poll-DHKDpCiq.mjs";
11
- import { parseWaitFlags, waitFlags } from "./wait-flags-Dzq9BGQY.mjs";
12
- import { Workspace, WorkspaceUpdateDatabaseInput, workspaceView } from "./workspace-BBXJczJK.mjs";
13
- import { waitForDatabaseProvisioned } from "./wait-8yV9_WIo.mjs";
14
- import { parseSchemasCsv } from "./parse-schemas-BqUdWUwq.mjs";
15
-
16
- //#region src/commands/workspace/database/update.ts
17
- var update_default = defineMetabaseCommand({
18
- meta: {
19
- name: "update",
20
- description: "Update a workspace's database (deprovisions then re-provisions with new input schemas)"
21
- },
22
- capabilities: {
23
- minVersion: 62,
24
- tokenFeature: "workspaces"
25
- },
26
- args: {
27
- ...outputFlags,
28
- ...profileFlag,
29
- ...connectionFlags,
30
- ...bodyInputFlags,
31
- ...waitFlags,
32
- schemas: {
33
- type: "string",
34
- description: "Comma-separated input schemas (alternative to --body / --file)"
35
- },
36
- id: {
37
- type: "positional",
38
- description: "Workspace id",
39
- required: true
40
- },
41
- "db-id": {
42
- type: "positional",
43
- description: "Database id",
44
- required: true
45
- }
46
- },
47
- outputSchema: Workspace,
48
- examples: [
49
- "mb workspace database update 1 5 --schemas analytics,github",
50
- "mb workspace database update 1 5 --schemas analytics --wait",
51
- "mb workspace database update 1 5 --file update.json"
52
- ],
53
- async run({ args, ctx, getClient }) {
54
- const workspaceId = parseId(args.id);
55
- const databaseId = parseId(args["db-id"], "db-id");
56
- const schemasFlag = args.schemas;
57
- const wait = parseWaitFlags(args);
58
- let body;
59
- if (schemasFlag !== void 0 && schemasFlag !== "") {
60
- const input_schemas = parseSchemasCsv(schemasFlag);
61
- body = WorkspaceUpdateDatabaseInput.parse({ input_schemas });
62
- } else body = await readBody({
63
- flag: args.body,
64
- file: args.file
65
- }, WorkspaceUpdateDatabaseInput);
66
- const client = await getClient();
67
- const initial = await client.requestParsed(Workspace, `/api/ee/workspace-manager/${workspaceId}/database/${databaseId}`, {
68
- method: "PUT",
69
- body
70
- });
71
- const final = wait.enabled ? await waitForDatabaseProvisioned(client, workspaceId, databaseId, wait.schedule) : initial;
72
- renderItem(final, workspaceView, ctx);
73
- }
74
- });
75
-
76
- //#endregion
77
- export { update_default as default };