@corsair-dev/googlecalendar 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyBhC,CAAC;AAEX,QAAA,MAAM,4BAA4B;;;;;;;;;;;;;;;;;CAExB,CAAC;AAEX,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,4BAA4B,CAAC,OAAO,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,4BAA4B,CAAC,cAAc,CAAC,CAAC;IAC5D;;;;OAIG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAC,OAAO,6BAA6B,CAAC,CAAC;CAC5E,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAC1C,iBAAiB,CAAC,2BAA2B,CAAC,CAAC;AAUhD,QAAA,MAAM,eAAe,EAAG,SAAkB,CAAC;AA8B3C,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,2BAA2B,IACzE,aAAa,CACZ,gBAAgB,EAChB,OAAO,oBAAoB,EAC3B,OAAO,6BAA6B,EACpC,OAAO,4BAA4B,EACnC,CAAC,EACD,OAAO,eAAe,CACtB,CAAC;AAEH,MAAM,MAAM,4BAA4B,GACvC,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;AAEvD,MAAM,MAAM,4BAA4B,CACvC,CAAC,SAAS,2BAA2B,IAClC,wBAAwB,CAAC,CAAC,CAAC,CAAC;AAEhC,wBAAgB,cAAc,CAAC,KAAK,CAAC,CAAC,SAAS,2BAA2B,EACzE,eAAe,GAAE,2BAA2B,GAC3C,CAAyC,GACxC,4BAA4B,CAAC,CAAC,CAAC,CAkHjC;AAMD,YAAY,EACX,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,4BAA4B,EAC5B,4BAA4B,EAC5B,aAAa,EACb,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,kCAAkC,EAClC,mBAAmB,GACnB,MAAM,kBAAkB,CAAC;AAM1B,YAAY,EACX,4BAA4B,EAC5B,mCAAmC,EACnC,6BAA6B,GAC7B,MAAM,mBAAmB,CAAC;AAE3B,mBAAmB,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{request as J}from"corsair/http";var G=class extends Error{constructor(r,a){super(r);this.code=a;this.name="GoogleCalendarAPIError"}},Q="https://www.googleapis.com/calendar/v3";async function X(t,n,r){let a=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:t,client_secret:n,refresh_token:r,grant_type:"refresh_token"})});if(!a.ok){let p=await a.text();throw new G(`Failed to refresh access token: ${p}`,a.status)}return await a.json()}async function k({accessToken:t,expiresAt:n,clientId:r,clientSecret:a,refreshToken:s,forceRefresh:p=!1}){let d=Math.floor(Date.now()/1e3);if(!p&&t&&n&&Number(n)>d+300)return{accessToken:t,expiresAt:Number(n),refreshed:!1};let c=await X(r,a,s);return{accessToken:c.access_token,expiresAt:d+c.expires_in,refreshed:!0}}async function h(t,n,r={}){let{method:a="GET",body:s,query:p}=r;return await J({BASE:Q,VERSION:"1.0.0",WITH_CREDENTIALS:!1,CREDENTIALS:"omit",TOKEN:n,HEADERS:{"Content-Type":"application/json"}},{method:a,url:t,body:a==="POST"||a==="PUT"||a==="PATCH"?s:void 0,mediaType:"application/json",query:p})}function ee(t){return t instanceof Error&&"status"in t&&t.status===401}async function u(t,n,r={}){try{return await h(t,n.key,r)}catch(a){if(ee(a)&&n._refreshAuth){let s=await n._refreshAuth();return await h(t,s,r)}throw a}}import{logEventFromContext as te}from"corsair/core";var x=async(t,n)=>{let r=await u("/freeBusy",t,{method:"POST",body:{timeMin:n.timeMin,timeMax:n.timeMax,timeZone:n.timeZone,groupExpansionMax:n.groupExpansionMax,calendarExpansionMax:n.calendarExpansionMax,items:n.items}});return await te(t,"googlecalendar.calendar.getAvailability",{...n},"completed"),r};import{logEventFromContext as E}from"corsair/core";var P=async(t,n)=>{let r=n.calendarId||"primary",a=await u(`/calendars/${r}/events`,t,{method:"POST",body:n.event});if(a.id&&t.db.events)try{await t.db.events.upsertByEntityId(a.id,{...a,id:a.id,calendarId:r,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await E(t,"googlecalendar.events.create",{...n},"completed"),a},A=async(t,n)=>{let r=n.calendarId||"primary",a=await u(`/calendars/${r}/events/${n.id}`,t,{method:"GET",query:{timeZone:n.timeZone,maxAttendees:n.maxAttendees}});if(a.id&&t.db.events)try{await t.db.events.upsertByEntityId(a.id,{...a,id:a.id,calendarId:r,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await E(t,"googlecalendar.events.get",{...n},"completed"),a},D=async(t,n)=>{let r=n.calendarId||"primary",a=await u(`/calendars/${r}/events`,t,{method:"GET",query:n});if(a.items&&t.db.events)try{for(let s of a.items)s.id&&await t.db.events.upsertByEntityId(s.id,{...s,id:s.id,calendarId:r,createdAt:new Date})}catch(s){console.warn("Failed to save events to database:",s)}return await E(t,"googlecalendar.events.getMany",{...n},"completed"),a},O=async(t,n)=>{let r=n.calendarId||"primary",a=await u(`/calendars/${r}/events/${n.id}`,t,{method:"PUT",body:n.event,query:{sendUpdates:n.sendUpdates,sendNotifications:n.sendNotifications,conferenceDataVersion:n.conferenceDataVersion,maxAttendees:n.maxAttendees,supportsAttachments:n.supportsAttachments}});if(a.id&&t.db.events)try{await t.db.events.upsertByEntityId(a.id,{...a,id:a.id,calendarId:r,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await E(t,"googlecalendar.events.update",{...n},"completed"),a},R=async(t,n)=>{let r=n.calendarId||"primary";if(await u(`/calendars/${r}/events/${n.id}`,t,{method:"DELETE",query:{sendUpdates:n.sendUpdates,sendNotifications:n.sendNotifications}}),t.db.events)try{await t.db.events.deleteByEntityId(n.id)}catch(a){console.warn("Failed to delete event from database:",a)}await E(t,"googlecalendar.events.delete",{...n},"completed")};import{z as e}from"zod";var f=e.object({date:e.string().optional().describe('All-day event date in "YYYY-MM-DD" format'),dateTime:e.string().optional().describe('RFC 3339 timestamp, e.g. "2024-12-25T10:00:00-07:00". Required for timed events.'),timeZone:e.string().optional().describe('IANA time zone name, e.g. "America/New_York"')}),N=e.object({id:e.string().optional(),email:e.string().optional().describe("Attendee's email address. Required when adding an attendee."),displayName:e.string().optional(),organizer:e.boolean().optional(),self:e.boolean().optional(),resource:e.boolean().optional(),optional:e.boolean().optional(),responseStatus:e.enum(["needsAction","declined","tentative","accepted"]).optional(),comment:e.string().optional(),additionalGuests:e.number().optional()}),M=e.object({id:e.string().optional(),email:e.string().optional(),displayName:e.string().optional(),self:e.boolean().optional()}),U=e.object({method:e.enum(["email","popup"]).optional(),minutes:e.number().optional()}),_=e.object({useDefault:e.boolean().optional().describe("Use the calendar default reminders"),overrides:e.array(U).optional().describe("Custom reminders. Only used when useDefault is false.")}),W=e.object({summary:e.string().optional().describe("Title of the event"),description:e.string().optional().describe("Description of the event. HTML is supported."),location:e.string().optional().describe("Geographic location of the event as free-form text"),start:f.optional().describe('Start time. Use "date" for all-day events, "dateTime" for timed events.'),end:f.optional().describe('End time. Use "date" for all-day events, "dateTime" for timed events.'),attendees:e.array(N).optional().describe("List of attendees. Each attendee must include an email."),recurrence:e.array(e.string()).optional().describe('RRULE / EXDATE lines per RFC 5545, e.g. ["RRULE:FREQ=WEEKLY;COUNT=5"]'),colorId:e.string().optional().describe("Color ID (1\u201311). Use the colors endpoint to see options."),transparency:e.enum(["opaque","transparent"]).optional().describe('"opaque" blocks time on the calendar (default); "transparent" does not'),visibility:e.enum(["default","public","private","confidential"]).optional(),eventType:e.enum(["default","outOfOffice","focusTime","workingLocation"]).optional(),status:e.enum(["confirmed","tentative","cancelled"]).optional(),reminders:_.optional(),guestsCanModify:e.boolean().optional(),guestsCanInviteOthers:e.boolean().optional(),guestsCanSeeOtherGuests:e.boolean().optional(),anyoneCanAddSelf:e.boolean().optional(),sequence:e.number().optional().describe("Sequence number for recurring event updates"),originalStartTime:f.optional().describe("Original start time for a recurring event instance"),recurringEventId:e.string().optional().describe("ID of the recurring event this instance belongs to")}),ae=e.object({calendarId:e.string().optional().describe('Calendar ID. Defaults to "primary".'),event:W.describe('Event body. Provide at minimum "summary", "start", and "end".'),sendUpdates:e.enum(["all","externalOnly","none"]).optional(),sendNotifications:e.boolean().optional(),conferenceDataVersion:e.number().optional(),maxAttendees:e.number().optional(),supportsAttachments:e.boolean().optional()}),re=e.object({calendarId:e.string().optional(),id:e.string(),timeZone:e.string().optional(),maxAttendees:e.number().optional()}),ie=e.object({calendarId:e.string().optional(),timeMin:e.string().optional(),timeMax:e.string().optional(),timeZone:e.string().optional(),updatedMin:e.string().optional(),singleEvents:e.boolean().optional(),maxResults:e.number().optional(),pageToken:e.string().optional(),q:e.string().optional(),orderBy:e.enum(["startTime","updated"]).optional(),iCalUID:e.string().optional(),showDeleted:e.boolean().optional(),showHiddenInvitations:e.boolean().optional()}),se=e.object({calendarId:e.string().optional().describe('Calendar ID. Defaults to "primary".'),id:e.string().describe("Event ID to update"),event:W.describe("Updated event fields"),sendUpdates:e.enum(["all","externalOnly","none"]).optional(),sendNotifications:e.boolean().optional(),conferenceDataVersion:e.number().optional(),maxAttendees:e.number().optional(),supportsAttachments:e.boolean().optional()}),le=e.object({calendarId:e.string().optional(),id:e.string(),sendUpdates:e.enum(["all","externalOnly","none"]).optional(),sendNotifications:e.boolean().optional()}),de=e.object({timeMin:e.string(),timeMax:e.string(),timeZone:e.string().optional(),groupExpansionMax:e.number().optional(),calendarExpansionMax:e.number().optional(),items:e.array(e.object({id:e.string()})).optional()}),m={eventsCreate:ae,eventsGet:re,eventsGetMany:ie,eventsUpdate:se,eventsDelete:le,calendarGetAvailability:de},C=e.object({id:e.string().optional(),status:e.enum(["confirmed","tentative","cancelled"]).optional(),htmlLink:e.string().optional(),created:e.string().optional(),updated:e.string().optional(),summary:e.string().optional(),description:e.string().optional(),location:e.string().optional(),colorId:e.string().optional(),creator:M.optional(),organizer:M.optional(),start:f.optional(),end:f.optional(),endTimeUnspecified:e.boolean().optional(),recurrence:e.array(e.string()).optional(),recurringEventId:e.string().optional(),originalStartTime:f.optional(),transparency:e.enum(["opaque","transparent"]).optional(),visibility:e.enum(["default","public","private","confidential"]).optional(),iCalUID:e.string().optional(),sequence:e.number().optional(),attendees:e.array(N).optional(),attendeesOmitted:e.boolean().optional(),hangoutLink:e.string().optional(),reminders:_.optional(),anyoneCanAddSelf:e.boolean().optional(),guestsCanInviteOthers:e.boolean().optional(),guestsCanModify:e.boolean().optional(),guestsCanSeeOtherGuests:e.boolean().optional(),privateCopy:e.boolean().optional(),locked:e.boolean().optional(),eventType:e.enum(["default","outOfOffice","focusTime","workingLocation"]).optional()}),pe=e.object({kind:e.string().optional(),etag:e.string().optional(),summary:e.string().optional(),description:e.string().optional(),updated:e.string().optional(),timeZone:e.string().optional(),accessRole:e.string().optional(),defaultReminders:e.array(U).optional(),nextPageToken:e.string().optional(),nextSyncToken:e.string().optional(),items:e.array(C).optional()}),ce=e.object({busy:e.array(e.object({start:e.string().optional(),end:e.string().optional()})).optional(),errors:e.array(e.object({domain:e.string().optional(),reason:e.string().optional()})).optional()}),ue=e.object({kind:e.string().optional(),calendars:e.record(e.string(),ce).optional(),groups:e.record(e.string(),e.object({calendars:e.array(e.string()).optional(),errors:e.array(e.object({domain:e.string().optional(),reason:e.string().optional()})).optional()})).optional(),timeMin:e.string().optional(),timeMax:e.string().optional()}),v={eventsCreate:C,eventsGet:C,eventsGetMany:pe,eventsUpdate:C,eventsDelete:e.void(),calendarGetAvailability:ue};var y={create:P,get:A,getMany:D,update:O,delete:R},j={getAvailability:x};import{z as o}from"zod";var S=o.object({date:o.string().optional(),dateTime:o.string().optional(),timeZone:o.string().optional()}),ge=o.object({id:o.string().optional(),email:o.string().optional(),displayName:o.string().optional(),organizer:o.boolean().optional(),self:o.boolean().optional(),resource:o.boolean().optional(),optional:o.boolean().optional(),responseStatus:o.enum(["needsAction","declined","tentative","accepted"]).optional(),comment:o.string().optional(),additionalGuests:o.number().optional()}),q=o.object({id:o.string().optional(),email:o.string().optional(),displayName:o.string().optional(),self:o.boolean().optional()}),me=o.object({method:o.enum(["email","popup"]).optional(),minutes:o.number().optional()}),ve=o.object({useDefault:o.boolean().optional(),overrides:o.array(me).optional()}),B=o.object({id:o.string(),status:o.enum(["confirmed","tentative","cancelled"]).optional(),htmlLink:o.string().optional(),created:o.string().optional(),updated:o.string().optional(),summary:o.string().optional(),description:o.string().optional(),location:o.string().optional(),colorId:o.string().optional(),creator:q.optional(),organizer:q.optional(),start:S.optional(),end:S.optional(),endTimeUnspecified:o.boolean().optional(),recurrence:o.array(o.string()).optional(),recurringEventId:o.string().optional(),originalStartTime:S.optional(),transparency:o.enum(["opaque","transparent"]).optional(),visibility:o.enum(["default","public","private","confidential"]).optional(),iCalUID:o.string().optional(),sequence:o.number().optional(),attendees:o.array(ge).optional(),attendeesOmitted:o.boolean().optional(),hangoutLink:o.string().optional(),reminders:ve.optional(),anyoneCanAddSelf:o.boolean().optional(),guestsCanInviteOthers:o.boolean().optional(),guestsCanModify:o.boolean().optional(),guestsCanSeeOtherGuests:o.boolean().optional(),privateCopy:o.boolean().optional(),locked:o.boolean().optional(),eventType:o.enum(["default","outOfOffice","focusTime","workingLocation"]).optional(),calendarId:o.string().optional(),createdAt:o.coerce.date().optional()}),L=o.object({id:o.string(),summary:o.string().optional(),description:o.string().optional(),location:o.string().optional(),timeZone:o.string().optional(),createdAt:o.coerce.date().optional()});var z={version:"1.0.0",entities:{events:B,calendars:L}};import{logEventFromContext as T}from"corsair/core";import{z as i}from"zod";var fe=i.object({data:i.string().optional(),attributes:i.record(i.string()).optional(),messageId:i.string().optional(),publishTime:i.string().optional()}),F=i.object({message:fe.optional(),subscription:i.string().optional(),event:i.unknown().optional()}),Ye=i.object({resourceId:i.string().optional(),resourceState:i.string().optional(),resourceUri:i.string().optional(),channelId:i.string().optional(),channelExpiration:i.string().optional(),channelToken:i.string().optional(),changed:i.string().optional()}),ye=i.object({type:i.literal("eventCreated"),calendarId:i.string(),event:i.custom(),timestamp:i.string()}),be=i.object({type:i.literal("eventUpdated"),calendarId:i.string(),event:i.custom(),timestamp:i.string()}),he=i.object({type:i.literal("eventDeleted"),calendarId:i.string(),eventId:i.string(),timestamp:i.string()}),K=i.union([ye,be,he]);function b(t){let n=Buffer.from(t,"base64").toString("utf-8");return JSON.parse(n)}function w(t){return n=>{let r=n.body;if(!r.message?.data)return!1;try{let a=b(r.message.data);return!!a.channelId&&!!a.resourceId&&!!a.resourceUri&&a.resourceUri.includes("/calendar/")}catch{return!1}}}var Ee=/\/calendars\/([^\/\?]+)/,Ce=/\/calendars\/[^\/]+\/events\/([^\/\?]+)/,Ge=120*1e3,ke=5e3;function Se(t){return{calendarId:t.match(Ee)?.[1],eventId:t.match(Ce)?.[1]}}function we(t){return!t.created||!t.updated?!1:Math.abs(new Date(t.updated).getTime()-new Date(t.created).getTime())<ke}function Te(t,n,r){return h(`/calendars/${n}/events/${r}`,t,{method:"GET"})}async function H(t,n){let r=new Date(Date.now()-Ge).toISOString();return(await h(`/calendars/${n}/events`,t,{method:"GET",query:{maxResults:10,orderBy:"updated",updatedMin:r,showDeleted:!0}})).items??[]}async function Ie(t,n,r){return r?Te(t,n,r):(await H(t,n)).at(-1)??null}async function xe(t,n,r,a){return r||((await H(t,n)).find(d=>d.status==="cancelled")?.id??a.resourceId??"")}async function $(t,n,r){r&&t.db.events&&await t.db.events.deleteByEntityId(r);let a={type:"eventDeleted",calendarId:n,eventId:r,timestamp:new Date().toISOString()};return await T(t,"googlecalendar.webhook.eventDeleted",{...a},"completed"),{eventData:a}}var V={match:w("eventChanged"),handler:async(t,n)=>{let r=n.payload;if(!r.message?.data)return{success:!1,error:"No message data in notification"};let a=b(r.message.data);if(!a.resourceUri)return{success:!1,error:"Invalid push notification format"};let{calendarId:s,eventId:p}=Se(a.resourceUri);if(!s)return{success:!1,error:"Could not parse calendar ID from resource URI"};let d=t.key;try{if(a.resourceState==="not_exists"){let g=await xe(d,s,p,a),{eventData:Y}=await $(t,s,g);return{success:!0,data:Y}}let l=await Ie(d,s,p);if(!l)return{success:!1,error:"No recently updated events found in calendar"};if(l.status==="cancelled"){let{eventData:g}=await $(t,s,l.id??"");return{success:!0,data:g}}let c="";if(l.id&&t.db.events&&(c=(await t.db.events.upsertByEntityId(l.id,{...l,id:l.id,calendarId:s,createdAt:new Date}))?.id??""),we(l)){let g={type:"eventCreated",calendarId:s,event:l,timestamp:new Date().toISOString()};return await T(t,"googlecalendar.webhook.eventCreated",{...g},"completed"),{success:!0,corsairEntityId:c,data:g}}let I={type:"eventUpdated",calendarId:s,event:l,timestamp:new Date().toISOString()};return await T(t,"googlecalendar.webhook.eventUpdated",{...I},"completed"),{success:!0,corsairEntityId:c,data:I}}catch(l){return console.error("Failed to process webhook:",l),{success:!1,error:`Failed to process event: ${l instanceof Error?l.message:"Unknown error"}`}}}};var Z={onEventChanged:V};var Pe={events:{create:y.create,get:y.get,getMany:y.getMany,update:y.update,delete:y.delete},calendar:{getAvailability:j.getAvailability}},Ae={"events.create":{input:m.eventsCreate,output:v.eventsCreate},"events.get":{input:m.eventsGet,output:v.eventsGet},"events.getMany":{input:m.eventsGetMany,output:v.eventsGetMany},"events.update":{input:m.eventsUpdate,output:v.eventsUpdate},"events.delete":{input:m.eventsDelete,output:v.eventsDelete},"calendar.getAvailability":{input:m.calendarGetAvailability,output:v.calendarGetAvailability}},De={onEventChanged:Z.onEventChanged},Oe={onEventChanged:{description:"A Google Calendar event was created, updated, or deleted",payload:F,response:K}},Re="oauth_2",Me={"events.create":{riskLevel:"write",description:"Create a new calendar event"},"events.get":{riskLevel:"read",description:"Get a specific calendar event"},"events.getMany":{riskLevel:"read",description:"List calendar events"},"events.update":{riskLevel:"write",description:"Update an existing calendar event"},"events.delete":{riskLevel:"destructive",description:"Delete a calendar event [DESTRUCTIVE]"},"calendar.getAvailability":{riskLevel:"read",description:"Get free/busy availability for a calendar"}};function ct(t={}){let n={...t,authType:t.authType??Re};return{id:"googlecalendar",schema:z,options:n,oauthConfig:{providerName:"Google",authUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/calendar"],authParams:{access_type:"offline",prompt:"consent"}},hooks:n.hooks,webhookHooks:n.webhookHooks,endpoints:Pe,webhooks:De,endpointMeta:Me,endpointSchemas:Ae,webhookSchemas:Oe,keyBuilder:async r=>{if(n.key)return n.key;if(r.authType==="oauth_2"){let[a,s,p]=await Promise.all([r.keys.get_access_token(),r.keys.get_expires_at(),r.keys.get_refresh_token()]);if(!p)throw new Error("[corsair:googlecalendar] No refresh token. Cannot get access token.");let d=await r.keys.get_integration_credentials();if(!d.client_id||!d.client_secret)throw new Error("[corsair:googlecalendar] No client id or client secret");try{let l=await k({accessToken:a,expiresAt:s,refreshToken:p,clientId:d.client_id,clientSecret:d.client_secret});return l.refreshed&&await Promise.all([r.keys.set_access_token(l.accessToken),r.keys.set_expires_at(String(l.expiresAt))]),r._refreshAuth=async()=>{let c=await k({accessToken:null,expiresAt:null,refreshToken:p,clientId:d.client_id,clientSecret:d.client_secret,forceRefresh:!0});return await r.keys.set_access_token(c.accessToken),await r.keys.set_expires_at(String(c.expiresAt)),c.accessToken},l.accessToken}catch(l){throw console.error("[corsair:googlecalendar] Failed to get valid access token:",l),l}}return""},pluginWebhookMatcher:r=>{let a=r.headers;if(!(a.from==="noreply@google.com"||typeof a["user-agent"]=="string"&&a["user-agent"].includes("APIs-Google")))return!1;let p=r.body;if(!p?.message?.data)return!1;try{let d=b(p.message.data);return!!d.resourceUri&&d.resourceUri.includes("calendar")}catch{return!1}}}}export{w as createGoogleCalendarWebhookMatcher,b as decodePubSubMessage,ct as googlecalendar,Ae as googlecalendarEndpointSchemas};
@@ -0,0 +1,333 @@
1
+ import { z } from 'zod';
2
+ export declare const GoogleCalendarEvent: z.ZodObject<{
3
+ id: z.ZodString;
4
+ status: z.ZodOptional<z.ZodEnum<["confirmed", "tentative", "cancelled"]>>;
5
+ htmlLink: z.ZodOptional<z.ZodString>;
6
+ created: z.ZodOptional<z.ZodString>;
7
+ updated: z.ZodOptional<z.ZodString>;
8
+ summary: z.ZodOptional<z.ZodString>;
9
+ description: z.ZodOptional<z.ZodString>;
10
+ location: z.ZodOptional<z.ZodString>;
11
+ colorId: z.ZodOptional<z.ZodString>;
12
+ creator: z.ZodOptional<z.ZodObject<{
13
+ id: z.ZodOptional<z.ZodString>;
14
+ email: z.ZodOptional<z.ZodString>;
15
+ displayName: z.ZodOptional<z.ZodString>;
16
+ self: z.ZodOptional<z.ZodBoolean>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ id?: string | undefined;
19
+ email?: string | undefined;
20
+ displayName?: string | undefined;
21
+ self?: boolean | undefined;
22
+ }, {
23
+ id?: string | undefined;
24
+ email?: string | undefined;
25
+ displayName?: string | undefined;
26
+ self?: boolean | undefined;
27
+ }>>;
28
+ organizer: z.ZodOptional<z.ZodObject<{
29
+ id: z.ZodOptional<z.ZodString>;
30
+ email: z.ZodOptional<z.ZodString>;
31
+ displayName: z.ZodOptional<z.ZodString>;
32
+ self: z.ZodOptional<z.ZodBoolean>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ id?: string | undefined;
35
+ email?: string | undefined;
36
+ displayName?: string | undefined;
37
+ self?: boolean | undefined;
38
+ }, {
39
+ id?: string | undefined;
40
+ email?: string | undefined;
41
+ displayName?: string | undefined;
42
+ self?: boolean | undefined;
43
+ }>>;
44
+ start: z.ZodOptional<z.ZodObject<{
45
+ date: z.ZodOptional<z.ZodString>;
46
+ dateTime: z.ZodOptional<z.ZodString>;
47
+ timeZone: z.ZodOptional<z.ZodString>;
48
+ }, "strip", z.ZodTypeAny, {
49
+ date?: string | undefined;
50
+ dateTime?: string | undefined;
51
+ timeZone?: string | undefined;
52
+ }, {
53
+ date?: string | undefined;
54
+ dateTime?: string | undefined;
55
+ timeZone?: string | undefined;
56
+ }>>;
57
+ end: z.ZodOptional<z.ZodObject<{
58
+ date: z.ZodOptional<z.ZodString>;
59
+ dateTime: z.ZodOptional<z.ZodString>;
60
+ timeZone: z.ZodOptional<z.ZodString>;
61
+ }, "strip", z.ZodTypeAny, {
62
+ date?: string | undefined;
63
+ dateTime?: string | undefined;
64
+ timeZone?: string | undefined;
65
+ }, {
66
+ date?: string | undefined;
67
+ dateTime?: string | undefined;
68
+ timeZone?: string | undefined;
69
+ }>>;
70
+ endTimeUnspecified: z.ZodOptional<z.ZodBoolean>;
71
+ recurrence: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
72
+ recurringEventId: z.ZodOptional<z.ZodString>;
73
+ originalStartTime: z.ZodOptional<z.ZodObject<{
74
+ date: z.ZodOptional<z.ZodString>;
75
+ dateTime: z.ZodOptional<z.ZodString>;
76
+ timeZone: z.ZodOptional<z.ZodString>;
77
+ }, "strip", z.ZodTypeAny, {
78
+ date?: string | undefined;
79
+ dateTime?: string | undefined;
80
+ timeZone?: string | undefined;
81
+ }, {
82
+ date?: string | undefined;
83
+ dateTime?: string | undefined;
84
+ timeZone?: string | undefined;
85
+ }>>;
86
+ transparency: z.ZodOptional<z.ZodEnum<["opaque", "transparent"]>>;
87
+ visibility: z.ZodOptional<z.ZodEnum<["default", "public", "private", "confidential"]>>;
88
+ iCalUID: z.ZodOptional<z.ZodString>;
89
+ sequence: z.ZodOptional<z.ZodNumber>;
90
+ attendees: z.ZodOptional<z.ZodArray<z.ZodObject<{
91
+ id: z.ZodOptional<z.ZodString>;
92
+ email: z.ZodOptional<z.ZodString>;
93
+ displayName: z.ZodOptional<z.ZodString>;
94
+ organizer: z.ZodOptional<z.ZodBoolean>;
95
+ self: z.ZodOptional<z.ZodBoolean>;
96
+ resource: z.ZodOptional<z.ZodBoolean>;
97
+ optional: z.ZodOptional<z.ZodBoolean>;
98
+ responseStatus: z.ZodOptional<z.ZodEnum<["needsAction", "declined", "tentative", "accepted"]>>;
99
+ comment: z.ZodOptional<z.ZodString>;
100
+ additionalGuests: z.ZodOptional<z.ZodNumber>;
101
+ }, "strip", z.ZodTypeAny, {
102
+ id?: string | undefined;
103
+ email?: string | undefined;
104
+ displayName?: string | undefined;
105
+ organizer?: boolean | undefined;
106
+ self?: boolean | undefined;
107
+ resource?: boolean | undefined;
108
+ optional?: boolean | undefined;
109
+ responseStatus?: "needsAction" | "declined" | "tentative" | "accepted" | undefined;
110
+ comment?: string | undefined;
111
+ additionalGuests?: number | undefined;
112
+ }, {
113
+ id?: string | undefined;
114
+ email?: string | undefined;
115
+ displayName?: string | undefined;
116
+ organizer?: boolean | undefined;
117
+ self?: boolean | undefined;
118
+ resource?: boolean | undefined;
119
+ optional?: boolean | undefined;
120
+ responseStatus?: "needsAction" | "declined" | "tentative" | "accepted" | undefined;
121
+ comment?: string | undefined;
122
+ additionalGuests?: number | undefined;
123
+ }>, "many">>;
124
+ attendeesOmitted: z.ZodOptional<z.ZodBoolean>;
125
+ hangoutLink: z.ZodOptional<z.ZodString>;
126
+ reminders: z.ZodOptional<z.ZodObject<{
127
+ useDefault: z.ZodOptional<z.ZodBoolean>;
128
+ overrides: z.ZodOptional<z.ZodArray<z.ZodObject<{
129
+ method: z.ZodOptional<z.ZodEnum<["email", "popup"]>>;
130
+ minutes: z.ZodOptional<z.ZodNumber>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ method?: "email" | "popup" | undefined;
133
+ minutes?: number | undefined;
134
+ }, {
135
+ method?: "email" | "popup" | undefined;
136
+ minutes?: number | undefined;
137
+ }>, "many">>;
138
+ }, "strip", z.ZodTypeAny, {
139
+ useDefault?: boolean | undefined;
140
+ overrides?: {
141
+ method?: "email" | "popup" | undefined;
142
+ minutes?: number | undefined;
143
+ }[] | undefined;
144
+ }, {
145
+ useDefault?: boolean | undefined;
146
+ overrides?: {
147
+ method?: "email" | "popup" | undefined;
148
+ minutes?: number | undefined;
149
+ }[] | undefined;
150
+ }>>;
151
+ anyoneCanAddSelf: z.ZodOptional<z.ZodBoolean>;
152
+ guestsCanInviteOthers: z.ZodOptional<z.ZodBoolean>;
153
+ guestsCanModify: z.ZodOptional<z.ZodBoolean>;
154
+ guestsCanSeeOtherGuests: z.ZodOptional<z.ZodBoolean>;
155
+ privateCopy: z.ZodOptional<z.ZodBoolean>;
156
+ locked: z.ZodOptional<z.ZodBoolean>;
157
+ eventType: z.ZodOptional<z.ZodEnum<["default", "outOfOffice", "focusTime", "workingLocation"]>>;
158
+ calendarId: z.ZodOptional<z.ZodString>;
159
+ createdAt: z.ZodOptional<z.ZodDate>;
160
+ }, "strip", z.ZodTypeAny, {
161
+ id: string;
162
+ location?: string | undefined;
163
+ status?: "tentative" | "confirmed" | "cancelled" | undefined;
164
+ start?: {
165
+ date?: string | undefined;
166
+ dateTime?: string | undefined;
167
+ timeZone?: string | undefined;
168
+ } | undefined;
169
+ end?: {
170
+ date?: string | undefined;
171
+ dateTime?: string | undefined;
172
+ timeZone?: string | undefined;
173
+ } | undefined;
174
+ description?: string | undefined;
175
+ organizer?: {
176
+ id?: string | undefined;
177
+ email?: string | undefined;
178
+ displayName?: string | undefined;
179
+ self?: boolean | undefined;
180
+ } | undefined;
181
+ summary?: string | undefined;
182
+ attendees?: {
183
+ id?: string | undefined;
184
+ email?: string | undefined;
185
+ displayName?: string | undefined;
186
+ organizer?: boolean | undefined;
187
+ self?: boolean | undefined;
188
+ resource?: boolean | undefined;
189
+ optional?: boolean | undefined;
190
+ responseStatus?: "needsAction" | "declined" | "tentative" | "accepted" | undefined;
191
+ comment?: string | undefined;
192
+ additionalGuests?: number | undefined;
193
+ }[] | undefined;
194
+ recurrence?: string[] | undefined;
195
+ colorId?: string | undefined;
196
+ transparency?: "opaque" | "transparent" | undefined;
197
+ visibility?: "default" | "public" | "private" | "confidential" | undefined;
198
+ eventType?: "default" | "outOfOffice" | "focusTime" | "workingLocation" | undefined;
199
+ reminders?: {
200
+ useDefault?: boolean | undefined;
201
+ overrides?: {
202
+ method?: "email" | "popup" | undefined;
203
+ minutes?: number | undefined;
204
+ }[] | undefined;
205
+ } | undefined;
206
+ guestsCanModify?: boolean | undefined;
207
+ guestsCanInviteOthers?: boolean | undefined;
208
+ guestsCanSeeOtherGuests?: boolean | undefined;
209
+ anyoneCanAddSelf?: boolean | undefined;
210
+ sequence?: number | undefined;
211
+ originalStartTime?: {
212
+ date?: string | undefined;
213
+ dateTime?: string | undefined;
214
+ timeZone?: string | undefined;
215
+ } | undefined;
216
+ recurringEventId?: string | undefined;
217
+ calendarId?: string | undefined;
218
+ updated?: string | undefined;
219
+ iCalUID?: string | undefined;
220
+ htmlLink?: string | undefined;
221
+ created?: string | undefined;
222
+ creator?: {
223
+ id?: string | undefined;
224
+ email?: string | undefined;
225
+ displayName?: string | undefined;
226
+ self?: boolean | undefined;
227
+ } | undefined;
228
+ endTimeUnspecified?: boolean | undefined;
229
+ attendeesOmitted?: boolean | undefined;
230
+ hangoutLink?: string | undefined;
231
+ privateCopy?: boolean | undefined;
232
+ locked?: boolean | undefined;
233
+ createdAt?: Date | undefined;
234
+ }, {
235
+ id: string;
236
+ location?: string | undefined;
237
+ status?: "tentative" | "confirmed" | "cancelled" | undefined;
238
+ start?: {
239
+ date?: string | undefined;
240
+ dateTime?: string | undefined;
241
+ timeZone?: string | undefined;
242
+ } | undefined;
243
+ end?: {
244
+ date?: string | undefined;
245
+ dateTime?: string | undefined;
246
+ timeZone?: string | undefined;
247
+ } | undefined;
248
+ description?: string | undefined;
249
+ organizer?: {
250
+ id?: string | undefined;
251
+ email?: string | undefined;
252
+ displayName?: string | undefined;
253
+ self?: boolean | undefined;
254
+ } | undefined;
255
+ summary?: string | undefined;
256
+ attendees?: {
257
+ id?: string | undefined;
258
+ email?: string | undefined;
259
+ displayName?: string | undefined;
260
+ organizer?: boolean | undefined;
261
+ self?: boolean | undefined;
262
+ resource?: boolean | undefined;
263
+ optional?: boolean | undefined;
264
+ responseStatus?: "needsAction" | "declined" | "tentative" | "accepted" | undefined;
265
+ comment?: string | undefined;
266
+ additionalGuests?: number | undefined;
267
+ }[] | undefined;
268
+ recurrence?: string[] | undefined;
269
+ colorId?: string | undefined;
270
+ transparency?: "opaque" | "transparent" | undefined;
271
+ visibility?: "default" | "public" | "private" | "confidential" | undefined;
272
+ eventType?: "default" | "outOfOffice" | "focusTime" | "workingLocation" | undefined;
273
+ reminders?: {
274
+ useDefault?: boolean | undefined;
275
+ overrides?: {
276
+ method?: "email" | "popup" | undefined;
277
+ minutes?: number | undefined;
278
+ }[] | undefined;
279
+ } | undefined;
280
+ guestsCanModify?: boolean | undefined;
281
+ guestsCanInviteOthers?: boolean | undefined;
282
+ guestsCanSeeOtherGuests?: boolean | undefined;
283
+ anyoneCanAddSelf?: boolean | undefined;
284
+ sequence?: number | undefined;
285
+ originalStartTime?: {
286
+ date?: string | undefined;
287
+ dateTime?: string | undefined;
288
+ timeZone?: string | undefined;
289
+ } | undefined;
290
+ recurringEventId?: string | undefined;
291
+ calendarId?: string | undefined;
292
+ updated?: string | undefined;
293
+ iCalUID?: string | undefined;
294
+ htmlLink?: string | undefined;
295
+ created?: string | undefined;
296
+ creator?: {
297
+ id?: string | undefined;
298
+ email?: string | undefined;
299
+ displayName?: string | undefined;
300
+ self?: boolean | undefined;
301
+ } | undefined;
302
+ endTimeUnspecified?: boolean | undefined;
303
+ attendeesOmitted?: boolean | undefined;
304
+ hangoutLink?: string | undefined;
305
+ privateCopy?: boolean | undefined;
306
+ locked?: boolean | undefined;
307
+ createdAt?: Date | undefined;
308
+ }>;
309
+ export declare const GoogleCalendar: z.ZodObject<{
310
+ id: z.ZodString;
311
+ summary: z.ZodOptional<z.ZodString>;
312
+ description: z.ZodOptional<z.ZodString>;
313
+ location: z.ZodOptional<z.ZodString>;
314
+ timeZone: z.ZodOptional<z.ZodString>;
315
+ createdAt: z.ZodOptional<z.ZodDate>;
316
+ }, "strip", z.ZodTypeAny, {
317
+ id: string;
318
+ location?: string | undefined;
319
+ description?: string | undefined;
320
+ timeZone?: string | undefined;
321
+ summary?: string | undefined;
322
+ createdAt?: Date | undefined;
323
+ }, {
324
+ id: string;
325
+ location?: string | undefined;
326
+ description?: string | undefined;
327
+ timeZone?: string | undefined;
328
+ summary?: string | undefined;
329
+ createdAt?: Date | undefined;
330
+ }>;
331
+ export type GoogleCalendarEvent = z.infer<typeof GoogleCalendarEvent>;
332
+ export type GoogleCalendar = z.infer<typeof GoogleCalendar>;
333
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../schema/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwCxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuC9B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;EAOzB,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}