import { program, Command } from '@/program.ts'; import { getConfig, getEnvToken } from '@/module/get-config.ts'; import { input, password } from '@inquirer/prompts'; import { loginInCommand } from '@/module/login/login-by-web.ts'; import { queryLogin, storage } from '@/module/query.ts'; import chalk from 'chalk'; import util from 'util'; const pick = (obj: any, keys: string[]) => { return keys.reduce((acc, key) => { acc[key] = obj[key]; return acc; }, {}); }; /** * 定义login命令,支持 `-u` 和 `-p` 参数来输入用户名和密码 */ const loginCommand = new Command('login') .description('Login to the application') .option('-u, --username ', 'Specify username') .option('-p, --password ', 'Specify password') .option('-f, --force', 'Force login') .option('-w, --web', 'Login on the web') .option('-e, --env', 'Login from KEVISUAL_TOKEN environment variable') .action(async (options) => { let { username, password } = options; if (options.web) { await loginInCommand(); return; } // 从环境变量登录 if (options.env) { const envToken = getEnvToken(); if (!envToken) { console.log('环境变量 KEVISUAL_TOKEN 未设置'); return; } const res = await showMe(false); if (res.code === 200) { console.log('Login success:', res.data?.username || res.data?.email); } else { console.log('Login failed:', res.message || 'Invalid token'); } return; } // 如果没有传递参数,则通过交互式输入 if (!username) { username = await input({ message: 'Enter your username:', }); } if (!password) { password = await password({ message: 'Enter your password:', }); } const token = storage.getItem('token'); if (token) { const res = await showMe(false); if (res.code === 200) { const data = res.data; if (data.username === username) { console.log('Already Login For', data.username); return; } } } const res = await queryLogin.login({ username, password, }).catch((err) => { return { code: 500, message: err.message || '' }; }); if (res.code === 200) { console.log('welcome', username); } else { console.log('登录失败', res.message || ''); } }); program.addCommand(loginCommand); export const getUsername = async () => { const token = getEnvToken(); const localToken = storage.getItem('token'); if (!token && !localToken) { console.log('请先登录'); return null; } let me = await queryLogin.getMe(localToken || token); if (me?.code === 401) { me = await queryLogin.getMe(); } if (me?.code === 200) { return me.data?.username; } return null; } const showMe = async (show = true) => { const token = getEnvToken(); const localToken = storage.getItem('token'); if (!token && !localToken) { console.log('请先登录'); return { code: 40400, message: '请先登录' }; } let me = await queryLogin.getMe(localToken || token); if (me?.code === 401) { me = await queryLogin.getMe(); } if (show) { console.log('Me', me.data); } return me; }; const switchOrgCommand = new Command('switch').argument('', 'Switch to another organization or username').action(async (username) => { const res = await queryLogin.switchUser(username); if (res.code === 200) { console.log('success switch to', username); } else { console.log('switch to', username, 'failed', res.message || ''); } }); program.addCommand(switchOrgCommand); const command = new Command('me') .option('-a, --all', 'show all info') .description('') .action(async (options) => { try { let res = await showMe(false); let isRefresh = false; if (res.code === 200 && res.data?.accessToken) { res = await showMe(false); isRefresh = true; } if (res.code === 40400) { return } if (res.code === 200) { if (isRefresh) { console.log(chalk.green('refresh token success'), '\n'); } } else { console.log( isRefresh ? chalk.red('refresh token failed, please login again.') : chalk.red('you need login first. \n run `envision login` to login'), '\n', ); return; } const baseURL = getConfig().baseURL; const pickData = pick(res?.data, ['username', 'type', 'orgs']); console.log(chalk.blue('baseURL', baseURL)); if (options.all) { console.log(chalk.blue(util.inspect(res?.data, { colors: true, depth: 4 }))); } else { // 打印pickData console.log(chalk.blue(util.inspect(pickData, { colors: true, depth: 4 }))); } } catch (error) { console.log('me error', error); } }); program.addCommand(command); const logoutCommand = new Command('logout').description('退出登陆').action(async () => { try { await queryLogin.logout(); storage.removeItem('token'); console.log('退出成功'); } catch (error) { console.log('退出失败', error); } }); program.addCommand(logoutCommand);