/* global chrome */
import LRU from "lru-cache";
const gapi_base = 'https://www.googleapis.com/calendar/v3';
const GApiError = {
invalidSyncToken: 1,
otherError: 2,
};
function to_params(dict) {
return Object.entries(dict).filter(([k, v]) => v).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
}
export function getAuthToken() {
return new Promise(resolver =>
chrome.identity.getAuthToken(
{interactive: true}, token => resolver(token)));
}
export function getCalendars(token) {
return fetch(`${gapi_base}/users/me/calendarList?${to_params({access_token: token})}`,
{ method: 'GET', async: true })
.then(response => response.json())
.then(data => data.items);
}
export function getColors(token) {
return fetch(`${gapi_base}/colors?${to_params({access_token: token})}`,
{ method: 'GET', async: true })
.then(response => response.json());
}
function getEvent(calId, eventId, token) {
return fetch(`${gapi_base}/calendars/${calId}/events/${eventId}?${to_params({access_token: token})}`,
{ method: 'GET', async: true })
.then(response => response.json());
}
function getEvents(calId, token, syncToken=null, timeMin=null, timeMax=null, resultsPerRequest=100) {
let results = [];
const singleFetch = (pageToken, syncToken) => fetch(`${gapi_base}/calendars/${calId}/events?${to_params({
access_token: token,
pageToken,
syncToken,
timeMin,
timeMax,
maxResults: resultsPerRequest
})}`, { method: 'GET', async: true })
.then(response => {
if (response.status === 200)
return response.json();
else if (response.status === 410)
throw GApiError.invalidSyncToken;
else throw GApiError.otherErrors;
})
.then(data => {
results.push(...data.items);
if (data.nextPageToken) {
return singleFetch(data.nextPageToken, '');
} else {
return ({
nextSyncToken: data.nextSyncToken,
results
});
}
})
return singleFetch('', syncToken);
}
export class GCalendar {
constructor(calId, name, options={maxCachedItems: 100, nDaysPerSlot: 10, largeQuery: 10}) {
this.calId = calId;
this.name = name;
this.token = getAuthToken();
this.syncToken = '';
this.cache = new LRU({
max: options.maxCachedItems,
dispose: (k, v) => this.onRemoveSlot(k, v)
});
this.eventMeta = {};
this.