@metabase/cli 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +427 -381
  2. package/dist/add-collection-CPL1njYZ.mjs +11 -0
  3. package/dist/{add-collection-DwxQDXzL.mjs → add-collection-CffaBB-Y.mjs} +5 -5
  4. package/dist/{api-key-BktzvPb7.mjs → api-key-9p1UPnXn.mjs} +1 -1
  5. package/dist/{archive-Cq4WKmJt.mjs → archive-BAcEXbT9.mjs} +7 -7
  6. package/dist/{archive-CLWtbvvH.mjs → archive-B_B3MQp0.mjs} +7 -7
  7. package/dist/{archive-kYoy5LK5.mjs → archive-GdGm7l2e.mjs} +6 -6
  8. package/dist/{archive-C1mF-9Kj.mjs → archive-uJrslh9r.mjs} +6 -6
  9. package/dist/auth-N4w5xtwW.mjs +19 -0
  10. package/dist/{body-rDrR-C1c.mjs → body-D6dHGjMT.mjs} +3 -3
  11. package/dist/{branches-CH2UcCpX.mjs → branches-Bpe40fEd.mjs} +7 -7
  12. package/dist/{cancel-CgLZcItQ.mjs → cancel-BWTY6oYI.mjs} +6 -6
  13. package/dist/{cancel-task-DcYrFsM6.mjs → cancel-task--BfiAXfS.mjs} +7 -7
  14. package/dist/card-4rZRb5bc.mjs +20 -0
  15. package/dist/{cards-C4NIaERo.mjs → cards-CVlFJxYh.mjs} +6 -6
  16. package/dist/cli.mjs +27 -26
  17. package/dist/collection-Cp_B02I4.mjs +19 -0
  18. package/dist/{create-Dh0p-c2Y.mjs → create-Bu-YhIDL.mjs} +9 -9
  19. package/dist/{create-BUCLNqiN.mjs → create-BykvNpSA.mjs} +12 -12
  20. package/dist/{create-CzfNOhOF.mjs → create-BzElku2l.mjs} +12 -12
  21. package/dist/{create-Cbh1cGj9.mjs → create-Cz3_Wxdt.mjs} +12 -12
  22. package/dist/{create-bqc_rmix.mjs → create-DP8RrLDi.mjs} +9 -9
  23. package/dist/{create-CB0Yp__0.mjs → create-DQVdMT2Y.mjs} +12 -12
  24. package/dist/{create-CNvd5T8h.mjs → create-DYoc9IXW.mjs} +10 -10
  25. package/dist/{create-branch-BJFH9Hda.mjs → create-branch-B49UQyCK.mjs} +7 -7
  26. package/dist/{create-QgN369N5.mjs → create-doyv3SxU.mjs} +13 -13
  27. package/dist/{create-DU0ZhnZu.mjs → create-izE3EKCt.mjs} +9 -9
  28. package/dist/{create-DvrVZ2hS.mjs → create-ov-De5dO.mjs} +11 -11
  29. package/dist/{credentials-DTP1xuKz.mjs → credentials-xKSoP6eh.mjs} +10 -9
  30. package/dist/{current-task-z_TiJ0kt.mjs → current-task-DweHmjlk.mjs} +7 -7
  31. package/dist/dashboard-BYBiA-IG.mjs +20 -0
  32. package/dist/{database-DQkUxTLd.mjs → database-BNlvldUL.mjs} +3 -3
  33. package/dist/db-CObVU22j.mjs +22 -0
  34. package/dist/{delete-CVYII8mq.mjs → delete-DIz9Tgz5.mjs} +8 -8
  35. package/dist/{delete-DeZQ1r9w.mjs → delete-DojHmKeM.mjs} +8 -8
  36. package/dist/{delete-runtime-BMzvfj_B.mjs → delete-runtime-BkAdygbs.mjs} +2 -2
  37. package/dist/{delete-table-ZiR9-ndv.mjs → delete-table-DjN8E3sd.mjs} +8 -8
  38. package/dist/{deprovision-BhD3J-Am.mjs → deprovision-_HDcBApz.mjs} +12 -12
  39. package/dist/{dirty-D9agt7Os.mjs → dirty-Co8V0SZ3.mjs} +7 -7
  40. package/dist/{docker-CHpV8PRz.mjs → docker-D9sC_37H.mjs} +6 -103
  41. package/dist/{eid-B5wawMmO.mjs → eid-Cr5r-t9B.mjs} +1 -1
  42. package/dist/{export-Bfk7JAlR.mjs → export-CVMFxoo1.mjs} +10 -10
  43. package/dist/field-CbljasCH.mjs +18 -0
  44. package/dist/{fields-7ByLsxLg.mjs → fields-Coha7vKv.mjs} +6 -6
  45. package/dist/{flag-pair-DtR1AiBQ.mjs → flag-pair-Fmcdkrfx.mjs} +1 -1
  46. package/dist/{get-DKy3DAJX.mjs → get-AOvWo48B.mjs} +6 -6
  47. package/dist/{get-cuHp9-6U.mjs → get-BOtKerj8.mjs} +6 -6
  48. package/dist/{get-D2m4jhwT.mjs → get-BSKoL8ek.mjs} +8 -8
  49. package/dist/{get-DUSR5i99.mjs → get-BVTz9B_H.mjs} +6 -6
  50. package/dist/{get-C3CcAJGg.mjs → get-Be6EFh94.mjs} +8 -8
  51. package/dist/{get-CQGeF-eP.mjs → get-Br6WayZv.mjs} +6 -6
  52. package/dist/{get-BE6Izpus.mjs → get-BxzCKVC6.mjs} +6 -6
  53. package/dist/{get-StkjKuh0.mjs → get-CJwzbVjc.mjs} +8 -8
  54. package/dist/{get-tISo-cmg.mjs → get-C_6K7MSW.mjs} +9 -9
  55. package/dist/{get-DikegGzi.mjs → get-DXv2FkA7.mjs} +6 -6
  56. package/dist/{get-bYc7eGYe.mjs → get-DZrV7v9d.mjs} +6 -6
  57. package/dist/{get-gOT_RarI.mjs → get-bNtA7vWe.mjs} +6 -6
  58. package/dist/{get-run-D59Yqaoh.mjs → get-run-CSrXHDGS.mjs} +6 -6
  59. package/dist/git-sync-BGkS8o5b.mjs +28 -0
  60. package/dist/{has-remote-changes-B1TciDVD.mjs → has-remote-changes-D6xgsuUr.mjs} +7 -7
  61. package/dist/{import-DnnmmJbp.mjs → import-Dv0ORSNw.mjs} +10 -10
  62. package/dist/{input-ikCiip6x.mjs → input-BQ-BZA8h.mjs} +1 -1
  63. package/dist/is-dirty-BOZ4xz92.mjs +10 -0
  64. package/dist/{is-dirty-DlfX7e39.mjs → is-dirty-WNi8a6O9.mjs} +4 -4
  65. package/dist/{items-DQFQSpjF.mjs → items-CTcAMknV.mjs} +10 -10
  66. package/dist/{key-NDEARu2L.mjs → key-CCJdVWKc.mjs} +1 -1
  67. package/dist/{license-DBh13sc8.mjs → license-DLLTpFvP.mjs} +3 -3
  68. package/dist/{list-BwjqQ6pp.mjs → list-8oVMvlLV.mjs} +5 -5
  69. package/dist/{list-Di529OJD.mjs → list-BNzdnE1c.mjs} +5 -5
  70. package/dist/{list-D067ZSE5.mjs → list-BxdXvGTK.mjs} +7 -7
  71. package/dist/{list-4kYCGv01.mjs → list-CbJeP0Z6.mjs} +6 -6
  72. package/dist/{list-9AOWhxqp.mjs → list-CocYwmnI.mjs} +8 -8
  73. package/dist/{list-Cy0VhXQs.mjs → list-DI7K3K6k.mjs} +5 -5
  74. package/dist/{list-iFVEdi2J.mjs → list-DSs0Q78i.mjs} +5 -5
  75. package/dist/{list-DJN-OvTZ.mjs → list-DhWG5jiW.mjs} +7 -7
  76. package/dist/{list-GFfR9SuT.mjs → list-DjhZU-FY.mjs} +5 -5
  77. package/dist/{list-DAZP-IM5.mjs → list-DvUjMQze.mjs} +5 -5
  78. package/dist/{list-DQj-QJAs.mjs → list-FXuSCYpa.mjs} +7 -7
  79. package/dist/{list-CP5RNjO6.mjs → list-NiwCL_1X.mjs} +6 -6
  80. package/dist/{list-DlKzgnqo.mjs → list-xQmtQPSl.mjs} +7 -7
  81. package/dist/{login-DxgkosGx.mjs → login-SXsSH0I1.mjs} +9 -9
  82. package/dist/{logout-BlVwqBog.mjs → logout-bgOXjxbN.mjs} +6 -6
  83. package/dist/{logs-CudNEkT4.mjs → logs-BnwVbFuD.mjs} +11 -10
  84. package/dist/{manifest-Dv5B9Blc.mjs → manifest-CGM7XNLC.mjs} +2 -2
  85. package/dist/measure-B54VtKym.mjs +19 -0
  86. package/dist/{metadata-BTJAFVvZ.mjs → metadata-B0WZT3Yb.mjs} +6 -6
  87. package/dist/{metadata-B2Td415K.mjs → metadata-Bu2HOmuX.mjs} +6 -6
  88. package/dist/{package-DV6Asqim.mjs → package-D-aVYFKM.mjs} +4 -2
  89. package/dist/{parse-id-B38zTlYs.mjs → parse-id-B3B-0hUA.mjs} +1 -1
  90. package/dist/{parse-ref-DGvh4aDn.mjs → parse-ref-D1yeDOn8.mjs} +1 -1
  91. package/dist/{parse-schemas-Ds-cVE-O.mjs → parse-schemas-DgtVLikM.mjs} +2 -2
  92. package/dist/{poll-Bh6oAifO.mjs → poll-BCnrcUVf.mjs} +2 -2
  93. package/dist/{poll-task-vPwV31Fs.mjs → poll-task-0b1V6G-8.mjs} +2 -2
  94. package/dist/{predicates-DiIiS3k7.mjs → predicates-CGO17Q15.mjs} +1 -1
  95. package/dist/{preflight-DxJb-hUV.mjs → preflight-5ACaYnDp.mjs} +3 -3
  96. package/dist/process-FjsqDwKo.mjs +105 -0
  97. package/dist/{prompt-Bf3DQ-qE.mjs → prompt-DgDNy_Pc.mjs} +1 -1
  98. package/dist/{provision-B-I0zuDe.mjs → provision-29Zt62Ft.mjs} +15 -15
  99. package/dist/{ps-CaiOFCv2.mjs → ps-BMFiRCi4.mjs} +4 -4
  100. package/dist/ps-C5FOLwL2.mjs +11 -0
  101. package/dist/{query-jmfqaXRP.mjs → query-DxA353Hy.mjs} +9 -9
  102. package/dist/{query-BtF1yWZZ.mjs → query-aba8MEe_.mjs} +13 -13
  103. package/dist/{remove-C2iv0g03.mjs → remove-B3ZEqBF7.mjs} +10 -9
  104. package/dist/{remove-xskleeru.mjs → remove-BfgU_CQi.mjs} +6 -6
  105. package/dist/{remove-collection-DhZghaZy.mjs → remove-collection-Brv72xUe.mjs} +9 -9
  106. package/dist/{render-DXv-D6fU.mjs → render-DuoDUTVL.mjs} +1 -1
  107. package/dist/{rescan-values-DW6u90ep.mjs → rescan-values-DIAdjoq7.mjs} +6 -6
  108. package/dist/{revision-message-flag-CWQbKhdl.mjs → revision-message-flag-oyq2xrDU.mjs} +1 -1
  109. package/dist/{run-DxVzhcF3.mjs → run-CgXRo0hD.mjs} +8 -8
  110. package/dist/{runs-BOHk1XnM.mjs → runs-DtLRw6xg.mjs} +8 -8
  111. package/dist/{runtime-cwBS8wwK.mjs → runtime-Br8L4NPm.mjs} +6 -6
  112. package/dist/{schema-tables-CcFbY_jN.mjs → schema-tables-DiKMY6lx.mjs} +6 -6
  113. package/dist/{schemas-DZmv_V62.mjs → schemas-Bvr8cOzo.mjs} +6 -6
  114. package/dist/{search-CYMuc7Fg.mjs → search-BT_TCcTd.mjs} +8 -8
  115. package/dist/segment-C2ui5dSd.mjs +19 -0
  116. package/dist/{set-CbGfQ7Ye.mjs → set-CAIkXlPy.mjs} +12 -12
  117. package/dist/{set-B_rrVwU4.mjs → set-DtG0KH6P.mjs} +9 -9
  118. package/dist/{setting-DqZY9NXP.mjs → setting-BDOi5fk_.mjs} +3 -3
  119. package/dist/{setup-DxmcAorA.mjs → setup-LjTvvlJy.mjs} +9 -9
  120. package/dist/snippet-BcgVYsoR.mjs +19 -0
  121. package/dist/{start-Cn0epTks.mjs → start-CXKt0Q7A.mjs} +18 -17
  122. package/dist/{stash-BFZIl9F4.mjs → stash-dRw1UEwg.mjs} +9 -9
  123. package/dist/{status-UALK3OJl.mjs → status-BEONmJWv.mjs} +5 -5
  124. package/dist/{status-FDIDmqvM.mjs → status-BWep0PFe.mjs} +5 -5
  125. package/dist/{status-BjCeJNLp.mjs → status-C2niMfrQ.mjs} +8 -8
  126. package/dist/{stop-DUwrDWw8.mjs → stop-BdedYfwU.mjs} +10 -9
  127. package/dist/{summary-CS4UGiFJ.mjs → summary-BPDA4K99.mjs} +6 -6
  128. package/dist/{sync-schema-IrHdJxmX.mjs → sync-schema-D95LLRpf.mjs} +6 -6
  129. package/dist/table-lCNGbvej.mjs +19 -0
  130. package/dist/transform-BGAm1s4f.mjs +24 -0
  131. package/dist/transform-job-cNTJ30pm.mjs +19 -0
  132. package/dist/{translate-B__zbDKm.mjs → translate-CG_Ka0dO.mjs} +10 -10
  133. package/dist/{tree-Mh0uQ_Wy.mjs → tree-DazZT7dR.mjs} +5 -5
  134. package/dist/{update-BfBsM_y1.mjs → update-659eQR1L.mjs} +14 -14
  135. package/dist/{update-B5_pp6Jj.mjs → update-9kVyE3BJ.mjs} +14 -14
  136. package/dist/{update-Masp5WeT.mjs → update-BBfvArCx.mjs} +10 -10
  137. package/dist/{update-Bw0WZix_.mjs → update-CJSDB6S8.mjs} +15 -15
  138. package/dist/{update-D2VI_5cy.mjs → update-DE6kjV-f.mjs} +13 -13
  139. package/dist/{update-1Di9hbPo.mjs → update-DSWZSfpw.mjs} +14 -14
  140. package/dist/{update-Cp1789qq.mjs → update-DTIWJxob.mjs} +10 -10
  141. package/dist/{update-B9DBMo30.mjs → update-WyRKlQPh.mjs} +11 -11
  142. package/dist/{update-j9vgemKR.mjs → update-bW-i6gjZ.mjs} +10 -10
  143. package/dist/{update-dashcard-CNiQw1MD.mjs → update-dashcard-BhD5x__K.mjs} +10 -10
  144. package/dist/{update-D8GwQTcL.mjs → update-djgvzO3K.mjs} +16 -16
  145. package/dist/upgrade-D58rvXHM.mjs +432 -0
  146. package/dist/{url-GFM76VIK.mjs → url-DKkSu2D8.mjs} +9 -8
  147. package/dist/{uuid-Uif0lNk8.mjs → uuid-BF20B59s.mjs} +7 -7
  148. package/dist/{validate-DCYx6jdL.mjs → validate-CB0bu50i.mjs} +3 -3
  149. package/dist/{validate-query-B07oGG4K.mjs → validate-query-CavIA0Q2.mjs} +3 -3
  150. package/dist/{values-DrwNHUAI.mjs → values-DyjmpcbT.mjs} +6 -6
  151. package/dist/{wait-DO7tS7NI.mjs → wait-CeUPCgdc.mjs} +2 -2
  152. package/dist/{wait-BoKk8CJy.mjs → wait-DhkTaV6E.mjs} +8 -8
  153. package/dist/{wait-flags-CjX2sEGm.mjs → wait-flags-BR-yqe7y.mjs} +2 -2
  154. package/dist/workspace-DtcBldk0.mjs +24 -0
  155. package/dist/{workspace-credentials-B6BL-X0d.mjs → workspace-credentials-Cctumbru.mjs} +1 -1
  156. package/package.json +4 -2
  157. package/dist/add-collection-SL08iMub.mjs +0 -11
  158. package/dist/auth-DfYkakP3.mjs +0 -19
  159. package/dist/card-ZCGU2JEh.mjs +0 -20
  160. package/dist/collection-D_uFLIAS.mjs +0 -19
  161. package/dist/dashboard-G1-dGLUR.mjs +0 -20
  162. package/dist/db-CBaEfumR.mjs +0 -22
  163. package/dist/field-BDJ1pEgr.mjs +0 -18
  164. package/dist/git-sync-BiTWfLgY.mjs +0 -28
  165. package/dist/is-dirty-DClGFOGV.mjs +0 -10
  166. package/dist/measure-C7SbdYQk.mjs +0 -19
  167. package/dist/ps-BmYQYC7t.mjs +0 -10
  168. package/dist/segment-Df4pfjco.mjs +0 -19
  169. package/dist/snippet-CwSHjQyn.mjs +0 -19
  170. package/dist/table-Cdr5bKp1.mjs +0 -19
  171. package/dist/transform-CeZusR_w.mjs +0 -24
  172. package/dist/transform-job-BOn9-CGa.mjs +0 -19
  173. package/dist/workspace-CyEX40D-.mjs +0 -24
  174. /package/dist/{workspace-DVuqKJGG.mjs → workspace-C5q4nbpY.mjs} +0 -0
