@corsair-dev/googlecalendar 0.1.5 → 0.1.6

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.
package/dist/client.d.ts CHANGED
@@ -2,18 +2,6 @@ export declare class GoogleCalendarAPIError extends Error {
2
2
  readonly code?: number | undefined;
3
3
  constructor(message: string, code?: number | undefined);
4
4
  }
5
- export declare function getValidAccessToken({ accessToken, expiresAt, clientId, clientSecret, refreshToken, forceRefresh, }: {
6
- clientId: string;
7
- clientSecret: string;
8
- accessToken?: string | null;
9
- expiresAt?: string | null;
10
- refreshToken: string;
11
- forceRefresh?: boolean;
12
- }): Promise<{
13
- accessToken: string;
14
- expiresAt: number;
15
- refreshed: boolean;
16
- }>;
17
5
  type CalendarRequestOptions = {
18
6
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
19
7
  body?: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../client.ts"],"names":[],"mappings":"AAGA,qBAAa,sBAAuB,SAAQ,KAAK;aAG/B,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAK9B;AAsCD,wBAAsB,mBAAmB,CAAC,EACzC,WAAW,EACX,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,YAAoB,GACpB,EAAE;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAuB1E;AAED,KAAK,sBAAsB,GAAG;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC9D,CAAC;AAEF,wBAAsB,mBAAmB,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,sBAA2B,GAClC,OAAO,CAAC,CAAC,CAAC,CA2BZ;AAUD,wBAAsB,gCAAgC,CAAC,CAAC,EACvD,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,EAC1D,OAAO,GAAE,sBAA2B,GAClC,OAAO,CAAC,CAAC,CAAC,CAUZ"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../client.ts"],"names":[],"mappings":"AAGA,qBAAa,sBAAuB,SAAQ,KAAK;aAG/B,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAK9B;AAID,KAAK,sBAAsB,GAAG;IAC7B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC9D,CAAC;AAEF,wBAAsB,mBAAmB,CAAC,CAAC,EAC1C,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,sBAA2B,GAClC,OAAO,CAAC,CAAC,CAAC,CA2BZ;AAUD,wBAAsB,gCAAgC,CAAC,CAAC,EACvD,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,EAC1D,OAAO,GAAE,sBAA2B,GAClC,OAAO,CAAC,CAAC,CAAC,CAUZ"}
package/dist/index.d.ts CHANGED
@@ -950,6 +950,11 @@ export type GoogleCalendarPluginOptions = {
950
950
  };
951
951
  export type GoogleCalendarKeyBuilderContext = KeyBuilderContext<GoogleCalendarPluginOptions>;
952
952
  declare const defaultAuthType: "oauth_2";
953
+ export declare const googleCalendarAuthConfig: {
954
+ readonly oauth_2: {
955
+ readonly account: readonly ["channel_id"];
956
+ };
957
+ };
953
958
  export type BaseGoogleCalendarPlugin<T extends GoogleCalendarPluginOptions> = CorsairPlugin<'googlecalendar', typeof GoogleCalendarSchema, typeof googleCalendarEndpointsNested, typeof googleCalendarWebhooksNested, T, typeof defaultAuthType>;
954
959
  export type InternalGoogleCalendarPlugin = BaseGoogleCalendarPlugin<GoogleCalendarPluginOptions>;
