miridev-cli
Version:
Official CLI tool for deploying static sites to miri.dev - Deploy your websites in seconds
103 lines (84 loc) • 3.8 kB
JavaScript
const chalk = require('chalk');
const { getCurrentUser } = require('../utils/auth');
const api = require('../utils/api');
/**
* 사이트 목록 조회
*/
async function listSites() {
console.log(chalk.blue.bold('\n📋 Your Sites\n'));
try {
const user = getCurrentUser();
if (!user) {
console.log(chalk.yellow('⚠️ You need to login to view your sites'));
console.log(chalk.gray('Guest deployments are not tracked'));
console.log(chalk.gray('Run "miridev login" to access your dashboard'));
return;
}
console.log(chalk.gray(`Loading sites for ${user.email}...`));
try {
const sites = await api.getUserSites();
if (sites.length === 0) {
console.log(chalk.gray('No sites found'));
console.log(chalk.gray('Run "miridev deploy" to deploy your first site'));
return;
}
// 사이트 목록 표시
console.log(chalk.green(`Found ${sites.length} site(s):\n`));
sites.forEach((site, index) => {
const isExpired = site.expiresAt && new Date(site.expiresAt) < new Date();
const statusColor = isExpired ? chalk.red : chalk.green;
const status = isExpired ? 'Expired' : 'Active';
console.log(`${chalk.cyan(`${index + 1}.`)} ${chalk.bold(site.name || site.id)}`);
console.log(` URL: ${chalk.cyan.underline(site.url)}`);
console.log(` Status: ${statusColor(status)}`);
console.log(` Created: ${new Date(site.createdAt).toLocaleString()}`);
if (site.expiresAt) {
console.log(` Expires: ${new Date(site.expiresAt).toLocaleString()}`);
}
if (site.customDomain) {
console.log(` Domain: ${chalk.cyan.underline(`https://${site.customDomain}`)}`);
}
console.log(` Files: ${site.fileCount || 0}`);
console.log(` Size: ${formatFileSize(site.totalSize || 0)}`);
console.log('');
});
// 요약 통계
const activeSites = sites.filter(site => !site.expiresAt || new Date(site.expiresAt) > new Date());
const totalSize = sites.reduce((sum, site) => sum + (site.totalSize || 0), 0);
console.log(chalk.gray('📊 Summary:'));
console.log(chalk.gray(` Active sites: ${activeSites.length}/${sites.length}`));
console.log(chalk.gray(` Total storage: ${formatFileSize(totalSize)}`));
console.log(chalk.gray(` Plan: ${user.plan || 'basic'}`));
} catch (error) {
// API가 아직 구현되지 않은 경우 또는 인증 오류
if (error.message.includes('구현되지 않았습니다')) {
console.log(chalk.yellow('🚧 Site listing feature is coming soon!'));
console.log(chalk.gray('This feature requires server-side implementation'));
console.log(chalk.gray('For now, you can track your deployments manually'));
} else if (error.message.includes('Authentication required')) {
console.log(chalk.yellow('⚠️ Authentication token may be expired or invalid'));
console.log(chalk.gray('Please run "miridev login" to refresh your session'));
} else {
console.log(chalk.red(`❌ Failed to fetch sites: ${error.message}`));
console.log(chalk.gray('Please check your connection and try again'));
}
}
} catch (error) {
console.error(chalk.red.bold('\n✗ Failed to load sites:'));
console.error(chalk.red(error.message));
process.exit(1);
}
}
/**
* 파일 크기를 읽기 쉬운 형태로 변환
*/
function formatFileSize(bytes) {
if (bytes === 0) { return '0 B'; }
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}
module.exports = {
listSites
};