@@ -0,0 +1,432 @@
1
+ import { package_default } from "./package-D-aVYFKM.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem, writeText } from "./render-DuoDUTVL.mjs";
4
+ import { AbortError, NetworkError, TimeoutError, UnknownError, errorMessage } from "./predicates-CGO17Q15.mjs";
5
+ import { HttpError, USER_AGENT, combineAborts, defineMetabaseCommand, outputFlags, parseJson, throwIfAborted } from "./runtime-Br8L4NPm.mjs";
6
+ import { promptConfirm } from "./prompt-DgDNy_Pc.mjs";
7
+ import { streamProcess } from "./process-FjsqDwKo.mjs";
8
+ import { z } from "zod";
9
+ import { realpathSync } from "node:fs";
10
+ import { compare, valid } from "semver";
11
+
12
+ //#region src/core/http/npm-registry.ts
13
+ const DEFAULT_REGISTRY = "https://registry.npmjs.org";
14
+ const DEFAULT_TIMEOUT_MS = 15e3;
15
+ const ERROR_BODY_BYTE_CAP = 8 * 1024;
16
+ const NpmDistTags = z.object({ latest: z.string() }).loose();
17
+ async function fetchNpmDistTags(packageName, opts = {}) {
18
+ const registry = opts.registry ?? DEFAULT_REGISTRY;
19
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
20
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
21
+ const url = buildDistTagsUrl(registry, packageName);
22
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
23
+ const { combined, processSignal } = combineAborts(timeoutSignal, opts.signal);
24
+ let response;
25
+ try {
26
+ response = await fetchImpl(url, {
27
+ method: "GET",
28
+ headers: {
29
+ accept: "application/json",
30
+ "user-agent": USER_AGENT
31
+ },
32
+ signal: combined
33
+ });
34
+ } catch (error) {
35
+ throwIfAborted(opts.signal, processSignal);
36
+ if (timeoutSignal.aborted) throw new TimeoutError(`npm registry request timed out after ${timeoutMs}ms`, {
37
+ kind: "http",
38
+ method: "GET",
39
+ url,
40
+ timeoutMs
41
+ });
42
+ const cause = errorMessage(error);
43
+ throw new NetworkError(`could not reach npm registry: ${cause}`, {
44
+ method: "GET",
45
+ url,
46
+ cause
47
+ });
48
+ }
49
+ if (!response.ok) {
50
+ const rawBody = await readErrorBody(response);
51
+ throw new HttpError({
52
+ status: response.status,
53
+ statusText: response.statusText,
54
+ method: "GET",
55
+ url,
56
+ responseHeaders: response.headers,
57
+ rawBody
58
+ });
59
+ }
60
+ const text = await response.text();
61
+ return parseJson(text, NpmDistTags, { source: url });
62
+ }
63
+ function buildDistTagsUrl(registry, packageName) {
64
+ const base = registry.replace(/\/+$/, "");
65
+ const encoded = packageName.replace("/", "%2F");
66
+ return `${base}/-/package/${encoded}/dist-tags`;
67
+ }
68
+ async function readErrorBody(response) {
69
+ try {
70
+ const text = await response.text();
71
+ return text.slice(0, ERROR_BODY_BYTE_CAP);
72
+ } catch (error) {
73
+ return `[body read failed: ${errorMessage(error)}]`;
74
+ }
75
+ }
76
+
77
+ //#endregion
78
+ //#region src/core/install-method.ts
79
+ const InstallMethodKindSchema = z.enum([
80
+ "npm-global",
81
+ "npm-local",
82
+ "npx",
83
+ "dev",
84
+ "unknown"
85
+ ]);
86
+ const PackageManagerSchema = z.enum([
87
+ "npm",
88
+ "pnpm",
89
+ "yarn",
90
+ "bun",
91
+ "unknown"
92
+ ]);
93
+ const GLOBAL_MARKERS = [
94
+ {
95
+ marker: "/.bun/install/global/node_modules/",
96
+ packageManager: "bun"
97
+ },
98
+ {
99
+ marker: "/Library/pnpm/global/",
100
+ packageManager: "pnpm"
101
+ },
102
+ {
103
+ marker: "/.local/share/pnpm/global/",
104
+ packageManager: "pnpm"
105
+ },
106
+ {
107
+ marker: "/share/pnpm/global/",
108
+ packageManager: "pnpm"
109
+ },
110
+ {
111
+ marker: "/AppData/Local/pnpm/global/",
112
+ packageManager: "pnpm"
113
+ },
114
+ {
115
+ marker: "/pnpm-global/node_modules/",
116
+ packageManager: "pnpm"
117
+ },
118
+ {
119
+ marker: "/.config/yarn/global/node_modules/",
120
+ packageManager: "yarn"
121
+ },
122
+ {
123
+ marker: "/AppData/Local/Yarn/Data/global/node_modules/",
124
+ packageManager: "yarn"
125
+ },
126
+ {
127
+ marker: "/lib/node_modules/",
128
+ packageManager: "npm"
129
+ },
130
+ {
131
+ marker: "/.npm-global/node_modules/",
132
+ packageManager: "npm"
133
+ },
134
+ {
135
+ marker: "/AppData/Roaming/npm/node_modules/",
136
+ packageManager: "npm"
137
+ }
138
+ ];
139
+ const NPX_MARKER = "/_npx/";
140
+ const NODE_MODULES_MARKER = "/node_modules/";
141
+ function detectInstallMethod(scriptPath, options = {}) {
142
+ if (scriptPath === void 0 || scriptPath === "") return {
143
+ kind: "unknown",
144
+ packageManager: "unknown",
145
+ realPath: ""
146
+ };
147
+ const realPath = safeRealpath(scriptPath);
148
+ const normalized = realPath.replaceAll("\\", "/");
149
+ if (realPath.endsWith(".ts")) return {
150
+ kind: "dev",
151
+ packageManager: "unknown",
152
+ realPath
153
+ };
154
+ if (normalized.includes(NPX_MARKER)) return {
155
+ kind: "npx",
156
+ packageManager: "npm",
157
+ realPath
158
+ };
159
+ for (const { marker, packageManager } of GLOBAL_MARKERS) if (normalized.includes(marker)) return {
160
+ kind: "npm-global",
161
+ packageManager,
162
+ realPath
163
+ };
164
+ const customPrefix = resolveNpmConfigPrefix(options.npmConfigPrefix);
165
+ if (customPrefix !== null && normalized.startsWith(customPrefix)) return {
166
+ kind: "npm-global",
167
+ packageManager: "npm",
168
+ realPath
169
+ };
170
+ if (normalized.includes(NODE_MODULES_MARKER)) return {
171
+ kind: "npm-local",
172
+ packageManager: "npm",
173
+ realPath
174
+ };
175
+ return {
176
+ kind: "dev",
177
+ packageManager: "unknown",
178
+ realPath
179
+ };
180
+ }
181
+ function resolveNpmConfigPrefix(override) {
182
+ const raw = override ?? process.env["npm_config_prefix"] ?? process.env["NPM_CONFIG_PREFIX"];
183
+ if (raw === void 0 || raw === "") return null;
184
+ const normalized = raw.replaceAll("\\", "/").replace(/\/+$/, "");
185
+ return `${normalized}/`;
186
+ }
187
+ function buildInstallCommand(install, packageName, targetVersion) {
188
+ const spec = `${packageName}@${targetVersion}`;
189
+ switch (install.kind) {
190
+ case "npm-global": return makeCommand(globalArgv(install.packageManager, spec));
191
+ case "npm-local": return makeCommand([
192
+ "npm",
193
+ "install",
194
+ spec
195
+ ]);
196
+ case "npx":
197
+ case "dev":
198
+ case "unknown": return null;
199
+ }
200
+ }
201
+ function globalArgv(packageManager, spec) {
202
+ switch (packageManager) {
203
+ case "pnpm": return [
204
+ "pnpm",
205
+ "add",
206
+ "-g",
207
+ spec
208
+ ];
209
+ case "yarn": return [
210
+ "yarn",
211
+ "global",
212
+ "add",
213
+ spec
214
+ ];
215
+ case "bun": return [
216
+ "bun",
217
+ "add",
218
+ "-g",
219
+ spec
220
+ ];
221
+ case "npm":
222
+ case "unknown": return [
223
+ "npm",
224
+ "install",
225
+ "-g",
226
+ spec
227
+ ];
228
+ }
229
+ }
230
+ function makeCommand(argv) {
231
+ return {
232
+ argv,
233
+ display: argv.join(" ")
234
+ };
235
+ }
236
+ function safeRealpath(path) {
237
+ try {
238
+ return realpathSync(path);
239
+ } catch (error) {
240
+ if (error instanceof Error) return path;
241
+ throw error;
242
+ }
243
+ }
244
+
245
+ //#endregion
246
+ //#region src/core/version.ts
247
+ const SEMVER_MESSAGE = "expected semver MAJOR.MINOR.PATCH[-prerelease][+build]";
248
+ const SemverString = z.string().refine((value) => valid(value) !== null, { message: SEMVER_MESSAGE });
249
+ function compareSemver(a, b) {
250
+ return compare(a, b);
251
+ }
252
+
253
+ //#endregion
254
+ //#region src/commands/upgrade.ts
255
+ const UpgradeCommandSchema = z.object({
256
+ argv: z.array(z.string()).min(1),
257
+ display: z.string()
258
+ });
259
+ const UpgradeStatus = z.object({
260
+ packageName: z.string(),
261
+ currentVersion: SemverString,
262
+ latestVersion: SemverString,
263
+ targetVersion: SemverString,
264
+ updateAvailable: z.boolean(),
265
+ changeRequired: z.boolean(),
266
+ installMethod: InstallMethodKindSchema,
267
+ packageManager: PackageManagerSchema,
268
+ binaryPath: z.string(),
269
+ command: UpgradeCommandSchema.nullable(),
270
+ canAutoInstall: z.boolean()
271
+ });
272
+ const upgradeStatusView = {
273
+ compactPick: UpgradeStatus,
274
+ tableColumns: [
275
+ {
276
+ key: "currentVersion",
277
+ label: "Current"
278
+ },
279
+ {
280
+ key: "latestVersion",
281
+ label: "Latest"
282
+ },
283
+ {
284
+ key: "targetVersion",
285
+ label: "Target"
286
+ },
287
+ {
288
+ key: "updateAvailable",
289
+ label: "Update available"
290
+ },
291
+ {
292
+ key: "installMethod",
293
+ label: "Install method"
294
+ },
295
+ {
296
+ key: "command",
297
+ label: "Upgrade command",
298
+ format: formatCommandCell
299
+ }
300
+ ]
301
+ };
302
+ var upgrade_default = defineMetabaseCommand({
303
+ meta: {
304
+ name: "upgrade",
305
+ description: "Upgrade the Metabase CLI itself to the latest published release"
306
+ },
307
+ args: {
308
+ ...outputFlags,
309
+ check: {
310
+ type: "boolean",
311
+ description: "Print update status without installing"
312
+ },
313
+ yes: {
314
+ type: "boolean",
315
+ description: "Skip the confirmation prompt",
316
+ alias: "y"
317
+ },
318
+ to: {
319
+ type: "string",
320
+ description: "Target version (default: latest published)"
321
+ },
322
+ registry: {
323
+ type: "string",
324
+ description: "npm registry URL (default: https://registry.npmjs.org)"
325
+ }
326
+ },
327
+ outputSchema: UpgradeStatus,
328
+ examples: [
329
+ "mb upgrade",
330
+ "mb upgrade --check",
331
+ "mb upgrade --check --json",
332
+ "mb upgrade --yes",
333
+ "mb upgrade --to 0.1.2"
334
+ ],
335
+ async run({ args, ctx }) {
336
+ const currentVersion = SemverString.parse(package_default.version);
337
+ const install = detectInstallMethod(process.argv[1]);
338
+ const distTags = await fetchNpmDistTags(package_default.name, distTagsOptions(args.registry));
339
+ const latestVersion = SemverString.parse(distTags.latest);
340
+ const targetVersion = resolveTargetVersion(args.to, latestVersion);
341
+ const updateAvailable = compareSemver(currentVersion, latestVersion) < 0;
342
+ const changeRequired = compareSemver(currentVersion, targetVersion) !== 0;
343
+ const command = buildInstallCommand(install, package_default.name, targetVersion);
344
+ const canAutoInstall = install.kind === "npm-global" && command !== null;
345
+ const status = {
346
+ packageName: package_default.name,
347
+ currentVersion,
348
+ latestVersion,
349
+ targetVersion,
350
+ updateAvailable,
351
+ changeRequired,
352
+ installMethod: install.kind,
353
+ packageManager: install.packageManager,
354
+ binaryPath: install.realPath,
355
+ command: command === null ? null : {
356
+ argv: [...command.argv],
357
+ display: command.display
358
+ },
359
+ canAutoInstall
360
+ };
361
+ emitStatus(status, install, command, ctx);
362
+ if (args.check || !changeRequired || command === null || !canAutoInstall) return;
363
+ const needsPrompt = !args.yes;
364
+ if (needsPrompt && !process.stdin.isTTY) return;
365
+ if (needsPrompt) {
366
+ const confirmed = await promptConfirm({
367
+ message: `Run "${command.display}" now?`,
368
+ initialValue: true
369
+ });
370
+ if (!confirmed) throw new AbortError();
371
+ }
372
+ const [bin, ...rest] = command.argv;
373
+ const exitCode = await streamProcess(bin, rest, { shell: process.platform === "win32" });
374
+ if (exitCode !== 0) throw new UnknownError({
375
+ originalMessage: `upgrade command exited with code ${exitCode ?? "unknown"}`,
376
+ stack: null
377
+ });
378
+ }
379
+ });
380
+ function distTagsOptions(registryArg) {
381
+ const registry = registryArg?.trim();
382
+ if (registry === void 0 || registry === "") return {};
383
+ return { registry };
384
+ }
385
+ function resolveTargetVersion(toArg, latestVersion) {
386
+ const trimmed = toArg?.trim();
387
+ if (trimmed === void 0 || trimmed === "") return latestVersion;
388
+ return SemverString.parse(trimmed);
389
+ }
390
+ function emitStatus(status, install, command, ctx) {
391
+ if (ctx.format === "json" || ctx.fields !== void 0 || ctx.full) {
392
+ renderItem(status, upgradeStatusView, ctx);
393
+ return;
394
+ }
395
+ writeText(buildHumanText(status, install, command));
396
+ }
397
+ function buildHumanText(status, install, command) {
398
+ if (!status.changeRequired) return `Up to date (${status.currentVersion}).`;
399
+ const header = [`Current version: ${status.currentVersion}`, `Latest version: ${status.latestVersion}`];
400
+ if (status.targetVersion !== status.latestVersion) header.push(`Target version: ${status.targetVersion}`);
401
+ const tail = buildHumanTail(install, command);
402
+ return [
403
+ ...header,
404
+ "",
405
+ ...tail
406
+ ].join("\n");
407
+ }
408
+ function buildHumanTail(install, command) {
409
+ switch (install.kind) {
410
+ case "npm-global": return [
411
+ `Installed via: ${install.packageManager} (global)`,
412
+ `Binary path: ${install.realPath}`,
413
+ ...command === null ? [] : [`Upgrade command: ${command.display}`]
414
+ ];
415
+ case "npm-local": return [
416
+ `Installed via: ${install.packageManager} (local install)`,
417
+ `Binary path: ${install.realPath}`,
418
+ ...command === null ? [] : [`Run in that project: ${command.display}`]
419
+ ];
420
+ case "npx": return [`Running via npx — no upgrade needed.`, `npx fetches the latest version on each invocation.`];
421
+ case "dev": return [`Running from source at ${install.realPath}.`, `Pull the latest changes from git and rebuild to upgrade.`];
422
+ case "unknown": return [`Could not detect how the CLI was installed${install.realPath === "" ? "" : ` (${install.realPath})`}.`, `Reinstall with your package manager — for example: npm install -g @metabase/cli@latest`];
423
+ }
424
+ }
425
+ function formatCommandCell(value) {
426
+ if (value === null || value === void 0) return "";
427
+ if (typeof value === "object" && "display" in value && typeof value.display === "string") return value.display;
428
+ return "";
429
+ }
430
+
431
+ //#endregion
432
+ export { upgrade_default as default };
@@ -1,11 +1,12 @@
1
- import "./package-DV6Asqim.mjs";
1
+ import "./package-D-aVYFKM.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderItem } from "./render-DXv-D6fU.mjs";
4
- import "./predicates-DiIiS3k7.mjs";
5
- import { defineMetabaseCommand, localUrl, outputFlags } from "./runtime-cwBS8wwK.mjs";
6
- import { parseId } from "./parse-id-B38zTlYs.mjs";
7
- import "./poll-Bh6oAifO.mjs";
8
- import { checkDockerReady, requireWorkspaceContainerLocation } from "./docker-CHpV8PRz.mjs";
3
+ import { renderItem } from "./render-DuoDUTVL.mjs";
4
+ import "./predicates-CGO17Q15.mjs";
5
+ import { defineMetabaseCommand, localUrl, outputFlags } from "./runtime-Br8L4NPm.mjs";
6
+ import { parseId } from "./parse-id-B3B-0hUA.mjs";
7
+ import "./poll-BCnrcUVf.mjs";
8
+ import "./process-FjsqDwKo.mjs";
9
+ import { checkDockerReady, requireWorkspaceContainerLocation } from "./docker-D9sC_37H.mjs";
9
10
  import { z } from "zod";
