const { readFileSync, writeFileSync, readdirSync, existsSync } = require('node:fs'); const { resolve } = require('node:path'); const VAULT_ROOT = resolve(__dirname, '..', '..'); const PERSONS_DIR = resolve(VAULT_ROOT, '00 Kontext/Personen'); const COMPANIES_DIR = resolve(VAULT_ROOT, '00 Kontext/Firmen'); function parseFrontmatter(content) { const match = content.match(/^---\n([\s\S]*?)\n---/); if (!match) return {}; const fm = {}; for (const line of match[1].split('\n')) { const colonIdx = line.indexOf(':'); if (colonIdx === -1) continue; const key = line.substring(0, colonIdx).trim(); let value = line.substring(colonIdx + 1).trim(); if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { value = value.slice(1, -1); } if (value.startsWith('[') || value.startsWith('{')) continue; fm[key] = value; } return fm; } function loadPersons() { if (!existsSync(PERSONS_DIR)) return []; return readdirSync(PERSONS_DIR) .filter(f => f.endsWith('.md')) .map(file => { const content = readFileSync(resolve(PERSONS_DIR, file), 'utf-8'); return { file, fm: parseFrontmatter(content) }; }); } function loadCompanies() { if (!existsSync(COMPANIES_DIR)) return []; return readdirSync(COMPANIES_DIR) .filter(f => f.endsWith('.md')) .map(file => { const content = readFileSync(resolve(COMPANIES_DIR, file), 'utf-8'); return { file, fm: parseFrontmatter(content) }; }); } function matchAttendeeToPersons(attendee, persons) { const emailMatch = persons.find(p => p.fm.email && p.fm.email.toLowerCase() === attendee.email.toLowerCase() ); if (emailMatch) { return { matched: true, file: emailMatch.file, matchType: 'email' }; } const nameMatch = persons.find(p => { const fullName = `${p.fm.vorname || ''} ${p.fm.nachname || ''}`.trim().toLowerCase(); return fullName && fullName === attendee.name.toLowerCase(); }); if (nameMatch) { return { matched: true, file: nameMatch.file, matchType: 'name' }; } return { matched: false }; } function resolveCompanyFromDomain(email, companies) { const domain = email.split('@')[1]?.toLowerCase(); if (!domain) return ''; const match = companies.find(c => c.fm.domain && c.fm.domain.toLowerCase() === domain ); if (match) { const name = match.file.replace('.md', ''); return `[[00 Kontext/Firmen/${name}]]`; } return domain; } function splitName(displayName) { const parts = displayName.trim().split(/\s+/); if (parts.length === 1) { return { vorname: parts[0], nachname: '' }; } const nachname = parts.pop(); return { vorname: parts.join(' '), nachname }; } function buildNewPersonNote({ name, email, firma }) { const { vorname, nachname } = splitName(name); return `--- tags: [person] vorname: ${vorname} nachname: ${nachname ? nachname : '""'} email: ${email} kategorie: Extern firma: "${firma}" status: ungeprüft --- # ${name} ## Zur Person - **E-Mail:** ${email} - **Firma:** ${firma} ## Notizen `; } function createPersonNote({ name, email }, companies) { const firma = resolveCompanyFromDomain(email, companies); const content = buildNewPersonNote({ name, email, firma }); const { vorname, nachname } = splitName(name); const fileName = nachname ? `${vorname} ${nachname}.md` : `${vorname}.md`; const filePath = resolve(PERSONS_DIR, fileName); if (!existsSync(filePath)) { writeFileSync(filePath, content, 'utf-8'); } return fileName; } function resolveAttendees(attendees) { const persons = loadPersons(); const companies = loadCompanies(); return attendees.map(attendee => { const match = matchAttendeeToPersons(attendee, persons); if (match.matched) { const personName = match.file.replace('.md', ''); return { wikilink: `[[${personName}]]`, name: attendee.name, isNew: false }; } const fileName = createPersonNote(attendee, companies); const personName = fileName.replace('.md', ''); return { wikilink: `[[${personName}]]`, name: attendee.name, isNew: true }; }); } module.exports = { parseFrontmatter, loadPersons, loadCompanies, matchAttendeeToPersons, resolveCompanyFromDomain, buildNewPersonNote, createPersonNote, resolveAttendees };