@graphit/cli 0.1.1 → 0.1.3

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 (71) hide show
  1. package/.claude-plugin/marketplace.json +25 -0
  2. package/.claude-plugin/plugin.json +23 -0
  3. package/.codex-plugin/plugin.json +22 -0
  4. package/package.json +4 -2
  5. package/{skill → skills/graphit}/SKILL.md +78 -23
  6. package/skills/graphit/cursor/graphit-chart-patterns.mdc +86 -0
  7. package/skills/graphit/graphit.mdc +117 -0
  8. package/skills/graphit/references/chart-patterns.md +80 -0
  9. package/dist/api/client.d.ts +0 -16
  10. package/dist/api/client.js +0 -67
  11. package/dist/api/client.js.map +0 -1
  12. package/dist/auth/credentials.d.ts +0 -15
  13. package/dist/auth/credentials.js +0 -34
  14. package/dist/auth/credentials.js.map +0 -1
  15. package/dist/auth/login.d.ts +0 -2
  16. package/dist/auth/login.js +0 -230
  17. package/dist/auth/login.js.map +0 -1
  18. package/dist/auth/token.d.ts +0 -5
  19. package/dist/auth/token.js +0 -42
  20. package/dist/auth/token.js.map +0 -1
  21. package/dist/commands/auth.d.ts +0 -2
  22. package/dist/commands/auth.js +0 -68
  23. package/dist/commands/auth.js.map +0 -1
  24. package/dist/commands/connector.d.ts +0 -2
  25. package/dist/commands/connector.js +0 -97
  26. package/dist/commands/connector.js.map +0 -1
  27. package/dist/commands/dashboard.d.ts +0 -2
  28. package/dist/commands/dashboard.js +0 -124
  29. package/dist/commands/dashboard.js.map +0 -1
  30. package/dist/commands/ds.d.ts +0 -2
  31. package/dist/commands/ds.js +0 -53
  32. package/dist/commands/ds.js.map +0 -1
  33. package/dist/commands/kb.d.ts +0 -2
  34. package/dist/commands/kb.js +0 -259
  35. package/dist/commands/kb.js.map +0 -1
  36. package/dist/commands/query.d.ts +0 -2
  37. package/dist/commands/query.js +0 -61
  38. package/dist/commands/query.js.map +0 -1
  39. package/dist/commands/setup.d.ts +0 -2
  40. package/dist/commands/setup.js +0 -173
  41. package/dist/commands/setup.js.map +0 -1
  42. package/dist/config.d.ts +0 -4
  43. package/dist/config.js +0 -9
  44. package/dist/config.js.map +0 -1
  45. package/dist/index.d.ts +0 -2
  46. package/dist/index.js +0 -24
  47. package/dist/index.js.map +0 -1
  48. package/dist/output/format.d.ts +0 -8
  49. package/dist/output/format.js +0 -30
  50. package/dist/output/format.js.map +0 -1
  51. package/dist/output/json.d.ts +0 -1
  52. package/dist/output/json.js +0 -4
  53. package/dist/output/json.js.map +0 -1
  54. package/dist/output/table.d.ts +0 -2
  55. package/dist/output/table.js +0 -17
  56. package/dist/output/table.js.map +0 -1
  57. package/skill/cursor/graphit-chart-patterns.mdc +0 -148
  58. package/skill/graphit.mdc +0 -135
  59. package/skill/references/chart-patterns.md +0 -257
  60. /package/{skill → skills/graphit}/cursor/graphit-chart-selection.mdc +0 -0
  61. /package/{skill → skills/graphit}/cursor/graphit-dashboard-planning.mdc +0 -0
  62. /package/{skill → skills/graphit}/cursor/graphit-domain-lenses.mdc +0 -0
  63. /package/{skill → skills/graphit}/cursor/graphit-kb-exploration.mdc +0 -0
  64. /package/{skill → skills/graphit}/cursor/graphit-sql-reference.mdc +0 -0
  65. /package/{skill → skills/graphit}/cursor/graphit-style.mdc +0 -0
  66. /package/{skill → skills/graphit}/references/chart-selection.md +0 -0
  67. /package/{skill → skills/graphit}/references/dashboard-planning.md +0 -0
  68. /package/{skill → skills/graphit}/references/domain-lenses.md +0 -0
  69. /package/{skill → skills/graphit}/references/graphit-style.md +0 -0
  70. /package/{skill → skills/graphit}/references/kb-exploration.md +0 -0
  71. /package/{skill → skills/graphit}/references/sql-reference.md +0 -0
