UNPKG

kawazu

Version:

kawazu CLI tool for real-time chat in your editor

305 lines (304 loc) 13.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.shareFile = shareFile; exports.listSharedFiles = listSharedFiles; exports.downloadSharedFile = downloadSharedFile; exports.revokeFileShare = revokeFileShare; const chalk_1 = __importDefault(require("chalk")); const inquirer_1 = __importDefault(require("inquirer")); const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const config_1 = require("../utils/config"); const file_1 = require("../utils/file"); async function shareFile(filePath, options = {}) { try { // ファイル存在確認 if (!fs_extra_1.default.existsSync(filePath)) { console.error(chalk_1.default.red('❌ ファイルが見つかりません:'), filePath); return; } // ファイル情報取得 const absolutePath = path_1.default.resolve(filePath); const fileName = path_1.default.basename(absolutePath); const fileExt = path_1.default.extname(fileName); const fileType = options.type || getFileType(fileExt); // ファイル内容読み取り const fileContent = await fs_extra_1.default.readFile(absolutePath, 'utf-8'); if (fileContent.length > 1000000) { // 1MB制限 console.error(chalk_1.default.red('❌ ファイルサイズが大きすぎます (最大1MB)')); return; } console.log(chalk_1.default.blue(`📤 ファイル共有: ${fileName}`)); // 設定取得 const config = await (0, config_1.loadConfig)(); if (!config.server_url) { console.error(chalk_1.default.red('❌ サーバーURLが設定されていません')); console.log(chalk_1.default.yellow('💡 設定方法: ') + chalk_1.default.cyan('kawazu config --server <URL>')); return; } // ルーム情報取得 let roomSlug = options.room; if (!roomSlug) { roomSlug = await (0, file_1.getCurrentRoomFromCodechat)(); if (!roomSlug) { console.error(chalk_1.default.red('❌ ルーム情報が見つかりません')); console.log(chalk_1.default.yellow('💡 --room オプションでルームを指定してください')); return; } } // ユーザー名確認 const username = config.default_username; if (!username) { console.error(chalk_1.default.red('❌ ユーザー名が設定されていません')); console.log(chalk_1.default.yellow('💡 設定方法: ') + chalk_1.default.cyan('kawazu config --username <名前>')); return; } // 対象ユーザー解析 const targetUsers = options.users ? options.users.split(',').map(u => u.trim()) : []; // 権限設定 const permission = options.permission || 'read'; // 有効期限設定 let expiryHours = 24; if (options.expires) { const hours = parseInt(options.expires); if (isNaN(hours) || hours <= 0) { console.error(chalk_1.default.red('❌ 無効な有効期限です')); return; } expiryHours = hours; } // 共有確認 console.log(chalk_1.default.yellow('\n📋 共有設定:')); console.log(` ファイル: ${chalk_1.default.cyan(fileName)}`); console.log(` ルーム: ${chalk_1.default.cyan(roomSlug)}`); console.log(` 権限: ${chalk_1.default.cyan(permission === 'read' ? '読み取り専用' : '読み書き可能')}`); console.log(` 対象: ${targetUsers.length > 0 ? chalk_1.default.cyan(targetUsers.join(', ')) : chalk_1.default.cyan('全参加者')}`); console.log(` 有効期限: ${chalk_1.default.cyan(expiryHours + '時間')}`); const { confirm } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'confirm', message: 'この設定でファイルを共有しますか?', default: true } ]); if (!confirm) { console.log(chalk_1.default.yellow('❌ ファイル共有をキャンセルしました')); return; } // API呼び出し const response = await fetch(`${config.server_url}/api/file-sharing/${roomSlug}/shares`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ owner_username: username, file_path: absolutePath, file_name: fileName, file_content: fileContent, file_type: fileType, target_users: targetUsers, permission_type: permission, expiry_hours: expiryHours }) }); const result = await response.json(); if (result.success) { console.log(chalk_1.default.green('\n✅ ファイル共有が作成されました!')); console.log(chalk_1.default.gray(`共有トークン: ${result.data.share_token}`)); console.log(chalk_1.default.gray(`有効期限: ${new Date(result.data.expires_at).toLocaleString()}`)); if (targetUsers.length > 0) { console.log(chalk_1.default.blue(`\n📬 ${targetUsers.length}人のユーザーに共有リクエストを送信しました`)); console.log(chalk_1.default.yellow('💡 相手が承認するまでお待ちください')); } else { console.log(chalk_1.default.blue('\n📬 ルーム内の全参加者に共有リクエストを送信しました')); } } else { console.error(chalk_1.default.red('❌ ファイル共有に失敗しました:'), result.error); } } catch (error) { console.error(chalk_1.default.red('❌ エラーが発生しました:'), error); } } async function listSharedFiles(roomSlug) { try { const config = await (0, config_1.loadConfig)(); if (!config.server_url || !config.default_username) { console.error(chalk_1.default.red('❌ 設定が不完全です')); console.log(chalk_1.default.yellow('💡 設定方法: ') + chalk_1.default.cyan('kawazu config')); return; } // ルーム情報取得 if (!roomSlug) { roomSlug = await (0, file_1.getCurrentRoomFromCodechat)(); if (!roomSlug) { console.error(chalk_1.default.red('❌ ルーム情報が見つかりません')); return; } } const response = await fetch(`${config.server_url}/api/file-sharing/${roomSlug}/shares?username=${config.default_username}`); const result = await response.json(); if (result.success) { const files = result.data; if (files.length === 0) { console.log(chalk_1.default.yellow('📁 共有されているファイルはありません')); return; } console.log(chalk_1.default.blue.bold(`\n📁 共有ファイル一覧 (${roomSlug})\n`)); files.forEach((file, index) => { const statusColor = file.status === 'approved' ? chalk_1.default.green : file.status === 'denied' ? chalk_1.default.red : chalk_1.default.yellow; const permissionIcon = file.permission_type === 'write' ? '✏️' : '👀'; console.log(`${index + 1}. ${permissionIcon} ${chalk_1.default.cyan(file.file_name)}`); console.log(` 所有者: ${chalk_1.default.gray(file.owner_username)}`); console.log(` ステータス: ${statusColor(getStatusText(file.status))}`); console.log(` 権限: ${chalk_1.default.gray(file.permission_type === 'read' ? '読み取り専用' : '読み書き可能')}`); if (file.expires_at) { const expiresAt = new Date(file.expires_at); const isExpired = expiresAt < new Date(); console.log(` 有効期限: ${isExpired ? chalk_1.default.red('期限切れ') : chalk_1.default.gray(expiresAt.toLocaleString())}`); } console.log(` トークン: ${chalk_1.default.gray(file.share_token)}`); console.log(''); }); } else { console.error(chalk_1.default.red('❌ ファイル一覧の取得に失敗しました:'), result.error); } } catch (error) { console.error(chalk_1.default.red('❌ エラーが発生しました:'), error); } } async function downloadSharedFile(shareToken, outputPath) { try { const config = await (0, config_1.loadConfig)(); if (!config.server_url || !config.default_username) { console.error(chalk_1.default.red('❌ 設定が不完全です')); return; } const response = await fetch(`${config.server_url}/api/file-sharing/shares/${shareToken}/content?username=${config.default_username}`); const result = await response.json(); if (result.success) { const data = result.data; const fileName = outputPath || data.file_name; const filePath = path_1.default.resolve(fileName); // ファイル上書き確認 if (fs_extra_1.default.existsSync(filePath)) { const { overwrite } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'overwrite', message: `ファイル ${fileName} は既に存在します。上書きしますか?`, default: false } ]); if (!overwrite) { console.log(chalk_1.default.yellow('❌ ダウンロードをキャンセルしました')); return; } } // ファイル保存 await fs_extra_1.default.writeFile(filePath, data.file_content, 'utf-8'); console.log(chalk_1.default.green(`✅ ファイルをダウンロードしました: ${fileName}`)); console.log(chalk_1.default.gray(`所有者: ${data.owner_username}`)); console.log(chalk_1.default.gray(`権限: ${data.permission_type === 'read' ? '読み取り専用' : '読み書き可能'}`)); if (data.expires_at) { console.log(chalk_1.default.gray(`有効期限: ${new Date(data.expires_at).toLocaleString()}`)); } } else { console.error(chalk_1.default.red('❌ ファイルのダウンロードに失敗しました:'), result.error); } } catch (error) { console.error(chalk_1.default.red('❌ エラーが発生しました:'), error); } } async function revokeFileShare(shareToken) { try { const config = await (0, config_1.loadConfig)(); if (!config.server_url || !config.default_username) { console.error(chalk_1.default.red('❌ 設定が不完全です')); return; } const { confirm } = await inquirer_1.default.prompt([ { type: 'confirm', name: 'confirm', message: 'このファイル共有を取り消しますか?', default: false } ]); if (!confirm) { console.log(chalk_1.default.yellow('❌ 取り消しをキャンセルしました')); return; } const response = await fetch(`${config.server_url}/api/file-sharing/shares/${shareToken}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username: config.default_username }) }); const result = await response.json(); if (result.success) { console.log(chalk_1.default.green('✅ ファイル共有を取り消しました')); console.log(chalk_1.default.gray(`ファイル: ${result.data.file_name}`)); } else { console.error(chalk_1.default.red('❌ ファイル共有の取り消しに失敗しました:'), result.error); } } catch (error) { console.error(chalk_1.default.red('❌ エラーが発生しました:'), error); } } // ヘルパー関数 function getFileType(extension) { const typeMap = { '.js': 'javascript', '.ts': 'typescript', '.jsx': 'javascript', '.tsx': 'typescript', '.py': 'python', '.java': 'java', '.cpp': 'cpp', '.c': 'c', '.cs': 'csharp', '.php': 'php', '.rb': 'ruby', '.go': 'go', '.rs': 'rust', '.html': 'html', '.css': 'css', '.scss': 'scss', '.sass': 'sass', '.json': 'json', '.xml': 'xml', '.yml': 'yaml', '.yaml': 'yaml', '.md': 'markdown', '.txt': 'text', '.sh': 'bash', '.sql': 'sql' }; return typeMap[extension.toLowerCase()] || 'text'; } function getStatusText(status) { switch (status) { case 'pending': return '承認待ち'; case 'approved': return '承認済み'; case 'denied': return '拒否'; default: return status; } }