UNPKG

n8n-nodes-nextcloud-calendar

Version:

n8n Node für die Integration mit Nextcloud Calendar

325 lines 11.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseEventResults = parseEventResults; exports.parseICalEvent = parseICalEvent; function parseICalDate(date) { const year = parseInt(date.substr(0, 4)); const month = parseInt(date.substr(4, 2)) - 1; const day = parseInt(date.substr(6, 2)); if (date.includes('T')) { const hour = parseInt(date.substr(9, 2)); const minute = parseInt(date.substr(11, 2)); const second = parseInt(date.substr(13, 2)); return new Date(Date.UTC(year, month, day, hour, minute, second)); } return new Date(Date.UTC(year, month, day)); } function parseICS(icsData) { const lines = icsData.split('\n').map(line => line.replace(/\r$/, '')); const event = {}; let inEvent = false; for (let i = 0; i < lines.length; i++) { const rawLine = lines[i].trim(); if (rawLine === 'BEGIN:VEVENT') { inEvent = true; continue; } if (rawLine === 'END:VEVENT') { break; } if (!inEvent || rawLine.length === 0) { continue; } const colonIdx = rawLine.indexOf(':'); if (colonIdx === -1) continue; const keyWithParams = rawLine.slice(0, colonIdx); const value = rawLine.slice(colonIdx + 1); const [key, ...paramParts] = keyWithParams.split(';'); const params = {}; for (const part of paramParts) { const idx = part.indexOf('='); if (idx > -1) { const pKey = part.slice(0, idx); const pVal = part.slice(idx + 1); params[pKey] = pVal; } } switch (key) { case 'UID': event.uid = value; break; case 'SUMMARY': event.summary = value; break; case 'DESCRIPTION': event.description = value; break; case 'LOCATION': event.location = value; break; case 'DTSTART': event.start = parseICalDate(value); if (params.TZID) event.tzidStart = params.TZID; break; case 'DTEND': event.end = parseICalDate(value); if (params.TZID) event.tzidEnd = params.TZID; break; case 'CREATED': event.created = parseICalDate(value); break; case 'LAST-MODIFIED': event.lastmodified = parseICalDate(value); break; case 'STATUS': event.status = value; break; case 'DTSTAMP': event.dtstamp = parseICalDate(value); break; case 'SEQUENCE': event.sequence = Number(value); break; case 'TRANSP': event.transparency = value; break; case 'CATEGORIES': event.categories = value.split(',').map(v => v.trim()).filter(Boolean); break; case 'CLASS': event.class = value; break; case 'RRULE': event.rrule = value; break; case 'RECURRENCE-ID': event.recurrenceId = value; break; case 'EXDATE': (event.exdate || (event.exdate = [])).push(value); break; case 'RDATE': (event.rdate || (event.rdate = [])).push(value); break; case 'PRIORITY': event.priority = Number(value); break; case 'DURATION': event.duration = value; break; case 'GEO': { const parts = value.split(';'); if (parts.length === 2) { const lat = Number(parts[0]); const lon = Number(parts[1]); if (!Number.isNaN(lat) && !Number.isNaN(lon)) { event.geo = { latitude: lat, longitude: lon }; } } break; } case 'ATTENDEE': { if (!event.attendee) { event.attendee = []; } const [paramsStr, email] = value.split('mailto:'); const attendee = { val: `mailto:${email}`, params: {} }; if (paramsStr) { paramsStr.split(';').forEach((param) => { const [paramKey, paramValue] = param.split('='); if (paramKey && paramValue) { attendee.params[paramKey] = paramValue; } }); } event.attendee.push(attendee); break; } case 'ORGANIZER': { const [orgParams, orgEmail] = value.split('mailto:'); event.organizer = { val: `mailto:${orgEmail}`, params: {} }; if (orgParams) { if (event.organizer && event.organizer.params) { orgParams.split(';').forEach((param) => { const [paramKey, paramValue] = param.split('='); if (paramKey && paramValue && event.organizer) { event.organizer.params[paramKey] = paramValue; } }); } } break; } default: { if (!event.raw) event.raw = {}; if (event.raw[key]) { const existing = event.raw[key]; if (Array.isArray(existing)) { existing.push(value); } else { event.raw[key] = [existing, value]; } } else { event.raw[key] = value; } break; } } } return { vevent: event }; } function parseEventResults(events) { const eventResults = []; for (const event of events) { const eventData = 'data' in event ? event.data : event.props?.['calendar-data']?._text; if (!eventData) { continue; } const parsedData = parseICS(eventData); const eventInfo = parsedData.vevent; const attendees = []; if (eventInfo.attendee) { const attendeeList = Array.isArray(eventInfo.attendee) ? eventInfo.attendee : eventInfo.attendee ? [eventInfo.attendee] : []; for (const attendee of attendeeList) { const email = attendee?.val?.replace('mailto:', '') ?? ''; const params = attendee?.params || {}; attendees.push({ email, displayName: params.CN, role: params.ROLE || 'REQ-PARTICIPANT', rsvp: params.RSVP === 'TRUE', status: params.PARTSTAT || 'NEEDS-ACTION', }); } } let organizer = { email: '', displayName: '' }; if (eventInfo.organizer && eventInfo.organizer.val) { organizer = { email: eventInfo.organizer.val.replace('mailto:', ''), displayName: eventInfo.organizer.params?.CN ?? '', }; } const url = 'url' in event ? event.url : event.href ?? ''; const etag = 'etag' in event ? event.etag : event.props?.getetag?._text ?? ''; eventResults.push({ url: url || '', etag: etag || '', uid: eventInfo.uid ?? '', title: eventInfo.summary ?? '', start: eventInfo.start?.toISOString(), end: eventInfo.end?.toISOString(), tzidStart: eventInfo.tzidStart, tzidEnd: eventInfo.tzidEnd, dtstamp: eventInfo.dtstamp?.toISOString(), description: eventInfo.description ?? '', location: eventInfo.location ?? '', created: eventInfo.created, lastModified: eventInfo.lastmodified, status: eventInfo.status, sequence: eventInfo.sequence, transparency: eventInfo.transparency, categories: eventInfo.categories, class: eventInfo.class, rrule: eventInfo.rrule, recurrenceId: eventInfo.recurrenceId, exdate: eventInfo.exdate, rdate: eventInfo.rdate, priority: eventInfo.priority, duration: eventInfo.duration, geo: eventInfo.geo, attendees, organizer, rawProperties: eventInfo.raw, }); } return eventResults.sort((a, b) => { const startA = a?.start ?? ''; const startB = b?.start ?? ''; if (startA < startB) { return -1; } else if (startA > startB) { return 1; } else { return 0; } }); } function parseICalEvent(calendarObject) { const icalData = parseICS(calendarObject.data); const event = icalData.vevent; const response = { uid: event.uid ?? '', title: event.summary ?? '', start: event.start?.toISOString(), end: event.end?.toISOString(), tzidStart: event.tzidStart, tzidEnd: event.tzidEnd, dtstamp: event.dtstamp?.toISOString(), description: event.description ?? '', location: event.location ?? '', url: calendarObject.url ?? '', etag: calendarObject.etag ?? '', created: event.created, lastModified: event.lastmodified, status: event.status, sequence: event.sequence, transparency: event.transparency, categories: event.categories, class: event.class, rrule: event.rrule, recurrenceId: event.recurrenceId, exdate: event.exdate, rdate: event.rdate, priority: event.priority, duration: event.duration, geo: event.geo, organizer: event.organizer ? { email: event.organizer.val.replace('mailto:', ''), displayName: event.organizer.params?.CN, } : undefined, attendees: !event.attendee ? undefined : Array.isArray(event.attendee) ? event.attendee.map((a) => ({ email: a.val.replace('mailto:', ''), displayName: a.params?.CN, role: a.params?.ROLE ?? 'REQ-PARTICIPANT', status: a.params?.PARTSTAT ?? 'NEEDS-ACTION', rsvp: a.params?.RSVP === 'TRUE', })) : [{ email: event.attendee.val.replace('mailto:', ''), displayName: event.attendee.params?.CN, role: event.attendee.params?.ROLE ?? 'REQ-PARTICIPANT', status: event.attendee.params?.PARTSTAT ?? 'NEEDS-ACTION', rsvp: event.attendee.params?.RSVP === 'TRUE', }], rawProperties: event.raw, }; return response; } //# sourceMappingURL=parser.js.map