10
11
 
11
12
  //#region src/commands/workspace/url.ts
@@ -37,7 +38,7 @@ var url_default = defineMetabaseCommand({
37
38
  }
38
39
  },
39
40
  outputSchema: UrlResult,
40
- examples: ["metabase workspace url 1", "metabase workspace url 1 --json"],
41
+ examples: ["mb workspace url 1", "mb workspace url 1 --json"],
41
42
  async run({ args, ctx }) {
42
43
  const workspaceId = parseId(args.id);
43
44
  await checkDockerReady();
@@ -1,8 +1,8 @@
1
- import "./package-DV6Asqim.mjs";
1
+ import "./package-D-aVYFKM.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { writeJson, writeText } from "./render-DXv-D6fU.mjs";
4
- import { ConfigError } from "./predicates-DiIiS3k7.mjs";
5
- import { defineMetabaseCommand, outputFlags, parseInteger } from "./runtime-cwBS8wwK.mjs";
3
+ import { writeJson, writeText } from "./render-DuoDUTVL.mjs";
4
+ import { ConfigError } from "./predicates-CGO17Q15.mjs";
5
+ import { defineMetabaseCommand, outputFlags, parseInteger } from "./runtime-Br8L4NPm.mjs";
6
6
  import { z } from "zod";
7
7
  import { randomUUID } from "node:crypto";
8
8
 
@@ -24,9 +24,9 @@ var uuid_default = defineMetabaseCommand({
24
24
  },
25
25
  outputSchema: UuidList,
26
26
  examples: [
27
- "metabase uuid",
28
- "metabase uuid --count 5",
29
- "metabase uuid --count 5 --json"
27
+ "mb uuid",
28
+ "mb uuid --count 5",
29
+ "mb uuid --count 5 --json"
30
30
  ],
31
31
  run({ args, ctx }) {
32
32
  const count = parseInteger(args.count, {
@@ -1,4 +1,4 @@
1
- import { ConfigError, escapeJsonPointerSegment, isPlainObject } from "./predicates-DiIiS3k7.mjs";
1
+ import { ConfigError, escapeJsonPointerSegment, isPlainObject } from "./predicates-CGO17Q15.mjs";
2
2
  import { z } from "zod";
3
3
  import Ajv2020 from "ajv/dist/2020.js";
4
4
  import addFormats from "ajv-formats";
@@ -1369,8 +1369,8 @@ function getValidator() {
1369
1369
  validator = compiled;
1370
1370
  return validator;
1371
1371
  }
1372
- const UUID_HINT_MESSAGE = "must be a UUID v4 (RFC 4122) — run `metabase uuid` (or `metabase uuid --count N`) to mint one. The MBQL 5 schema rejects placeholder strings (`a1`, `uuid-1`, etc.); agents must call the CLI for UUIDs rather than authoring them.";
1373
- const FIELD_SLOT1_HINT_MESSAGE = "must be the field options object — MBQL 5 field refs are [\"field\", {options}, fieldId]; the legacy MBQL 4 shape [\"field\", id, opts] is not accepted here. (Tip: `metabase uuid` mints `lib/uuid` strings if you need them.)";
1372
+ const UUID_HINT_MESSAGE = "must be a UUID v4 (RFC 4122) — run `mb uuid` (or `mb uuid --count N`) to mint one. The MBQL 5 schema rejects placeholder strings (`a1`, `uuid-1`, etc.); agents must call the CLI for UUIDs rather than authoring them.";
1373
+ const FIELD_SLOT1_HINT_MESSAGE = "must be the field options object — MBQL 5 field refs are [\"field\", {options}, fieldId]; the legacy MBQL 4 shape [\"field\", id, opts] is not accepted here. (Tip: `mb uuid` mints `lib/uuid` strings if you need them.)";
1374
1374
  function clauseSlot1HintMessage(operator, slot1) {
1375
1375
  return `must be the clause options object — every MBQL 5 clause is ["${operator}", {options}, ...args]; got ${describeJsonValue(slot1)} at index 1`;
1376
1376
  }
@@ -1,6 +1,6 @@
1
- import { writeJson } from "./render-DXv-D6fU.mjs";
2
- import { ConfigError } from "./predicates-DiIiS3k7.mjs";
3
- import { assertNotLegacyEnvelopeWrappingMbql5, isMbql5Query, validateQuery } from "./validate-DCYx6jdL.mjs";
1
+ import { writeJson } from "./render-DuoDUTVL.mjs";
2
+ import { ConfigError } from "./predicates-CGO17Q15.mjs";
3
+ import { assertNotLegacyEnvelopeWrappingMbql5, isMbql5Query, validateQuery } from "./validate-CB0bu50i.mjs";
4
4
 
5
5
  //#region src/commands/validate-query.ts
6
6
  const skipValidateFlag = { "skip-validate": {
@@ -1,9 +1,9 @@
1
- import "./package-DV6Asqim.mjs";
1
+ import "./package-D-aVYFKM.mjs";
2
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";
3
+ import { renderItem } from "./render-DuoDUTVL.mjs";
4
+ import "./predicates-CGO17Q15.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-Br8L4NPm.mjs";
6
+ import { parseId } from "./parse-id-B3B-0hUA.mjs";
7
7
  import { FieldValues, fieldValuesView } from "./field-B3gvaqpK.mjs";
8
8
 
9
9
  //#region src/commands/field/values.ts
@@ -23,7 +23,7 @@ var values_default = defineMetabaseCommand({
23
23
  }
24
24
  },
25
25
  outputSchema: FieldValues,
26
- examples: ["metabase field values 100", "metabase field values 100 --json"],
26
+ examples: ["mb field values 100", "mb field values 100 --json"],
27
27
  async run({ args, ctx, getClient }) {
28
28
  const id = parseId(args.id);
29
29
  const client = await getClient();
@@ -1,5 +1,5 @@
1
- import { pollUntil } from "./poll-Bh6oAifO.mjs";
2
- import { Workspace } from "./workspace-DVuqKJGG.mjs";
1
+ import { pollUntil } from "./poll-BCnrcUVf.mjs";
2
+ import { Workspace } from "./workspace-C5q4nbpY.mjs";
3
3
 
4
4
  //#region src/commands/workspace/database/wait.ts
5
5
  async function waitForDatabaseProvisioned(client, workspaceId, databaseId, schedule) {
@@ -1,11 +1,11 @@
1
- import "./package-DV6Asqim.mjs";
1
+ import "./package-D-aVYFKM.mjs";
2
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 { SyncTaskOrIdle, pollSyncTask, syncTaskIdleView, syncTaskView, throwIfFailedTask } from "./poll-task-vPwV31Fs.mjs";
8
- import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-Bh6oAifO.mjs";
3
+ import { renderItem } from "./render-DuoDUTVL.mjs";
4
+ import "./predicates-CGO17Q15.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-Br8L4NPm.mjs";
6
+ import { parseId } from "./parse-id-B3B-0hUA.mjs";
7
+ import { SyncTaskOrIdle, pollSyncTask, syncTaskIdleView, syncTaskView, throwIfFailedTask } from "./poll-task-0b1V6G-8.mjs";
8
+ import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-BCnrcUVf.mjs";
9
9
 
10
10
  //#region src/commands/git-sync/wait.ts
11
11
  const WaitResult = SyncTaskOrIdle;
@@ -30,7 +30,7 @@ var wait_default = defineMetabaseCommand({
30
30
  }
31
31
  },
32
32
  outputSchema: WaitResult,
33
- examples: ["metabase git-sync wait", "metabase git-sync wait --timeout 300000 --json"],
33
+ examples: ["mb git-sync wait", "mb git-sync wait --timeout 300000 --json"],
34
34
  async run({ args, ctx, getClient }) {
35
35
  const timeoutMs = parseId(args.timeout, "timeout");
36
36
  const intervalMs = parseId(args.interval, "interval");
@@ -1,5 +1,5 @@
1
- import { parseId } from "./parse-id-B38zTlYs.mjs";
2
- import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-Bh6oAifO.mjs";
1
+ import { parseId } from "./parse-id-B3B-0hUA.mjs";
2
+ import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-BCnrcUVf.mjs";
3
3
 
4
4
  //#region src/commands/wait-flags.ts
5
5
  const waitFlags = {
@@ -0,0 +1,24 @@
1
+ import { defineCommand } from "citty";
2
+
3
+ //#region src/commands/workspace/index.ts
4
+ var workspace_default = defineCommand({
5
+ meta: {
6
+ name: "workspace",
7
+ description: "Manage Metabase workspaces (workspace-manager)"
8
+ },
9
+ subCommands: {
10
+ list: () => import("./list-CbJeP0Z6.mjs").then((mod) => mod.default),
11
+ create: () => import("./create-DYoc9IXW.mjs").then((mod) => mod.default),
12
+ database: () => import("./database-BNlvldUL.mjs").then((mod) => mod.default),
13
+ start: () => import("./start-CXKt0Q7A.mjs").then((mod) => mod.default),
14
+ stop: () => import("./stop-BdedYfwU.mjs").then((mod) => mod.default),
15
+ remove: () => import("./remove-B3ZEqBF7.mjs").then((mod) => mod.default),
16
+ logs: () => import("./logs-BnwVbFuD.mjs").then((mod) => mod.default),
17
+ url: () => import("./url-DKkSu2D8.mjs").then((mod) => mod.default),
18
+ credentials: () => import("./credentials-xKSoP6eh.mjs").then((mod) => mod.default),
19
+ ps: () => import("./ps-C5FOLwL2.mjs").then((mod) => mod.default)
20
+ }
21
+ });
22
+
23
+ //#endregion
24
+ export { workspace_default as default };
@@ -1,4 +1,4 @@
1
- import { ConfigError, ValidationError, errorMessage } from "./predicates-DiIiS3k7.mjs";
1
+ import { ConfigError, ValidationError, errorMessage } from "./predicates-CGO17Q15.mjs";
2
2
  import { z } from "zod";
3
3
  import { randomBytes } from "node:crypto";
4
4
  import { YAMLParseError, parse, stringify } from "yaml";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metabase/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Metabase CLI",
5
5
  "license": "AGPL-3.0",
6
6
  "repository": {
@@ -8,7 +8,7 @@
8
8
  "url": "git+https://github.com/metabase/mb-cli.git"
9
9
  },
10
10
  "bin": {
11
- "metabase": "./dist/cli.mjs"
11
+ "mb": "./dist/cli.mjs"
12
12
  },
13
13
  "files": [
14
14
  "dist"
@@ -45,12 +45,14 @@
45
45
  "ajv-formats": "^3.0.1",
46
46
  "citty": "^0.2.2",
47
47
  "cli-table3": "^0.6.5",
48
+ "semver": "^7.8.0",
48
49
  "yaml": "^2.8.4",
49
50
  "zod": "^4.0.0"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/js-yaml": "^4.0.9",
53
54
  "@types/node": "^22.10.0",
55
+ "@types/semver": "^7.7.1",
54
56
  "execa": "^9.5.2",
55
57
  "fast-check": "^4.7.0",
56
58
  "js-yaml": "^4.1.0",
@@ -1,11 +0,0 @@
1
- import "./package-DV6Asqim.mjs";
2
- import "./command-augment-D9pI9Vbh.mjs";
3
- import "./render-DXv-D6fU.mjs";
4
- import "./predicates-DiIiS3k7.mjs";
5
- import "./runtime-cwBS8wwK.mjs";
6
- import "./parse-id-B38zTlYs.mjs";
7
- import "./poll-task-vPwV31Fs.mjs";
8
- import "./poll-Bh6oAifO.mjs";
9
- import { SyncSettingsUpdateResult, add_collection_default, setCollectionRemoteSynced, syncSettingsUpdateView } from "./add-collection-DwxQDXzL.mjs";
10
-
11
- export { add_collection_default as default };