/**
* 接続管理ユーティリティ
*/
import { readFile, writeFile, mkdir } from 'fs/promises';
import { existsSync } from 'fs';
import { join, dirname } from 'path';
import { homedir } from 'os';
import type { MTConnection } from '../types/index.js';
import { MTClient } from './mt-client.js';
// 設定ファイルのパス
const CONFIG_DIR = join(homedir(), '.config', 'mt-content-refactor');
const CONNECTIONS_FILE = join(CONFIG_DIR, 'connections.json');
// アクティブな接続を保持
let activeConnectionId: string | null = null;
const clientCache = new Map<string, MTClient>();
/**
* 設定ディレクトリを初期化
*/
async function ensureConfigDir(): Promise<void> {
if (!existsSync(CONFIG_DIR)) {
await mkdir(CONFIG_DIR, { recursive: true });
}
}
/**
* 接続一覧を読み込み
*/
export async function loadConnections(): Promise<MTConnection[]> {
await ensureConfigDir();
if (!existsSync(CONNECTIONS_FILE)) {
return [];
}
const content = await readFile(CONNECTIONS_FILE, 'utf-8');
return JSON.parse(content);
}
/**
* 接続一覧を保存
*/
export async function saveConnections(connections: MTConnection[]): Promise<void> {
await ensureConfigDir();
await writeFile(CONNECTIONS_FILE, JSON.stringify(connections, null, 2));
}
/**
* 接続を追加
*/
export async function addConnection(connection: MTConnection): Promise<void> {
const connections = await loadConnections();
// 同じIDが存在する場合は更新
const existingIndex = connections.findIndex(c => c.id === connection.id);
if (existingIndex >= 0) {
connections[existingIndex] = connection;
} else {
connections.push(connection);
}
await saveConnections(connections);
// キャッシュをクリア
clientCache.delete(connection.id);
}
/**
* 接続を削除
*/
export async function removeConnection(connectionId: string): Promise<boolean> {
const connections = await loadConnections();
const filtered = connections.filter(c => c.id !== connectionId);
if (filtered.length === connections.length) {
return false;
}
await saveConnections(filtered);
// アクティブな接続だった場合はクリア
if (activeConnectionId === connectionId) {
activeConnectionId = null;
}
// キャッシュをクリア
clientCache.delete(connectionId);
return true;
}
/**
* 接続を取得
*/
export async function getConnection(connectionId: string): Promise<MTConnection | null> {
const connections = await loadConnections();
return connections.find(c => c.id === connectionId) || null;
}
/**
* アクティブな接続を設定
*/
export async function setActiveConnection(connectionId: string): Promise<boolean> {
const connection = await getConnection(connectionId);
if (!connection) {
return false;
}
activeConnectionId = connectionId;
return true;
}
/**
* アクティブな接続IDを取得
*/
export function getActiveConnectionId(): string | null {
return activeConnectionId;
}
/**
* MTクライアントを取得
*/
export async function getMTClient(connectionId?: string): Promise<MTClient | null> {
const targetId = connectionId || activeConnectionId;
if (!targetId) {
return null;
}
// キャッシュから取得
if (clientCache.has(targetId)) {
return clientCache.get(targetId)!;
}
const connection = await getConnection(targetId);
if (!connection) {
return null;
}
const client = new MTClient(connection);
clientCache.set(targetId, client);
return client;
}
/**
* アクティブなMTクライアントを取得(必須)
*/
export async function requireMTClient(connectionId?: string): Promise<MTClient> {
const client = await getMTClient(connectionId);
if (!client) {
throw new Error(
connectionId
? `接続 '${connectionId}' が見つかりません`
: 'アクティブな接続がありません。mt_use_connection で接続を選択してください。'
);
}
return client;
}