import { Config, VaultInfo } from '../utils/types.js';
import { CredentialManager } from '../security/credential-manager.js';
import fs from 'fs-extra';
import path from 'path';
import { glob } from 'glob';
export class VaultManager {
constructor(
_config: Config,
private credentialManager: CredentialManager
) {}
async discoverVaults(basePath: string): Promise<VaultInfo[]> {
const vaults: VaultInfo[] = [];
try {
const entries = await fs.readdir(basePath, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const vaultPath = path.join(basePath, entry.name);
if (await this.isValidVault(vaultPath)) {
const info = await this.getVaultInfo(vaultPath);
vaults.push(info);
}
}
}
} catch (error) {
console.error(`Failed to discover vaults in ${basePath}:`, error);
}
return vaults;
}
async getVaultInfo(vaultPath: string): Promise<VaultInfo> {
const hasRestApi = await this.credentialManager.hasRestAPI(vaultPath);
let pluginVersion: string | undefined;
if (hasRestApi) {
const creds = await this.credentialManager.getVaultCredentials(vaultPath);
pluginVersion = creds?.pluginVersion;
}
// Count markdown files
let fileCount: number | undefined;
try {
const files = await glob('**/*.md', {
cwd: vaultPath,
ignore: ['**/.obsidian/**'],
});
fileCount = files.length;
} catch {
// Ignore error
}
return {
name: path.basename(vaultPath),
path: vaultPath,
hasRestApi,
pluginVersion,
fileCount,
};
}
async isValidVault(vaultPath: string): Promise<boolean> {
try {
const obsidianDir = path.join(vaultPath, '.obsidian');
const stats = await fs.stat(obsidianDir);
return stats.isDirectory();
} catch {
return false;
}
}
}