mastra
Version:
cli for mastra
244 lines (242 loc) • 7.9 kB
JavaScript
import { MASTRA_PLATFORM_API_URL } from './chunk-L2SGSIJI.js';
import { execFileSync } from 'child_process';
import { randomBytes } from 'crypto';
import { readFileSync } from 'fs';
import { mkdir, writeFile, chmod, readFile, unlink } from 'fs/promises';
import { createServer } from 'http';
import { homedir, release } from 'os';
import { join } from 'path';
var CREDENTIALS_DIR = join(homedir(), ".mastra");
var CREDENTIALS_FILE = join(CREDENTIALS_DIR, "credentials.json");
async function saveCredentials(creds) {
await mkdir(CREDENTIALS_DIR, { recursive: true, mode: 448 });
await writeFile(CREDENTIALS_FILE, JSON.stringify(creds, null, 2), { mode: 384 });
await chmod(CREDENTIALS_DIR, 448).catch(() => {
});
await chmod(CREDENTIALS_FILE, 384).catch(() => {
});
}
async function loadCredentials() {
try {
const data = await readFile(CREDENTIALS_FILE, "utf-8");
return JSON.parse(data);
} catch {
return null;
}
}
async function clearCredentials() {
try {
await unlink(CREDENTIALS_FILE);
} catch {
}
}
async function getCurrentOrgId() {
const envOrgId = process.env.MASTRA_ORG_ID;
if (envOrgId) return envOrgId;
const creds = await loadCredentials();
if (!creds) return null;
return creds.currentOrgId ?? creds.organizationId;
}
async function setCurrentOrgId(orgId) {
const creds = await loadCredentials();
if (!creds) throw new Error("Not logged in");
creds.currentOrgId = orgId;
await saveCredentials(creds);
}
function isWSL() {
if (process.platform !== "linux") return false;
try {
return /microsoft|wsl/i.test(release()) || /microsoft|wsl/i.test(readFileSync("/proc/version", "utf-8"));
} catch {
return false;
}
}
function openBrowser(url) {
if (process.platform === "darwin") {
execFileSync("open", [url]);
} else if (process.platform === "win32") {
execFileSync("cmd", ["/c", "start", "", url]);
} else if (isWSL()) {
execFileSync("powershell.exe", ["-NoProfile", "-Command", `Start-Process '${url.replace(/'/g, "''")}'`]);
} else {
execFileSync("xdg-open", [url]);
}
}
async function verifyToken(token) {
try {
const res = await fetch(`${MASTRA_PLATFORM_API_URL}/v1/auth/verify`, {
headers: { Authorization: `Bearer ${token}` }
});
return res.ok;
} catch {
return false;
}
}
async function tryRefreshToken(creds) {
if (!creds.refreshToken) return null;
try {
const res = await fetch(`${MASTRA_PLATFORM_API_URL}/v1/auth/refresh-token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ refreshToken: creds.refreshToken })
});
if (!res.ok) return null;
const data = await res.json();
creds.token = data.accessToken;
creds.refreshToken = data.refreshToken;
await saveCredentials(creds);
return data.accessToken;
} catch {
return null;
}
}
function callbackPage({ success }) {
const title = success ? "Logged in!" : "Login failed";
const message = success ? "You can close this tab and return to the terminal." : "Missing parameters. Close this tab and try again.";
return `<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>${title} \u2014 Mastra</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #0d0d0d;
color: #ffffff;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.container {
text-align: center;
}
.logo {
margin-bottom: 1.5rem;
}
h1 {
font-size: 1.75rem;
font-weight: 600;
margin: 0 0 0.75rem 0;
}
p {
color: #9ca3af;
font-size: 1rem;
margin: 0;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="container">
<h1>${title}</h1>
<p>${message}</p>
</div>
</body>
</html>`;
}
async function login() {
console.info("\nLogging in to Mastra...\n");
const server = createServer();
const state = randomBytes(16).toString("hex");
const port = await new Promise((resolve) => {
server.listen(0, "127.0.0.1", () => {
const addr = server.address();
if (typeof addr === "object" && addr) {
resolve(addr.port);
}
});
});
const loginUrl = `${MASTRA_PLATFORM_API_URL}/v1/auth/login?product=cli&cli_port=${port}&state=${state}`;
console.info(` Opening browser...
`);
try {
openBrowser(loginUrl);
} catch {
console.info(` Could not open browser automatically.`);
console.info(` Open this URL manually: ${loginUrl}
`);
if (isWSL()) {
console.info(` Note: If login times out, ensure localhost forwarding is enabled in your .wslconfig.
`);
}
}
const result = await new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
server.close(() => {
reject(new Error("Login timed out (60s)"));
});
server.closeAllConnections();
}, 6e4);
server.on("request", (req, res) => {
const url = new URL(req.url, `http://localhost:${port}`);
if (url.pathname === "/callback") {
const callbackState = url.searchParams.get("state");
const token = url.searchParams.get("token");
const refreshToken = url.searchParams.get("refresh_token");
const userParam = url.searchParams.get("user");
const orgId = url.searchParams.get("org");
if (callbackState !== state || !token || !userParam || !orgId) {
res.writeHead(400, { "Content-Type": "text/html" });
res.end(callbackPage({ success: false }));
return;
}
const user = JSON.parse(decodeURIComponent(userParam));
res.writeHead(200, { "Content-Type": "text/html", Connection: "close" });
res.end(callbackPage({ success: true }));
clearTimeout(timeout);
server.close(() => {
resolve({ token, refreshToken, user, organizationId: orgId });
});
server.closeAllConnections();
}
});
});
const creds = {
token: result.token,
...result.refreshToken ? { refreshToken: result.refreshToken } : {},
user: result.user,
organizationId: result.organizationId
};
await saveCredentials(creds);
console.info(` Logged in as ${creds.user.email}
`);
return creds;
}
function isInteractive() {
return Boolean(process.stdin.isTTY && process.stdout.isTTY) && !process.env.CI;
}
async function getToken() {
const envToken = process.env.MASTRA_API_TOKEN;
if (envToken) return envToken;
const creds = await loadCredentials();
if (!creds) {
if (!isInteractive()) {
throw new Error("Not logged in. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.");
}
const newCreds2 = await login();
return newCreds2.token;
}
if (await verifyToken(creds.token)) return creds.token;
const refreshed = await tryRefreshToken(creds);
if (refreshed) return refreshed;
if (!isInteractive()) {
throw new Error("Session expired. Run `mastra auth login` interactively or set MASTRA_API_TOKEN.");
}
const newCreds = await login();
return newCreds.token;
}
async function validateOrgAccess(token, orgId) {
const { fetchOrgs } = await import('./api-C4LNCE5C.js');
const orgs = await fetchOrgs(token);
const hasAccess = orgs.some((o) => o.id === orgId);
if (!hasAccess) {
throw new Error(`No access to organization ${orgId}. Run: mastra auth orgs`);
}
}
export { clearCredentials, getCurrentOrgId, getToken, loadCredentials, login, saveCredentials, setCurrentOrgId, tryRefreshToken, validateOrgAccess, verifyToken };
//# sourceMappingURL=chunk-EXG3XKBK.js.map
//# sourceMappingURL=chunk-EXG3XKBK.js.map