kawazu
Version:
kawazu CLI tool for real-time chat in your editor
138 lines (137 loc) • 6.18 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRoom = createRoom;
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const inquirer_1 = __importDefault(require("inquirer"));
const node_fetch_1 = __importDefault(require("node-fetch"));
const config_1 = require("../utils/config");
const join_1 = require("./join");
async function createRoom(roomName, options) {
// 認証チェック
console.log(chalk_1.default.blue('🔍 認証状態を確認中...'));
let config = await (0, config_1.requireAuth)();
const spinner = (0, ora_1.default)('ルームを作成中...').start();
try {
// ルームスラッグの生成(ルーム名から自動生成)
const slug = generateSlug(roomName);
// プライベートルームの場合はパスワードを取得
let password = options.password;
if (options.private && !password) {
spinner.stop();
const { inputPassword } = await inquirer_1.default.prompt([
{
type: 'password',
name: 'inputPassword',
message: 'プライベートルーム用のパスワードを入力してください:',
validate: (input) => input.length >= 4 || 'パスワードは4文字以上で入力してください'
}
]);
password = inputPassword;
spinner.start('ルームを作成中...');
}
// API リクエストデータ
const roomData = {
name: roomName,
slug: slug,
is_private: options.private || false,
password: password
};
// API リクエスト(認証トークン付き)
const response = await (0, node_fetch_1.default)(`${config.server_url}/api/rooms`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${config.auth_token}`
},
body: JSON.stringify(roomData)
});
const result = await response.json();
if (!response.ok || !result.success) {
spinner.fail('ルーム作成に失敗しました');
if (result.error) {
console.error(chalk_1.default.red(`❌ ${result.error}`));
if (result.details) {
result.details.forEach(detail => {
console.error(chalk_1.default.red(` ${detail.field}: ${detail.message}`));
});
}
}
return;
}
spinner.succeed(`ルーム "${roomName}" を作成しました!`);
// 作成したルームの情報を表示
console.log(chalk_1.default.green(`\n📝 ルーム情報:`));
console.log(` 名前: ${result.data.name}`);
console.log(` ID: ${result.data.slug}`);
console.log(` プライベート: ${result.data.is_private ? 'はい' : 'いいえ'}`);
// CLIコマンドの表示
const cliCommand = result.data.is_private
? `kawazu join ${result.data.slug} -p ${password}`
: `kawazu join ${result.data.slug}`;
console.log(chalk_1.default.blue(`\n💡 参加コマンド:`));
console.log(chalk_1.default.cyan(` ${cliCommand}`));
// 自動参加の確認
const { autoJoin } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'autoJoin',
message: '作成したルームにすぐに参加しますか?',
default: true
}
]);
if (autoJoin) {
console.log(chalk_1.default.yellow('\n🚀 ルームに参加しています...\n'));
// ユーザー名の取得(認証済みユーザー名を優先)
const username = config.user_username || await promptUsername();
// 作成したルームに参加
await (0, join_1.joinRoom)(result.data.slug, {
username,
password: password
});
}
else {
console.log(chalk_1.default.green('\n✅ ルームが作成されました。上記のコマンドで参加できます。'));
}
}
catch (error) {
spinner.fail('ルーム作成でエラーが発生しました');
console.error(chalk_1.default.red(`❌ ${error.message}`));
if (error.code === 'ECONNREFUSED') {
console.log(chalk_1.default.yellow('💡 APIサーバーが起動していない可能性があります'));
console.log(chalk_1.default.gray(` サーバーURL: ${config.server_url}`));
}
}
}
function generateSlug(name) {
return name
.toLowerCase()
.trim()
.replace(/[^a-z0-9\s-]/g, '') // 英数字、スペース、ハイフンのみ残す
.replace(/\s+/g, '-') // スペースをハイフンに変換
.replace(/-+/g, '-') // 連続ハイフンを1つに
.replace(/^-|-$/g, ''); // 先頭末尾のハイフンを削除
}
async function promptUsername() {
const { username } = await inquirer_1.default.prompt([
{
type: 'input',
name: 'username',
message: 'チャット用のユーザー名を入力してください:',
validate: (input) => {
const trimmed = input.trim();
if (trimmed.length === 0)
return 'ユーザー名を入力してください';
if (trimmed.length > 50)
return 'ユーザー名は50文字以内で入力してください';
if (!/^[a-zA-Z0-9_-]+$/.test(trimmed))
return 'ユーザー名は英数字、ハイフン、アンダースコアのみ使用できます';
return true;
}
}
]);
return username.trim();
}