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

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 (110) hide show
  1. package/README.md +0 -237
  2. package/dist/{archive-BPG5c88Y.mjs → archive-CsWeHXle.mjs} +4 -5
  3. package/dist/{auth--Hpjwlaf.mjs → auth-BF7IjZIH.mjs} +3 -3
  4. package/dist/{body-DwU2s6Pg.mjs → body-Dv9hQ0Qk.mjs} +2 -2
  5. package/dist/{branches-BbcoJXfp.mjs → branches-BujtceGr.mjs} +4 -5
  6. package/dist/{cancel-task-BDas45YO.mjs → cancel-task-CT2xUMRg.mjs} +4 -5
  7. package/dist/card-_Ta7zdYe.mjs +19 -0
  8. package/dist/cli.mjs +13 -17
  9. package/dist/{create-DpnjQvPw.mjs → create-B8ektf-R.mjs} +6 -7
  10. package/dist/{create-_UOeEXAj.mjs → create-CI2Cunq5.mjs} +6 -7
  11. package/dist/{create-CwVcoq0O.mjs → create-DdbU3TLX.mjs} +6 -7
  12. package/dist/{create-branch-sDttBORB.mjs → create-branch-goZBTNnr.mjs} +4 -5
  13. package/dist/{current-task-BGt1mqaX.mjs → current-task-DBjRNCFq.mjs} +4 -5
  14. package/dist/{db-Dm2u2ISJ.mjs → db-DMghzgb6.mjs} +2 -2
  15. package/dist/{delete-DRBTgyus.mjs → delete-8vGU35r3.mjs} +5 -6
  16. package/dist/{delete-DUC_stoL.mjs → delete-B27KLF5X.mjs} +5 -6
  17. package/dist/{delete-runtime-inOVw3IX.mjs → delete-runtime-Byr60cR3.mjs} +2 -4
  18. package/dist/{delete-table-9Is631O_.mjs → delete-table-BNaJ_gA4.mjs} +5 -6
  19. package/dist/{dirty-CLjHbz6J.mjs → dirty-aNUuph4I.mjs} +4 -5
  20. package/dist/{export-D2Anfu3p.mjs → export-QDkuuzSE.mjs} +5 -6
  21. package/dist/{field-Dhs2AND3.mjs → field-DaYo_90x.mjs} +1 -1
  22. package/dist/{get-DhIoNeOp.mjs → get-BGBIzMKY.mjs} +4 -5
  23. package/dist/{get-CAVVmdMX.mjs → get-COXHplHP.mjs} +4 -5
  24. package/dist/{get-CAPLfawI.mjs → get-Cl8-IauC.mjs} +4 -5
  25. package/dist/{get-DDWpubE8.mjs → get-Cwpj7lDe.mjs} +5 -6
  26. package/dist/{get-BHJA78zg.mjs → get-DI_IJvgk.mjs} +4 -5
  27. package/dist/{get-2po1uv9i.mjs → get-Dh_acl8q.mjs} +4 -5
  28. package/dist/{get-qPOsuTPw.mjs → get-i6LWOByV.mjs} +4 -5
  29. package/dist/{has-remote-changes-DAL5jetW.mjs → has-remote-changes-hjKoQuRy.mjs} +4 -5
  30. package/dist/{import-CUMxUfSF.mjs → import-HJsSKRYx.mjs} +5 -6
  31. package/dist/{input-BNqSFl38.mjs → input-Dojr-RTw.mjs} +1 -1
  32. package/dist/{is-dirty-B10S6MG0.mjs → is-dirty-1Qy7hiHB.mjs} +2 -3
  33. package/dist/is-dirty-DpKn9HJp.mjs +8 -0
  34. package/dist/{key-CyhOpgWt.mjs → key-DBxPSFwi.mjs} +1 -1
  35. package/dist/{license-DtsGJi3l.mjs → license-MoWse3ZI.mjs} +3 -3
  36. package/dist/{list-Y7iGsOfE.mjs → list-Bk6RsbJl.mjs} +3 -4
  37. package/dist/{list-DeFGwhhJ.mjs → list-C4Ajrw8f.mjs} +3 -4
  38. package/dist/{list-C5MGydGU.mjs → list-C8tdLOH5.mjs} +3 -4
  39. package/dist/{list-evtQS7jl.mjs → list-CBSBHtK-.mjs} +3 -4
  40. package/dist/{list-qetY9OIN.mjs → list-CWt3fqrZ.mjs} +3 -4
  41. package/dist/{list-OBx5B3gd.mjs → list-C_PRdL5e.mjs} +5 -6
  42. package/dist/{login-Dqw9ZtCx.mjs → login-C9WTwNn6.mjs} +4 -5
  43. package/dist/{logout-DwYJ5OUi.mjs → logout-oLszGCOg.mjs} +3 -4
  44. package/dist/{package-t8dKf4m_.mjs → package-BGfw4ZWJ.mjs} +1 -2
  45. package/dist/parse-id-BhmmfyCP.mjs +14 -0
  46. package/dist/{poll-D2sXM5rc.mjs → poll-ILanYysl.mjs} +1 -1
  47. package/dist/{poll-task-Byiunmaj.mjs → poll-task-DbpsiQhl.mjs} +2 -2
  48. package/dist/{prompt-fXeNtj0M.mjs → prompt-DpT8yAVy.mjs} +1 -1
  49. package/dist/{query-BnGVGeM3.mjs → query-PihYi-UZ.mjs} +4 -5
  50. package/dist/{remove-Bx48o-0S.mjs → remove-B2hVYn1v.mjs} +3 -4
  51. package/dist/{run-D4NgvaRh.mjs → run-C2so6Qp6.mjs} +27 -11
  52. package/dist/{runtime-DUgFfYkN.mjs → runtime-C9CEZhcn.mjs} +335 -203
  53. package/dist/{search-4wKx5ug2.mjs → search-CopOytXY.mjs} +4 -5
  54. package/dist/{set-BZnCRL4c.mjs → set-BcF7M1GQ.mjs} +4 -5
  55. package/dist/{set-DCjrmTFm.mjs → set-CbibegpA.mjs} +6 -7
  56. package/dist/{setting-C4vQSqer.mjs → setting-U3NtBMFo.mjs} +3 -3
  57. package/dist/{stash-ZZkmW_V7.mjs → stash-DOBbYozC.mjs} +5 -6
  58. package/dist/{status-DezF-PIM.mjs → status-Buf1ZbNR.mjs} +5 -6
  59. package/dist/{status-JH6BZppo.mjs → status-CUcs8XBH.mjs} +2 -3
  60. package/dist/{status-9KAPIpX8.mjs → status-D1F5XHae.mjs} +2 -3
  61. package/dist/sync-BPyGXfUk.mjs +26 -0
  62. package/dist/{table-BvAr2ixC.mjs → table-Cfk7oSvw.mjs} +1 -1
  63. package/dist/{table-D-Mb5Nvw.mjs → table-D7nJt7JO.mjs} +2 -2
  64. package/dist/transform-UbyewMxY.mjs +21 -0
  65. package/dist/transform-job-CrYkr-Ma.mjs +19 -0
  66. package/dist/{update-DxKlQ0hP.mjs → update-CL8tRbxr.mjs} +7 -8
  67. package/dist/{update-CDtm71m2.mjs → update-DU2oU2j-.mjs} +7 -8
  68. package/dist/{wait-Cj_8wu4y.mjs → wait-Bugr9eXD.mjs} +5 -6
  69. package/package.json +1 -2
  70. package/dist/api-key-D9XxErQn.mjs +0 -13
  71. package/dist/card-D4zZSPUb.mjs +0 -19
  72. package/dist/create-Bd_U1zWU.mjs +0 -124
  73. package/dist/create-CCzsCZMm.mjs +0 -47
  74. package/dist/credentials-C0xKke5D.mjs +0 -84
  75. package/dist/database-4V1iiPEx.mjs +0 -17
  76. package/dist/deprovision-BAMzZc6f.mjs +0 -60
  77. package/dist/docker-QWVMG2gl.mjs +0 -605
  78. package/dist/eid-BNhutC1U.mjs +0 -13
  79. package/dist/flag-pair-CWvvzDJ_.mjs +0 -17
  80. package/dist/is-dirty-CUuq-aB6.mjs +0 -9
  81. package/dist/list-B8s7Qnzk.mjs +0 -31
  82. package/dist/logs-B_lrY7Js.mjs +0 -57
  83. package/dist/parse-id-C1prc9US.mjs +0 -12
  84. package/dist/provision-DC4_HWZD.mjs +0 -80
  85. package/dist/ps-1bZKIwWh.mjs +0 -9
  86. package/dist/ps-BiOrecEe.mjs +0 -78
  87. package/dist/remove-DecoZzNd.mjs +0 -97
  88. package/dist/render-DlBijc5i.mjs +0 -179
  89. package/dist/setup-Dqh9hN6l.mjs +0 -70
  90. package/dist/start-xXQypG5L.mjs +0 -324
  91. package/dist/stop-br-ZOnve.mjs +0 -80
  92. package/dist/sync-C7VOWD00.mjs +0 -26
  93. package/dist/transform-CqxZwhGs.mjs +0 -21
  94. package/dist/transform-job-HjbqjEoP.mjs +0 -19
  95. package/dist/translate-DJxDVAE4.mjs +0 -110
  96. package/dist/update-DYVeVjk2.mjs +0 -76
  97. package/dist/url-DP88YHNo.mjs +0 -53
  98. package/dist/wait-DwZN3ZwR.mjs +0 -19
  99. package/dist/wait-flags-CjW4ogUJ.mjs +0 -35
  100. package/dist/workspace-CbwR0vX_.mjs +0 -24
  101. package/dist/workspace-Dr9lWU3D.mjs +0 -72
  102. package/dist/workspace-credentials-q5RRFMT8.mjs +0 -139
  103. /package/dist/{body-flags-7oqLhu5j.mjs → body-flags-BUA9XV1u.mjs} +0 -0
  104. /package/dist/{card-C31pGtBZ.mjs → card-CsXk8T6A.mjs} +0 -0
  105. /package/dist/{database-BTX5qbSv.mjs → database-PA9Goi25.mjs} +0 -0
  106. /package/dist/{field-QwBMAWsq.mjs → field-C8IVs6rp.mjs} +0 -0
  107. /package/dist/{manifest-wzEFG0JB.mjs → manifest-CAdjQYH8.mjs} +0 -0
  108. /package/dist/{setting-DM7pm7yh.mjs → setting-26ckqHAP.mjs} +0 -0
  109. /package/dist/{transform-DfVkUttP.mjs → transform-B5uRpg1G.mjs} +0 -0
  110. /package/dist/{transform-job-DuB_OjhO.mjs → transform-job-C7QXWTVE.mjs} +0 -0
