@polargrid/cli 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 (50) hide show
  1. package/README.md +129 -0
  2. package/dist/bin/polargrid.d.ts +3 -0
  3. package/dist/bin/polargrid.d.ts.map +1 -0
  4. package/dist/bin/polargrid.js +48 -0
  5. package/dist/bin/polargrid.js.map +1 -0
  6. package/dist/commands/config.d.ts +3 -0
  7. package/dist/commands/config.d.ts.map +1 -0
  8. package/dist/commands/config.js +88 -0
  9. package/dist/commands/config.js.map +1 -0
  10. package/dist/commands/keys.d.ts +3 -0
  11. package/dist/commands/keys.d.ts.map +1 -0
  12. package/dist/commands/keys.js +134 -0
  13. package/dist/commands/keys.js.map +1 -0
  14. package/dist/commands/login.d.ts +5 -0
  15. package/dist/commands/login.d.ts.map +1 -0
  16. package/dist/commands/login.js +87 -0
  17. package/dist/commands/login.js.map +1 -0
  18. package/dist/commands/orgs.d.ts +3 -0
  19. package/dist/commands/orgs.d.ts.map +1 -0
  20. package/dist/commands/orgs.js +119 -0
  21. package/dist/commands/orgs.js.map +1 -0
  22. package/dist/commands/regions.d.ts +3 -0
  23. package/dist/commands/regions.d.ts.map +1 -0
  24. package/dist/commands/regions.js +108 -0
  25. package/dist/commands/regions.js.map +1 -0
  26. package/dist/commands/test.d.ts +3 -0
  27. package/dist/commands/test.d.ts.map +1 -0
  28. package/dist/commands/test.js +186 -0
  29. package/dist/commands/test.js.map +1 -0
  30. package/dist/index.d.ts +5 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +6 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/lib/api.d.ts +40 -0
  35. package/dist/lib/api.d.ts.map +1 -0
  36. package/dist/lib/api.js +237 -0
  37. package/dist/lib/api.js.map +1 -0
  38. package/dist/lib/auth.d.ts +19 -0
  39. package/dist/lib/auth.d.ts.map +1 -0
  40. package/dist/lib/auth.js +308 -0
  41. package/dist/lib/auth.js.map +1 -0
  42. package/dist/lib/config.d.ts +27 -0
  43. package/dist/lib/config.d.ts.map +1 -0
  44. package/dist/lib/config.js +114 -0
  45. package/dist/lib/config.js.map +1 -0
  46. package/dist/lib/output.d.ts +34 -0
  47. package/dist/lib/output.d.ts.map +1 -0
  48. package/dist/lib/output.js +214 -0
  49. package/dist/lib/output.js.map +1 -0
  50. package/package.json +53 -0
