UNPKG

calendar-link

Version:

📅 Calendar link generator for popular services, like Google, Outlook, and Yahoo.

290 lines • 9.55 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ics = exports.msTeams = exports.aol = exports.yahoo = exports.office365Mobile = exports.office365 = exports.outlookMobile = exports.outlook = exports.google = exports.eventify = void 0; const dayjs_1 = __importDefault(require("dayjs")); const utc_1 = __importDefault(require("dayjs/plugin/utc")); const utils_1 = require("./utils"); dayjs_1.default.extend(utc_1.default); function stringify(input) { const params = new URLSearchParams(); Object.keys(input) .sort() .forEach((key) => { const value = input[key]; if (value != null) { params.append(key, value); } }); return params.toString().replace(/\+/g, "%20"); } function formatTimes({ startTime, endTime }, dateTimeFormat) { const format = utils_1.TimeFormats[dateTimeFormat]; return { start: startTime.format(format), end: endTime.format(format) }; } const eventify = (event, toUtc = true) => { const { start, end, duration, ...rest } = event; const startTime = toUtc ? (0, dayjs_1.default)(start).utc() : (0, dayjs_1.default)(start); const endTime = end ? toUtc ? (0, dayjs_1.default)(end).utc() : (0, dayjs_1.default)(end) : (() => { if (event.allDay) { return startTime.add(1, "day"); } if (duration && duration.length == 2) { const value = Number(duration[0]); const unit = duration[1]; return startTime.add(value, unit); } return startTime; })(); return { ...rest, startTime: startTime, endTime: endTime, }; }; exports.eventify = eventify; const google = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent); const { start, end } = formatTimes(event, event.allDay ? "allDay" : "dateTimeUTC"); const details = { action: "TEMPLATE", text: event.title, details: event.description, location: event.location, trp: event.busy, dates: start + "/" + end, recur: event.rRule ? "RRULE:" + event.rRule : undefined, }; if (event.guests && event.guests.length) { details.add = event.guests.join(); } return `https://calendar.google.com/calendar/render?${stringify(details)}`; }; exports.google = google; const outlook = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent, false); const { start, end } = formatTimes(event, "dateTimeLocal"); const details = { path: "/calendar/action/compose", rru: "addevent", startdt: start, enddt: end, subject: event.title, body: event.description, location: event.location, allday: event.allDay || false, }; return `https://outlook.live.com/calendar/0/action/compose?${stringify(details)}`; }; exports.outlook = outlook; const outlookMobile = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent, false); const { start, end } = formatTimes(event, "dateTimeLocal"); const details = { path: "/calendar/action/compose", rru: "addevent", startdt: start, enddt: end, subject: event.title, body: event.description, location: event.location, allday: event.allDay || false, }; return `https://outlook.live.com/calendar/0/deeplink/compose?${stringify(details)}`; }; exports.outlookMobile = outlookMobile; const office365 = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent, false); const { start, end } = formatTimes(event, "dateTimeLocal"); const details = { path: "/calendar/action/compose", rru: "addevent", startdt: start, enddt: end, subject: event.title, body: event.description, location: event.location, allday: event.allDay || false, }; return `https://outlook.office.com/calendar/0/action/compose?${stringify(details)}`; }; exports.office365 = office365; const office365Mobile = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent, false); const { start, end } = formatTimes(event, "dateTimeLocal"); const details = { path: "/calendar/action/compose", rru: "addevent", startdt: start, enddt: end, subject: event.title, body: event.description, location: event.location, allday: event.allDay || false, }; return `https://outlook.office.com/calendar/0/deeplink/compose?${stringify(details)}`; }; exports.office365Mobile = office365Mobile; const yahoo = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent); const { start, end } = formatTimes(event, event.allDay ? "allDay" : "dateTimeUTC"); const details = { v: 60, title: event.title, st: start, et: end, desc: event.description, in_loc: event.location, dur: event.allDay ? "allday" : false, }; return `https://calendar.yahoo.com/?${stringify(details)}`; }; exports.yahoo = yahoo; const aol = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent); const { start, end } = formatTimes(event, event.allDay ? "allDay" : "dateTimeUTC"); const details = { v: 60, title: event.title, st: start, et: end, desc: event.description, in_loc: event.location, dur: event.allDay ? "allday" : false, }; return `https://calendar.aol.com/?${stringify(details)}`; }; exports.aol = aol; // https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/deep-link-workflow?tabs=teamsjs-v2#configure-deep-link-manually-to-open-a-meeting-scheduling-dialog const msTeams = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent); const details = { subject: event.title, content: event.description, startTime: event.startTime.toISOString(), endTime: event.endTime.toISOString(), }; if (event.guests && event.guests.length) { details.attendees = event.guests.join(); } return `https://teams.microsoft.com/l/meeting/new?${stringify(details)}`; }; exports.msTeams = msTeams; const ics = (calendarEvent) => { const event = (0, exports.eventify)(calendarEvent); const formattedDescription = (event.description || "") .replace(/,/gm, ",") .replace(/;/gm, ";") .replace(/\r\n/gm, "\n") .replace(/\n/gm, "\\n") .replace(/(\\n)[\s\t]+/gm, "\\n"); const formattedLocation = (event.location || "") .replace(/,/gm, ",") .replace(/;/gm, ";") .replace(/\r\n/gm, "\n") .replace(/\n/gm, "\\n") .replace(/(\\n)[\s\t]+/gm, "\\n"); const { start, end } = formatTimes(event, event.allDay ? "allDay" : "dateTimeUTC"); const dateStamp = (0, dayjs_1.default)(new Date()).utc().format(utils_1.TimeFormats["dateTimeUTC"]); const calendarChunks = [ { key: "BEGIN", value: "VCALENDAR", }, { key: "VERSION", value: "2.0", }, { key: "PRODID", value: "-//AnandChowdhary//calendar-link//EN" }, { key: "BEGIN", value: "VEVENT", }, { key: "URL", value: event.url, }, { key: "DTSTART", value: start, }, { key: "DTEND", value: end, }, { key: "DTSTAMP", value: dateStamp, }, ...(event.allDay ? [ { key: "X-MICROSOFT-CDO-ALLDAYEVENT", value: "TRUE" }, { key: "X-MICROSOFT-MSNCALENDAR-ALLDAYEVENT", value: "TRUE" } ] : []), { key: "RRULE", value: event.rRule, }, { key: "SUMMARY", value: event.title, }, { key: "DESCRIPTION", value: formattedDescription, }, { key: "LOCATION", value: formattedLocation, }, { key: "ORGANIZER", value: event.organizer, }, { key: "STATUS", value: event.status, }, { key: "UID", value: event.uid || Math.floor(Math.random() * 100000).toString().replace(".", ""), }, { key: "END", value: "VEVENT", }, { key: "END", value: "VCALENDAR", }, ]; let calendarUrl = ""; calendarChunks.forEach((chunk) => { if (chunk.value) { if (chunk.key == "ORGANIZER") { const value = chunk.value; calendarUrl += `${chunk.key};${encodeURIComponent(`CN=${value.name}:MAILTO:${value.email}\r\n`)}`; } else { calendarUrl += `${chunk.key}:${encodeURIComponent(`${chunk.value}\r\n`)}`; } } }); return `data:text/calendar;charset=utf8,${calendarUrl}`; }; exports.ics = ics; //# sourceMappingURL=index.js.map