@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,124 @@
1
+ import { getMetabaseAugment } from "./command-augment-D9pI9Vbh.mjs";
2
+ import { defineCommand } from "citty";
3
+ import { z } from "zod";
4
+
5
+ //#region src/output/manifest.ts
6
+ function writeManifest(manifest) {
7
+ process.stdout.write(JSON.stringify(manifest, null, 2) + "\n");
8
+ }
9
+
10
+ //#endregion
11
+ //#region src/runtime/manifest.ts
12
+ const ManifestArg = z.object({
13
+ name: z.string(),
14
+ type: z.enum([
15
+ "string",
16
+ "boolean",
17
+ "positional",
18
+ "enum"
19
+ ]),
20
+ required: z.boolean(),
21
+ description: z.string().optional(),
22
+ default: z.union([
23
+ z.string(),
24
+ z.boolean(),
25
+ z.number()
26
+ ]).optional(),
27
+ alias: z.array(z.string()).optional(),
28
+ options: z.array(z.string()).optional()
29
+ });
30
+ const ManifestEntry = z.object({
31
+ command: z.string(),
32
+ description: z.string(),
33
+ examples: z.array(z.string()),
34
+ args: z.array(ManifestArg),
35
+ outputSchema: z.unknown().nullable()
36
+ });
37
+ const Manifest = z.object({
38
+ version: z.literal(1),
39
+ commands: z.array(ManifestEntry)
40
+ });
41
+ async function buildManifest(root) {
42
+ return {
43
+ version: 1,
44
+ commands: await walk(root, [])
45
+ };
46
+ }
47
+ async function walk(cmd, path) {
48
+ const meta = await resolveCitty(cmd.meta);
49
+ if (meta?.hidden === true) return [];
50
+ const subCommands = await resolveCitty(cmd.subCommands);
51
+ if (subCommands && Object.keys(subCommands).length > 0) {
52
+ const groups = await Promise.all(Object.entries(subCommands).map(async ([name, lazy]) => {
53
+ const sub = await resolveCitty(lazy);
54
+ return sub ? walk(sub, [...path, name]) : [];
55
+ }));
56
+ return groups.flat();
57
+ }
58
+ const args = await resolveCitty(cmd.args) ?? {};
59
+ const augment = getMetabaseAugment(cmd);
60
+ return [{
61
+ command: path.join(" "),
62
+ description: readDescription(meta),
63
+ examples: augment ? Array.from(augment.examples) : [],
64
+ args: convertArgs(args),
65
+ outputSchema: augment?.outputSchema ? z.toJSONSchema(augment.outputSchema) : null
66
+ }];
67
+ }
68
+ function readDescription(meta) {
69
+ if (meta === void 0) return "";
70
+ return typeof meta.description === "string" ? meta.description : "";
71
+ }
72
+ function convertArgs(args) {
73
+ return Object.entries(args).map(([name, def]) => convertArg(name, def));
74
+ }
75
+ function convertArg(name, def) {
76
+ const arg = {
77
+ name,
78
+ type: def.type ?? "string",
79
+ required: def.required === true && def.default === void 0
80
+ };
81
+ if (def.description) arg.description = def.description;
82
+ if (isPrimitiveDefault(def.default)) arg.default = def.default;
83
+ const alias = readAlias(def);
84
+ if (alias.length > 0) arg.alias = alias;
85
+ const options = readOptions(def);
86
+ if (options.length > 0) arg.options = options;
87
+ return arg;
88
+ }
89
+ function readOptions(def) {
90
+ if (!("options" in def) || !Array.isArray(def.options)) return [];
91
+ return [...def.options];
92
+ }
93
+ function readAlias(def) {
94
+ if (!("alias" in def) || def.alias === void 0) return [];
95
+ return Array.isArray(def.alias) ? def.alias : [def.alias];
96
+ }
97
+ function isPrimitiveDefault(value) {
98
+ return typeof value === "string" || typeof value === "boolean" || typeof value === "number";
99
+ }
100
+ async function resolveCitty(value) {
101
+ if (value === void 0) return void 0;
102
+ if (typeof value === "function") return value();
103
+ return value;
104
+ }
105
+
106
+ //#endregion
107
+ //#region src/commands/manifest.ts
108
+ function createManifestCommand(root) {
109
+ return defineCommand({
110
+ meta: {
111
+ name: "__manifest",
112
+ description: "Emit machine-readable command manifest as JSON (for agents)",
113
+ hidden: true
114
+ },
115
+ args: {},
116
+ async run() {
117
+ const manifest = await buildManifest(root);
118
+ writeManifest(manifest);
119
+ }
120
+ });
121
+ }
122
+
123
+ //#endregion
124
+ export { createManifestCommand };
@@ -0,0 +1,73 @@
1
+ //#region package.json
2
+ var name = "@metabase/cli";
3
+ var version = "0.1.0-alpha.workspaces-commands.818a8f1";
4
+ var description = "Metabase CLI";
5
+ var license = "AGPL-3.0";
6
+ var repository = {
7
+ "type": "git",
8
+ "url": "git+https://github.com/metabase/mb-cli.git"
9
+ };
10
+ var bin = { "metabase": "./dist/cli.mjs" };
11
+ var files = ["dist"];
12
+ var type = "module";
13
+ var publishConfig = {
14
+ "access": "public",
15
+ "registry": "https://registry.npmjs.org/"
16
+ };
17
+ var scripts = {
18
+ "build": "tsdown",
19
+ "dev": "tsdown --watch",
20
+ "start": "node dist/cli.mjs",
21
+ "test": "vitest run --project unit",
22
+ "test:watch": "vitest --project unit",
23
+ "test:e2e": "vitest run --project e2e",
24
+ "test:e2e:watch": "vitest --project e2e",
25
+ "e2e:up": "docker compose -f tests/e2e/docker-compose.yml up -d --wait",
26
+ "e2e:down": "docker compose -f tests/e2e/docker-compose.yml down -v",
27
+ "e2e:bootstrap": "bun tests/e2e/setup/bootstrap.ts",
28
+ "e2e:logs": "docker compose -f tests/e2e/docker-compose.yml logs -f metabase",
29
+ "typecheck": "tsc --noEmit",
30
+ "lint": "oxlint",
31
+ "lint:fix": "oxlint --fix",
32
+ "format": "oxfmt",
33
+ "format:check": "oxfmt --check",
34
+ "prepublishOnly": "tsdown && publint"
35
+ };
36
+ var dependencies = {
37
+ "@clack/prompts": "^0.8.2",
38
+ "@napi-rs/keyring": "^1.3.0",
39
+ "citty": "^0.2.2",
40
+ "cli-table3": "^0.6.5",
41
+ "yaml": "^2.8.4",
42
+ "zod": "^4.0.0"
43
+ };
44
+ var devDependencies = {
45
+ "@types/node": "^22.10.0",
46
+ "execa": "^9.5.2",
47
+ "fast-check": "^4.7.0",
48
+ "oxfmt": "^0.47.0",
49
+ "oxlint": "^1.62.0",
50
+ "publint": "^0.3.0",
51
+ "tsdown": "^0.9.0",
52
+ "typescript": "^5.7.2",
53
+ "vitest": "^2.1.8"
54
+ };
55
+ var engines = { "node": ">=20.6" };
56
+ var package_default = {
57
+ name,
58
+ version,
59
+ description,
60
+ license,
61
+ repository,
62
+ bin,
63
+ files,
64
+ type,
65
+ publishConfig,
66
+ scripts,
67
+ dependencies,
68
+ devDependencies,
69
+ engines
70
+ };
71
+
72
+ //#endregion
73
+ export { package_default };
@@ -0,0 +1,12 @@
1
+ import { parseInteger } from "./runtime-DUgFfYkN.mjs";
2
+
3
+ //#region src/commands/parse-id.ts
4
+ function parseId(value, name = "id") {
5
+ return parseInteger(value, {
6
+ name,
7
+ min: 1
8
+ });
9
+ }
10
+
11
+ //#endregion
12
+ export { parseId };
@@ -0,0 +1,49 @@
1
+ import { TimeoutError, combineAborts, throwIfAborted } from "./runtime-DUgFfYkN.mjs";
2
+ import { setTimeout } from "node:timers/promises";
3
+
4
+ //#region src/runtime/poll.ts
5
+ const DEFAULT_INTERVAL_MS = 2e3;
6
+ const DEFAULT_MAX_INTERVAL_MS = 3e4;
7
+ const DEFAULT_TIMEOUT_MS = 6e5;
8
+ async function pollUntil(fn, done, opts = {}) {
9
+ const intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS;
10
+ const maxIntervalMs = opts.maxIntervalMs ?? DEFAULT_MAX_INTERVAL_MS;
11
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
12
+ const backoff = opts.backoff ?? "fixed";
13
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
14
+ const { combined, processSignal } = combineAborts(timeoutSignal, opts.signal);
15
+ let interval = intervalMs;
16
+ let attempts = 0;
17
+ while (true) {
18
+ throwIfAborted(processSignal);
19
+ if (combined.aborted) throw pollTimeout(timeoutMs, attempts);
20
+ let value;
21
+ try {
22
+ value = await fn(combined);
23
+ } catch (error) {
24
+ throwIfAborted(processSignal);
25
+ if (combined.aborted) throw pollTimeout(timeoutMs, attempts);
26
+ throw error;
27
+ }
28
+ attempts += 1;
29
+ if (done(value)) return value;
30
+ try {
31
+ await setTimeout(interval, void 0, { signal: combined });
32
+ } catch (error) {
33
+ throwIfAborted(processSignal);
34
+ if (combined.aborted) throw pollTimeout(timeoutMs, attempts);
35
+ throw error;
36
+ }
37
+ if (backoff === "exponential") interval = Math.min(interval * 2, maxIntervalMs);
38
+ }
39
+ }
40
+ function pollTimeout(timeoutMs, attempts) {
41
+ return new TimeoutError(`Polling timed out after ${timeoutMs}ms`, {
42
+ kind: "polling",
43
+ timeoutMs,
44
+ attempts
45
+ });
46
+ }
47
+
48
+ //#endregion
49
+ export { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS, pollUntil };
@@ -0,0 +1,194 @@
1
+ import { parseJson } from "./runtime-DUgFfYkN.mjs";
2
+ import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS, pollUntil } from "./poll-D2sXM5rc.mjs";
3
+ import { z } from "zod";
4
+
5
+ //#region src/domain/remote-sync.ts
6
+ const SyncTaskStatus = z.enum([
7
+ "running",
8
+ "successful",
9
+ "errored",
10
+ "cancelled",
11
+ "timed-out",
12
+ "conflict"
13
+ ]);
14
+ const SyncTaskType = z.enum(["import", "export"]);
15
+ const SyncTask = z.object({
16
+ id: z.number().int().positive(),
17
+ sync_task_type: SyncTaskType,
18
+ status: SyncTaskStatus,
19
+ progress: z.number().min(0).max(1).nullable(),
20
+ started_at: z.string(),
21
+ ended_at: z.string().nullable().optional(),
22
+ last_progress_report_at: z.string().nullable().optional(),
23
+ version: z.string().nullable().optional(),
24
+ initiated_by: z.number().int().positive().nullable().optional(),
25
+ cancelled: z.boolean().nullable().optional(),
26
+ error_message: z.string().nullable().optional(),
27
+ conflicts: z.array(z.string()).nullable().optional()
28
+ }).loose();
29
+ const SyncTaskCompact = SyncTask.pick({
30
+ id: true,
31
+ sync_task_type: true,
32
+ status: true,
33
+ progress: true,
34
+ version: true,
35
+ error_message: true
36
+ }).strip();
37
+ const syncTaskView = {
38
+ compactPick: SyncTaskCompact,
39
+ tableColumns: [
40
+ {
41
+ key: "id",
42
+ label: "ID"
43
+ },
44
+ {
45
+ key: "sync_task_type",
46
+ label: "Type"
47
+ },
48
+ {
49
+ key: "status",
50
+ label: "Status"
51
+ },
52
+ {
53
+ key: "progress",
54
+ label: "Progress"
55
+ },
56
+ {
57
+ key: "version",
58
+ label: "Version"
59
+ },
60
+ {
61
+ key: "error_message",
62
+ label: "Error"
63
+ }
64
+ ]
65
+ };
66
+ const SyncDirtyItem = z.object({
67
+ id: z.number().int(),
68
+ name: z.string().nullable(),
69
+ model: z.string(),
70
+ sync_status: z.string(),
71
+ collection_id: z.number().int().positive().nullable().optional(),
72
+ description: z.string().nullable().optional(),
73
+ display: z.string().nullable().optional(),
74
+ query_type: z.string().nullable().optional(),
75
+ table_id: z.number().int().positive().nullable().optional(),
76
+ table_name: z.string().nullable().optional()
77
+ }).loose();
78
+ const SyncDirtyItemCompact = SyncDirtyItem.pick({
79
+ id: true,
80
+ name: true,
81
+ model: true,
82
+ sync_status: true,
83
+ collection_id: true
84
+ }).strip();
85
+ const syncDirtyItemView = {
86
+ compactPick: SyncDirtyItemCompact,
87
+ tableColumns: [
88
+ {
89
+ key: "id",
90
+ label: "ID"
91
+ },
92
+ {
93
+ key: "model",
94
+ label: "Model"
95
+ },
96
+ {
97
+ key: "name",
98
+ label: "Name"
99
+ },
100
+ {
101
+ key: "sync_status",
102
+ label: "Status"
103
+ },
104
+ {
105
+ key: "collection_id",
106
+ label: "Collection"
107
+ }
108
+ ]
109
+ };
110
+
111
+ //#endregion
112
+ //#region src/commands/sync/poll-task.ts
113
+ const TERMINAL_STATUSES = new Set([
114
+ "successful",
115
+ "errored",
116
+ "cancelled",
117
+ "timed-out",
118
+ "conflict"
119
+ ]);
120
+ const FAILURE_STATUSES = new Set([
121
+ "errored",
122
+ "timed-out",
123
+ "conflict"
124
+ ]);
125
+ const REMOTE_SYNC_PATHS = {
126
+ currentTask: "/api/ee/remote-sync/current-task",
127
+ cancelTask: "/api/ee/remote-sync/current-task/cancel",
128
+ isDirty: "/api/ee/remote-sync/is-dirty",
129
+ hasRemoteChanges: "/api/ee/remote-sync/has-remote-changes",
130
+ dirty: "/api/ee/remote-sync/dirty",
131
+ import: "/api/ee/remote-sync/import",
132
+ export: "/api/ee/remote-sync/export",
133
+ stash: "/api/ee/remote-sync/stash",
134
+ branches: "/api/ee/remote-sync/branches",
135
+ createBranch: "/api/ee/remote-sync/create-branch"
136
+ };
137
+ const SyncTaskIdle = z.object({ status: z.literal("idle") });
138
+ const SyncTaskOrIdle = z.union([SyncTask, SyncTaskIdle]);
139
+ const syncTaskIdleView = {
140
+ compactPick: SyncTaskIdle,
141
+ tableColumns: [{
142
+ key: "status",
143
+ label: "Status"
144
+ }]
145
+ };
146
+ const pollFlags = {
147
+ wait: {
148
+ type: "boolean",
149
+ description: "Poll the resulting task until it reaches a terminal status",
150
+ default: true
151
+ },
152
+ timeout: {
153
+ type: "string",
154
+ description: "Polling timeout in ms (used with --wait)",
155
+ default: String(DEFAULT_TIMEOUT_MS)
156
+ },
157
+ interval: {
158
+ type: "string",
159
+ description: "Polling interval in ms (used with --wait)",
160
+ default: String(DEFAULT_INTERVAL_MS)
161
+ }
162
+ };
163
+ function isTerminal(status) {
164
+ return TERMINAL_STATUSES.has(status);
165
+ }
166
+ function isFailure(status) {
167
+ return FAILURE_STATUSES.has(status);
168
+ }
169
+ async function fetchOptionalParsed(client, path, schema) {
170
+ const response = await client.requestRaw(path, {
171
+ method: "GET",
172
+ expectContentType: "binary"
173
+ });
174
+ if (response.status === 204) return null;
175
+ const text = await response.text();
176
+ return parseJson(text, schema, { source: response.url });
177
+ }
178
+ async function fetchCurrentTask(client) {
179
+ return await fetchOptionalParsed(client, REMOTE_SYNC_PATHS.currentTask, SyncTask);
180
+ }
181
+ async function pollSyncTask(client, opts) {
182
+ return await pollUntil(async () => fetchCurrentTask(client), (task) => task === null || isTerminal(task.status), {
183
+ backoff: "exponential",
184
+ ...opts
185
+ });
186
+ }
187
+ function throwIfFailedTask(final, verb) {
188
+ if (final === null || !isFailure(final.status)) return;
189
+ const detail = final.error_message ? `: ${final.error_message}` : "";
190
+ throw new Error(`sync ${verb} ${final.status}${detail}`);
191
+ }
192
+
193
+ //#endregion
194
+ export { REMOTE_SYNC_PATHS, SyncDirtyItem, SyncDirtyItemCompact, SyncTask, SyncTaskOrIdle, fetchCurrentTask, fetchOptionalParsed, pollFlags, pollSyncTask, syncDirtyItemView, syncTaskIdleView, syncTaskView, throwIfFailedTask };
@@ -0,0 +1,40 @@
1
+ import { AbortError, ConfigError } from "./runtime-DUgFfYkN.mjs";
2
+ import { confirm, isCancel, password, text } from "@clack/prompts";
3
+
4
+ //#region src/output/prompt.ts
5
+ async function promptText(opts) {
6
+ requireTty(opts.message);
7
+ const value = await text({
8
+ message: opts.message,
9
+ ...opts.placeholder !== void 0 && { placeholder: opts.placeholder },
10
+ ...opts.initialValue !== void 0 && { initialValue: opts.initialValue },
11
+ ...opts.validate !== void 0 && { validate: opts.validate }
12
+ });
13
+ if (isCancel(value)) throw new AbortError();
14
+ return value;
15
+ }
16
+ async function promptPassword(opts) {
17
+ requireTty(opts.message);
18
+ const value = await password({
19
+ message: opts.message,
20
+ ...opts.mask !== void 0 && { mask: opts.mask },
21
+ ...opts.validate !== void 0 && { validate: opts.validate }
22
+ });
23
+ if (isCancel(value)) throw new AbortError();
24
+ return value;
25
+ }
26
+ async function promptConfirm(opts) {
27
+ requireTty(opts.message);
28
+ const value = await confirm({
29
+ message: opts.message,
30
+ ...opts.initialValue !== void 0 && { initialValue: opts.initialValue }
31
+ });
32
+ if (isCancel(value)) throw new AbortError();
33
+ return value;
34
+ }
35
+ function requireTty(prompt) {
36
+ if (!process.stdin.isTTY) throw new ConfigError(`cannot prompt "${prompt}" — stdin is not a TTY`);
37
+ }
38
+
39
+ //#endregion
40
+ export { promptConfirm, promptPassword, promptText };
@@ -0,0 +1,80 @@
1
+ import "./package-t8dKf4m_.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import { renderItem } from "./render-DlBijc5i.mjs";
4
+ import { ConfigError, connectionFlags, defineMetabaseCommand, outputFlags, parseCsv, 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 { parseId } from "./parse-id-C1prc9US.mjs";
9
+ import "./poll-D2sXM5rc.mjs";
10
+ import { parseWaitFlags, waitFlags } from "./wait-flags-CjW4ogUJ.mjs";
11
+ import { Workspace, WorkspaceProvisionInput, workspaceView } from "./workspace-Dr9lWU3D.mjs";
12
+ import { waitForDatabaseProvisioned } from "./wait-DwZN3ZwR.mjs";
13
+
14
+ //#region src/commands/workspace/database/provision.ts
15
+ var provision_default = defineMetabaseCommand({
16
+ meta: {
17
+ name: "provision",
18
+ description: "Provision a database into a workspace"
19
+ },
20
+ args: {
21
+ ...outputFlags,
22
+ ...profileFlag,
23
+ ...connectionFlags,
24
+ ...bodyInputFlags,
25
+ ...waitFlags,
26
+ "database-id": {
27
+ type: "string",
28
+ description: "Database id (alternative to --body / --file)"
29
+ },
30
+ schemas: {
31
+ type: "string",
32
+ description: "Comma-separated input schemas (alternative to --body / --file)"
33
+ },
34
+ id: {
35
+ type: "positional",
36
+ description: "Workspace id",
37
+ required: true
38
+ }
39
+ },
40
+ outputSchema: Workspace,
41
+ examples: [
42
+ "metabase workspace database provision 1 --database-id 5 --schemas analytics,github",
43
+ "metabase workspace database provision 1 --database-id 5 --schemas analytics --wait",
44
+ "metabase workspace database provision 1 --file provision.json"
45
+ ],
46
+ async run({ args, ctx, getClient }) {
47
+ const workspaceId = parseId(args.id);
48
+ const databaseIdFlag = args["database-id"];
49
+ const schemasFlag = args.schemas;
50
+ const wait = parseWaitFlags(args);
51
+ let body;
52
+ if (databaseIdFlag !== void 0 && databaseIdFlag !== "") {
53
+ const databaseId = parseId(databaseIdFlag, "--database-id");
54
+ const schemas = parseSchemas(schemasFlag);
55
+ body = WorkspaceProvisionInput.parse({
56
+ database_id: databaseId,
57
+ input_schemas: schemas
58
+ });
59
+ } else body = await readBody({
60
+ flag: args.body,
61
+ file: args.file
62
+ }, WorkspaceProvisionInput);
63
+ const client = await getClient();
64
+ const initial = await client.requestParsed(Workspace, `/api/ee/workspace-manager/${workspaceId}/database`, {
65
+ method: "POST",
66
+ body
67
+ });
68
+ const final = wait.enabled ? await waitForDatabaseProvisioned(client, workspaceId, body.database_id, wait.schedule) : initial;
69
+ renderItem(final, workspaceView, ctx);
70
+ }
71
+ });
72
+ function parseSchemas(raw) {
73
+ if (raw === void 0 || raw === "") throw new ConfigError("--schemas is required when using --database-id");
74
+ const parts = parseCsv(raw);
75
+ if (parts.length === 0) throw new ConfigError("--schemas must contain at least one schema name");
76
+ return parts;
77
+ }
78
+
79
+ //#endregion
80
+ export { provision_default as default };
@@ -0,0 +1,9 @@
1
+ import "./package-t8dKf4m_.mjs";
2
+ import "./command-augment-D9pI9Vbh.mjs";
3
+ import "./render-DlBijc5i.mjs";
4
+ import "./runtime-DUgFfYkN.mjs";
5
+ import "./poll-D2sXM5rc.mjs";
6
+ import "./docker-QWVMG2gl.mjs";
7
+ import { LocalWorkspace, LocalWorkspaceCompact, LocalWorkspaceListEnvelope, LocalWorkspaceState, localWorkspaceView, ps_default } from "./ps-BiOrecEe.mjs";
8
+
9
+ export { ps_default as default };
@@ -0,0 +1,78 @@
1
+ import { renderList } from "./render-DlBijc5i.mjs";
2
+ import { defineMetabaseCommand, listEnvelopeSchema, localUrl, outputFlags, wrapList } from "./runtime-DUgFfYkN.mjs";
3
+ import { CONTAINER_STATES, checkDockerReady, listWorkspaceContainers } from "./docker-QWVMG2gl.mjs";
4
+ import { z } from "zod";
5
+
6
+ //#region src/commands/workspace/ps.ts
7
+ const LocalWorkspaceState = z.enum(CONTAINER_STATES);
8
+ const LocalWorkspace = z.object({
9
+ workspace_id: z.number().int().positive(),
10
+ workspace_name: z.string(),
11
+ container_name: z.string(),
12
+ state: LocalWorkspaceState,
13
+ status: z.string(),
14
+ image: z.string(),
15
+ profile: z.string().nullable(),
16
+ parent_url: z.string().nullable(),
17
+ host_port: z.number().int().positive().nullable(),
18
+ url: z.string().nullable()
19
+ });
20
+ const LocalWorkspaceCompact = LocalWorkspace.pick({
21
+ workspace_id: true,
22
+ workspace_name: true,
23
+ state: true,
24
+ url: true
25
+ }).strip();
26
+ const localWorkspaceView = {
27
+ compactPick: LocalWorkspaceCompact,
28
+ tableColumns: [
29
+ {
30
+ key: "workspace_id",
31
+ label: "ID"
32
+ },
33
+ {
34
+ key: "workspace_name",
35
+ label: "Name"
36
+ },
37
+ {
38
+ key: "state",
39
+ label: "State"
40
+ },
41
+ {
42
+ key: "url",
43
+ label: "URL",
44
+ format: (value) => typeof value === "string" ? value : "—"
45
+ }
46
+ ]
47
+ };
48
+ const LocalWorkspaceListEnvelope = listEnvelopeSchema(LocalWorkspaceCompact);
49
+ var ps_default = defineMetabaseCommand({
50
+ meta: {
51
+ name: "ps",
52
+ description: "List workspaces with a local container (running or stopped)"
53
+ },
54
+ args: { ...outputFlags },
55
+ outputSchema: LocalWorkspaceListEnvelope,
56
+ examples: ["metabase workspace ps", "metabase workspace ps --json"],
57
+ async run({ ctx }) {
58
+ await checkDockerReady();
59
+ const summaries = await listWorkspaceContainers();
60
+ const items = summaries.map((summary) => ({
61
+ workspace_id: summary.workspaceId,
62
+ workspace_name: summary.workspaceName,
63
+ container_name: summary.name,
64
+ state: summary.state,
65
+ status: summary.status,
66
+ image: summary.image,
67
+ profile: summary.profile,
68
+ parent_url: summary.parentUrl,
69
+ host_port: summary.hostPort,
70
+ url: summary.hostPort !== null && summary.state === "running" ? localUrl(summary.hostPort) : null
71
+ }));
72
+ items.sort((a, b) => a.workspace_id - b.workspace_id);
73
+ renderList(wrapList(items), localWorkspaceView, ctx);
74
+ }
75
+ });
76
+
77
+ //#endregion
78
+ export { LocalWorkspace, LocalWorkspaceCompact, LocalWorkspaceListEnvelope, LocalWorkspaceState, localWorkspaceView, ps_default };