tailar 0.2.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.
- package/LICENSE +22 -0
- package/README.md +183 -0
- package/README.npm.md +183 -0
- package/dist/api/client.d.ts +47 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +329 -0
- package/dist/api/client.js.map +1 -0
- package/dist/auth/browser.d.ts +11 -0
- package/dist/auth/browser.d.ts.map +1 -0
- package/dist/auth/browser.js +46 -0
- package/dist/auth/browser.js.map +1 -0
- package/dist/auth/flow.d.ts +28 -0
- package/dist/auth/flow.d.ts.map +1 -0
- package/dist/auth/flow.js +171 -0
- package/dist/auth/flow.js.map +1 -0
- package/dist/auth/storage.d.ts +30 -0
- package/dist/auth/storage.d.ts.map +1 -0
- package/dist/auth/storage.js +112 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/commands/add.d.ts +8 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +285 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +230 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +176 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/installers/dependencies.d.ts +27 -0
- package/dist/installers/dependencies.d.ts.map +1 -0
- package/dist/installers/dependencies.js +185 -0
- package/dist/installers/dependencies.js.map +1 -0
- package/dist/installers/files.d.ts +50 -0
- package/dist/installers/files.d.ts.map +1 -0
- package/dist/installers/files.js +211 -0
- package/dist/installers/files.js.map +1 -0
- package/dist/installers/install-feature.d.ts +20 -0
- package/dist/installers/install-feature.d.ts.map +1 -0
- package/dist/installers/install-feature.js +169 -0
- package/dist/installers/install-feature.js.map +1 -0
- package/dist/installers/post-install.d.ts +18 -0
- package/dist/installers/post-install.d.ts.map +1 -0
- package/dist/installers/post-install.js +228 -0
- package/dist/installers/post-install.js.map +1 -0
- package/dist/installers/templates.d.ts +22 -0
- package/dist/installers/templates.d.ts.map +1 -0
- package/dist/installers/templates.js +62 -0
- package/dist/installers/templates.js.map +1 -0
- package/dist/registry/loader.d.ts +21 -0
- package/dist/registry/loader.d.ts.map +1 -0
- package/dist/registry/loader.js +83 -0
- package/dist/registry/loader.js.map +1 -0
- package/dist/registry/query.d.ts +55 -0
- package/dist/registry/query.d.ts.map +1 -0
- package/dist/registry/query.js +123 -0
- package/dist/registry/query.js.map +1 -0
- package/dist/types/config.d.ts +85 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/registry.d.ts +180 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/registry.js +8 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/types/wizard.d.ts +43 -0
- package/dist/types/wizard.d.ts.map +1 -0
- package/dist/types/wizard.js +59 -0
- package/dist/types/wizard.js.map +1 -0
- package/dist/utils/clack-wizard.d.ts +9 -0
- package/dist/utils/clack-wizard.d.ts.map +1 -0
- package/dist/utils/clack-wizard.js +328 -0
- package/dist/utils/clack-wizard.js.map +1 -0
- package/dist/utils/config.d.ts +49 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +121 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +56 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +93 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/package-manager.d.ts +41 -0
- package/dist/utils/package-manager.d.ts.map +1 -0
- package/dist/utils/package-manager.js +118 -0
- package/dist/utils/package-manager.js.map +1 -0
- package/dist/utils/prompts.d.ts +22 -0
- package/dist/utils/prompts.d.ts.map +1 -0
- package/dist/utils/prompts.js +142 -0
- package/dist/utils/prompts.js.map +1 -0
- package/dist/utils/validation.d.ts +50 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +108 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client Module
|
|
3
|
+
*
|
|
4
|
+
* Handles all API interactions with the Tailar web API
|
|
5
|
+
*/
|
|
6
|
+
import fetch from "node-fetch";
|
|
7
|
+
import { logger } from "../utils/logger.js";
|
|
8
|
+
import { getAuthHeaders, authenticate, isAuthenticated } from "../auth/flow.js";
|
|
9
|
+
import { getStoredToken, clearToken } from "../auth/storage.js";
|
|
10
|
+
// Lazy-load API_BASE_URL to ensure .env file is loaded first
|
|
11
|
+
// This is a function because .env file is loaded after module imports
|
|
12
|
+
function getApiBaseUrl() {
|
|
13
|
+
return process.env.API_BASE_URL || "https://tailar.dev/api/cli";
|
|
14
|
+
}
|
|
15
|
+
const MAX_RETRIES = 3;
|
|
16
|
+
const RETRY_DELAY = 1000; // 1 second
|
|
17
|
+
/** Avoid infinite spinner when API is unreachable (default tailar.dev or wrong host). */
|
|
18
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 45_000;
|
|
19
|
+
/**
|
|
20
|
+
* Make an authenticated API request with retry logic
|
|
21
|
+
*/
|
|
22
|
+
async function apiRequest(endpoint, options = {}) {
|
|
23
|
+
const { requireAuth = false, retries = MAX_RETRIES, method, body, headers: customHeaders, } = options;
|
|
24
|
+
let attempt = 0;
|
|
25
|
+
let lastError = null;
|
|
26
|
+
while (attempt <= retries) {
|
|
27
|
+
try {
|
|
28
|
+
const headers = {
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
"User-Agent": "tailar-cli",
|
|
31
|
+
...(customHeaders || {}),
|
|
32
|
+
};
|
|
33
|
+
// Add auth headers if required
|
|
34
|
+
if (requireAuth) {
|
|
35
|
+
try {
|
|
36
|
+
const authHeaders = await getAuthHeaders();
|
|
37
|
+
Object.assign(headers, authHeaders);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
// Not authenticated, try to authenticate
|
|
41
|
+
if (error instanceof Error &&
|
|
42
|
+
error.message.includes("Not authenticated")) {
|
|
43
|
+
logger.info("Authentication required. Starting authentication flow...");
|
|
44
|
+
await authenticate();
|
|
45
|
+
// Retry with new auth headers
|
|
46
|
+
const authHeaders = await getAuthHeaders();
|
|
47
|
+
Object.assign(headers, authHeaders);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const fetchInit = {
|
|
55
|
+
method: method || "GET",
|
|
56
|
+
headers,
|
|
57
|
+
};
|
|
58
|
+
if (body) {
|
|
59
|
+
fetchInit.body = body;
|
|
60
|
+
}
|
|
61
|
+
const fullUrl = `${getApiBaseUrl()}${endpoint}`;
|
|
62
|
+
const timeoutMs = Number(process.env.TAILAR_CLI_REQUEST_TIMEOUT_MS) ||
|
|
63
|
+
DEFAULT_REQUEST_TIMEOUT_MS;
|
|
64
|
+
const abortController = new AbortController();
|
|
65
|
+
const timeoutId = setTimeout(() => abortController.abort(), timeoutMs);
|
|
66
|
+
fetchInit.signal = abortController.signal;
|
|
67
|
+
let response;
|
|
68
|
+
try {
|
|
69
|
+
response = await fetch(fullUrl, fetchInit);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
const aborted = e instanceof Error &&
|
|
73
|
+
(e.name === "AbortError" || e.message.includes("aborted"));
|
|
74
|
+
if (aborted) {
|
|
75
|
+
throw new Error(`Request timed out after ${timeoutMs}ms (${fullUrl}). ` +
|
|
76
|
+
`If you run the Tailar web app locally, set API_BASE_URL in this project's .env, e.g. API_BASE_URL=http://localhost:3000/api/cli`);
|
|
77
|
+
}
|
|
78
|
+
throw e;
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
clearTimeout(timeoutId);
|
|
82
|
+
}
|
|
83
|
+
// Handle authentication errors
|
|
84
|
+
if (response.status === 401) {
|
|
85
|
+
if (requireAuth && attempt === 0) {
|
|
86
|
+
// Try to re-authenticate once
|
|
87
|
+
logger.warn("Authentication expired. Re-authenticating...");
|
|
88
|
+
await authenticate();
|
|
89
|
+
attempt++;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
throw new Error("Authentication failed. Please run authentication again.");
|
|
93
|
+
}
|
|
94
|
+
// Handle subscription errors
|
|
95
|
+
if (response.status === 403) {
|
|
96
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
97
|
+
const reason = errorData.reason || errorData.error || "Subscription required";
|
|
98
|
+
throw new Error(`Access denied: ${reason}\n` +
|
|
99
|
+
`Visit https://tailar.dev/choose-plan to upgrade your subscription.`);
|
|
100
|
+
}
|
|
101
|
+
// Handle not found errors
|
|
102
|
+
if (response.status === 404) {
|
|
103
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
104
|
+
throw new Error(errorData.error || "Resource not found");
|
|
105
|
+
}
|
|
106
|
+
// Handle other errors
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
109
|
+
throw new Error(errorData.error || `API request failed: ${response.statusText}`);
|
|
110
|
+
}
|
|
111
|
+
return (await response.json());
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
115
|
+
// Don't retry on authentication/subscription errors
|
|
116
|
+
if (lastError.message.includes("Authentication") ||
|
|
117
|
+
lastError.message.includes("Access denied") ||
|
|
118
|
+
lastError.message.includes("not found")) {
|
|
119
|
+
throw lastError;
|
|
120
|
+
}
|
|
121
|
+
// Retry on network errors
|
|
122
|
+
if (attempt < retries) {
|
|
123
|
+
attempt++;
|
|
124
|
+
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY * attempt));
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
throw lastError;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
throw lastError || new Error("API request failed");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Fetch registry.json from API
|
|
134
|
+
*/
|
|
135
|
+
export async function fetchRegistry(options = {}) {
|
|
136
|
+
try {
|
|
137
|
+
const params = new URLSearchParams();
|
|
138
|
+
if (options.version) {
|
|
139
|
+
params.append("version", options.version);
|
|
140
|
+
}
|
|
141
|
+
const endpoint = `/registry${params.toString() ? `?${params.toString()}` : ""}`;
|
|
142
|
+
// Registry is public endpoint (no auth required)
|
|
143
|
+
const registry = await apiRequest(endpoint, {
|
|
144
|
+
requireAuth: false,
|
|
145
|
+
method: "GET",
|
|
146
|
+
});
|
|
147
|
+
return registry;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
logger.error(`Failed to fetch registry: ${error instanceof Error ? error.message : String(error)}`);
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Fetch a single component file from API
|
|
156
|
+
*/
|
|
157
|
+
export async function fetchComponentFile(type, name, filePath, options = {}) {
|
|
158
|
+
try {
|
|
159
|
+
const params = new URLSearchParams();
|
|
160
|
+
params.append("path", filePath);
|
|
161
|
+
if (options.variant) {
|
|
162
|
+
params.append("variant", options.variant);
|
|
163
|
+
}
|
|
164
|
+
const endpoint = `/components/${type}/${name}/file?${params.toString()}`;
|
|
165
|
+
// If requireAuth is true, check authentication upfront and use auth headers from the start
|
|
166
|
+
// This prevents repeated authentication prompts for paid components
|
|
167
|
+
if (options.requireAuth === true) {
|
|
168
|
+
// Check if already authenticated
|
|
169
|
+
if (!(await isAuthenticated())) {
|
|
170
|
+
logger.info("Authentication required. Starting authentication flow...");
|
|
171
|
+
await authenticate();
|
|
172
|
+
}
|
|
173
|
+
// Use auth headers from the start
|
|
174
|
+
const response = await fetch(`${getApiBaseUrl()}${endpoint}`, {
|
|
175
|
+
method: "GET",
|
|
176
|
+
headers: {
|
|
177
|
+
"User-Agent": "tailar-cli",
|
|
178
|
+
...(await getAuthHeaders()),
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
if (!response.ok) {
|
|
182
|
+
if (response.status === 403) {
|
|
183
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
184
|
+
const reason = errorData.reason || errorData.error || "Subscription required";
|
|
185
|
+
throw new Error(`Access denied: ${reason}\n` +
|
|
186
|
+
`Visit https://tailar.dev/choose-plan to upgrade your subscription.`);
|
|
187
|
+
}
|
|
188
|
+
throw new Error(`Failed to fetch file: ${response.statusText}`);
|
|
189
|
+
}
|
|
190
|
+
return await response.text();
|
|
191
|
+
}
|
|
192
|
+
// For free components (requireAuth === false or undefined), try without auth first
|
|
193
|
+
// This allows free components to work without authentication
|
|
194
|
+
let response = await fetch(`${getApiBaseUrl()}${endpoint}`, {
|
|
195
|
+
method: "GET",
|
|
196
|
+
headers: {
|
|
197
|
+
"User-Agent": "tailar-cli",
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
// Handle 401 responses - component requires authentication
|
|
201
|
+
if (response.status === 401) {
|
|
202
|
+
// Try to authenticate and retry
|
|
203
|
+
logger.info("Authentication required. Starting authentication flow...");
|
|
204
|
+
await authenticate();
|
|
205
|
+
// Retry with auth headers
|
|
206
|
+
const retryResponse = await fetch(`${getApiBaseUrl()}${endpoint}`, {
|
|
207
|
+
method: "GET",
|
|
208
|
+
headers: {
|
|
209
|
+
"User-Agent": "tailar-cli",
|
|
210
|
+
...(await getAuthHeaders()),
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
if (!retryResponse.ok) {
|
|
214
|
+
throw new Error(`Failed to fetch file: ${retryResponse.statusText}`);
|
|
215
|
+
}
|
|
216
|
+
return await retryResponse.text();
|
|
217
|
+
}
|
|
218
|
+
if (response.status === 403) {
|
|
219
|
+
const errorData = (await response.json().catch(() => ({})));
|
|
220
|
+
const reason = errorData.reason || errorData.error || "Subscription required";
|
|
221
|
+
throw new Error(`Access denied: ${reason}\n` +
|
|
222
|
+
`Visit https://tailar.dev/choose-plan to upgrade your subscription.`);
|
|
223
|
+
}
|
|
224
|
+
if (!response.ok) {
|
|
225
|
+
throw new Error(`Failed to fetch file: ${response.statusText}`);
|
|
226
|
+
}
|
|
227
|
+
return await response.text();
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
if (error instanceof Error && error.message.includes("Access denied")) {
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
logger.error(`Failed to fetch component file: ${error instanceof Error ? error.message : String(error)}`);
|
|
234
|
+
throw error;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Fetch component metadata from API
|
|
239
|
+
* @param requireAuth - If true, requires authentication (default: true for proper access checking)
|
|
240
|
+
*/
|
|
241
|
+
export async function fetchComponentMetadata(type, name, requireAuth = true) {
|
|
242
|
+
try {
|
|
243
|
+
const endpoint = `/components/${type}/${name}`;
|
|
244
|
+
// Metadata endpoint requires auth for proper subscription checking
|
|
245
|
+
const metadata = await apiRequest(endpoint, {
|
|
246
|
+
requireAuth,
|
|
247
|
+
method: "GET",
|
|
248
|
+
});
|
|
249
|
+
return metadata;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
logger.error(`Failed to fetch component metadata: ${error instanceof Error ? error.message : String(error)}`);
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Check if user has access to a component (via metadata endpoint)
|
|
258
|
+
* @param registryEntry - Optional registry entry to check subscription requirements before API call
|
|
259
|
+
*/
|
|
260
|
+
export async function checkSubscription(type, name, registryEntry) {
|
|
261
|
+
// If registry entry is provided and component doesn't require subscription, allow access immediately
|
|
262
|
+
if (registryEntry &&
|
|
263
|
+
(!registryEntry.requiresSubscription ||
|
|
264
|
+
(registryEntry.subscriptionTier || 0) === 0)) {
|
|
265
|
+
return { accessible: true };
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
// For paid components or when registry entry is not provided, check via API
|
|
269
|
+
// Require auth for proper subscription checking
|
|
270
|
+
const metadata = await fetchComponentMetadata(type, name, true);
|
|
271
|
+
if (!metadata.requiresSubscription) {
|
|
272
|
+
return { accessible: true };
|
|
273
|
+
}
|
|
274
|
+
// For paid components, isAccessible must be explicitly true
|
|
275
|
+
// If it's false, undefined, or missing, deny access
|
|
276
|
+
// This handles the case where unauthenticated users get isAccessible: false
|
|
277
|
+
if (metadata.isAccessible !== true) {
|
|
278
|
+
// If isAccessible is explicitly false, use the reason from API
|
|
279
|
+
if (metadata.isAccessible === false && metadata.reason) {
|
|
280
|
+
return {
|
|
281
|
+
accessible: false,
|
|
282
|
+
reason: metadata.reason,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// isAccessible is false with no reason: server treated the request as anonymous.
|
|
286
|
+
// This happens when a locally-valid token was revoked server-side.
|
|
287
|
+
// If we have stored credentials, clear them and trigger a fresh auth flow.
|
|
288
|
+
const storedToken = await getStoredToken();
|
|
289
|
+
if (storedToken) {
|
|
290
|
+
logger.warn("Session revoked or expired. Re-authenticating...");
|
|
291
|
+
await clearToken();
|
|
292
|
+
await authenticate();
|
|
293
|
+
// Retry once with the new token
|
|
294
|
+
const retryMetadata = await fetchComponentMetadata(type, name, true);
|
|
295
|
+
if (!retryMetadata.requiresSubscription ||
|
|
296
|
+
retryMetadata.isAccessible === true) {
|
|
297
|
+
return { accessible: true };
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
accessible: false,
|
|
301
|
+
reason: retryMetadata.reason ?? "Subscription required.",
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return {
|
|
305
|
+
accessible: false,
|
|
306
|
+
reason: "Authentication and subscription required. Please authenticate first.",
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
return { accessible: true };
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
// If authentication fails or API error, deny access
|
|
313
|
+
if (error instanceof Error &&
|
|
314
|
+
(error.message.includes("Authentication") ||
|
|
315
|
+
error.message.includes("Not authenticated") ||
|
|
316
|
+
error.message.includes("Authentication required"))) {
|
|
317
|
+
return {
|
|
318
|
+
accessible: false,
|
|
319
|
+
reason: "Authentication required. Please authenticate first.",
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
// For other errors, deny access
|
|
323
|
+
return {
|
|
324
|
+
accessible: false,
|
|
325
|
+
reason: error instanceof Error ? error.message : "Failed to verify access",
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Utility
|
|
3
|
+
*
|
|
4
|
+
* Cross-platform browser opening functionality
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Open URL in default browser
|
|
8
|
+
* Cross-platform support (macOS, Linux, Windows)
|
|
9
|
+
*/
|
|
10
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC5D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Utility
|
|
3
|
+
*
|
|
4
|
+
* Cross-platform browser opening functionality
|
|
5
|
+
*/
|
|
6
|
+
import { logger } from "../utils/logger.js";
|
|
7
|
+
/**
|
|
8
|
+
* Open URL in default browser
|
|
9
|
+
* Cross-platform support (macOS, Linux, Windows)
|
|
10
|
+
*/
|
|
11
|
+
export async function openBrowser(url) {
|
|
12
|
+
try {
|
|
13
|
+
// Use Node.js built-in child_process for cross-platform support
|
|
14
|
+
const { exec } = await import("child_process");
|
|
15
|
+
const { promisify } = await import("util");
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
const platform = process.platform;
|
|
18
|
+
let command;
|
|
19
|
+
if (platform === "win32") {
|
|
20
|
+
// Windows
|
|
21
|
+
command = `start "" "${url}"`;
|
|
22
|
+
}
|
|
23
|
+
else if (platform === "darwin") {
|
|
24
|
+
// macOS
|
|
25
|
+
command = `open "${url}"`;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// Linux and other Unix-like systems
|
|
29
|
+
command = `xdg-open "${url}"`;
|
|
30
|
+
}
|
|
31
|
+
await execAsync(command);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
// Fallback: try using 'open' package if available
|
|
35
|
+
try {
|
|
36
|
+
const open = (await import("open")).default;
|
|
37
|
+
await open(url);
|
|
38
|
+
}
|
|
39
|
+
catch (fallbackError) {
|
|
40
|
+
logger.error(`Failed to open browser: ${error}`);
|
|
41
|
+
logger.info(`Please open this URL manually: ${url}`);
|
|
42
|
+
throw new Error(`Could not open browser. Please visit: ${url}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,IAAI,CAAC;QACH,gEAAgE;QAChE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAElC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,IAAI,OAAe,CAAC;QAEpB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,UAAU;YACV,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC;QAChC,CAAC;aAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,QAAQ;YACR,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,oCAAoC;YACpC,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC;QAChC,CAAC;QAED,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kDAAkD;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5C,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Flow Module
|
|
3
|
+
*
|
|
4
|
+
* Handles CLI authentication via device code flow
|
|
5
|
+
*/
|
|
6
|
+
import { type TokenData } from "./storage.js";
|
|
7
|
+
/**
|
|
8
|
+
* Generate device code and start authentication flow
|
|
9
|
+
*/
|
|
10
|
+
export declare function authenticate(): Promise<TokenData>;
|
|
11
|
+
/**
|
|
12
|
+
* Refresh an expired access token
|
|
13
|
+
*/
|
|
14
|
+
export declare function refreshToken(refreshTokenValue: string): Promise<TokenData>;
|
|
15
|
+
/**
|
|
16
|
+
* Get Authorization header with current valid token
|
|
17
|
+
* Automatically refreshes token if expired
|
|
18
|
+
*/
|
|
19
|
+
export declare function getAuthHeaders(): Promise<Record<string, string>>;
|
|
20
|
+
/**
|
|
21
|
+
* Check if user is authenticated
|
|
22
|
+
*/
|
|
23
|
+
export declare function isAuthenticated(): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Logout (clear stored tokens)
|
|
26
|
+
*/
|
|
27
|
+
export declare function logout(): Promise<void>;
|
|
28
|
+
//# sourceMappingURL=flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../src/auth/flow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AA4BtB;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,CA+FvD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,SAAS,CAAC,CAsCpB;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAsBtE;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAGxD;AAED;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAG5C"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Flow Module
|
|
3
|
+
*
|
|
4
|
+
* Handles CLI authentication via device code flow
|
|
5
|
+
*/
|
|
6
|
+
import fetch from "node-fetch";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { logger } from "../utils/logger.js";
|
|
9
|
+
import { openBrowser } from "./browser.js";
|
|
10
|
+
import { getStoredToken, saveToken, clearToken, isTokenValid, } from "./storage.js";
|
|
11
|
+
// Lazy-load API_BASE_URL to ensure .env file is loaded first
|
|
12
|
+
// This is a function because .env file is loaded after module imports
|
|
13
|
+
function getApiBaseUrl() {
|
|
14
|
+
return process.env.API_BASE_URL || "https://tailar.dev/api/cli";
|
|
15
|
+
}
|
|
16
|
+
const POLL_INTERVAL = 2000; // 2 seconds
|
|
17
|
+
const MAX_WAIT_TIME = 10 * 60 * 1000; // 10 minutes
|
|
18
|
+
/**
|
|
19
|
+
* Generate device code and start authentication flow
|
|
20
|
+
*/
|
|
21
|
+
export async function authenticate() {
|
|
22
|
+
logger.info("Starting authentication...");
|
|
23
|
+
try {
|
|
24
|
+
// Step 1: Get device code
|
|
25
|
+
const deviceCodeResponse = await fetch(`${getApiBaseUrl()}/device-code`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
if (!deviceCodeResponse.ok) {
|
|
32
|
+
throw new Error(`Failed to get device code: ${deviceCodeResponse.statusText}`);
|
|
33
|
+
}
|
|
34
|
+
const deviceData = (await deviceCodeResponse.json());
|
|
35
|
+
logger.break();
|
|
36
|
+
logger.info("To authenticate, please visit:");
|
|
37
|
+
logger.log(` ${deviceData.verificationUrl}`);
|
|
38
|
+
logger.break();
|
|
39
|
+
logger.info("Enter this code when prompted:");
|
|
40
|
+
logger.log(` ${chalk.bold(deviceData.userCode)}`);
|
|
41
|
+
logger.break();
|
|
42
|
+
// Step 2: Open browser
|
|
43
|
+
try {
|
|
44
|
+
await openBrowser(deviceData.verificationUrl);
|
|
45
|
+
logger.info("Opening browser...");
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
logger.warn("Could not open browser automatically");
|
|
49
|
+
logger.info(`Please visit: ${deviceData.verificationUrl}`);
|
|
50
|
+
}
|
|
51
|
+
// Step 3: Poll for authorization
|
|
52
|
+
const spinner = logger.spinner("Waiting for authorization...");
|
|
53
|
+
const startTime = Date.now();
|
|
54
|
+
while (Date.now() - startTime < MAX_WAIT_TIME) {
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
|
56
|
+
const tokenResponse = await fetch(`${getApiBaseUrl()}/token`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
},
|
|
61
|
+
body: JSON.stringify({
|
|
62
|
+
deviceCode: deviceData.deviceCode,
|
|
63
|
+
grantType: "device_code",
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
const tokenData = (await tokenResponse.json());
|
|
67
|
+
if ("error" in tokenData) {
|
|
68
|
+
if (tokenData.error === "authorization_pending") {
|
|
69
|
+
// Still waiting for authorization
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
spinner.fail();
|
|
74
|
+
throw new Error(`Authentication failed: ${tokenData.error}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Success! We got tokens
|
|
79
|
+
spinner.succeed("Authorization successful!");
|
|
80
|
+
const expiresAt = Math.floor(Date.now() / 1000) + tokenData.expiresIn;
|
|
81
|
+
const tokenDataToStore = {
|
|
82
|
+
accessToken: tokenData.accessToken,
|
|
83
|
+
refreshToken: tokenData.refreshToken,
|
|
84
|
+
expiresAt,
|
|
85
|
+
};
|
|
86
|
+
await saveToken(tokenDataToStore);
|
|
87
|
+
logger.success("Authentication complete!");
|
|
88
|
+
return tokenDataToStore;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
spinner.fail();
|
|
92
|
+
throw new Error("Authentication timeout. Please try again.");
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger.error(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Refresh an expired access token
|
|
101
|
+
*/
|
|
102
|
+
export async function refreshToken(refreshTokenValue) {
|
|
103
|
+
try {
|
|
104
|
+
const response = await fetch(`${getApiBaseUrl()}/refresh`, {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers: {
|
|
107
|
+
"Content-Type": "application/json",
|
|
108
|
+
},
|
|
109
|
+
body: JSON.stringify({
|
|
110
|
+
refreshToken: refreshTokenValue,
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
const errorData = (await response.json());
|
|
115
|
+
throw new Error(`Token refresh failed: ${errorData.error || response.statusText}`);
|
|
116
|
+
}
|
|
117
|
+
const tokenData = (await response.json());
|
|
118
|
+
const expiresAt = Math.floor(Date.now() / 1000) + tokenData.expiresIn;
|
|
119
|
+
const tokenDataToStore = {
|
|
120
|
+
accessToken: tokenData.accessToken,
|
|
121
|
+
refreshToken: tokenData.refreshToken,
|
|
122
|
+
expiresAt,
|
|
123
|
+
};
|
|
124
|
+
await saveToken(tokenDataToStore);
|
|
125
|
+
return tokenDataToStore;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
logger.error(`Token refresh failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get Authorization header with current valid token
|
|
134
|
+
* Automatically refreshes token if expired
|
|
135
|
+
*/
|
|
136
|
+
export async function getAuthHeaders() {
|
|
137
|
+
let tokenData = await getStoredToken();
|
|
138
|
+
if (!tokenData) {
|
|
139
|
+
throw new Error("Not authenticated. Please run authentication first.");
|
|
140
|
+
}
|
|
141
|
+
// Check if token is expired or about to expire
|
|
142
|
+
if (!isTokenValid(tokenData)) {
|
|
143
|
+
logger.info("Token expired, refreshing...");
|
|
144
|
+
try {
|
|
145
|
+
tokenData = await refreshToken(tokenData.refreshToken);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
// Refresh failed, clear token and require re-authentication
|
|
149
|
+
await clearToken();
|
|
150
|
+
throw new Error("Token refresh failed. Please authenticate again.");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
Authorization: `Bearer ${tokenData.accessToken}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if user is authenticated
|
|
159
|
+
*/
|
|
160
|
+
export async function isAuthenticated() {
|
|
161
|
+
const tokenData = await getStoredToken();
|
|
162
|
+
return tokenData !== null && isTokenValid(tokenData);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Logout (clear stored tokens)
|
|
166
|
+
*/
|
|
167
|
+
export async function logout() {
|
|
168
|
+
await clearToken();
|
|
169
|
+
logger.success("Logged out successfully");
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/auth/flow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,6DAA6D;AAC7D,sEAAsE;AACtE,SAAS,aAAa;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,4BAA4B,CAAC;AAClE,CAAC;AACD,MAAM,aAAa,GAAG,IAAI,CAAC,CAAC,YAAY;AACxC,MAAM,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAoBnD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAE1C,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,kBAAkB,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,EAAE,cAAc,EAAE;YACvE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,8BAA8B,kBAAkB,CAAC,UAAU,EAAE,CAC9D,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,MAAM,kBAAkB,CAAC,IAAI,EAAE,CAAuB,CAAC;QAE3E,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,EAAE,CAAC;QAEf,uBAAuB;QACvB,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC,iBAAiB,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,iCAAiC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,aAAa,EAAE,CAAC;YAC9C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;YAEnE,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,EAAE,QAAQ,EAAE;gBAC5D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,UAAU,EAAE,UAAU,CAAC,UAAU;oBACjC,SAAS,EAAE,aAAa;iBACzB,CAAC;aACH,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,CAEvB,CAAC;YAEvB,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;gBACzB,IAAI,SAAS,CAAC,KAAK,KAAK,uBAAuB,EAAE,CAAC;oBAChD,kCAAkC;oBAClC,SAAS;gBACX,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,yBAAyB;gBACzB,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;gBAE7C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC;gBACtE,MAAM,gBAAgB,GAAc;oBAClC,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,YAAY,EAAE,SAAS,CAAC,YAAY;oBACpC,SAAS;iBACV,CAAC;gBAEF,MAAM,SAAS,CAAC,gBAAgB,CAAC,CAAC;gBAClC,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;gBAE3C,OAAO,gBAAgB,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,0BACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACF,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,iBAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,EAAE,UAAU,EAAE;YACzD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,YAAY,EAAE,iBAAiB;aAChC,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAuB,CAAC;YAChE,MAAM,IAAI,KAAK,CACb,yBAAyB,SAAS,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,EAAE,CAClE,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAkB,CAAC;QAE3D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC;QACtE,MAAM,gBAAgB,GAAc;YAClC,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,SAAS;SACV,CAAC;QAEF,MAAM,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAClC,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CACV,yBACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACF,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,SAAS,GAAG,MAAM,cAAc,EAAE,CAAC;IAEvC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,+CAA+C;IAC/C,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,4DAA4D;YAC5D,MAAM,UAAU,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,OAAO;QACL,aAAa,EAAE,UAAU,SAAS,CAAC,WAAW,EAAE;KACjD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,SAAS,GAAG,MAAM,cAAc,EAAE,CAAC;IACzC,OAAO,SAAS,KAAK,IAAI,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,MAAM,UAAU,EAAE,CAAC;IACnB,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Storage Module
|
|
3
|
+
*
|
|
4
|
+
* Handles storing and retrieving CLI authentication tokens
|
|
5
|
+
* Platform-specific path resolution for credentials file
|
|
6
|
+
*/
|
|
7
|
+
export interface TokenData {
|
|
8
|
+
accessToken: string;
|
|
9
|
+
refreshToken: string;
|
|
10
|
+
expiresAt: number;
|
|
11
|
+
userId?: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read stored token from credentials file
|
|
16
|
+
*/
|
|
17
|
+
export declare function getStoredToken(): Promise<TokenData | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Save token to credentials file
|
|
20
|
+
*/
|
|
21
|
+
export declare function saveToken(tokenData: TokenData): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Clear stored token (delete credentials file)
|
|
24
|
+
*/
|
|
25
|
+
export declare function clearToken(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Check if token exists and is not expired
|
|
28
|
+
*/
|
|
29
|
+
export declare function isTokenValid(tokenData: TokenData | null): boolean;
|
|
30
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/auth/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8BD;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2BhE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBnE;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAUhD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAUjE"}
|