@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.
- package/.claude-plugin/marketplace.json +25 -0
- package/.claude-plugin/plugin.json +23 -0
- package/.codex-plugin/plugin.json +22 -0
- package/package.json +4 -2
- package/{skill → skills/graphit}/SKILL.md +78 -23
- package/skills/graphit/cursor/graphit-chart-patterns.mdc +86 -0
- package/skills/graphit/graphit.mdc +117 -0
- package/skills/graphit/references/chart-patterns.md +80 -0
- package/dist/api/client.d.ts +0 -16
- package/dist/api/client.js +0 -67
- package/dist/api/client.js.map +0 -1
- package/dist/auth/credentials.d.ts +0 -15
- package/dist/auth/credentials.js +0 -34
- package/dist/auth/credentials.js.map +0 -1
- package/dist/auth/login.d.ts +0 -2
- package/dist/auth/login.js +0 -230
- package/dist/auth/login.js.map +0 -1
- package/dist/auth/token.d.ts +0 -5
- package/dist/auth/token.js +0 -42
- package/dist/auth/token.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -2
- package/dist/commands/auth.js +0 -68
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/connector.d.ts +0 -2
- package/dist/commands/connector.js +0 -97
- package/dist/commands/connector.js.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -2
- package/dist/commands/dashboard.js +0 -124
- package/dist/commands/dashboard.js.map +0 -1
- package/dist/commands/ds.d.ts +0 -2
- package/dist/commands/ds.js +0 -53
- package/dist/commands/ds.js.map +0 -1
- package/dist/commands/kb.d.ts +0 -2
- package/dist/commands/kb.js +0 -259
- package/dist/commands/kb.js.map +0 -1
- package/dist/commands/query.d.ts +0 -2
- package/dist/commands/query.js +0 -61
- package/dist/commands/query.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -2
- package/dist/commands/setup.js +0 -173
- package/dist/commands/setup.js.map +0 -1
- package/dist/config.d.ts +0 -4
- package/dist/config.js +0 -9
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -24
- package/dist/index.js.map +0 -1
- package/dist/output/format.d.ts +0 -8
- package/dist/output/format.js +0 -30
- package/dist/output/format.js.map +0 -1
- package/dist/output/json.d.ts +0 -1
- package/dist/output/json.js +0 -4
- package/dist/output/json.js.map +0 -1
- package/dist/output/table.d.ts +0 -2
- package/dist/output/table.js +0 -17
- package/dist/output/table.js.map +0 -1
- package/skill/cursor/graphit-chart-patterns.mdc +0 -148
- package/skill/graphit.mdc +0 -135
- package/skill/references/chart-patterns.md +0 -257
- /package/{skill → skills/graphit}/cursor/graphit-chart-selection.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-dashboard-planning.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-domain-lenses.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-kb-exploration.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-sql-reference.mdc +0 -0
- /package/{skill → skills/graphit}/cursor/graphit-style.mdc +0 -0
- /package/{skill → skills/graphit}/references/chart-selection.md +0 -0
- /package/{skill → skills/graphit}/references/dashboard-planning.md +0 -0
- /package/{skill → skills/graphit}/references/domain-lenses.md +0 -0
- /package/{skill → skills/graphit}/references/graphit-style.md +0 -0
- /package/{skill → skills/graphit}/references/kb-exploration.md +0 -0
- /package/{skill → skills/graphit}/references/sql-reference.md +0 -0
package/dist/auth/credentials.js
DELETED
|
@@ -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"}
|
package/dist/auth/login.d.ts
DELETED
package/dist/auth/login.js
DELETED
|
@@ -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, "&")
|
|
11
|
-
.replace(/</g, "<")
|
|
12
|
-
.replace(/>/g, ">")
|
|
13
|
-
.replace(/"/g, """);
|
|
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
|
package/dist/auth/login.js.map
DELETED
|
@@ -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"}
|
package/dist/auth/token.d.ts
DELETED
package/dist/auth/token.js
DELETED
|
@@ -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
|
package/dist/auth/token.js.map
DELETED
|
@@ -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"}
|
package/dist/commands/auth.d.ts
DELETED
package/dist/commands/auth.js
DELETED
|
@@ -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,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,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
|