import { addLog, ErrorLog } from '@mintlify/previewing'; import { Box, Text } from 'ink'; import { z } from 'zod'; import { authenticatedFetch } from './authenticatedFetch.js'; import { getConfigValue, setConfigValue } from './config.js'; import { API_URL } from './constants.js'; import { getCliVersion } from './helpers.js'; import { getAccessToken } from './keyring.js'; const StatusResponseSchema = z.object({ user: z.object({ email: z.string() }), org: z.object({ name: z.string() }), subdomains: z.array(z.string()).default([]), }); export async function getCliStatus( accessToken: string ): Promise | null> { try { const res = await fetch(`${API_URL}/api/cli/status`, { headers: { Authorization: `Bearer ${accessToken}` }, }); if (!res.ok) return null; const json = await res.json().catch(() => null); const parsed = StatusResponseSchema.safeParse(json); return parsed.success ? parsed.data : null; } catch { return null; } } export type CliStatusResult = | { ok: true; status: z.infer } | { ok: false; reason: 'unauthenticated' | 'unreachable' | 'invalid'; detail?: string }; /** * Like getCliStatus, but refreshes an expired session and says why it failed, so commands can * tell "log in again" apart from "the server is down" and from "not allowed". */ export async function fetchCliStatus(signal?: AbortSignal): Promise { let res: Response; try { res = await authenticatedFetch(`${API_URL}/api/cli/status`, { signal }); } catch (error) { const detail = error instanceof Error ? error.message : String(error); if (/not authenticated/i.test(detail)) return { ok: false, reason: 'unauthenticated' }; return { ok: false, reason: 'unreachable', detail }; } if (res.status === 401 || res.status === 403) return { ok: false, reason: 'unauthenticated' }; if (!res.ok) return { ok: false, reason: 'unreachable', detail: `HTTP ${res.status}` }; const parsed = StatusResponseSchema.safeParse(await res.json().catch(() => null)); if (!parsed.success) return { ok: false, reason: 'invalid' }; return { ok: true, status: parsed.data }; } export async function getCliSubdomains(accessToken: string): Promise { const status = await getCliStatus(accessToken); return status?.subdomains ?? []; } export async function status(): Promise { const accessToken = (await getAccessToken().catch(() => null)) ?? process.env.MINTLIFY_SESSION_TOKEN; if (!accessToken) { addLog(); return; } try { const res = await authenticatedFetch(`${API_URL}/api/cli/status`); if (!res.ok) { addLog(); return; } const json = await res.json().catch(() => null); const parsed = StatusResponseSchema.safeParse(json); if (!parsed.success) { addLog(); return; } const { user, org, subdomains } = parsed.data; const version = getCliVersion(); const cached = getConfigValue('subdomain'); const subdomain = (cached && subdomains.includes(cached) ? cached : subdomains[0]) ?? null; if (subdomain && subdomain !== cached) await setConfigValue('subdomain', subdomain).catch(() => undefined); addLog( {version && ( Version {version} )} Email {user.email} Organization {org.name} {subdomain && ( Subdomain {subdomain} )} ); } catch (e) { addLog(); } }