mifi / ical-expander

ICS / iCal / iCalendar parser / expander
MIT License
64 stars 21 forks source link
calendar expand ical ics parse range recurring rrule timezone

ical-expander đź“… npm version Test local branches Known Vulnerabilities

ICS / iCal / iCalendar parser / expander.

Wrapper around ical.js that automatically handles EXDATE (excluded recursive occurrences), RRULE and recurring events overridden by RECURRENCE-ID.

Also handles timezones, and includes timezones from the IANA Time Zone Database, so that it parses correctly when a timezone definition is not available in the ICS file itself. zones.json can be found here and compiled by running compile-zones.js.

Be careful as the processing done in this library is synchronous and will block the JS event loop while processing. Especially when processing large ICS files and with high maxIterations values.

Install

npm install ical-expander

⚠️ Warning: This package uses ES6 features, and might require transpiling if used in browsers

Example

Download .ics from google calendar for example.

const IcalExpander = require('ical-expander');
const fs = require('fs');

const ics = fs.readFileSync('./basic.ics', 'utf-8');

const icalExpander = new IcalExpander({ ics, maxIterations: 100 });
const events = icalExpander.between(new Date('2017-01-24T00:00:00.000Z'), new Date('2017-03-30T00:00:00.000Z'));

const mappedEvents = events.events.map(e => ({ startDate: e.startDate, summary: e.summary }));
const mappedOccurrences = events.occurrences.map(o => ({ startDate: o.startDate, summary: o.item.summary }));
const allEvents = [].concat(mappedEvents, mappedOccurrences);

console.log(allEvents.map(e => `${e.startDate.toJSDate().toISOString()} - ${e.summary}`).join('\n'));

Usage

Constructor

const icalExpander = new IcalExpander({ ics, maxIterations })

between()

icalExpander.between(after, before)

Include all events occuring between after and before. i.e. with a start time before before JS Date and an end time after JS Date.

Example of events included between a date range:

range:    ---------- after |-----------------------| before -------------
event 1:                   |          start <------|------------> end
event 2:         start <---|---------------> end   |
event 3:      start <------|-----------------------|--------------> end
event 4:                   |    start <---> end    |                                                   

Example of events not included between a date range:

range:    -------------------- after |--------| before ------------------
event 5:  start <------> end         |        |
event 6:                             |        |          start <---> end

before()

icalExpander.before(before) is an alias for icalExpander.between(undefined, before)

after()

icalExpander.after() is an alias for icalExpander.between(after)

all()

icalExpander.all() is an alias for icalExpander.between()
Do not run this with maxIterations: 0

Return value

All methods return:

{
  events: [],
  occurrences: [],
}

icalExpander.component

Root ICAL.Component from parsed data.

TODO

See also: