@metabase/cli 0.1.0-alpha.workspaces-commands.818a8f1

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 (107) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +762 -0
  3. package/dist/api-key-D9XxErQn.mjs +13 -0
  4. package/dist/archive-BPG5c88Y.mjs +38 -0
  5. package/dist/auth--Hpjwlaf.mjs +18 -0
  6. package/dist/body-DwU2s6Pg.mjs +19 -0
  7. package/dist/body-flags-7oqLhu5j.mjs +14 -0
  8. package/dist/branches-BbcoJXfp.mjs +41 -0
  9. package/dist/cancel-task-BDas45YO.mjs +29 -0
  10. package/dist/card-C31pGtBZ.mjs +113 -0
  11. package/dist/card-D4zZSPUb.mjs +19 -0
  12. package/dist/cli.d.mts +1 -0
  13. package/dist/cli.mjs +61 -0
  14. package/dist/command-augment-D9pI9Vbh.mjs +11 -0
  15. package/dist/create-Bd_U1zWU.mjs +124 -0
  16. package/dist/create-CCzsCZMm.mjs +47 -0
  17. package/dist/create-CwVcoq0O.mjs +43 -0
  18. package/dist/create-DpnjQvPw.mjs +43 -0
  19. package/dist/create-_UOeEXAj.mjs +39 -0
  20. package/dist/create-branch-sDttBORB.mjs +54 -0
  21. package/dist/credentials-C0xKke5D.mjs +84 -0
  22. package/dist/current-task-BGt1mqaX.mjs +35 -0
  23. package/dist/database-4V1iiPEx.mjs +17 -0
  24. package/dist/database-BTX5qbSv.mjs +33 -0
  25. package/dist/db-Dm2u2ISJ.mjs +17 -0
  26. package/dist/delete-DRBTgyus.mjs +47 -0
  27. package/dist/delete-DUC_stoL.mjs +47 -0
  28. package/dist/delete-runtime-inOVw3IX.mjs +58 -0
  29. package/dist/delete-table-9Is631O_.mjs +47 -0
  30. package/dist/deprovision-BAMzZc6f.mjs +60 -0
  31. package/dist/dirty-CLjHbz6J.mjs +32 -0
  32. package/dist/docker-QWVMG2gl.mjs +605 -0
  33. package/dist/eid-BNhutC1U.mjs +13 -0
  34. package/dist/export-D2Anfu3p.mjs +97 -0
  35. package/dist/field-Dhs2AND3.mjs +13 -0
  36. package/dist/field-QwBMAWsq.mjs +76 -0
  37. package/dist/flag-pair-CWvvzDJ_.mjs +17 -0
  38. package/dist/get-2po1uv9i.mjs +35 -0
  39. package/dist/get-BHJA78zg.mjs +35 -0
  40. package/dist/get-CAPLfawI.mjs +35 -0
  41. package/dist/get-CAVVmdMX.mjs +49 -0
  42. package/dist/get-DDWpubE8.mjs +36 -0
  43. package/dist/get-DhIoNeOp.mjs +35 -0
  44. package/dist/get-qPOsuTPw.mjs +35 -0
  45. package/dist/has-remote-changes-DAL5jetW.mjs +63 -0
  46. package/dist/import-CUMxUfSF.mjs +92 -0
  47. package/dist/input-BNqSFl38.mjs +33 -0
  48. package/dist/is-dirty-B10S6MG0.mjs +35 -0
  49. package/dist/is-dirty-CUuq-aB6.mjs +9 -0
  50. package/dist/key-CyhOpgWt.mjs +12 -0
  51. package/dist/license-DtsGJi3l.mjs +17 -0
  52. package/dist/list-B8s7Qnzk.mjs +31 -0
  53. package/dist/list-C5MGydGU.mjs +31 -0
  54. package/dist/list-DeFGwhhJ.mjs +60 -0
  55. package/dist/list-OBx5B3gd.mjs +39 -0
  56. package/dist/list-Y7iGsOfE.mjs +31 -0
  57. package/dist/list-evtQS7jl.mjs +39 -0
  58. package/dist/list-qetY9OIN.mjs +31 -0
  59. package/dist/login-Dqw9ZtCx.mjs +172 -0
  60. package/dist/logout-DwYJ5OUi.mjs +74 -0
  61. package/dist/logs-B_lrY7Js.mjs +57 -0
  62. package/dist/manifest-wzEFG0JB.mjs +124 -0
  63. package/dist/package-t8dKf4m_.mjs +73 -0
  64. package/dist/parse-id-C1prc9US.mjs +12 -0
  65. package/dist/poll-D2sXM5rc.mjs +49 -0
  66. package/dist/poll-task-Byiunmaj.mjs +194 -0
  67. package/dist/prompt-fXeNtj0M.mjs +40 -0
  68. package/dist/provision-DC4_HWZD.mjs +80 -0
  69. package/dist/ps-1bZKIwWh.mjs +9 -0
  70. package/dist/ps-BiOrecEe.mjs +78 -0
  71. package/dist/query-BnGVGeM3.mjs +100 -0
  72. package/dist/remove-Bx48o-0S.mjs +62 -0
  73. package/dist/remove-DecoZzNd.mjs +97 -0
  74. package/dist/render-DlBijc5i.mjs +179 -0
  75. package/dist/run-D4NgvaRh.mjs +87 -0
  76. package/dist/runtime-DUgFfYkN.mjs +950 -0
  77. package/dist/search-4wKx5ug2.mjs +171 -0
  78. package/dist/set-BZnCRL4c.mjs +66 -0
  79. package/dist/set-DCjrmTFm.mjs +66 -0
  80. package/dist/setting-C4vQSqer.mjs +18 -0
  81. package/dist/setting-DM7pm7yh.mjs +55 -0
  82. package/dist/setup-Dqh9hN6l.mjs +70 -0
  83. package/dist/start-xXQypG5L.mjs +324 -0
  84. package/dist/stash-ZZkmW_V7.mjs +106 -0
  85. package/dist/status-9KAPIpX8.mjs +31 -0
  86. package/dist/status-DezF-PIM.mjs +63 -0
  87. package/dist/status-JH6BZppo.mjs +55 -0
  88. package/dist/stop-br-ZOnve.mjs +80 -0
  89. package/dist/sync-C7VOWD00.mjs +26 -0
  90. package/dist/table-BvAr2ixC.mjs +75 -0
  91. package/dist/table-D-Mb5Nvw.mjs +16 -0
  92. package/dist/transform-CqxZwhGs.mjs +21 -0
  93. package/dist/transform-DfVkUttP.mjs +137 -0
  94. package/dist/transform-job-DuB_OjhO.mjs +91 -0
  95. package/dist/transform-job-HjbqjEoP.mjs +19 -0
  96. package/dist/translate-DJxDVAE4.mjs +110 -0
  97. package/dist/update-CDtm71m2.mjs +50 -0
  98. package/dist/update-DYVeVjk2.mjs +76 -0
  99. package/dist/update-DxKlQ0hP.mjs +50 -0
  100. package/dist/url-DP88YHNo.mjs +53 -0
  101. package/dist/wait-Cj_8wu4y.mjs +52 -0
  102. package/dist/wait-DwZN3ZwR.mjs +19 -0
  103. package/dist/wait-flags-CjW4ogUJ.mjs +35 -0
  104. package/dist/workspace-CbwR0vX_.mjs +24 -0
  105. package/dist/workspace-Dr9lWU3D.mjs +72 -0
  106. package/dist/workspace-credentials-q5RRFMT8.mjs +139 -0
  107. package/package.json +62 -0
