UNPKG

gcal-commander

Version:

A command-line interface for Google Calendar operations

148 lines (147 loc) 5.76 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CalendarService = void 0; const googleapis_1 = require("googleapis"); const promises_1 = require("node:fs/promises"); const tsyringe_1 = require("tsyringe"); const tokens_1 = require("../di/tokens"); const paths_1 = require("../utils/paths"); let CalendarService = class CalendarService { authService; calendar = null; hasReauthenticated = false; constructor(authService) { this.authService = authService; } async createEvent(params) { return this.withRetryOnScopeError(async () => { await this.ensureInitialized(); const eventResource = { description: params.description, end: params.end, location: params.location, start: params.start, summary: params.summary, }; if (params.attendees?.length) { eventResource.attendees = params.attendees.map((email) => ({ email })); } try { const response = await this.calendar.events.insert({ calendarId: params.calendarId, requestBody: eventResource, sendUpdates: params.sendUpdates || 'none', }); return response.data; } catch (error) { throw new Error(`Failed to create event: ${error}`); } }); } async getEvent(eventId, calendarId = 'primary') { return this.withRetryOnScopeError(async () => { await this.ensureInitialized(); try { const response = await this.calendar.events.get({ calendarId, eventId, }); return response.data; } catch (error) { throw new Error(`Failed to get event: ${error}`); } }); } async listCalendars() { return this.withRetryOnScopeError(async () => { await this.ensureInitialized(); try { const response = await this.calendar.calendarList.list(); return response.data.items || []; } catch (error) { throw new Error(`Failed to list calendars: ${error}`); } }); } async listEvents(params) { return this.withRetryOnScopeError(async () => { await this.ensureInitialized(); const { calendarId, maxResults, timeMax, timeMin } = params; try { const response = await this.calendar.events.list({ calendarId, maxResults, orderBy: 'startTime', singleEvents: true, timeMax, timeMin, }); return response.data.items || []; } catch (error) { throw new Error(`Failed to list events: ${error}`); } }); } async deleteTokenAndReinitialize() { const TOKEN_PATH = paths_1.AppPaths.getTokenPath(); try { await (0, promises_1.unlink)(TOKEN_PATH); // Token deleted, will re-authenticate with updated permissions } catch { // Token file might not exist, which is fine } this.calendar = null; this.hasReauthenticated = true; await this.ensureInitialized(); } async ensureInitialized() { if (!this.calendar) { const auth = await this.authService.getCalendarAuth(); this.calendar = googleapis_1.google.calendar({ auth: auth.client, version: 'v3' }); } } isScopeError(error) { const errorString = String(error); return (errorString.includes('insufficient authentication scopes') || errorString.includes('Request had insufficient authentication scopes') || errorString.includes('access_denied') || errorString.includes('scope') || errorString.includes('401') || errorString.includes('403')); } async withRetryOnScopeError(operation) { try { return await operation(); } catch (error) { if (this.isScopeError(error) && !this.hasReauthenticated) { await this.deleteTokenAndReinitialize(); return operation(); } throw error; } } }; exports.CalendarService = CalendarService; exports.CalendarService = CalendarService = __decorate([ (0, tsyringe_1.injectable)(), __param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.AuthService)), __metadata("design:paramtypes", [Object]) ], CalendarService);