@@ -1,34 +0,0 @@
1
- import { readFile, writeFile, unlink, mkdir, chmod } from "node:fs/promises";
2
- import { homedir } from "node:os";
3
- import { join, dirname } from "node:path";
4
- import { existsSync } from "node:fs";
5
- const CREDENTIALS_PATH = join(homedir(), ".graphit", "credentials.json");
6
- export function getCredentialsPath() {
7
- return CREDENTIALS_PATH;
8
- }
9
- export async function readCredentials() {
10
- try {
11
- const raw = await readFile(CREDENTIALS_PATH, "utf-8");
12
- return JSON.parse(raw);
13
- }
14
- catch {
15
- return null;
16
- }
17
- }
18
- export async function writeCredentials(creds) {
19
- const dir = dirname(CREDENTIALS_PATH);
20
- if (!existsSync(dir)) {
21
- await mkdir(dir, { recursive: true });
22
- }
23
- await writeFile(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), "utf-8");
24
- await chmod(CREDENTIALS_PATH, 0o600);
25
- }
26
- export async function deleteCredentials() {
27
- try {
28
- await unlink(CREDENTIALS_PATH);
29
- }
30
- catch {
31
- // File may not exist
32
- }
33
- }
34
- //# sourceMappingURL=credentials.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/auth/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAcrC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAEzE,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAwB;IAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3E,MAAM,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,qBAAqB;IACvB,CAAC;AACH,CAAC"}
@@ -1,2 +0,0 @@
1
- import { type StoredCredentials } from "./credentials.js";
2
- export declare function performLogin(): Promise<StoredCredentials>;
@@ -1,230 +0,0 @@
1
- import { createServer } from "node:http";
2
- import { randomBytes, createHash } from "node:crypto";
3
- import { writeCredentials } from "./credentials.js";
4
- import { apiClient } from "../api/client.js";
5
- import { getFrontendUrl } from "../config.js";
6
- import open from "open";
7
- const AUTH_TIMEOUT_MS = 120_000;
8
- function escapeHtml(str) {
9
- return str
10
- .replace(/&/g, "&amp;")
11
- .replace(/</g, "&lt;")
12
- .replace(/>/g, "&gt;")
13
- .replace(/"/g, "&quot;");
14
- }
15
- function renderCallbackPage(variant, title, message) {
16
- const safeTitle = escapeHtml(title);
17
- const safeMessage = escapeHtml(message);
18
- const statusIcon = variant === "success"
19
- ? `<svg width="56" height="56" viewBox="0 0 56 56" fill="none">
20
- <circle cx="28" cy="28" r="28" fill="#4DB6AC"/>
21
- <path d="M17 28.5L24 35.5L39 20.5" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
22
- </svg>`
23
- : `<svg width="56" height="56" viewBox="0 0 56 56" fill="none">
24
- <circle cx="28" cy="28" r="28" fill="#B91C1C"/>
25
- <path d="M20 20L36 36M36 20L20 36" stroke="#fff" stroke-width="3" stroke-linecap="round"/>
26
- </svg>`;
27
- return `<!DOCTYPE html>
28
- <html lang="en">
29
- <head>
30
- <meta charset="utf-8">
31
- <meta name="viewport" content="width=device-width, initial-scale=1">
32
- <title>${safeTitle} - Graphit</title>
33
- <link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700&display=swap">
34
- <style>
35
- * { margin: 0; padding: 0; box-sizing: border-box; }
36
-
37
- body {
38
- font-family: 'Satoshi', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
39
- min-height: 100vh;
40
- display: flex;
41
- align-items: center;
42
- justify-content: center;
43
- overflow: hidden;
44
- position: relative;
45
- }
46
-
47
- /* Mesh gradient background matching AuthLayout */
48
- .bg-base {
49
- position: fixed; inset: 0;
50
- background: linear-gradient(135deg, #1a1a1c 0%, #1c2e2b 40%, #222224 70%, #1a2520 100%);
51
- }
52
- .bg-orb-bl {
53
- position: fixed; inset: 0;
54
- background: radial-gradient(ellipse 70% 65% at 15% 85%, rgba(77,182,172,0.45) 0%, rgba(77,182,172,0.15) 40%, transparent 70%);
55
- }
56
- .bg-orb-tr {
57
- position: fixed; inset: 0;
58
- background: radial-gradient(ellipse 55% 50% at 85% 15%, rgba(77,182,172,0.35) 0%, rgba(56,142,133,0.10) 45%, transparent 70%);
59
- }
60
- .bg-wash {
61
- position: fixed; inset: 0;
62
- background: radial-gradient(ellipse 45% 55% at 75% 55%, rgba(128,203,196,0.20) 0%, transparent 60%);
63
- }
64
- .bg-pool {
65
- position: fixed; inset: 0;
66
- background: radial-gradient(ellipse 50% 45% at 30% 40%, rgba(38,120,110,0.30) 0%, transparent 60%);
67
- }
68
- .bg-vignette {
69
- position: fixed; inset: 0;
70
- background: radial-gradient(ellipse 75% 75% at 50% 50%, transparent 10%, rgba(16,16,18,0.85) 100%);
71
- }
72
-
73
- .content {
74
- position: relative;
75
- z-index: 10;
76
- text-align: center;
77
- padding: 48px 40px;
78
- max-width: 400px;
79
- }
80
-
81
- .card {
82
- background: rgba(255,255,255,0.08);
83
- backdrop-filter: blur(24px);
84
- -webkit-backdrop-filter: blur(24px);
85
- border: 1px solid rgba(255,255,255,0.12);
86
- border-radius: 16px;
87
- padding: 40px 32px;
88
- }
89
-
90
- .icon { margin-bottom: 20px; }
91
-
92
- h1 {
93
- font-size: 20px;
94
- font-weight: 700;
95
- color: #fff;
96
- letter-spacing: -0.02em;
97
- margin-bottom: 8px;
98
- }
99
-
100
- p {
101
- font-size: 14px;
102
- color: rgba(255,255,255,0.5);
103
- line-height: 1.6;
104
- }
105
- </style>
106
- </head>
107
- <body>
108
- <div class="bg-base"></div>
109
- <div class="bg-orb-bl"></div>
110
- <div class="bg-orb-tr"></div>
111
- <div class="bg-wash"></div>
112
- <div class="bg-pool"></div>
113
- <div class="bg-vignette"></div>
114
-
115
- <div class="content">
116
- <div class="card">
117
- <div class="icon">${statusIcon}</div>
118
- <h1>${safeTitle}</h1>
119
- <p>${safeMessage}</p>
120
- </div>
121
- </div>
122
- </body>
123
- </html>`;
124
- }
125
- function generateCodeVerifier() {
126
- return randomBytes(32).toString("base64url");
127
- }
128
- function computeCodeChallenge(verifier) {
129
- return createHash("sha256").update(verifier).digest("base64url");
130
- }
131
- function generateState() {
132
- return randomBytes(32).toString("hex");
133
- }
134
- export async function performLogin() {
135
- const state = generateState();
136
- const codeVerifier = generateCodeVerifier();
137
- const codeChallenge = computeCodeChallenge(codeVerifier);
138
- const { port, result } = await startCallbackServer(state, codeVerifier);
139
- const callbackUrl = `http://127.0.0.1:${port}/callback`;
140
- await apiClient.postUnauthed("/api/v1/cli/auth/init", {
141
- state,
142
- code_challenge: codeChallenge,
143
- callback_url: callbackUrl,
144
- });
145
- const frontendUrl = getFrontendUrl();
146
- const authUrl = `${frontendUrl}/auth/cli?state=${state}&callback=${encodeURIComponent(callbackUrl)}`;
147
- console.log("\nOpening browser to log in to Graphit...");
148
- console.log(` -> ${authUrl}\n`);
149
- await open(authUrl);
150
- console.log("Waiting for authentication...\n");
151
- return result;
152
- }
153
- async function startCallbackServer(expectedState, codeVerifier) {
154
- return new Promise((resolveServer) => {
155
- let resolveLogin;
156
- let rejectLogin;
157
- const loginPromise = new Promise((res, rej) => {
158
- resolveLogin = res;
159
- rejectLogin = rej;
160
- });
161
- const timeout = setTimeout(() => {
162
- server.close();
163
- rejectLogin(new Error("Login timed out. Please try again."));
164
- }, AUTH_TIMEOUT_MS);
165
- const server = createServer(async (req, res) => {
166
- const url = new URL(req.url || "/", `http://127.0.0.1`);
167
- if (url.pathname !== "/callback") {
168
- res.writeHead(404);
169
- res.end("Not found");
170
- return;
171
- }
172
- const code = url.searchParams.get("code");
173
- const returnedState = url.searchParams.get("state");
174
- if (returnedState !== expectedState) {
175
- res.writeHead(400, { "Content-Type": "text/html" });
176
- res.end(renderCallbackPage("error", "Authentication failed", "State mismatch - possible CSRF attack."));
177
- clearTimeout(timeout);
178
- server.close();
179
- rejectLogin(new Error("State mismatch in callback - possible CSRF."));
180
- return;
181
- }
182
- if (!code) {
183
- const error = url.searchParams.get("error") || "No authorization code received";
184
- res.writeHead(400, { "Content-Type": "text/html" });
185
- res.end(renderCallbackPage("error", "Authentication failed", error));
186
- clearTimeout(timeout);
187
- server.close();
188
- rejectLogin(new Error(error));
189
- return;
190
- }
191
- try {
192
- const tokenResp = await apiClient.postUnauthed("/api/v1/cli/auth/token", {
193
- code,
194
- code_verifier: codeVerifier,
195
- state: expectedState,
196
- });
197
- const creds = {
198
- refresh_token: tokenResp.refresh_token,
199
- user_id: tokenResp.user_id,
200
- email: tokenResp.email,
201
- org_id: tokenResp.org_id,
202
- org_name: tokenResp.org_name,
203
- seat_type: tokenResp.seat_type,
204
- created_at: new Date().toISOString(),
205
- };
206
- await writeCredentials(creds);
207
- res.writeHead(200, { "Content-Type": "text/html" });
208
- res.end(renderCallbackPage("success", "Logged in to Graphit", "You can close this tab and return to your terminal."));
209
- clearTimeout(timeout);
210
- server.close();
211
- resolveLogin(creds);
212
- }
213
- catch (err) {
214
- const msg = err instanceof Error ? err.message : String(err);
215
- res.writeHead(500, { "Content-Type": "text/html" });
216
- res.end(renderCallbackPage("error", "Authentication failed", msg));
217
- clearTimeout(timeout);
218
- server.close();
219
- rejectLogin(err instanceof Error ? err : new Error(msg));
220
- }
221
- });
222
- server.listen(0, "127.0.0.1", () => {
223
- const addr = server.address();
224
- if (addr && typeof addr === "object") {
225
- resolveServer({ port: addr.port, result: loginPromise });
226
- }
227
- });
228
- });
229
- }
230
- //# sourceMappingURL=login.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/auth/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAA0B,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,eAAe,GAAG,OAAO,CAAC;AAEhC,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,kBAAkB,CACzB,OAA4B,EAC5B,KAAa,EACb,OAAe;IAEf,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAExC,MAAM,UAAU,GACd,OAAO,KAAK,SAAS;QACnB,CAAC,CAAC;;;gBAGQ;QACV,CAAC,CAAC;;;gBAGQ,CAAC;IAEf,OAAO;;;;;WAKE,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAqFM,UAAU;YACxB,SAAS;WACV,WAAW;;;;QAId,CAAC;AACT,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAqBD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAC;IAC5C,MAAM,aAAa,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAEzD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,oBAAoB,IAAI,WAAW,CAAC;IAExD,MAAM,SAAS,CAAC,YAAY,CAC1B,uBAAuB,EACvB;QACE,KAAK;QACL,cAAc,EAAE,aAAa;QAC7B,YAAY,EAAE,WAAW;KAC1B,CACF,CAAC;IAEF,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,GAAG,WAAW,mBAAmB,KAAK,aAAa,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IAErG,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,QAAQ,OAAO,IAAI,CAAC,CAAC;IAEjC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IAEpB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,aAAqB,EACrB,YAAoB;IAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;QACnC,IAAI,YAAgD,CAAC;QACrD,IAAI,WAAiC,CAAC;QAEtC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC/D,YAAY,GAAG,GAAG,CAAC;YACnB,WAAW,GAAG,GAAG,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC/D,CAAC,EAAE,eAAe,CAAC,CAAC;QAEpB,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAExD,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACjC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,aAAa,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEpD,IAAI,aAAa,KAAK,aAAa,EAAE,CAAC;gBACpC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;gBACpD,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,EAAE,uBAAuB,EAAE,wCAAwC,CAAC,CAAC,CAAC;gBACxG,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC,CAAC;gBACtE,OAAO;YACT,CAAC;YAED,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,gCAAgC,CAAC;gBAChF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;gBACpD,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,EAAE,uBAAuB,EAAE,KAAK,CAAC,CAAC,CAAC;gBACrE,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,YAAY,CAC5C,wBAAwB,EACxB;oBACE,IAAI;oBACJ,aAAa,EAAE,YAAY;oBAC3B,KAAK,EAAE,aAAa;iBACrB,CACF,CAAC;gBAEF,MAAM,KAAK,GAAsB;oBAC/B,aAAa,EAAE,SAAS,CAAC,aAAa;oBACtC,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,MAAM,EAAE,SAAS,CAAC,MAAM;oBACxB,QAAQ,EAAE,SAAS,CAAC,QAAQ;oBAC5B,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACrC,CAAC;gBAEF,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAE9B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;gBACpD,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,SAAS,EAAE,sBAAsB,EAAE,qDAAqD,CAAC,CAAC,CAAC;gBAEtH,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC7D,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;gBACpD,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAC,CAAC;gBACnE,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,WAAW,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,aAAa,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,5 +0,0 @@
1
- export interface TokenResult {
2
- id_token: string;
3
- user_id: string;
4
- }
5
- export declare function getValidIdToken(): Promise<TokenResult>;
@@ -1,42 +0,0 @@
1
- import { readCredentials, writeCredentials } from "./credentials.js";
2
- const FIREBASE_TOKEN_URL = "https://securetoken.googleapis.com/v1/token";
3
- const FIREBASE_API_KEY = process.env.GRAPHIT_FIREBASE_API_KEY || "AIzaSyCxahikMb2o0BroW1gqn2aWNad6S6-n-gI";
4
- const TOKEN_BUFFER_SECONDS = 60;
5
- export async function getValidIdToken() {
6
- const creds = await readCredentials();
7
- if (!creds) {
8
- throw new Error("Not logged in. Run `graphit auth login` first.");
9
- }
10
- if (creds.id_token &&
11
- creds.id_token_expiry &&
12
- creds.id_token_expiry > Date.now() / 1000 + TOKEN_BUFFER_SECONDS) {
13
- return { id_token: creds.id_token, user_id: creds.user_id };
14
- }
15
- const resp = await fetch(`${FIREBASE_TOKEN_URL}?key=${FIREBASE_API_KEY}`, {
16
- method: "POST",
17
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
18
- body: new URLSearchParams({
19
- grant_type: "refresh_token",
20
- refresh_token: creds.refresh_token,
21
- }),
22
- signal: AbortSignal.timeout(5000),
23
- });
24
- if (!resp.ok) {
25
- const body = await resp.text();
26
- if (body.includes("TOKEN_EXPIRED") || body.includes("INVALID_REFRESH_TOKEN")) {
27
- throw new Error("Session expired. Run `graphit auth login` to re-authenticate.");
28
- }
29
- throw new Error(`Token refresh failed (${resp.status}): ${body}`);
30
- }
31
- const data = (await resp.json());
32
- const expiresIn = parseInt(data.expires_in, 10);
33
- const expiry = Date.now() / 1000 + expiresIn;
34
- await writeCredentials({
35
- ...creds,
36
- refresh_token: data.refresh_token || creds.refresh_token,
37
- id_token: data.id_token,
38
- id_token_expiry: expiry,
39
- });
40
- return { id_token: data.id_token, user_id: data.user_id };
41
- }
42
- //# sourceMappingURL=token.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/auth/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,kBAAkB,GAAG,6CAA6C,CAAC;AACzE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,yCAAyC,CAAC;AAC3G,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAOhC,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;IACtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IACE,KAAK,CAAC,QAAQ;QACd,KAAK,CAAC,eAAe;QACrB,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,oBAAoB,EAChE,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,KAAK,CACtB,GAAG,kBAAkB,QAAQ,gBAAgB,EAAE,EAC/C;QACE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,IAAI,eAAe,CAAC;YACxB,UAAU,EAAE,eAAe;YAC3B,aAAa,EAAE,KAAK,CAAC,aAAa;SACnC,CAAC;QACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;KAClC,CACF,CAAC;IAEF,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAK9B,CAAC;IAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAE7C,MAAM,gBAAgB,CAAC;QACrB,GAAG,KAAK;QACR,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,KAAK,CAAC,aAAa;QACxD,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,eAAe,EAAE,MAAM;KACxB,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;AAC5D,CAAC"}
@@ -1,2 +0,0 @@
1
- import { Command } from "commander";
2
- export declare function registerAuthCommands(program: Command): void;
@@ -1,68 +0,0 @@
1
- import { readCredentials, deleteCredentials, getCredentialsPath } from "../auth/credentials.js";
2
- import { performLogin } from "../auth/login.js";
3
- import { apiClient } from "../api/client.js";
4
- import { output, errorOutput } from "../output/format.js";
5
- export function registerAuthCommands(program) {
6
- const auth = program.command("auth").description("Authentication commands");
7
- auth
8
- .command("login")
9
- .description("Log in to Graphit via browser")
10
- .action(async function () {
11
- try {
12
- const creds = await performLogin();
13
- console.log(`Logged in as ${creds.email}`);
14
- console.log(`Organization: ${creds.org_name}`);
15
- console.log(`Seat type: ${creds.seat_type}`);
16
- console.log(`\nCredentials saved to ${getCredentialsPath()}`);
17
- }
18
- catch (err) {
19
- errorOutput(err);
20
- }
21
- });
22
- auth
23
- .command("status")
24
- .description("Show current authentication status")
25
- .action(async function () {
26
- try {
27
- const creds = await readCredentials();
28
- if (!creds) {
29
- errorOutput(new Error("Not logged in. Run `graphit auth login` first."));
30
- return;
31
- }
32
- const me = await apiClient.get("/api/v1/cli/me");
33
- const tokenExpiry = creds.id_token_expiry
34
- ? new Date(creds.id_token_expiry * 1000).toISOString()
35
- : "none";
36
- output(this, {
37
- email: me.email,
38
- org_name: me.org_name,
39
- org_id: me.org_id,
40
- seat_type: me.seat_type,
41
- token_expiry: tokenExpiry,
42
- credentials: getCredentialsPath(),
43
- }, { keyValue: true });
44
- }
45
- catch (err) {
46
- errorOutput(err);
47
- }
48
- });
49
- auth
50
- .command("logout")
51
- .description("Log out and clear stored credentials")
52
- .action(async function () {
53
- try {
54
- try {
55
- await apiClient.post("/api/v1/cli/auth/revoke", {});
56
- }
57
- catch {
58
- // Best-effort server-side revocation
59
- }
60
- await deleteCredentials();
61
- console.log("Logged out. Credentials removed.");
62
- }
63
- catch (err) {
64
- errorOutput(err);
65
- }
66
- });
67
- }
68
- //# sourceMappingURL=auth.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAU1D,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;IAE5E,IAAI;SACD,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,KAAK;QACX,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,0BAA0B,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,oCAAoC,CAAC;SACjD,MAAM,CAAC,KAAK;QACX,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,WAAW,CAAC,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAC;gBACzE,OAAO;YACT,CAAC;YAED,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,CAAa,gBAAgB,CAAC,CAAC;YAE7D,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe;gBACvC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;gBACtD,CAAC,CAAC,MAAM,CAAC;YAEX,MAAM,CAAC,IAAI,EAAE;gBACX,KAAK,EAAE,EAAE,CAAC,KAAK;gBACf,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,YAAY,EAAE,WAAW;gBACzB,WAAW,EAAE,kBAAkB,EAAE;aAClC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,KAAK;QACX,IAAI,CAAC;YACH,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,IAAI,CAAO,yBAAyB,EAAE,EAAE,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;YACD,MAAM,iBAAiB,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,2 +0,0 @@
1
- import { Command } from "commander";
2
- export declare function registerConnectorCommands(program: Command): void;
@@ -1,97 +0,0 @@
1
- import { readFile, stat } from "node:fs/promises";
2
- import { apiClient } from "../api/client.js";
3
- import { output, errorOutput } from "../output/format.js";
4
- export function registerConnectorCommands(program) {
5
- const connector = program.command("connector").description("Connection management");
6
- connector
7
- .command("list")
8
- .description("List active connections")
9
- .action(async function () {
10
- try {
11
- const resp = await apiClient.get("/api/v1/cli/connectors");
12
- output(this, resp.connectors, {
13
- columns: ["id", "name", "account", "auth_type"],
14
- });
15
- }
16
- catch (err) {
17
- errorOutput(err);
18
- }
19
- });
20
- const add = connector.command("add").description("Add a new connection");
21
- add
22
- .command("snowflake-keypair")
23
- .description("Add Snowflake via keypair auth")
24
- .requiredOption("--account <account>", "Snowflake account identifier")
25
- .requiredOption("--user <user>", "Snowflake username")
26
- .requiredOption("--key <path>", "Path to private key file (.p8)")
27
- .option("--warehouse <wh>", "Default warehouse")
28
- .option("--role <role>", "Default role")
29
- .option("--database <db>", "Default database")
30
- .action(async function () {
31
- try {
32
- const opts = this.opts();
33
- const keyStats = await stat(opts.key);
34
- const mode = keyStats.mode & 0o777;
35
- if (mode > 0o600) {
36
- console.error(`Warning: Key file has loose permissions (${mode.toString(8)}). Consider chmod 600.`);
37
- }
38
- const keyPem = await readFile(opts.key, "utf-8");
39
- const resp = await apiClient.post("/api/v1/cli/connectors/snowflake-keypair", {
40
- account: opts.account,
41
- user: opts.user,
42
- private_key_pem: keyPem,
43
- warehouse: opts.warehouse || null,
44
- role: opts.role || null,
45
- database: opts.database || null,
46
- });
47
- output(this, resp, { keyValue: true });
48
- }
49
- catch (err) {
50
- errorOutput(err);
51
- }
52
- });
53
- add
54
- .command("snowflake-oauth")
55
- .description("Add Snowflake via OAuth (opens browser)")
56
- .action(function () {
57
- console.error(JSON.stringify({
58
- error: "Snowflake OAuth is configured via the Graphit web app. Use snowflake-keypair for CLI setup.",
59
- }));
60
- process.exit(1);
61
- });
62
- add
63
- .command("github")
64
- .description("Add GitHub connection (opens browser)")
65
- .action(function () {
66
- console.error(JSON.stringify({
67
- error: "GitHub connections are configured via the Graphit web app.",
68
- }));
69
- process.exit(1);
70
- });
71
- connector
72
- .command("test <id>")
73
- .description("Test a connection")
74
- .action(async function (id) {
75
- try {
76
- const resp = await apiClient.post(`/api/v1/cli/connectors/${id}/test`, {});
77
- output(this, resp, { keyValue: true });
78
- }
79
- catch (err) {
80
- errorOutput(err);
81
- }
82
- });
83
- connector
84
- .command("remove <id>")
85
- .description("Remove a connection (requires --yes)")
86
- .requiredOption("--yes", "Confirm removal")
87
- .action(async function (id) {
88
- try {
89
- await apiClient.delete(`/api/v1/cli/connectors/${id}`);
90
- console.log(JSON.stringify({ status: "removed", id }));
91
- }
92
- catch (err) {
93
- errorOutput(err);
94
- }
95
- });
96
- }
97
- //# sourceMappingURL=connector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connector.js","sourceRoot":"","sources":["../../src/commands/connector.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { Command } from "commander";
2
- export declare function registerDashboardCommands(program: Command): void;
@@ -1,124 +0,0 @@
1
- import { readFile } from "node:fs/promises";
2
- import { apiClient } from "../api/client.js";
3
- import { getFrontendUrl } from "../config.js";
4
- import { output, errorOutput } from "../output/format.js";
5
- function dashboardUrl(id) {
6
- return `${getFrontendUrl()}/custom-dashboards/${id}`;
7
- }
8
- export function registerDashboardCommands(program) {
9
- const dashboard = program.command("dashboard").description("Custom dashboard management");
10
- dashboard
11
- .command("list")
12
- .description("List custom dashboards")
13
- .action(async function () {
14
- try {
15
- const resp = await apiClient.get("/api/v1/cli/dashboards");
16
- const withUrls = resp.dashboards.map((d) => ({
17
- ...d,
18
- url: dashboardUrl(d.id),
19
- }));
20
- output(this, withUrls, {
21
- columns: ["id", "name", "has_content", "url"],
22
- });
23
- }
24
- catch (err) {
25
- errorOutput(err);
26
- }
27
- });
28
- dashboard
29
- .command("create")
30
- .description("Create a new custom dashboard")
31
- .requiredOption("--name <name>", "Dashboard name")
32
- .action(async function () {
33
- try {
34
- const opts = this.opts();
35
- const resp = await apiClient.post("/api/v1/cli/dashboards", {
36
- name: opts.name,
37
- });
38
- output(this, { ...resp, url: dashboardUrl(resp.id) }, { keyValue: true });
39
- }
40
- catch (err) {
41
- errorOutput(err);
42
- }
43
- });
44
- dashboard
45
- .command("get <id>")
46
- .description("Get dashboard details")
47
- .option("--html", "Include HTML content in output")
48
- .action(async function (id) {
49
- try {
50
- const opts = this.opts();
51
- const params = opts.html ? "?include_html=true" : "";
52
- const resp = await apiClient.get(`/api/v1/cli/dashboards/${id}${params}`);
53
- output(this, resp, { keyValue: true });
54
- }
55
- catch (err) {
56
- errorOutput(err);
57
- }
58
- });
59
- dashboard
60
- .command("update-html <id>")
61
- .description("Replace dashboard HTML content")
62
- .option("--file <path>", "Read HTML from a local file")
63
- .option("--stdin", "Read HTML from stdin")
64
- .action(async function (id) {
65
- try {
66
- const opts = this.opts();
67
- let html;
68
- if (opts.file) {
69
- html = await readFile(opts.file, "utf-8");
70
- }
71
- else if (opts.stdin) {
72
- html = await readStdin();
73
- }
74
- else {
75
- errorOutput(new Error("Specify --file <path> or --stdin"));
76
- return;
77
- }
78
- const resp = await apiClient.put(`/api/v1/cli/dashboards/${id}/html`, { html });
79
- output(this, { ...resp, url: dashboardUrl(resp.id) }, { keyValue: true });
80
- }
81
- catch (err) {
82
- errorOutput(err);
83
- }
84
- });
85
- dashboard
86
- .command("get-html <id>")
87
- .description("Get the current HTML content of a dashboard")
88
- .action(async function (id) {
89
- try {
90
- const resp = await apiClient.get(`/api/v1/cli/dashboards/${id}?include_html=true`);
91
- if (!resp.html) {
92
- console.log("<!-- Canvas is empty - no HTML content yet -->");
93
- }
94
- else {
95
- console.log(resp.html);
96
- }
97
- }
98
- catch (err) {
99
- errorOutput(err);
100
- }
101
- });
102
- dashboard
103
- .command("delete <id>")
104
- .description("Delete a custom dashboard (requires --yes)")
105
- .requiredOption("--yes", "Confirm deletion")
106
- .action(async function (id) {
107
- try {
108
- await apiClient.delete(`/api/v1/cli/dashboards/${id}`);
109
- console.log(JSON.stringify({ status: "deleted", id }));
110
- }
111
- catch (err) {
112
- errorOutput(err);
113
- }
114
- });
115
- }
116
- function readStdin() {
117
- return new Promise((resolve, reject) => {
118
- const chunks = [];
119
- process.stdin.on("data", (chunk) => chunks.push(chunk));
120
- process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
121
- process.stdin.on("error", reject);
122
- });
123
- }
124
- //# sourceMappingURL=dashboard.js.map