955
960
  export type ExternalGoogleCalendarPlugin<T extends GoogleCalendarPluginOptions> = BaseGoogleCalendarPlugin<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{AuthMissingError as Y}from"corsair/core";import{request as Q}from"corsair/http";var k=class extends Error{constructor(a,r){super(a);this.code=r;this.name="GoogleCalendarAPIError"}},X="https://www.googleapis.com/calendar/v3";async function ee(t,n,a){let r=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:a,grant_type:"refresh_token"})});if(!r.ok){let c=await r.text();throw new k(`Failed to refresh access token: ${c}`,r.status)}return await r.json()}async function S({accessToken:t,expiresAt:n,clientId:a,clientSecret:r,refreshToken:s,forceRefresh:c=!1}){let d=Math.floor(Date.now()/1e3);if(!c&&t&&n&&Number(n)>d+300)return{accessToken:t,expiresAt:Number(n),refreshed:!1};let p=await ee(a,r,s);return{accessToken:p.access_token,expiresAt:d+p.expires_in,refreshed:!0}}async function E(t,n,a={}){let{method:r="GET",body:s,query:c}=a;return await Q({BASE:X,VERSION:"1.0.0",WITH_CREDENTIALS:!1,CREDENTIALS:"omit",TOKEN:n,HEADERS:{"Content-Type":"application/json"}},{method:r,url:t,body:r==="POST"||r==="PUT"||r==="PATCH"?s:void 0,mediaType:"application/json",query:c})}function te(t){return t instanceof Error&&"status"in t&&t.status===401}async function g(t,n,a={}){try{return await E(t,n.key,a)}catch(r){if(te(r)&&n._refreshAuth){let s=await n._refreshAuth();return await E(t,s,a)}throw r}}import{logEventFromContext as ne}from"corsair/core";var x=async(t,n)=>{let a=await g("/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 ne(t,"googlecalendar.calendar.getAvailability",{...n},"completed"),a};import{logEventFromContext as C}from"corsair/core";var A=async(t,n)=>{let a=n.calendarId||"primary",r=await g(`/calendars/${a}/events`,t,{method:"POST",body:n.event});if(r.id&&t.db.events)try{await t.db.events.upsertByEntityId(r.id,{...r,id:r.id,calendarId:a,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await C(t,"googlecalendar.events.create",{...n},"completed"),r},P=async(t,n)=>{let a=n.calendarId||"primary",r=await g(`/calendars/${a}/events/${n.id}`,t,{method:"GET",query:{timeZone:n.timeZone,maxAttendees:n.maxAttendees}});if(r.id&&t.db.events)try{await t.db.events.upsertByEntityId(r.id,{...r,id:r.id,calendarId:a,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await C(t,"googlecalendar.events.get",{...n},"completed"),r},D=async(t,n)=>{let a=n.calendarId||"primary",r=await g(`/calendars/${a}/events`,t,{method:"GET",query:n});if(r.items&&t.db.events)try{for(let s of r.items)s.id&&await t.db.events.upsertByEntityId(s.id,{...s,id:s.id,calendarId:a,createdAt:new Date})}catch(s){console.warn("Failed to save events to database:",s)}return await C(t,"googlecalendar.events.getMany",{...n},"completed"),r},O=async(t,n)=>{let a=n.calendarId||"primary",r=await g(`/calendars/${a}/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(r.id&&t.db.events)try{await t.db.events.upsertByEntityId(r.id,{...r,id:r.id,calendarId:a,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await C(t,"googlecalendar.events.update",{...n},"completed"),r},M=async(t,n)=>{let a=n.calendarId||"primary";if(await g(`/calendars/${a}/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(r){console.warn("Failed to delete event from database:",r)}await C(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"')}),U=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()}),R=e.object({id:e.string().optional(),email:e.string().optional(),displayName:e.string().optional(),self:e.boolean().optional()}),N=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(N).optional().describe("Custom reminders. Only used when useDefault is false.")}),re=e.object({fileUrl:e.string().optional(),title:e.string().optional(),mimeType:e.string().optional(),iconLink:e.string().optional(),fileId:e.string().optional()}),ie=e.object({createRequest:e.object({requestId:e.string().optional(),conferenceSolutionKey:e.object({type:e.string().optional()}).optional(),status:e.object({statusCode:e.string().optional()}).optional()}).optional(),entryPoints:e.array(e.object({entryPointType:e.string().optional(),uri:e.string().optional(),label:e.string().optional(),pin:e.string().optional(),accessCode:e.string().optional(),meetingCode:e.string().optional(),passcode:e.string().optional(),password:e.string().optional()})).optional(),conferenceSolution:e.object({key:e.object({type:e.string().optional()}).optional(),name:e.string().optional(),iconUri:e.string().optional()}).optional(),conferenceId:e.string().optional(),signature:e.string().optional(),notes:e.string().optional()}),j=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(U).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","birthday","fromGmail"]).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")}),se=e.object({calendarId:e.string().optional().describe('Calendar ID. Defaults to "primary".'),event:j.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()}),le=e.object({calendarId:e.string().optional(),id:e.string(),timeZone:e.string().optional(),maxAttendees:e.number().optional()}),de=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()}),pe=e.object({calendarId:e.string().optional().describe('Calendar ID. Defaults to "primary".'),id:e.string().describe("Event ID to update"),event:j.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()}),ce=e.object({calendarId:e.string().optional(),id:e.string(),sendUpdates:e.enum(["all","externalOnly","none"]).optional(),sendNotifications:e.boolean().optional()}),ge=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:se,eventsGet:le,eventsGetMany:de,eventsUpdate:pe,eventsDelete:ce,calendarGetAvailability:ge},G=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:R.optional(),organizer:R.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(U).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(),conferenceData:ie.optional(),attachments:e.array(re).optional(),source:e.object({url:e.string().optional(),title:e.string().optional()}).optional(),gadget:e.object({type:e.string().optional(),title:e.string().optional(),link:e.string().optional(),iconLink:e.string().optional(),width:e.number().optional(),height:e.number().optional(),display:e.string().optional(),preferences:e.record(e.string(),e.string()).optional()}).optional(),eventType:e.enum(["default","outOfOffice","focusTime","workingLocation","birthday","fromGmail"]).optional()}),ue=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(N).optional(),nextPageToken:e.string().optional(),nextSyncToken:e.string().optional(),items:e.array(G).optional()}),me=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()}),ve=e.object({kind:e.string().optional(),calendars:e.record(e.string(),me).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:G,eventsGet:G,eventsGetMany:ue,eventsUpdate:G,eventsDelete:e.void(),calendarGetAvailability:ve};var b={create:A,get:P,getMany:D,update:O,delete:M},W={getAvailability:x};import{z as o}from"zod";var w=o.object({date:o.string().optional(),dateTime:o.string().optional(),timeZone:o.string().optional()}),ye=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()}),fe=o.object({method:o.enum(["email","popup"]).optional(),minutes:o.number().optional()}),be=o.object({useDefault:o.boolean().optional(),overrides:o.array(fe).optional()}),L=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:w.optional(),end:w.optional(),endTimeUnspecified:o.boolean().optional(),recurrence:o.array(o.string()).optional(),recurringEventId:o.string().optional(),originalStartTime:w.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(ye).optional(),attendeesOmitted:o.boolean().optional(),hangoutLink:o.string().optional(),reminders:be.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","birthday","fromGmail"]).optional(),calendarId:o.string().optional(),createdAt:o.coerce.date().optional()}),B=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:L,calendars:B}};import{logEventFromContext as I}from"corsair/core";import{z as i}from"zod";var he=i.object({data:i.string().optional(),attributes:i.record(i.string(),i.string()).optional(),messageId:i.string().optional(),publishTime:i.string().optional()}),F=i.object({message:he.optional(),subscription:i.string().optional(),event:i.unknown().optional()}),Xe=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()}),Ee=i.object({type:i.literal("eventCreated"),calendarId:i.string(),event:i.custom(),timestamp:i.string()}),Ce=i.object({type:i.literal("eventUpdated"),calendarId:i.string(),event:i.custom(),timestamp:i.string()}),Ge=i.object({type:i.literal("eventDeleted"),calendarId:i.string(),eventId:i.string(),timestamp:i.string()}),K=i.union([Ee,Ce,Ge]);function h(t){let n=Buffer.from(t,"base64").toString("utf-8");return JSON.parse(n)}function T(t){return n=>{let a=n.body;if(!a.message?.data)return!1;try{let r=h(a.message.data);return!!r.channelId&&!!r.resourceId&&!!r.resourceUri&&r.resourceUri.includes("/calendar/")}catch{return!1}}}var ke=/\/calendars\/([^\/\?]+)/,Se=/\/calendars\/[^\/]+\/events\/([^\/\?]+)/,we=120*1e3,Te=5e3;function Ie(t){return{calendarId:t.match(ke)?.[1],eventId:t.match(Se)?.[1]}}function xe(t){return!t.created||!t.updated?!1:Math.abs(new Date(t.updated).getTime()-new Date(t.created).getTime())<Te}function Ae(t,n,a){return E(`/calendars/${n}/events/${a}`,t,{method:"GET"})}async function H(t,n){let a=new Date(Date.now()-we).toISOString();return(await E(`/calendars/${n}/events`,t,{method:"GET",query:{maxResults:10,orderBy:"updated",updatedMin:a,showDeleted:!0}})).items??[]}async function Pe(t,n,a){return a?Ae(t,n,a):(await H(t,n)).at(-1)??null}async function De(t,n,a,r){return a||((await H(t,n)).find(d=>d.status==="cancelled")?.id??r.resourceId??"")}async function $(t,n,a){a&&t.db.events&&await t.db.events.deleteByEntityId(a);let r={type:"eventDeleted",calendarId:n,eventId:a,timestamp:new Date().toISOString()};return await I(t,"googlecalendar.webhook.eventDeleted",{...r},"completed"),{eventData:r}}var V={match:T("eventChanged"),handler:async(t,n)=>{let a=n.payload;if(!a.message?.data)return{success:!1,error:"No message data in notification"};let r=h(a.message.data);if(!r.resourceUri)return{success:!1,error:"Invalid push notification format"};let{calendarId:s,eventId:c}=Ie(r.resourceUri);if(!s)return{success:!1,error:"Could not parse calendar ID from resource URI"};let d=t.key;try{if(r.resourceState==="not_exists"){let u=await De(d,s,c,r),{eventData:J}=await $(t,s,u);return{success:!0,data:J}}let l=await Pe(d,s,c);if(!l)return{success:!1,error:"No recently updated events found in calendar"};if(l.status==="cancelled"){let{eventData:u}=await $(t,s,l.id??"");return{success:!0,data:u}}let p="";if(l.id&&t.db.events&&(p=(await t.db.events.upsertByEntityId(l.id,{...l,id:l.id,calendarId:s,createdAt:new Date}))?.id??""),xe(l)){let u={type:"eventCreated",calendarId:s,event:l,timestamp:new Date().toISOString()};return await I(t,"googlecalendar.webhook.eventCreated",{...u},"completed"),{success:!0,corsairEntityId:p,data:u}}let y={type:"eventUpdated",calendarId:s,event:l,timestamp:new Date().toISOString()};return await I(t,"googlecalendar.webhook.eventUpdated",{...y},"completed"),{success:!0,corsairEntityId:p,data:y}}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 Oe={events:{create:b.create,get:b.get,getMany:b.getMany,update:b.update,delete:b.delete},calendar:{getAvailability:W.getAvailability}},Me={"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}},Re={onEventChanged:Z.onEventChanged},Ue={onEventChanged:{description:"A Google Calendar event was created, updated, or deleted",payload:F,response:K}},Ne="oauth_2",_e={"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 vt(t={}){let n={...t,authType:t.authType??Ne};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:Oe,webhooks:Re,endpointMeta:_e,endpointSchemas:Me,webhookSchemas:Ue,keyBuilder:async a=>{let r=a.authType;if(n.key)return n.key;if(a.authType==="oauth_2"){let[s,c,d]=await Promise.all([a.keys.get_access_token(),a.keys.get_expires_at(),a.keys.get_refresh_token()]);if(!d)throw new Y("googlecalendar","oauth_2");let l=await a.keys.get_integration_credentials();if(!l.client_id||!l.client_secret)throw new Error("[corsair:googlecalendar] No client id or client secret");try{let p=await S({accessToken:s,expiresAt:c,refreshToken:d,clientId:l.client_id,clientSecret:l.client_secret});return p.refreshed&&await Promise.all([a.keys.set_access_token(p.accessToken),a.keys.set_expires_at(String(p.expiresAt))]),a._refreshAuth=async()=>{let y=await S({accessToken:null,expiresAt:null,refreshToken:d,clientId:l.client_id,clientSecret:l.client_secret,forceRefresh:!0});return await a.keys.set_access_token(y.accessToken),await a.keys.set_expires_at(String(y.expiresAt)),y.accessToken},p.accessToken}catch(p){throw console.error("[corsair:googlecalendar] Failed to get valid access token:",p),p}}throw new Y("googlecalendar","oauth_2")},pluginWebhookMatcher:a=>{let r=a.headers;if(!(r.from==="noreply@google.com"||typeof r["user-agent"]=="string"&&r["user-agent"].includes("APIs-Google")))return!1;let c=a.body;if(!c?.message?.data)return!1;try{let d=h(c.message.data);return!!d.resourceUri&&d.resourceUri.includes("calendar")}catch{return!1}}}}export{T as createGoogleCalendarWebhookMatcher,h as decodePubSubMessage,vt as googlecalendar,Me as googlecalendarEndpointSchemas};
1
+ import{AuthMissingError as Ne,getOAuthAccessToken as We}from"corsair/core";import{logEventFromContext as te}from"corsair/core";import{request as Q}from"corsair/http";var X="https://www.googleapis.com/calendar/v3";async function h(t,o,i={}){let{method:a="GET",body:s,query:d}=i;return await Q({BASE:X,VERSION:"1.0.0",WITH_CREDENTIALS:!1,CREDENTIALS:"omit",TOKEN:o,HEADERS:{"Content-Type":"application/json"}},{method:a,url:t,body:a==="POST"||a==="PUT"||a==="PATCH"?s:void 0,mediaType:"application/json",query:d})}function ee(t){return t instanceof Error&&"status"in t&&t.status===401}async function c(t,o,i={}){try{return await h(t,o.key,i)}catch(a){if(ee(a)&&o._refreshAuth){let s=await o._refreshAuth();return await h(t,s,i)}throw a}}var T=async(t,o)=>{let i=await c("/freeBusy",t,{method:"POST",body:{timeMin:o.timeMin,timeMax:o.timeMax,timeZone:o.timeZone,groupExpansionMax:o.groupExpansionMax,calendarExpansionMax:o.calendarExpansionMax,items:o.items}});return await te(t,"googlecalendar.calendar.getAvailability",{...o},"completed"),i};import{logEventFromContext as f}from"corsair/core";var I=async(t,o)=>{let i=o.calendarId||"primary",a=await c(`/calendars/${i}/events`,t,{method:"POST",body:o.event});if(a.id&&t.db.events)try{await t.db.events.upsertByEntityId(a.id,{...a,id:a.id,calendarId:i,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await f(t,"googlecalendar.events.create",{...o},"completed"),a},x=async(t,o)=>{let i=o.calendarId||"primary",a=await c(`/calendars/${i}/events/${o.id}`,t,{method:"GET",query:{timeZone:o.timeZone,maxAttendees:o.maxAttendees}});if(a.id&&t.db.events)try{await t.db.events.upsertByEntityId(a.id,{...a,id:a.id,calendarId:i,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await f(t,"googlecalendar.events.get",{...o},"completed"),a},P=async(t,o)=>{let i=o.calendarId||"primary",a=await c(`/calendars/${i}/events`,t,{method:"GET",query:o});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:i,createdAt:new Date})}catch(s){console.warn("Failed to save events to database:",s)}return await f(t,"googlecalendar.events.getMany",{...o},"completed"),a},A=async(t,o)=>{let i=o.calendarId||"primary",a=await c(`/calendars/${i}/events/${o.id}`,t,{method:"PUT",body:o.event,query:{sendUpdates:o.sendUpdates,sendNotifications:o.sendNotifications,conferenceDataVersion:o.conferenceDataVersion,maxAttendees:o.maxAttendees,supportsAttachments:o.supportsAttachments}});if(a.id&&t.db.events)try{await t.db.events.upsertByEntityId(a.id,{...a,id:a.id,calendarId:i,createdAt:new Date})}catch(s){console.warn("Failed to save event to database:",s)}return await f(t,"googlecalendar.events.update",{...o},"completed"),a},D=async(t,o)=>{let i=o.calendarId||"primary";if(await c(`/calendars/${i}/events/${o.id}`,t,{method:"DELETE",query:{sendUpdates:o.sendUpdates,sendNotifications:o.sendNotifications}}),t.db.events)try{await t.db.events.deleteByEntityId(o.id)}catch(a){console.warn("Failed to delete event from database:",a)}await f(t,"googlecalendar.events.delete",{...o},"completed")};import{z as e}from"zod";var v=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"')}),M=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()}),O=e.object({id:e.string().optional(),email:e.string().optional(),displayName:e.string().optional(),self:e.boolean().optional()}),R=e.object({method:e.enum(["email","popup"]).optional(),minutes:e.number().optional()}),U=e.object({useDefault:e.boolean().optional().describe("Use the calendar default reminders"),overrides:e.array(R).optional().describe("Custom reminders. Only used when useDefault is false.")}),ae=e.object({fileUrl:e.string().optional(),title:e.string().optional(),mimeType:e.string().optional(),iconLink:e.string().optional(),fileId:e.string().optional()}),ie=e.object({createRequest:e.object({requestId:e.string().optional(),conferenceSolutionKey:e.object({type:e.string().optional()}).optional(),status:e.object({statusCode:e.string().optional()}).optional()}).optional(),entryPoints:e.array(e.object({entryPointType:e.string().optional(),uri:e.string().optional(),label:e.string().optional(),pin:e.string().optional(),accessCode:e.string().optional(),meetingCode:e.string().optional(),passcode:e.string().optional(),password:e.string().optional()})).optional(),conferenceSolution:e.object({key:e.object({type:e.string().optional()}).optional(),name:e.string().optional(),iconUri:e.string().optional()}).optional(),conferenceId:e.string().optional(),signature:e.string().optional(),notes:e.string().optional()}),N=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:v.optional().describe('Start time. Use "date" for all-day events, "dateTime" for timed events.'),end:v.optional().describe('End time. Use "date" for all-day events, "dateTime" for timed events.'),attendees:e.array(M).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","birthday","fromGmail"]).optional(),status:e.enum(["confirmed","tentative","cancelled"]).optional(),reminders:U.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:v.optional().describe("Original start time for a recurring event instance"),recurringEventId:e.string().optional().describe("ID of the recurring event this instance belongs to")}),re=e.object({calendarId:e.string().optional().describe('Calendar ID. Defaults to "primary".'),event:N.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()}),se=e.object({calendarId:e.string().optional(),id:e.string(),timeZone:e.string().optional(),maxAttendees:e.number().optional()}),le=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()}),de=e.object({calendarId:e.string().optional().describe('Calendar ID. Defaults to "primary".'),id:e.string().describe("Event ID to update"),event:N.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()}),pe=e.object({calendarId:e.string().optional(),id:e.string(),sendUpdates:e.enum(["all","externalOnly","none"]).optional(),sendNotifications:e.boolean().optional()}),ce=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()}),u={eventsCreate:re,eventsGet:se,eventsGetMany:le,eventsUpdate:de,eventsDelete:pe,calendarGetAvailability:ce},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:O.optional(),organizer:O.optional(),start:v.optional(),end:v.optional(),endTimeUnspecified:e.boolean().optional(),recurrence:e.array(e.string()).optional(),recurringEventId:e.string().optional(),originalStartTime:v.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(M).optional(),attendeesOmitted:e.boolean().optional(),hangoutLink:e.string().optional(),reminders:U.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(),conferenceData:ie.optional(),attachments:e.array(ae).optional(),source:e.object({url:e.string().optional(),title:e.string().optional()}).optional(),gadget:e.object({type:e.string().optional(),title:e.string().optional(),link:e.string().optional(),iconLink:e.string().optional(),width:e.number().optional(),height:e.number().optional(),display:e.string().optional(),preferences:e.record(e.string(),e.string()).optional()}).optional(),eventType:e.enum(["default","outOfOffice","focusTime","workingLocation","birthday","fromGmail"]).optional()}),ge=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(R).optional(),nextPageToken:e.string().optional(),nextSyncToken:e.string().optional(),items:e.array(C).optional()}),ue=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()}),me=e.object({kind:e.string().optional(),calendars:e.record(e.string(),ue).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()}),m={eventsCreate:C,eventsGet:C,eventsGetMany:ge,eventsUpdate:C,eventsDelete:e.void(),calendarGetAvailability:me};var b={create:I,get:x,getMany:P,update:A,delete:D},W={getAvailability:T};import{z as n}from"zod";var G=n.object({date:n.string().optional(),dateTime:n.string().optional(),timeZone:n.string().optional()}),ve=n.object({id:n.string().optional(),email:n.string().optional(),displayName:n.string().optional(),organizer:n.boolean().optional(),self:n.boolean().optional(),resource:n.boolean().optional(),optional:n.boolean().optional(),responseStatus:n.enum(["needsAction","declined","tentative","accepted"]).optional(),comment:n.string().optional(),additionalGuests:n.number().optional()}),j=n.object({id:n.string().optional(),email:n.string().optional(),displayName:n.string().optional(),self:n.boolean().optional()}),be=n.object({method:n.enum(["email","popup"]).optional(),minutes:n.number().optional()}),ye=n.object({useDefault:n.boolean().optional(),overrides:n.array(be).optional()}),q=n.object({id:n.string(),status:n.enum(["confirmed","tentative","cancelled"]).optional(),htmlLink:n.string().optional(),created:n.string().optional(),updated:n.string().optional(),summary:n.string().optional(),description:n.string().optional(),location:n.string().optional(),colorId:n.string().optional(),creator:j.optional(),organizer:j.optional(),start:G.optional(),end:G.optional(),endTimeUnspecified:n.boolean().optional(),recurrence:n.array(n.string()).optional(),recurringEventId:n.string().optional(),originalStartTime:G.optional(),transparency:n.enum(["opaque","transparent"]).optional(),visibility:n.enum(["default","public","private","confidential"]).optional(),iCalUID:n.string().optional(),sequence:n.number().optional(),attendees:n.array(ve).optional(),attendeesOmitted:n.boolean().optional(),hangoutLink:n.string().optional(),reminders:ye.optional(),anyoneCanAddSelf:n.boolean().optional(),guestsCanInviteOthers:n.boolean().optional(),guestsCanModify:n.boolean().optional(),guestsCanSeeOtherGuests:n.boolean().optional(),privateCopy:n.boolean().optional(),locked:n.boolean().optional(),eventType:n.enum(["default","outOfOffice","focusTime","workingLocation","birthday","fromGmail"]).optional(),calendarId:n.string().optional(),createdAt:n.coerce.date().optional()}),B=n.object({id:n.string(),summary:n.string().optional(),description:n.string().optional(),location:n.string().optional(),timeZone:n.string().optional(),createdAt:n.coerce.date().optional()});var L={version:"1.0.0",entities:{events:q,calendars:B}};import{googleChannelSubscribe as he}from"corsair/core";var _=(t,o)=>he(t,{webhookUrl:o.webhookUrl,watchUrl:"https://www.googleapis.com/calendar/v3/calendars/primary/events/watch"});import{logEventFromContext as S}from"corsair/core";import{z as r}from"zod";var fe=r.object({data:r.string().optional(),attributes:r.record(r.string(),r.string()).optional(),messageId:r.string().optional(),publishTime:r.string().optional()}),z=r.object({message:fe.optional(),subscription:r.string().optional(),event:r.unknown().optional()}),lt=r.object({resourceId:r.string().optional(),resourceState:r.string().optional(),resourceUri:r.string().optional(),channelId:r.string().optional(),channelExpiration:r.string().optional(),channelToken:r.string().optional(),changed:r.string().optional()}),Ee=r.object({type:r.literal("eventCreated"),calendarId:r.string(),event:r.custom(),timestamp:r.string()}),Ce=r.object({type:r.literal("eventUpdated"),calendarId:r.string(),event:r.custom(),timestamp:r.string()}),Ge=r.object({type:r.literal("eventDeleted"),calendarId:r.string(),eventId:r.string(),timestamp:r.string()}),F=r.union([Ee,Ce,Ge]);function y(t){let o=Buffer.from(t,"base64").toString("utf-8");return JSON.parse(o)}function k(t){return o=>{let i=o.body;if(!i.message?.data)return!1;try{let a=y(i.message.data);return!!a.channelId&&!!a.resourceId&&!!a.resourceUri&&a.resourceUri.includes("/calendar/")}catch{return!1}}}var ke=/\/calendars\/([^\/\?]+)/,Se=/\/calendars\/[^\/]+\/events\/([^\/\?]+)/,we=120*1e3,Te=5e3;function Ie(t){return{calendarId:t.match(ke)?.[1],eventId:t.match(Se)?.[1]}}function xe(t){return!t.created||!t.updated?!1:Math.abs(new Date(t.updated).getTime()-new Date(t.created).getTime())<Te}function Pe(t,o,i){return h(`/calendars/${o}/events/${i}`,t,{method:"GET"})}async function H(t,o){let i=new Date(Date.now()-we).toISOString();return(await h(`/calendars/${o}/events`,t,{method:"GET",query:{maxResults:10,orderBy:"updated",updatedMin:i,showDeleted:!0}})).items??[]}async function Ae(t,o,i){return i?Pe(t,o,i):(await H(t,o)).at(-1)??null}async function De(t,o,i,a){return i||((await H(t,o)).find(p=>p.status==="cancelled")?.id??a.resourceId??"")}async function K(t,o,i){i&&t.db.events&&await t.db.events.deleteByEntityId(i);let a={type:"eventDeleted",calendarId:o,eventId:i,timestamp:new Date().toISOString()};return await S(t,"googlecalendar.webhook.eventDeleted",{...a},"completed"),{eventData:a}}var $={match:k("eventChanged"),handler:async(t,o)=>{let i=o.payload;if(!i.message?.data)return{success:!1,error:"No message data in notification"};let a=y(i.message.data);if(!a.resourceUri)return{success:!1,error:"Invalid push notification format"};let{calendarId:s,eventId:d}=Ie(a.resourceUri);if(!s)return{success:!1,error:"Could not parse calendar ID from resource URI"};let p=t.key;try{if(a.resourceState==="not_exists"){let g=await De(p,s,d,a),{eventData:J}=await K(t,s,g);return{success:!0,data:J}}let l=await Ae(p,s,d);if(!l)return{success:!1,error:"No recently updated events found in calendar"};if(l.status==="cancelled"){let{eventData:g}=await K(t,s,l.id??"");return{success:!0,data:g}}let E="";if(l.id&&t.db.events&&(E=(await t.db.events.upsertByEntityId(l.id,{...l,id:l.id,calendarId:s,createdAt:new Date}))?.id??""),xe(l)){let g={type:"eventCreated",calendarId:s,event:l,timestamp:new Date().toISOString()};return await S(t,"googlecalendar.webhook.eventCreated",{...g},"completed"),{success:!0,corsairEntityId:E,data:g}}let w={type:"eventUpdated",calendarId:s,event:l,timestamp:new Date().toISOString()};return await S(t,"googlecalendar.webhook.eventUpdated",{...w},"completed"),{success:!0,corsairEntityId:E,data:w}}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:$};import{asRecord as Oe,decodePubSubData as Me,firstString as V,getHeader as Re,readBodyRecord as Ue}from"corsair/core";function Y(t){let o=V([Re(t.headers,"x-goog-channel-id")]);if(o)return{linkType:"channel_id",externalId:o};let i=Ue(t);if(!i)return null;let a=Oe(Me(i)),s=V([a?.channelId]);return s?{linkType:"channel_id",externalId:s}:null}var je={events:{create:b.create,get:b.get,getMany:b.getMany,update:b.update,delete:b.delete},calendar:{getAvailability:W.getAvailability}},qe={"events.create":{input:u.eventsCreate,output:m.eventsCreate},"events.get":{input:u.eventsGet,output:m.eventsGet},"events.getMany":{input:u.eventsGetMany,output:m.eventsGetMany},"events.update":{input:u.eventsUpdate,output:m.eventsUpdate},"events.delete":{input:u.eventsDelete,output:m.eventsDelete},"calendar.getAvailability":{input:u.calendarGetAvailability,output:m.calendarGetAvailability}},Be={onEventChanged:Z.onEventChanged},Le={onEventChanged:{description:"A Google Calendar event was created, updated, or deleted",payload:z,response:F}},_e="oauth_2",ze={"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"}},Fe={oauth_2:{account:["channel_id"]}};function It(t={}){let o={...t,authType:t.authType??_e};return{id:"googlecalendar",authConfig:Fe,schema:L,options:o,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:o.hooks,webhookHooks:o.webhookHooks,endpoints:je,webhooks:Be,endpointMeta:ze,endpointSchemas:qe,webhookSchemas:Le,keyBuilder:async i=>{let a=i.authType;if(o.key)return o.key;if(i.authType==="oauth_2")return We(i,{plugin:"googlecalendar",tokenUrl:"https://oauth2.googleapis.com/token"});throw new Ne("googlecalendar","oauth_2")},pluginWebhookMatcher:i=>{let a=i.headers;if(!(a.from==="noreply@google.com"||typeof a["user-agent"]=="string"&&a["user-agent"].includes("APIs-Google")))return!1;let d=i.body;if(!d?.message?.data)return!1;try{let p=y(d.message.data);return!!p.resourceUri&&p.resourceUri.includes("calendar")}catch{return!1}},pluginTenantWebhookMatcher:Y,subscribe:_}}export{k as createGoogleCalendarWebhookMatcher,y as decodePubSubMessage,Fe as googleCalendarAuthConfig,It as googlecalendar,qe as googlecalendarEndpointSchemas};
@@ -0,0 +1,9 @@
1
+ import { googleChannelSubscribe } from 'corsair/core';
2
+ /**
3
+ * BYO subscribe for Google Calendar — thin wrapper over the shared Google
4
+ * channel watch, on the connected user's primary calendar.
5
+ */
6
+ export declare const googlecalendarSubscribe: (ctx: Parameters<typeof googleChannelSubscribe>[0], input: {
7
+ webhookUrl: string;
8
+ }) => Promise<import("corsair/core").CorsairPluginSubscribeResult | null>;
9
+ //# sourceMappingURL=subscribe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe.d.ts","sourceRoot":"","sources":["../subscribe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GACnC,KAAK,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,EACjD,OAAO;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,wEAM3B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=subscribe.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe.test.d.ts","sourceRoot":"","sources":["../subscribe.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { RawWebhookRequest, WebhookTenantMatch } from 'corsair/core';
2
+ export declare function matchGoogleCalendarTenantWebhook(request: RawWebhookRequest): WebhookTenantMatch | null;
3
+ //# sourceMappingURL=tenant-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-matcher.d.ts","sourceRoot":"","sources":["../../webhooks/tenant-matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAW1E,wBAAgB,gCAAgC,CAC/C,OAAO,EAAE,iBAAiB,GACxB,kBAAkB,GAAG,IAAI,CAiB3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corsair-dev/googlecalendar",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Google calendar plugin for Corsair",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -18,7 +18,7 @@
18
18
  }
19
19
  },
20
20
  "peerDependencies": {
21
- "corsair": ">=0.1.0",
21
+ "corsair": ">=0.1.120",
22
22
  "zod": "^4.1.13"
23
23
  },
24
24
  "devDependencies": {
@@ -28,7 +28,7 @@
28
28
  "typescript": "^5.9.3",
29
29
  "zod": "^4.1.13",
30
30
  "jest": "^29.7.0",
31
- "corsair": "0.1.76"
31
+ "corsair": "0.1.120"
32
32
  },
33
33
  "keywords": [
34
34
  "corsair",