@@ -0,0 +1,237 @@
1
+ import { createClient } from '@supabase/supabase-js';
2
+ import { getCredentials, getConfig, saveCredentials } from './config.js';
3
+ let supabaseClient = null;
4
+ export function getSupabaseClient() {
5
+ if (supabaseClient) {
6
+ return supabaseClient;
7
+ }
8
+ const config = getConfig();
9
+ if (!config.supabase_url || !config.supabase_anon_key) {
10
+ throw new Error('Supabase configuration not found. Please run `polargrid config set supabase_url <url>` and `polargrid config set supabase_anon_key <key>`');
11
+ }
12
+ supabaseClient = createClient(config.supabase_url, config.supabase_anon_key, {
13
+ auth: {
14
+ autoRefreshToken: true,
15
+ persistSession: false, // We handle session persistence ourselves
16
+ },
17
+ });
18
+ return supabaseClient;
19
+ }
20
+ export async function setSession(session) {
21
+ const client = getSupabaseClient();
22
+ await client.auth.setSession({
23
+ access_token: session.access_token,
24
+ refresh_token: session.refresh_token,
25
+ });
26
+ }
27
+ export async function restoreSession() {
28
+ const credentials = getCredentials();
29
+ if (!credentials?.access_token || !credentials?.refresh_token) {
30
+ return false;
31
+ }
32
+ try {
33
+ const client = getSupabaseClient();
34
+ const { data, error } = await client.auth.setSession({
35
+ access_token: credentials.access_token,
36
+ refresh_token: credentials.refresh_token,
37
+ });
38
+ if (error) {
39
+ // Try to refresh the token
40
+ const { data: refreshData, error: refreshError } = await client.auth.refreshSession({
41
+ refresh_token: credentials.refresh_token,
42
+ });
43
+ if (refreshError || !refreshData.session) {
44
+ return false;
45
+ }
46
+ // Save the new tokens
47
+ saveCredentials({
48
+ ...credentials,
49
+ access_token: refreshData.session.access_token,
50
+ refresh_token: refreshData.session.refresh_token,
51
+ expires_at: new Date(Date.now() + (refreshData.session.expires_in || 3600) * 1000).toISOString(),
52
+ });
53
+ return true;
54
+ }
55
+ return !!data.session;
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
61
+ export async function getCurrentUser() {
62
+ try {
63
+ const restored = await restoreSession();
64
+ if (!restored) {
65
+ return null;
66
+ }
67
+ const client = getSupabaseClient();
68
+ const { data: { user }, error } = await client.auth.getUser();
69
+ if (error || !user) {
70
+ return null;
71
+ }
72
+ return {
73
+ id: user.id,
74
+ email: user.email || '',
75
+ };
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ export async function getUserOrganizations(userId) {
82
+ const client = getSupabaseClient();
83
+ const { data, error } = await client
84
+ .from('organization_members')
85
+ .select(`
86
+ role,
87
+ organizations:organization_id (
88
+ id,
89
+ name,
90
+ slug,
91
+ plan,
92
+ created_at,
93
+ created_by,
94
+ avatar_url
95
+ )
96
+ `)
97
+ .eq('user_id', userId);
98
+ if (error) {
99
+ throw new Error(`Failed to fetch organizations: ${error.message}`);
100
+ }
101
+ const userOrgs = data?.map(item => ({
102
+ role: item.role,
103
+ organization: item.organizations,
104
+ })) || [];
105
+ // Sort by created_at
106
+ userOrgs.sort((a, b) => {
107
+ const dateA = new Date(a.organization.created_at).getTime();
108
+ const dateB = new Date(b.organization.created_at).getTime();
109
+ return dateA - dateB;
110
+ });
111
+ return userOrgs;
112
+ }
113
+ export async function getCurrentOrganization(userId) {
114
+ const client = getSupabaseClient();
115
+ const { data: profile, error: profileError } = await client
116
+ .from('user_profiles')
117
+ .select('current_org_id')
118
+ .eq('id', userId)
119
+ .single();
120
+ if (profileError || !profile?.current_org_id) {
121
+ return null;
122
+ }
123
+ const { data: org, error: orgError } = await client
124
+ .from('organizations')
125
+ .select('id, name, slug, plan, created_at, created_by, avatar_url')
126
+ .eq('id', profile.current_org_id)
127
+ .single();
128
+ if (orgError) {
129
+ throw new Error(`Failed to fetch organization: ${orgError.message}`);
130
+ }
131
+ return org;
132
+ }
133
+ export async function switchOrganization(userId, orgId) {
134
+ const client = getSupabaseClient();
135
+ // Verify user has access to this org
136
+ const { data: membership, error: membershipError } = await client
137
+ .from('organization_members')
138
+ .select('*')
139
+ .eq('user_id', userId)
140
+ .eq('organization_id', orgId)
141
+ .single();
142
+ if (membershipError || !membership) {
143
+ throw new Error('Access denied to organization');
144
+ }
145
+ // Update current org
146
+ const { error: updateError } = await client
147
+ .from('user_profiles')
148
+ .update({ current_org_id: orgId })
149
+ .eq('id', userId);
150
+ if (updateError) {
151
+ throw new Error(`Failed to switch organization: ${updateError.message}`);
152
+ }
153
+ }
154
+ export async function getApiKeys(userId) {
155
+ const client = getSupabaseClient();
156
+ const { data, error } = await client
157
+ .from('api_keys')
158
+ .select('id, name, key_preview, permissions, created_at, last_used_at, project_id')
159
+ .eq('created_by', userId)
160
+ .is('revoked_at', null)
161
+ .is('deleted_at', null)
162
+ .order('created_at', { ascending: false });
163
+ if (error) {
164
+ throw new Error(`Failed to fetch API keys: ${error.message}`);
165
+ }
166
+ return data || [];
167
+ }
168
+ export async function createApiKey(userId, name, permissions = 'read-write', projectId) {
169
+ const client = getSupabaseClient();
170
+ // Generate API key
171
+ const fullKey = generateApiKey();
172
+ const keyPreview = fullKey.substring(0, 12);
173
+ // For CLI, we'll store a hash (the server-side encryption isn't available here)
174
+ // In production, this should call a server endpoint that handles encryption
175
+ const keyHash = await hashString(fullKey);
176
+ const { data, error } = await client
177
+ .from('api_keys')
178
+ .insert({
179
+ name,
180
+ key_hash: keyHash,
181
+ key_preview: keyPreview,
182
+ permissions,
183
+ project_id: projectId || null,
184
+ created_by: userId,
185
+ })
186
+ .select('id, name, key_preview, permissions, created_at, last_used_at, project_id')
187
+ .single();
188
+ if (error) {
189
+ throw new Error(`Failed to create API key: ${error.message}`);
190
+ }
191
+ return {
192
+ key: data,
193
+ fullKey,
194
+ };
195
+ }
196
+ export async function revokeApiKey(userId, keyId) {
197
+ const client = getSupabaseClient();
198
+ // Verify ownership
199
+ const { data: key, error: fetchError } = await client
200
+ .from('api_keys')
201
+ .select('id, created_by')
202
+ .eq('id', keyId)
203
+ .eq('created_by', userId)
204
+ .single();
205
+ if (fetchError || !key) {
206
+ throw new Error('API key not found or access denied');
207
+ }
208
+ const { error } = await client
209
+ .from('api_keys')
210
+ .update({
211
+ revoked_at: new Date().toISOString(),
212
+ deleted_at: new Date().toISOString(),
213
+ })
214
+ .eq('id', keyId);
215
+ if (error) {
216
+ throw new Error(`Failed to revoke API key: ${error.message}`);
217
+ }
218
+ }
219
+ // ============================================================================
220
+ // HELPER FUNCTIONS
221
+ // ============================================================================
222
+ function generateApiKey() {
223
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
224
+ let result = 'pg_';
225
+ for (let i = 0; i < 40; i++) {
226
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
227
+ }
228
+ return result;
229
+ }
230
+ async function hashString(str) {
231
+ const encoder = new TextEncoder();
232
+ const data = encoder.encode(str);
233
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
234
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
235
+ return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
236
+ }
237
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface AuthResult {
2
+ success: boolean;
3
+ userId?: string;
4
+ email?: string;
5
+ error?: string;
6
+ }
7
+ /**
8
+ * Perform browser-based OAuth login
9
+ */
10
+ export declare function browserLogin(): Promise<AuthResult>;
11
+ /**
12
+ * Login with API key (for CI/CD headless mode)
13
+ */
14
+ export declare function apiKeyLogin(apiKey: string): Promise<AuthResult>;
15
+ /**
16
+ * Logout - clear stored credentials
17
+ */
18
+ export declare function logout(): void;
19
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,CA8HxD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+BrE;AAED;;GAEG;AACH,wBAAgB,MAAM,IAAI,IAAI,CAE7B"}
@@ -0,0 +1,308 @@
1
+ import { createServer } from 'http';
2
+ import open from 'open';
3
+ import { parse as parseUrl } from 'url';
4
+ import { getSupabaseClient } from './api.js';
5
+ import { clearCredentials, getConfig, saveCredentials } from './config.js';
6
+ const CALLBACK_PORT_START = 54321;
7
+ const CALLBACK_PORT_END = 54330;
8
+ /**
9
+ * Perform browser-based OAuth login
10
+ */
11
+ export async function browserLogin() {
12
+ return new Promise((resolve) => {
13
+ let server = null;
14
+ let resolved = false;
15
+ let timeoutId = null;
16
+ const finish = (result) => {
17
+ if (resolved)
18
+ return;
19
+ resolved = true;
20
+ if (timeoutId) {
21
+ clearTimeout(timeoutId);
22
+ timeoutId = null;
23
+ }
24
+ if (server) {
25
+ // Force close all connections immediately
26
+ server.closeAllConnections?.();
27
+ server.close();
28
+ server = null;
29
+ }
30
+ resolve(result);
31
+ };
32
+ const handleCallback = async (req, res) => {
33
+ if (resolved) {
34
+ res.writeHead(200);
35
+ res.end('Already processed');
36
+ return;
37
+ }
38
+ const url = parseUrl(req.url || '', true);
39
+ if (url.pathname !== '/callback') {
40
+ res.writeHead(404);
41
+ res.end('Not found');
42
+ return;
43
+ }
44
+ const { access_token, refresh_token, expires_in, error, error_description } = url.query;
45
+ res.writeHead(200, {
46
+ 'Content-Type': 'text/html; charset=utf-8',
47
+ });
48
+ if (error) {
49
+ res.end(buildErrorPage(String(error_description || error)));
50
+ finish({ success: false, error: String(error_description || error) });
51
+ return;
52
+ }
53
+ if (!access_token || !refresh_token) {
54
+ res.end(buildErrorPage('Missing tokens in response'));
55
+ finish({ success: false, error: 'Missing tokens in response' });
56
+ return;
57
+ }
58
+ try {
59
+ const client = getSupabaseClient();
60
+ const { data, error: sessionError } = await client.auth.setSession({
61
+ access_token: String(access_token),
62
+ refresh_token: String(refresh_token),
63
+ });
64
+ if (sessionError || !data.user) {
65
+ throw new Error(sessionError?.message || 'Failed to get user');
66
+ }
67
+ const expiresIn = parseInt(String(expires_in)) || 3600;
68
+ saveCredentials({
69
+ access_token: String(access_token),
70
+ refresh_token: String(refresh_token),
71
+ expires_at: new Date(Date.now() + expiresIn * 1000).toISOString(),
72
+ user_id: data.user.id,
73
+ email: data.user.email,
74
+ });
75
+ res.end(buildSuccessPage(data.user.email || ''));
76
+ finish({
77
+ success: true,
78
+ userId: data.user.id,
79
+ email: data.user.email,
80
+ });
81
+ }
82
+ catch (err) {
83
+ const message = err instanceof Error ? err.message : 'Unknown error';
84
+ res.end(buildErrorPage(message));
85
+ finish({ success: false, error: message });
86
+ }
87
+ };
88
+ const tryPort = (port) => {
89
+ if (port > CALLBACK_PORT_END) {
90
+ finish({ success: false, error: 'Could not find available port for callback server' });
91
+ return;
92
+ }
93
+ server = createServer(handleCallback);
94
+ server.on('error', () => {
95
+ server = null;
96
+ tryPort(port + 1);
97
+ });
98
+ server.listen(port, '127.0.0.1', () => {
99
+ const callbackUrl = `http://localhost:${port}/callback`;
100
+ const config = getConfig();
101
+ const consoleUrl = config.api_base_url || 'https://app.polargrid.ai';
102
+ const authUrl = `${consoleUrl}/cli-auth?redirect=${encodeURIComponent(callbackUrl)}`;
103
+ console.log(`\nOpening browser for authentication...`);
104
+ console.log(`If the browser doesn't open, visit: ${authUrl}\n`);
105
+ open(authUrl).catch(() => {
106
+ console.log(`Please open this URL in your browser:\n${authUrl}\n`);
107
+ });
108
+ // Timeout after 5 minutes
109
+ timeoutId = setTimeout(() => {
110
+ finish({ success: false, error: 'Authentication timed out' });
111
+ }, 5 * 60 * 1000);
112
+ });
113
+ };
114
+ tryPort(CALLBACK_PORT_START);
115
+ });
116
+ }
117
+ /**
118
+ * Login with API key (for CI/CD headless mode)
119
+ */
120
+ export async function apiKeyLogin(apiKey) {
121
+ try {
122
+ const config = getConfig();
123
+ const apiBaseUrl = config.api_base_url || 'https://api.polargrid.ai';
124
+ const response = await fetch(`${apiBaseUrl}/api/auth/inference-token`, {
125
+ method: 'POST',
126
+ headers: {
127
+ 'Authorization': `Bearer ${apiKey}`,
128
+ 'Content-Type': 'application/json',
129
+ },
130
+ });
131
+ if (!response.ok) {
132
+ const text = await response.text();
133
+ return { success: false, error: `Authentication failed: ${text}` };
134
+ }
135
+ const data = await response.json();
136
+ saveCredentials({
137
+ access_token: data.token,
138
+ refresh_token: '',
139
+ expires_at: new Date(Date.now() + (data.expires_in || 3600) * 1000).toISOString(),
140
+ user_id: 'api-key-user',
141
+ });
142
+ return { success: true, userId: 'api-key-user' };
143
+ }
144
+ catch (err) {
145
+ return { success: false, error: err instanceof Error ? err.message : 'Unknown error' };
146
+ }
147
+ }
148
+ /**
149
+ * Logout - clear stored credentials
150
+ */
151
+ export function logout() {
152
+ clearCredentials();
153
+ }
154
+ // HTML page builders
155
+ function buildSuccessPage(email) {
156
+ return `<!DOCTYPE html>
157
+ <html>
158
+ <head>
159
+ <meta charset="UTF-8">
160
+ <title>Authentication Successful - PolarGrid</title>
161
+ <style>
162
+ body {
163
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
164
+ display: flex;
165
+ justify-content: center;
166
+ align-items: center;
167
+ height: 100vh;
168
+ margin: 0;
169
+ background: linear-gradient(135deg, #fafafa 0%, #f4f4f5 100%);
170
+ background-image:
171
+ linear-gradient(30deg, rgba(99, 102, 241, 0.015) 50%, transparent 50%),
172
+ linear-gradient(150deg, rgba(139, 92, 246, 0.015) 50%, transparent 50%);
173
+ background-size: 60px 60px, 80px 80px;
174
+ }
175
+ .card {
176
+ text-align: center;
177
+ padding: 48px;
178
+ background: white;
179
+ border-radius: 16px;
180
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
181
+ max-width: 400px;
182
+ }
183
+ .icon {
184
+ width: 48px;
185
+ height: 48px;
186
+ background: #dcfce7;
187
+ border-radius: 50%;
188
+ display: flex;
189
+ align-items: center;
190
+ justify-content: center;
191
+ margin: 0 auto 16px;
192
+ }
193
+ .icon svg {
194
+ width: 24px;
195
+ height: 24px;
196
+ color: #22c55e;
197
+ }
198
+ h1 {
199
+ color: #22c55e;
200
+ margin: 0 0 12px 0;
201
+ font-weight: 600;
202
+ font-size: 24px;
203
+ }
204
+ .email {
205
+ color: #374151;
206
+ margin: 0 0 8px 0;
207
+ font-size: 16px;
208
+ }
209
+ .email strong {
210
+ font-weight: 600;
211
+ }
212
+ .hint {
213
+ color: #6b7280;
214
+ margin: 0;
215
+ font-size: 14px;
216
+ }
217
+ </style>
218
+ </head>
219
+ <body>
220
+ <div class="card">
221
+ <div class="icon">
222
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
223
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
224
+ </svg>
225
+ </div>
226
+ <h1>Authentication Successful</h1>
227
+ <p class="email">Logged in as <strong>${email}</strong></p>
228
+ <p class="hint">You can close this window and return to the terminal.</p>
229
+ </div>
230
+ </body>
231
+ </html>`;
232
+ }
233
+ function buildErrorPage(message) {
234
+ return `<!DOCTYPE html>
235
+ <html>
236
+ <head>
237
+ <meta charset="UTF-8">
238
+ <title>Authentication Failed - PolarGrid</title>
239
+ <style>
240
+ body {
241
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
242
+ display: flex;
243
+ justify-content: center;
244
+ align-items: center;
245
+ height: 100vh;
246
+ margin: 0;
247
+ background: linear-gradient(135deg, #fafafa 0%, #f4f4f5 100%);
248
+ background-image:
249
+ linear-gradient(30deg, rgba(99, 102, 241, 0.015) 50%, transparent 50%),
250
+ linear-gradient(150deg, rgba(139, 92, 246, 0.015) 50%, transparent 50%);
251
+ background-size: 60px 60px, 80px 80px;
252
+ }
253
+ .card {
254
+ text-align: center;
255
+ padding: 48px;
256
+ background: white;
257
+ border-radius: 16px;
258
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
259
+ max-width: 400px;
260
+ }
261
+ .icon {
262
+ width: 48px;
263
+ height: 48px;
264
+ background: #fee2e2;
265
+ border-radius: 50%;
266
+ display: flex;
267
+ align-items: center;
268
+ justify-content: center;
269
+ margin: 0 auto 16px;
270
+ }
271
+ .icon svg {
272
+ width: 24px;
273
+ height: 24px;
274
+ color: #ef4444;
275
+ }
276
+ h1 {
277
+ color: #ef4444;
278
+ margin: 0 0 12px 0;
279
+ font-weight: 600;
280
+ font-size: 24px;
281
+ }
282
+ .message {
283
+ color: #374151;
284
+ margin: 0 0 8px 0;
285
+ font-size: 16px;
286
+ }
287
+ .hint {
288
+ color: #6b7280;
289
+ margin: 0;
290
+ font-size: 14px;
291
+ }
292
+ </style>
293
+ </head>
294
+ <body>
295
+ <div class="card">
296
+ <div class="icon">
297
+ <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
298
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
299
+ </svg>
300
+ </div>
301
+ <h1>Authentication Failed</h1>
302
+ <p class="message">${message}</p>
303
+ <p class="hint">You can close this window.</p>
304
+ </div>
305
+ </body>
306
+ </html>`;
307
+ }
308
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA2C,MAAM,MAAM,CAAC;AAC7E,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,KAAK,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAClC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAShC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,SAAS,GAA0B,IAAI,CAAC;QAE5C,MAAM,MAAM,GAAG,CAAC,MAAkB,EAAE,EAAE;YACpC,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAEhB,IAAI,SAAS,EAAE,CAAC;gBACd,YAAY,CAAC,SAAS,CAAC,CAAC;gBACxB,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,IAAI,MAAM,EAAE,CAAC;gBACX,0CAA0C;gBAC1C,MAAM,CAAC,mBAAmB,EAAE,EAAE,CAAC;gBAC/B,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;YAED,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAE,EAAE;YACzE,IAAI,QAAQ,EAAE,CAAC;gBACb,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YAED,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;YAE1C,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,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;YAExF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,0BAA0B;aAC3C,CAAC,CAAC;YAEH,IAAI,KAAK,EAAE,CAAC;gBACV,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,iBAAiB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC5D,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,iBAAiB,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtE,OAAO;YACT,CAAC;YAED,IAAI,CAAC,YAAY,IAAI,CAAC,aAAa,EAAE,CAAC;gBACpC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,4BAA4B,CAAC,CAAC,CAAC;gBACtD,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;gBAChE,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;gBACnC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;oBACjE,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC;oBAClC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;iBACrC,CAAC,CAAC;gBAEH,IAAI,YAAY,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,YAAY,EAAE,OAAO,IAAI,oBAAoB,CAAC,CAAC;gBACjE,CAAC;gBAED,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC;gBACvD,eAAe,CAAC;oBACd,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC;oBAClC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;oBACpC,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;oBACjE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;oBACrB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;iBACvB,CAAC,CAAC;gBAEH,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBACjD,MAAM,CAAC;oBACL,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;oBACpB,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK;iBACvB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;gBACrE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;gBACjC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE;YAC/B,IAAI,IAAI,GAAG,iBAAiB,EAAE,CAAC;gBAC7B,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mDAAmD,EAAE,CAAC,CAAC;gBACvF,OAAO;YACT,CAAC;YAED,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;YAEtC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,MAAM,GAAG,IAAI,CAAC;gBACd,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;gBACpC,MAAM,WAAW,GAAG,oBAAoB,IAAI,WAAW,CAAC;gBACxD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,IAAI,0BAA0B,CAAC;gBACrE,MAAM,OAAO,GAAG,GAAG,UAAU,sBAAsB,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;gBAErF,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;gBACvD,OAAO,CAAC,GAAG,CAAC,uCAAuC,OAAO,IAAI,CAAC,CAAC;gBAEhE,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBACvB,OAAO,CAAC,GAAG,CAAC,0CAA0C,OAAO,IAAI,CAAC,CAAC;gBACrE,CAAC,CAAC,CAAC;gBAEH,0BAA0B;gBAC1B,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC1B,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;gBAChE,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,IAAI,0BAA0B,CAAC;QAErE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,2BAA2B,EAAE;YACrE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,MAAM,EAAE;gBACnC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,IAAI,EAAE,EAAE,CAAC;QACrE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA4C,CAAC;QAE7E,eAAe,CAAC;YACd,YAAY,EAAE,IAAI,CAAC,KAAK;YACxB,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;YACjF,OAAO,EAAE,cAAc;SACxB,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACzF,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM;IACpB,gBAAgB,EAAE,CAAC;AACrB,CAAC;AAED,qBAAqB;AACrB,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CAuEmC,KAAK;;;;QAIzC,CAAC;AACT,CAAC;AAED,SAAS,cAAc,CAAC,OAAe;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAoEgB,OAAO;;;;QAIxB,CAAC;AACT,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface Credentials {
2
+ access_token: string;
3
+ refresh_token: string;
4
+ expires_at: string;
5
+ user_id: string;
6
+ email?: string;
7
+ current_org_id?: string;
8
+ }
9
+ export interface Config {
10
+ default_region?: string;
11
+ output_format?: 'json' | 'table' | 'plain';
12
+ api_base_url?: string;
13
+ supabase_url?: string;
14
+ supabase_anon_key?: string;
15
+ }
16
+ export declare function getCredentials(): Credentials | null;
17
+ export declare function saveCredentials(credentials: Credentials): void;
18
+ export declare function clearCredentials(): void;
19
+ export declare function isLoggedIn(): boolean;
20
+ export declare function updateCurrentOrg(orgId: string): void;
21
+ export declare function getConfig(): Config;
22
+ export declare function saveConfig(config: Config): void;
23
+ export declare function getConfigValue(key: keyof Config): string | undefined;
24
+ export declare function setConfigValue(key: string, value: string): void;
25
+ export declare function deleteConfigValue(key: string): void;
26
+ export declare function listConfig(): Record<string, string | undefined>;
27
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,MAAM;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAmBD,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAUnD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAK9D;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAQvC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAapC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMpD;AAMD,wBAAgB,SAAS,IAAI,MAAM,CAWlC;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAK/C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,MAAM,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAInD;AAED,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAO/D"}