import { globSync } from "glob"; import MarkdownDocument from "./document.js"; /** * Load documents from an Obsidian vault * @param vaultPath The path to the vault to load * @param ignorePatterns A glob pattern to ignore files for * @returns A promise which resolves as an array of laoded Documents */ function loadVaultDocuments( vaultPath: string, ignorePatterns: string[] = [], ): MarkdownDocument[] { const discoveredMarkdownDocuments = globSync(`${vaultPath}/**/*.md`, { ignore: ignorePatterns, }); const markdownDocuments: MarkdownDocument[] = []; for (const filePath of discoveredMarkdownDocuments) { const file = new MarkdownDocument(filePath, vaultPath); if (markdownDocuments.some((check) => check.slug === file.slug)) { throw new Error("Duplicate slug: " + file.slug); } markdownDocuments.push(file); } return markdownDocuments; } /** * Build a VaultIndex from a list of loaded Documents * @param vaultDocs An array of all the documents to index * @returns A VaultIndex, which is an object that maps document slugs to information */ function buildVaultIndex( vaultDocs: MarkdownDocument[], ): Record { const index: Record = {}; for (const document of vaultDocs) { index[document.slug] = document; } return index; } interface VaultOptions { ignorePatterns?: string[]; } export default class Vault { documents: MarkdownDocument[] = []; slugs: string[] = []; index: Record = {}; readonly vaultPath: string; readonly size: number = 0; private ignorePatterns: string[] = []; constructor(vaultRootPath: string, options?: VaultOptions) { this.vaultPath = vaultRootPath; this.ignorePatterns = options?.ignorePatterns ?? []; const allFiles = loadVaultDocuments(this.vaultPath, this.ignorePatterns); const allSlugs = allFiles.map((doc) => doc.slug); this.documents = allFiles; this.slugs = allSlugs; this.size = allFiles.length; this.index = buildVaultIndex(allFiles); } map(fn: (document: MarkdownDocument) => MarkdownDocument) { this.documents = this.documents.map(fn); return this; } write() { this.documents.forEach((doc) => { doc.write(); }); } }