@@ -0,0 +1,171 @@
1
+ import "./package-t8dKf4m_.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderList } from "./render-DlBijc5i.mjs";
4
+ import { ConfigError, connectionFlags, defineMetabaseCommand, listEnvelopeSchema, outputFlags, parseCsv, profileFlag } from "./runtime-DUgFfYkN.mjs";
5
+ import { parseId } from "./parse-id-C1prc9US.mjs";
6
+ import { z } from "zod";
7
+
8
+ //#region src/domain/search.ts
9
+ const SEARCH_MODELS = [
10
+ "card",
11
+ "dataset",
12
+ "metric",
13
+ "dashboard",
14
+ "collection",
15
+ "database",
16
+ "table",
17
+ "segment",
18
+ "measure",
19
+ "snippet",
20
+ "document",
21
+ "action",
22
+ "transform",
23
+ "indexed-entity"
24
+ ];
25
+ const SearchModel = z.enum(SEARCH_MODELS);
26
+ const SearchResultCollection = z.object({
27
+ id: z.union([
28
+ z.number().int(),
29
+ z.string(),
30
+ z.null()
31
+ ]),
32
+ name: z.string().nullable(),
33
+ authority_level: z.string().nullable(),
34
+ type: z.string().nullable()
35
+ }).loose();
36
+ const SearchResult = z.object({
37
+ id: z.union([z.number().int(), z.string()]),
38
+ name: z.string(),
39
+ model: SearchModel,
40
+ description: z.string().nullable(),
41
+ archived: z.boolean().nullable(),
42
+ collection: SearchResultCollection.nullable()
43
+ }).loose();
44
+ const SearchResultCompact = SearchResult.pick({
45
+ id: true,
46
+ name: true,
47
+ model: true,
48
+ description: true,
49
+ archived: true
50
+ }).strip();
51
+ const searchResultView = {
52
+ compactPick: SearchResultCompact,
53
+ tableColumns: [
54
+ {
55
+ key: "id",
56
+ label: "ID"
57
+ },
58
+ {
59
+ key: "model",
60
+ label: "Model"
61
+ },
62
+ {
63
+ key: "name",
64
+ label: "Name"
65
+ },
66
+ {
67
+ key: "archived",
68
+ label: "Archived"
69
+ }
70
+ ]
71
+ };
72
+
73
+ //#endregion
74
+ //#region src/commands/search.ts
75
+ const DEFAULT_LIMIT = 20;
76
+ const SEARCH_MODELS_DESCRIPTION = `Comma-separated model filter: ${SEARCH_MODELS.join(",")}`;
77
+ const SearchApiResponse = z.object({
78
+ data: z.array(SearchResult),
79
+ total: z.number().int().nonnegative(),
80
+ limit: z.number().int().nullable()
81
+ }).loose();
82
+ const SearchListEnvelope = listEnvelopeSchema(SearchResultCompact);
83
+ var search_default = defineMetabaseCommand({
84
+ meta: {
85
+ name: "search",
86
+ description: "Search Metabase content (cards, dashboards, collections, …)"
87
+ },
88
+ args: {
89
+ ...outputFlags,
90
+ ...profileFlag,
91
+ ...connectionFlags,
92
+ query: {
93
+ type: "positional",
94
+ description: "Search query string",
95
+ required: false
96
+ },
97
+ models: {
98
+ type: "string",
99
+ description: SEARCH_MODELS_DESCRIPTION,
100
+ alias: "m"
101
+ },
102
+ archived: {
103
+ type: "boolean",
104
+ description: "Include archived items",
105
+ default: false
106
+ },
107
+ limit: {
108
+ type: "string",
109
+ description: "Max results to return",
110
+ default: String(DEFAULT_LIMIT)
111
+ },
112
+ "table-db-id": {
113
+ type: "string",
114
+ description: "Restrict to items on a given database id"
115
+ },
116
+ verified: {
117
+ type: "boolean",
118
+ description: "Only verified content"
119
+ }
120
+ },
121
+ outputSchema: SearchListEnvelope,
122
+ examples: [
123
+ "metabase search orders",
124
+ "metabase search --models card,dashboard --limit 10 --json",
125
+ "metabase search products --archived"
126
+ ],
127
+ async run({ args, ctx, getClient }) {
128
+ const limit = parseId(args.limit, "--limit");
129
+ const tableDbIdRaw = args["table-db-id"];
130
+ const tableDbId = tableDbIdRaw ? parseId(tableDbIdRaw, "--table-db-id") : void 0;
131
+ const models = parseModels(args.models);
132
+ const client = await getClient();
133
+ const response = await client.requestParsed(SearchApiResponse, "/api/search", { query: {
134
+ q: nonEmpty(args.query),
135
+ models,
136
+ archived: args.archived ? true : void 0,
137
+ limit,
138
+ table_db_id: tableDbId,
139
+ verified: args.verified ? true : void 0
140
+ } });
141
+ const envelope = {
142
+ data: response.data,
143
+ returned: response.data.length,
144
+ total: response.total,
145
+ limit: response.limit ?? void 0
146
+ };
147
+ renderList(envelope, searchResultView, ctx);
148
+ }
149
+ });
150
+ function nonEmpty(value) {
151
+ if (typeof value !== "string") return void 0;
152
+ const trimmed = value.trim();
153
+ return trimmed.length === 0 ? void 0 : trimmed;
154
+ }
155
+ function parseModels(raw) {
156
+ if (raw === void 0 || raw === "") return void 0;
157
+ const parts = parseCsv(raw);
158
+ if (parts.length === 0) return void 0;
159
+ const accepted = [];
160
+ const rejected = [];
161
+ for (const part of parts) {
162
+ const result = SearchModel.safeParse(part);
163
+ if (result.success) accepted.push(result.data);
164
+ else rejected.push(part);
165
+ }
166
+ if (rejected.length > 0) throw new ConfigError(`invalid --models value: ${rejected.join(", ")} (expected one of: ${SEARCH_MODELS.join(", ")})`);
167
+ return accepted;
168
+ }
169
+
170
+ //#endregion
171
+ export { search_default as default };
@@ -0,0 +1,66 @@
1
+ import "./package-t8dKf4m_.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem, warn } from "./render-DlBijc5i.mjs";
4
+ import { ConfigError, defineMetabaseCommand, outputFlags, readEnvLicenseToken, writeLicense } from "./runtime-DUgFfYkN.mjs";
5
+ import { readInput } from "./input-BNqSFl38.mjs";
6
+ import { promptPassword } from "./prompt-fXeNtj0M.mjs";
7
+ import { z } from "zod";
8
+
9
+ //#region src/commands/license/set.ts
10
+ const LicenseSetResult = z.object({ stored: z.literal(true) });
11
+ const licenseSetView = {
12
+ compactPick: LicenseSetResult,
13
+ tableColumns: [{
14
+ key: "stored",
15
+ label: "Stored"
16
+ }]
17
+ };
18
+ var set_default = defineMetabaseCommand({
19
+ meta: {
20
+ name: "set",
21
+ description: "Store a Metabase license token"
22
+ },
23
+ args: {
24
+ ...outputFlags,
25
+ token: {
26
+ type: "positional",
27
+ description: "License token (visible in shell history; pipe on stdin instead)",
28
+ required: false
29
+ }
30
+ },
31
+ outputSchema: LicenseSetResult,
32
+ examples: [
33
+ "echo $METABASE_LICENSE_TOKEN | metabase license set",
34
+ "metabase license set < token.txt",
35
+ "metabase license set $METABASE_LICENSE_TOKEN"
36
+ ],
37
+ async run({ args, ctx }) {
38
+ const token = await resolveToken(args.token);
39
+ const location = await writeLicense(token);
40
+ if (location.backend === "file") warn(`warning: OS keychain unavailable; license stored as plaintext at ${location.path}`);
41
+ const result = { stored: true };
42
+ renderItem(result, licenseSetView, ctx);
43
+ }
44
+ });
45
+ async function resolveToken(positional) {
46
+ if (positional) {
47
+ warn("warning: license token passed as positional is visible in shell history and process listings — pipe the token on stdin or set METABASE_LICENSE_TOKEN instead");
48
+ return positional;
49
+ }
50
+ const piped = (await readInput({ required: false })).trim();
51
+ if (piped) return piped;
52
+ const envToken = readEnvLicenseToken();
53
+ if (envToken) return envToken;
54
+ return promptForToken();
55
+ }
56
+ async function promptForToken() {
57
+ if (!process.stdin.isTTY) throw new ConfigError("license token, piped stdin, or METABASE_LICENSE_TOKEN required when stdin is not a TTY");
58
+ return promptPassword({
59
+ message: "License token",
60
+ mask: "•",
61
+ validate: (input) => input ? void 0 : "License token is required"
62
+ });
63
+ }
64
+
65
+ //#endregion
66
+ export { set_default as default };
@@ -0,0 +1,66 @@
1
+ import "./package-t8dKf4m_.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem } from "./render-DlBijc5i.mjs";
4
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-DUgFfYkN.mjs";
5
+ import "./input-BNqSFl38.mjs";
6
+ import { readBody } from "./body-DwU2s6Pg.mjs";
7
+ import { SettingValue, settingValueView } from "./setting-DM7pm7yh.mjs";
8
+ import { parseSettingKey } from "./key-CyhOpgWt.mjs";
9
+ import { z } from "zod";
10
+
11
+ //#region src/commands/setting/set.ts
12
+ var set_default = defineMetabaseCommand({
13
+ meta: {
14
+ name: "set",
15
+ description: "Set a setting value (parsed strictly as JSON)"
16
+ },
17
+ args: {
18
+ ...outputFlags,
19
+ ...profileFlag,
20
+ ...connectionFlags,
21
+ file: {
22
+ type: "string",
23
+ description: "Path to a file containing the JSON value"
24
+ },
25
+ key: {
26
+ type: "positional",
27
+ description: "Setting key",
28
+ required: true
29
+ },
30
+ value: {
31
+ type: "positional",
32
+ description: "JSON-encoded value",
33
+ required: false
34
+ }
35
+ },
36
+ outputSchema: SettingValue,
37
+ examples: [
38
+ `metabase setting set remote-sync-branch '"main"'`,
39
+ `metabase setting set anon-tracking-enabled true`,
40
+ `echo '"main"' | metabase setting set remote-sync-branch`,
41
+ `metabase setting set remote-sync-branch --file value.json`,
42
+ `metabase setting set remote-sync-branch null`
43
+ ],
44
+ async run({ args, ctx, getClient }) {
45
+ const key = parseSettingKey(args.key);
46
+ const value = await readBody({
47
+ file: args.file,
48
+ positional: args.value,
49
+ source: `setting ${key} value`
50
+ }, z.unknown());
51
+ const client = await getClient();
52
+ await client.requestRaw(`/api/setting/${encodeURIComponent(key)}`, {
53
+ method: "PUT",
54
+ body: { value },
55
+ expectContentType: "binary"
56
+ });
57
+ const item = {
58
+ key,
59
+ value
60
+ };
61
+ renderItem(item, settingValueView, ctx);
62
+ }
63
+ });
64
+
65
+ //#endregion
66
+ export { set_default as default };
@@ -0,0 +1,18 @@
1
+ import { defineCommand } from "citty";
2
+
3
+ //#region src/commands/setting/index.ts
4
+ var setting_default = defineCommand({
5
+ meta: {
6
+ name: "setting",
7
+ description: "Inspect and update Metabase settings",
8
+ alias: "settings"
9
+ },
10
+ subCommands: {
11
+ list: () => import("./list-Y7iGsOfE.mjs").then((m) => m.default),
12
+ get: () => import("./get-CAVVmdMX.mjs").then((m) => m.default),
13
+ set: () => import("./set-DCjrmTFm.mjs").then((m) => m.default)
14
+ }
15
+ });
16
+
17
+ //#endregion
18
+ export { setting_default as default };
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/domain/setting.ts
4
+ const Setting = z.object({
5
+ key: z.string(),
6
+ value: z.unknown(),
7
+ is_env_setting: z.boolean(),
8
+ env_name: z.string(),
9
+ description: z.string(),
10
+ default: z.unknown()
11
+ }).loose();
12
+ const SettingCompact = Setting.pick({
13
+ key: true,
14
+ value: true,
15
+ is_env_setting: true,
16
+ env_name: true
17
+ }).strip();
18
+ const settingView = {
19
+ compactPick: SettingCompact,
20
+ tableColumns: [
21
+ {
22
+ key: "key",
23
+ label: "Key"
24
+ },
25
+ {
26
+ key: "value",
27
+ label: "Value"
28
+ },
29
+ {
30
+ key: "is_env_setting",
31
+ label: "From env"
32
+ },
33
+ {
34
+ key: "env_name",
35
+ label: "Env name"
36
+ }
37
+ ]
38
+ };
39
+ const SettingValue = z.object({
40
+ key: z.string(),
41
+ value: z.unknown()
42
+ });
43
+ const settingValueView = {
44
+ compactPick: SettingValue,
45
+ tableColumns: [{
46
+ key: "key",
47
+ label: "Key"
48
+ }, {
49
+ key: "value",
50
+ label: "Value"
51
+ }]
52
+ };
53
+
54
+ //#endregion
55
+ export { Setting, SettingCompact, SettingValue, settingValueView, settingView };
@@ -0,0 +1,70 @@
1
+ import "./package-t8dKf4m_.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem } from "./render-DlBijc5i.mjs";
4
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-DUgFfYkN.mjs";
5
+ import "./input-BNqSFl38.mjs";
6
+ import { readBody } from "./body-DwU2s6Pg.mjs";
7
+ import { bodyInputFlags } from "./body-flags-7oqLhu5j.mjs";
8
+ import { z } from "zod";
9
+
10
+ //#region src/domain/setup.ts
11
+ const SetupUserInput = z.object({
12
+ first_name: z.string().nullable().optional(),
13
+ last_name: z.string().nullable().optional(),
14
+ email: z.string().min(1),
15
+ password: z.string().min(1)
16
+ }).loose();
17
+ const SetupPrefsInput = z.object({
18
+ site_name: z.string().min(1),
19
+ site_locale: z.string().min(1).nullable().optional()
20
+ }).loose();
21
+ const SetupInput = z.object({
22
+ token: z.string().min(1),
23
+ user: SetupUserInput,
24
+ prefs: SetupPrefsInput
25
+ }).loose();
26
+ const SetupResult = z.object({ id: z.string() }).loose();
27
+ const SetupResultCompact = SetupResult.pick({ id: true }).strip();
28
+ const setupResultView = {
29
+ compactPick: SetupResultCompact,
30
+ tableColumns: [{
31
+ key: "id",
32
+ label: "Session"
33
+ }]
34
+ };
35
+
36
+ //#endregion
37
+ //#region src/commands/setup.ts
38
+ var setup_default = defineMetabaseCommand({
39
+ meta: {
40
+ name: "setup",
41
+ description: "Complete the initial Metabase setup wizard with a default user"
42
+ },
43
+ args: {
44
+ ...outputFlags,
45
+ ...profileFlag,
46
+ ...connectionFlags,
47
+ ...bodyInputFlags
48
+ },
49
+ outputSchema: SetupResult,
50
+ examples: [
51
+ "cat setup.json | metabase setup",
52
+ "metabase setup --file setup.json",
53
+ "metabase setup --body '{\"token\":\"...\",\"user\":{\"email\":\"a@b.c\",\"password\":\"...\"}}'"
54
+ ],
55
+ async run({ args, ctx, getClient }) {
56
+ const body = await readBody({
57
+ flag: args.body,
58
+ file: args.file
59
+ }, SetupInput);
60
+ const client = await getClient();
61
+ const result = await client.requestParsed(SetupResult, "/api/setup", {
62
+ method: "POST",
63
+ body
64
+ });
65
+ renderItem(result, setupResultView, ctx);
66
+ }
67
+ });
68
+
69
+ //#endregion
70
+ export { setup_default as default };