@@ -1,57 +0,0 @@
1
- import "./package-t8dKf4m_.mjs";
2
- import "./command-augment-D9pI9Vbh.mjs";
3
- import { ConfigError, defineMetabaseCommand, outputFlags, parseInteger } from "./runtime-DUgFfYkN.mjs";
4
- import { parseId } from "./parse-id-C1prc9US.mjs";
5
- import "./poll-D2sXM5rc.mjs";
6
- import { checkDockerReady, containerLifecycleStatus, containerNameFor, streamLogs } from "./docker-QWVMG2gl.mjs";
7
-
8
- //#region src/commands/workspace/logs.ts
9
- const DEFAULT_TAIL = 200;
10
- var logs_default = defineMetabaseCommand({
11
- meta: {
12
- name: "logs",
13
- description: "Stream the local container's logs (passthrough to `docker logs`)"
14
- },
15
- args: {
16
- ...outputFlags,
17
- id: {
18
- type: "positional",
19
- description: "Workspace id",
20
- required: true
21
- },
22
- follow: {
23
- type: "boolean",
24
- alias: "f",
25
- description: "Follow log output (stream indefinitely; Ctrl-C to exit)",
26
- default: false
27
- },
28
- tail: {
29
- type: "string",
30
- description: `Number of lines from the end of the logs (default: ${DEFAULT_TAIL})`,
31
- default: String(DEFAULT_TAIL)
32
- }
33
- },
34
- examples: [
35
- "metabase workspace logs 1",
36
- "metabase workspace logs 1 --follow",
37
- "metabase workspace logs 1 --tail 500"
38
- ],
39
- async run({ args }) {
40
- const workspaceId = parseId(args.id);
41
- const containerName = containerNameFor(workspaceId);
42
- const tail = parseInteger(args.tail ?? String(DEFAULT_TAIL), {
43
- name: "--tail",
44
- min: 0
45
- });
46
- await checkDockerReady();
47
- const status = await containerLifecycleStatus(containerName);
48
- if (status === "missing") throw new ConfigError(`no container for workspace ${workspaceId} — run \`metabase workspace start ${workspaceId}\` first`);
49
- await streamLogs(containerName, {
50
- follow: args.follow === true,
51
- tail
52
- });
53
- }
54
- });
55
-
56
- //#endregion
57
- export { logs_default as default };
@@ -1,12 +0,0 @@
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 };
@@ -1,80 +0,0 @@
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 };
@@ -1,9 +0,0 @@
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 };
@@ -1,78 +0,0 @@
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 };
@@ -1,97 +0,0 @@
1
- import "./package-t8dKf4m_.mjs";
2
- import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderItem } from "./render-DlBijc5i.mjs";
4
- import { defineMetabaseCommand, outputFlags } from "./runtime-DUgFfYkN.mjs";
5
- import { parseId } from "./parse-id-C1prc9US.mjs";
6
- import { promptConfirm } from "./prompt-fXeNtj0M.mjs";
7
- import "./poll-D2sXM5rc.mjs";
8
- import { checkDockerReady, containerNameFor, removeContainer, removeVolume, volumeNameFor } from "./docker-QWVMG2gl.mjs";
9
- import { z } from "zod";
10
-
11
- //#region src/commands/workspace/remove.ts
12
- const RemoveResult = z.object({
13
- workspace_id: z.number().int().positive(),
14
- container_name: z.string(),
15
- volume_name: z.string(),
16
- removed_container: z.boolean(),
17
- removed_volume: z.boolean()
18
- });
19
- const removeResultView = {
20
- compactPick: RemoveResult.pick({
21
- workspace_id: true,
22
- removed_container: true,
23
- removed_volume: true
24
- }).strip(),
25
- tableColumns: [
26
- {
27
- key: "workspace_id",
28
- label: "ID"
29
- },
30
- {
31
- key: "container_name",
32
- label: "Container"
33
- },
34
- {
35
- key: "volume_name",
36
- label: "Volume"
37
- },
38
- {
39
- key: "removed_container",
40
- label: "Removed Container"
41
- },
42
- {
43
- key: "removed_volume",
44
- label: "Removed Volume"
45
- }
46
- ]
47
- };
48
- var remove_default = defineMetabaseCommand({
49
- meta: {
50
- name: "remove",
51
- description: "Stop and remove the local container + app-db volume (does not affect remote)"
52
- },
53
- args: {
54
- ...outputFlags,
55
- id: {
56
- type: "positional",
57
- description: "Workspace id",
58
- required: true
59
- },
60
- "keep-volume": {
61
- type: "boolean",
62
- description: "Keep the workspace's app-db volume (faster restart, app-db survives)",
63
- default: false
64
- },
65
- yes: {
66
- type: "boolean",
67
- description: "Skip the confirmation prompt",
68
- default: false
69
- }
70
- },
71
- outputSchema: RemoveResult,
72
- examples: ["metabase workspace remove 1 --yes", "metabase workspace remove 1 --keep-volume --yes"],
73
- async run({ args, ctx }) {
74
- const workspaceId = parseId(args.id);
75
- const containerName = containerNameFor(workspaceId);
76
- const volumeName = volumeNameFor(workspaceId);
77
- const shouldRemoveVolume = args["keep-volume"] !== true;
78
- await checkDockerReady();
79
- if (!args.yes) {
80
- const confirmed = await promptConfirm({ message: shouldRemoveVolume ? `Remove container ${containerName} and its app-db volume ${volumeName}?` : `Remove container ${containerName}? (volume ${volumeName} will be kept)` });
81
- if (!confirmed) return;
82
- }
83
- const removedContainer = await removeContainer(containerName);
84
- const removedVolume = shouldRemoveVolume ? await removeVolume(volumeName) : false;
85
- const result = {
86
- workspace_id: workspaceId,
87
- container_name: containerName,
88
- volume_name: volumeName,
89
- removed_container: removedContainer,
90
- removed_volume: removedVolume
91
- };
92
- renderItem(result, removeResultView, ctx);
93
- }
94
- });
95
-
96
- //#endregion
97
- export { remove_default as default };
@@ -1,179 +0,0 @@
1
- import { ConfigError } from "./runtime-DUgFfYkN.mjs";
2
- import Table from "cli-table3";
3
-
4
- //#region src/output/cap.ts
5
- function capListEnvelope(envelope, maxBytes) {
6
- if (maxBytes <= 0) return envelope;
7
- const fullBytes = jsonByteLength(envelope);
8
- if (fullBytes <= maxBytes) return envelope;
9
- let lo = 0;
10
- let hi = envelope.data.length;
11
- while (lo < hi) {
12
- const mid = Math.ceil((lo + hi) / 2);
13
- if (jsonByteLength(truncate(envelope, mid, fullBytes)) <= maxBytes) lo = mid;
14
- else hi = mid - 1;
15
- }
16
- return truncate(envelope, lo, fullBytes);
17
- }
18
- function truncate(envelope, count, originalBytes) {
19
- return {
20
- ...envelope,
21
- data: envelope.data.slice(0, count),
22
- returned: count,
23
- truncated: {
24
- reason: "max_bytes",
25
- bytes: originalBytes
26
- }
27
- };
28
- }
29
- function jsonByteLength(value) {
30
- return Buffer.byteLength(JSON.stringify(value), "utf8");
31
- }
32
-
33
- //#endregion
34
- //#region src/output/notice.ts
35
- function warn(message) {
36
- process.stderr.write(message + "\n");
37
- }
38
- function listTruncationNotice(bytes) {
39
- return `… cut at ${bytes} bytes; rerun with --max-bytes 0`;
40
- }
41
- function itemOversizeNotice(bytes) {
42
- return `… item is ${bytes} bytes (exceeds --max-bytes); narrow with --fields, or pass --max-bytes 0`;
43
- }
44
-
45
- //#endregion
46
- //#region src/output/projection.ts
47
- function applyProjection(value, view, full, fields) {
48
- if (fields !== void 0) {
49
- if (fields.length === 0) throw new ConfigError("--fields requires at least one path");
50
- return projectFields(value, fields);
51
- }
52
- if (full) return value;
53
- const parsed = view.compactPick.safeParse(value);
54
- if (parsed.success) return parsed.data;
55
- throw new ConfigError(`compact projection failed: ${parsed.error.message}`);
56
- }
57
- function projectFields(value, fields) {
58
- const out = {};
59
- for (const path of fields) {
60
- if (path.length === 0) throw new ConfigError(`empty field path`);
61
- const parts = path.split(".");
62
- if (parts.some((part) => part.length === 0)) throw new ConfigError(`invalid field path: "${path}"`);
63
- setPath(out, parts, pickPath(value, parts));
64
- }
65
- return out;
66
- }
67
- function pickPath(value, parts) {
68
- let cursor = value;
69
- for (const part of parts) {
70
- if (!isPlainObject(cursor) || !Object.hasOwn(cursor, part)) throw new ConfigError(`unknown field path: "${parts.join(".")}"`);
71
- cursor = Reflect.get(cursor, part);
72
- }
73
- return cursor;
74
- }
75
- function setPath(target, parts, value) {
76
- let cursor = target;
77
- const lastIndex = parts.length - 1;
78
- for (const [index, part] of parts.entries()) {
79
- if (index === lastIndex) {
80
- cursor[part] = value;
81
- return;
82
- }
83
- const existing = cursor[part];
84
- if (isPlainObject(existing)) cursor = existing;
85
- else {
86
- const next = {};
87
- cursor[part] = next;
88
- cursor = next;
89
- }
90
- }
91
- }
92
- function isPlainObject(value) {
93
- return typeof value === "object" && value !== null && !Array.isArray(value);
94
- }
95
-
96
- //#endregion
97
- //#region src/output/table.ts
98
- function renderTable(rows, columns) {
99
- const head = columns.map((column) => column.label ?? column.key);
100
- const widths = columns.map((column) => column.width ?? null);
101
- const hasWidth = widths.some((width) => width !== null);
102
- const table = new Table(hasWidth ? {
103
- head,
104
- colWidths: widths
105
- } : { head });
106
- for (const row of rows) table.push(columns.map((column) => formatCell(row, column)));
107
- return table.toString();
108
- }
109
- function formatCell(row, column) {
110
- const value = row[column.key];
111
- if (column.format !== void 0) return column.format(value);
112
- return formatScalar(value);
113
- }
114
- function formatScalar(value) {
115
- if (value === null || value === void 0) return "";
116
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
117
- return JSON.stringify(value);
118
- }
119
-
120
- //#endregion
121
- //#region src/output/render.ts
122
- function renderItem(item, view, opts) {
123
- const projected = applyProjection(item, view, opts.full, opts.fields);
124
- const body = renderItemBody(item, view, projected, opts) + "\n";
125
- process.stdout.write(body);
126
- emitItemOversizeNotice(body, opts.maxBytes);
127
- }
128
- function renderList(envelope, view, opts) {
129
- if (opts.format === "json" || opts.fields !== void 0) {
130
- renderJsonEnvelope(envelope, view, opts);
131
- return;
132
- }
133
- if (envelope.data.length === 0) {
134
- process.stdout.write("(no results)\n");
135
- return;
136
- }
137
- const capped = capListEnvelope(envelope, opts.maxBytes);
138
- process.stdout.write(renderTable(capped.data, view.tableColumns) + "\n");
139
- if (capped.truncated !== void 0) warn(listTruncationNotice(capped.truncated.bytes));
140
- }
141
- function renderJsonEnvelope(envelope, view, opts) {
142
- const projectedItems = envelope.data.map((item) => applyProjection(item, view, opts.full, opts.fields));
143
- const projectedEnvelope = {
144
- ...envelope,
145
- data: projectedItems
146
- };
147
- const capped = capListEnvelope(projectedEnvelope, opts.maxBytes);
148
- process.stdout.write(JSON.stringify(capped, null, 2) + "\n");
149
- if (capped.truncated !== void 0) warn(listTruncationNotice(capped.truncated.bytes));
150
- }
151
- function renderItemBody(item, view, projected, opts) {
152
- if (opts.format === "json" || opts.fields !== void 0) return JSON.stringify(projected, null, 2);
153
- if (!opts.full) return renderKeyValueLines(columnPairs(item, view.tableColumns));
154
- return renderKeyValueLines(objectPairs(projected));
155
- }
156
- function columnPairs(item, columns) {
157
- return columns.map((column) => [column.label ?? column.key, formatCell(item, column)]);
158
- }
159
- function objectPairs(value) {
160
- if (!isPlainObject(value)) {
161
- const scalar = formatScalar(value);
162
- return scalar === "" ? [] : [["", scalar]];
163
- }
164
- return Object.entries(value).map(([key, raw]) => [key, formatScalar(raw)]);
165
- }
166
- function renderKeyValueLines(pairs) {
167
- if (pairs.length === 0) return "";
168
- const padding = Math.max(...pairs.map(([label]) => label.length));
169
- return pairs.map(([label, value]) => `${label.padEnd(padding)} ${value}`).join("\n");
170
- }
171
- function emitItemOversizeNotice(body, maxBytes) {
172
- if (maxBytes <= 0) return;
173
- const bytes = Buffer.byteLength(body, "utf8");
174
- if (bytes <= maxBytes) return;
175
- warn(itemOversizeNotice(bytes));
176
- }
177
-
178
- //#endregion
179
- export { renderItem, renderList, warn };
@@ -1,70 +0,0 @@
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 };