@corsair-dev/gmail 0.1.3 → 0.1.5

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,7 @@ export declare class GmailAPIError 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
- }>;
5
+ export declare const GMAIL_API_BASE = "https://gmail.googleapis.com/gmail/v1";
17
6
  type GmailRequestOptions = {
18
7
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
19
8
  body?: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../client.ts"],"names":[],"mappings":"AAGA,qBAAa,aAAc,SAAQ,KAAK;aAGtB,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,mBAAmB,GAAG;IAC1B,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,gBAAgB,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,CAAC,CAAC,CA2BZ;AAUD;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,CAAC,EACpD,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,mBAAwB,GAC/B,OAAO,CAAC,CAAC,CAAC,CAUZ"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../client.ts"],"names":[],"mappings":"AAGA,qBAAa,aAAc,SAAQ,KAAK;aAGtB,IAAI,CAAC,EAAE,MAAM;gBAD7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA;CAK9B;AAED,eAAO,MAAM,cAAc,0CAA0C,CAAC;AAEtE,KAAK,mBAAmB,GAAG;IAC1B,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,gBAAgB,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,CAAC,CAAC,CA2BZ;AAUD;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,CAAC,EACpD,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,mBAAwB,GAC/B,OAAO,CAAC,CAAC,CAAC,CAUZ"}
package/dist/index.d.ts CHANGED
@@ -3,13 +3,19 @@ import type { GmailEndpointInputs, GmailEndpointOutputs } from './endpoints';
3
3
  import type { GmailCredentials } from './schema';
4
4
  import { GmailSchema } from './schema';
5
5
  import type { GmailWebhookOutputs, GmailWebhookPayload, MessageDeletedEvent, MessageLabelChangedEvent, MessageReceivedEvent } from './webhooks';
6
+ import type { GmailWebhookEventType } from './webhooks/types';
6
7
  /**
7
8
  * Auth config extending the base OAuth2 fields with Gmail-specific fields.
8
- * - integration: topic_id (Google Cloud Pub/Sub topic for push notifications)
9
+ * - integration: topic_id (Google Cloud Pub/Sub topic for push notifications),
10
+ * pubsub_audience (push subscription's OIDC identity — SA email or audience —
11
+ * reported to Hub as the webhook verification secret for verifyPubsub)
12
+ * - account: email_address (mailbox identity), last_history_id (cursor of the
13
+ * last processed history record, used as startHistoryId for webhook syncs)
9
14
  */
10
15
  export declare const gmailAuthConfig: {
11
16
  readonly oauth_2: {
12
- readonly integration: readonly ["topic_id"];
17
+ readonly integration: readonly ["topic_id", "pubsub_audience"];
18
+ readonly account: readonly ["email_address", "last_history_id"];
13
19
  };
14
20
  };
15
21
  export type GmailContext = CorsairPluginContext<typeof GmailSchema, GmailPluginOptions, undefined, typeof gmailAuthConfig>;
@@ -674,6 +680,16 @@ export type GmailPluginOptions = {
674
680
  credentials?: GmailCredentials;
675
681
  hooks?: InternalGmailPlugin['hooks'];
676
682
  webhookHooks?: InternalGmailPlugin['webhookHooks'];
683
+ /**
684
+ * Which Gmail webhook event types to process and store.
685
+ * When omitted, all event types are processed (default).
686
+ *
687
+ * @example
688
+ * gmail({
689
+ * webhookEvents: ['messageReceived', 'messageDeleted'],
690
+ * })
691
+ */
692
+ webhookEvents?: GmailWebhookEventType[];
677
693
  /**
678
694
  * Permission configuration for the Gmail plugin.
679
695
  * Controls what the AI agent is allowed to do.
@@ -692,7 +708,7 @@ export type BaseGmailPlugin<T extends GmailPluginOptions> = CorsairPlugin<'gmail
692
708
  export type InternalGmailPlugin = BaseGmailPlugin<GmailPluginOptions>;
693
709
  export type ExternalGmailPlugin<T extends GmailPluginOptions> = BaseGmailPlugin<T>;
694
710
  export declare function gmail<const T extends GmailPluginOptions>(incomingOptions?: GmailPluginOptions & T): ExternalGmailPlugin<T>;
695
- export type { GmailEventName, GmailPushNotification, GmailWebhookEvent, GmailWebhookOutputs, GmailWebhookPayload, MessageDeletedEvent, MessageLabelChangedEvent, MessageReceivedEvent, PubSubMessage, PubSubNotification, } from './webhooks/types';
711
+ export type { GmailEventName, GmailPushNotification, GmailWebhookEvent, GmailWebhookEventType, GmailWebhookOutputs, GmailWebhookPayload, MessageDeletedEvent, MessageLabelChangedEvent, MessageReceivedEvent, PubSubMessage, PubSubNotification, } from './webhooks/types';
696
712
  export { createGmailWebhookMatcher, decodePubSubMessage, } from './webhooks/types';
697
713
  export type { GmailEndpointInputs, GmailEndpointOutputs, } from './endpoints/types';
698
714
  export type { GmailCredentials } from './schema';
@@ -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{request as Ae}from"corsair/http";var j=class extends Error{constructor(a,o){super(a);this.code=o;this.name="GmailAPIError"}},Oe="https://gmail.googleapis.com/gmail/v1";async function je(e,t,a){let o=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:e,client_secret:t,refresh_token:a,grant_type:"refresh_token"})});if(!o.ok){let i=await o.text();throw new j(`Failed to refresh access token: ${i}`,o.status)}return await o.json()}async function B({accessToken:e,expiresAt:t,clientId:a,clientSecret:o,refreshToken:n,forceRefresh:i=!1}){let d=Math.floor(Date.now()/1e3);if(!i&&e&&t&&Number(t)>d+300)return{accessToken:e,expiresAt:Number(t),refreshed:!1};let p=await je(a,o,n);return{accessToken:p.access_token,expiresAt:d+p.expires_in,refreshed:!0}}async function y(e,t,a={}){let{method:o="GET",body:n,query:i}=a;return await Ae({BASE:Oe,VERSION:"1.0.0",WITH_CREDENTIALS:!1,CREDENTIALS:"omit",TOKEN:t,HEADERS:{"Content-Type":"application/json"}},{method:o,url:e,body:o==="POST"||o==="PUT"||o==="PATCH"?n:void 0,mediaType:"application/json",query:o==="GET"?i:void 0})}function Be(e){return e instanceof Error&&"status"in e&&e.status===401}async function c(e,t,a={}){try{return await y(e,t.key,a)}catch(o){if(Be(o)&&t._refreshAuth){let n=await t._refreshAuth();return await y(e,n,a)}throw o}}import{logEventFromContext as M}from"corsair/core";var z=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/drafts`,e,{method:"GET",query:{maxResults:t.maxResults,pageToken:t.pageToken,q:t.q}});if(a.drafts&&e.db.drafts)try{for(let o of a.drafts)o.id&&await e.db.drafts.upsertByEntityId(o.id,{...o,id:o.id,messageId:o.message?.id,createdAt:new Date})}catch(o){console.warn("Failed to save drafts to database:",o)}return await M(e,"gmail.drafts.list",{...t},"completed"),a},V=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/drafts/${t.id}`,e,{method:"GET",query:{format:t.format}});if(a.id&&e.db.drafts)try{await e.db.drafts.upsertByEntityId(a.id,{...a,id:a.id,messageId:a.message?.id,createdAt:new Date})}catch(o){console.warn("Failed to save draft to database:",o)}return await M(e,"gmail.drafts.get",{...t},"completed"),a},K=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/drafts`,e,{method:"POST",body:t.draft});return a.id&&await e.endpoints.drafts.get({id:a.id,userId:t.userId}),await M(e,"gmail.drafts.create",{...t},"completed"),a},Y=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/drafts/${t.id}`,e,{method:"PUT",body:t.draft});return a.id&&await e.endpoints.drafts.get({id:a.id,userId:t.userId}),await M(e,"gmail.drafts.update",{...t},"completed"),a},Z=async(e,t)=>{if(await c(`/users/${t.userId||"me"}/drafts/${t.id}`,e,{method:"DELETE"}),e.db.drafts)try{await e.db.drafts.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete draft from database:",a)}await M(e,"gmail.drafts.delete",{...t},"completed")},J=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/drafts/send`,e,{method:"POST",body:{id:t.id,message:t.message}});return await M(e,"gmail.drafts.send",{...t},"completed"),a};import{logEventFromContext as v}from"corsair/core";var X=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/labels`,e,{method:"GET"});if(a.labels&&e.db.labels)try{for(let o of a.labels)o.id&&await e.db.labels.upsertByEntityId(o.id,{...o,id:o.id,createdAt:new Date})}catch(o){console.warn("Failed to save labels to database:",o)}return await v(e,"gmail.labels.list",{...t},"completed"),a},Q=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/labels/${t.id}`,e,{method:"GET"});if(a.id&&e.db.labels)try{await e.db.labels.upsertByEntityId(a.id,{id:a.id,name:a.name,messageListVisibility:a.messageListVisibility,labelListVisibility:a.labelListVisibility,type:a.type,messagesTotal:a.messagesTotal,messagesUnread:a.messagesUnread,threadsTotal:a.threadsTotal,threadsUnread:a.threadsUnread,createdAt:new Date})}catch(o){console.warn("Failed to save label to database:",o)}return await v(e,"gmail.labels.get",{...t},"completed"),a},ee=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/labels`,e,{method:"POST",body:t.label});return a.id&&await e.endpoints.labels.get({id:a.id,userId:t.userId}),await v(e,"gmail.labels.create",{...t},"completed"),a},te=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/labels/${t.id}`,e,{method:"PUT",body:t.label});return a.id&&await e.endpoints.labels.get({id:a.id,userId:t.userId}),await v(e,"gmail.labels.update",{...t},"completed"),a},se=async(e,t)=>{if(await c(`/users/${t.userId||"me"}/labels/${t.id}`,e,{method:"DELETE"}),e.db.labels)try{await e.db.labels.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete label from database:",a)}await v(e,"gmail.labels.delete",{...t},"completed")};import{logEventFromContext as I}from"corsair/core";function U(e,t){return e?.headers?e.headers.find(o=>o.name?.toLowerCase()===t.toLowerCase())?.value:void 0}function _e(e){if(e.payload)return U(e.payload,"Subject")}function Ne(e){if(e.payload)return U(e.payload,"From")}function We(e){if(e.payload)return U(e.payload,"To")}function ae(e){if(!e)return;let t,a;if(e.body?.data)try{let o=Buffer.from(e.body.data,"base64").toString("utf-8");e.mimeType==="text/plain"?t=o:e.mimeType==="text/html"&&(a=o)}catch{}if(e.parts&&e.parts.length>0)for(let o of e.parts){let n=ae(o);n&&(o.mimeType==="text/plain"?t=n:o.mimeType==="text/html"&&!t&&(a=n))}return t||a}function qe(e){if(e.payload)return ae(e.payload)}var oe=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/messages`,e,{method:"GET",query:{q:t.q,maxResults:t.maxResults,pageToken:t.pageToken,labelIds:t.labelIds?.join(","),includeSpamTrash:t.includeSpamTrash}});if(a.messages&&e.db.messages)try{for(let o of a.messages)o.id&&await e.db.messages.upsertByEntityId(o.id,{...o,id:o.id,createdAt:new Date})}catch(o){console.warn("Failed to save messages to database:",o)}return await I(e,"gmail.messages.list",{...t},"completed"),a},ie=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/messages/${t.id}`,e,{method:"GET",query:{format:t.format,metadataHeaders:t.metadataHeaders?.join(",")}});if(a.id&&e.db.messages)try{let o=_e(a),n=qe(a),i=Ne(a),d=We(a);await e.db.messages.upsertByEntityId(a.id,{...a,subject:o,body:n,from:i,to:d,id:a.id,createdAt:new Date})}catch(o){console.warn("Failed to save message to database:",o)}return await I(e,"gmail.messages.get",{...t},"completed"),a},ne=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/messages/send`,e,{method:"POST",body:{raw:t.raw,threadId:t.threadId}});return a.id&&await e.endpoints.messages.get({id:a.id,userId:t.userId}),await I(e,"gmail.messages.send",{...t},"completed"),a},re=async(e,t)=>{if(await c(`/users/${t.userId||"me"}/messages/${t.id}`,e,{method:"DELETE"}),e.db.messages)try{await e.db.messages.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete message from database:",a)}await I(e,"gmail.messages.delete",{...t},"completed")},de=async(e,t)=>{let a={};t.addLabelIds&&t.addLabelIds.length>0&&(a.addLabelIds=t.addLabelIds),t.removeLabelIds&&t.removeLabelIds.length>0&&(a.removeLabelIds=t.removeLabelIds);let o=await c(`/users/${t.userId||"me"}/messages/${t.id}/modify`,e,{method:"POST",body:a});return o.id&&await e.endpoints.messages.get({id:o.id,userId:t.userId}),await I(e,"gmail.messages.modify",{...t},"completed"),o},le=async(e,t)=>{let a={ids:t.ids};t.addLabelIds&&t.addLabelIds.length>0&&(a.addLabelIds=t.addLabelIds),t.removeLabelIds&&t.removeLabelIds.length>0&&(a.removeLabelIds=t.removeLabelIds),await c(`/users/${t.userId||"me"}/messages/batchModify`,e,{method:"POST",body:a}),await I(e,"gmail.messages.batchModify",{...t},"completed")},me=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/messages/${t.id}/trash`,e,{method:"POST"});return a.id&&await e.endpoints.messages.get({id:a.id,userId:t.userId}),await I(e,"gmail.messages.trash",{...t},"completed"),a},pe=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/messages/${t.id}/untrash`,e,{method:"POST"});return a.id&&await e.endpoints.messages.get({id:a.id,userId:t.userId}),await I(e,"gmail.messages.untrash",{...t},"completed"),a};import{logEventFromContext as S}from"corsair/core";var ge=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/threads`,e,{method:"GET",query:{q:t.q,maxResults:t.maxResults,pageToken:t.pageToken,labelIds:t.labelIds?.join(","),includeSpamTrash:t.includeSpamTrash}});if(a.threads&&e.db.threads)try{for(let o of a.threads)o.id&&await e.db.threads.upsertByEntityId(o.id,{...o,id:o.id,createdAt:new Date})}catch(o){console.warn("Failed to save threads to database:",o)}return await S(e,"gmail.threads.list",{...t},"completed"),a},ce=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/threads/${t.id}`,e,{method:"GET",query:{format:t.format,metadataHeaders:t.metadataHeaders?.join(",")}});if(a.id&&e.db.threads)try{await e.db.threads.upsertByEntityId(a.id,{...a,id:a.id,createdAt:new Date})}catch(o){console.warn("Failed to save thread to database:",o)}return await S(e,"gmail.threads.get",{...t},"completed"),a},ue=async(e,t)=>{let a={};t.addLabelIds&&t.addLabelIds.length>0&&(a.addLabelIds=t.addLabelIds),t.removeLabelIds&&t.removeLabelIds.length>0&&(a.removeLabelIds=t.removeLabelIds);let o=await c(`/users/${t.userId||"me"}/threads/${t.id}/modify`,e,{method:"POST",body:a});return o.id&&await e.endpoints.threads.get({id:o.id,userId:t.userId}),await S(e,"gmail.threads.modify",{...t},"completed"),o},he=async(e,t)=>{if(await c(`/users/${t.userId||"me"}/threads/${t.id}`,e,{method:"DELETE"}),e.db.threads)try{await e.db.threads.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete thread from database:",a)}await S(e,"gmail.threads.delete",{...t},"completed")},fe=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/threads/${t.id}/trash`,e,{method:"POST"});return a.id&&await e.endpoints.threads.get({id:a.id,userId:t.userId}),await S(e,"gmail.threads.trash",{...t},"completed"),a},be=async(e,t)=>{let a=await c(`/users/${t.userId||"me"}/threads/${t.id}/untrash`,e,{method:"POST"});return a.id&&await e.endpoints.threads.get({id:a.id,userId:t.userId}),await S(e,"gmail.threads.untrash",{...t},"completed"),a};import{z as s}from"zod";var ye="Base64url-encoded RFC 2822 email \u2014 do NOT pass plain email text. Build the MIME message (From, To, Subject, Content-Type headers, blank line, body; lines separated by \\r\\n), then base64url-encode: standard base64, replace + with -, / with _, remove trailing =.",$=s.object({raw:s.string().optional().describe(ye),threadId:s.string().optional()}),ze=s.object({userId:s.string().optional(),q:s.string().optional(),maxResults:s.number().optional(),pageToken:s.string().optional(),labelIds:s.array(s.string()).optional(),includeSpamTrash:s.boolean().optional()}),Ve=s.object({userId:s.string().optional(),id:s.string(),format:s.enum(["minimal","full","raw","metadata"]).optional(),metadataHeaders:s.array(s.string()).optional()}),Ke=s.object({userId:s.string().optional(),raw:s.string().describe(ye),threadId:s.string().optional()}),Ye=s.object({userId:s.string().optional(),id:s.string()}),Ze=s.object({userId:s.string().optional(),id:s.string(),addLabelIds:s.array(s.string()).optional(),removeLabelIds:s.array(s.string()).optional()}),Je=s.object({userId:s.string().optional(),ids:s.array(s.string()).optional(),addLabelIds:s.array(s.string()).optional(),removeLabelIds:s.array(s.string()).optional()}),Xe=s.object({userId:s.string().optional(),id:s.string()}),Qe=s.object({userId:s.string().optional(),id:s.string()}),et=s.object({userId:s.string().optional()}),tt=s.object({userId:s.string().optional(),id:s.string()}),st=s.object({userId:s.string().optional(),label:s.object({name:s.string().optional(),messageListVisibility:s.enum(["show","hide"]).optional(),labelListVisibility:s.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),color:s.object({textColor:s.string().optional(),backgroundColor:s.string().optional()}).optional()})}),at=s.object({userId:s.string().optional(),id:s.string(),label:s.object({name:s.string().optional(),messageListVisibility:s.enum(["show","hide"]).optional(),labelListVisibility:s.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),color:s.object({textColor:s.string().optional(),backgroundColor:s.string().optional()}).optional()})}),ot=s.object({userId:s.string().optional(),id:s.string()}),it=s.object({userId:s.string().optional(),maxResults:s.number().optional(),pageToken:s.string().optional(),q:s.string().optional()}),nt=s.object({userId:s.string().optional(),id:s.string(),format:s.enum(["minimal","full","raw","metadata"]).optional()}),rt=s.object({userId:s.string().optional(),draft:s.object({message:$.optional()}).optional().describe("Draft payload. message.raw must be a base64url-encoded RFC 2822 email, not plain text.")}),dt=s.object({userId:s.string().optional(),id:s.string(),draft:s.object({message:$.optional()}).optional().describe("Updated draft payload. message.raw must be a base64url-encoded RFC 2822 email, not plain text.")}),lt=s.object({userId:s.string().optional(),id:s.string()}),mt=s.object({userId:s.string().optional(),id:s.string().optional(),message:$.optional().describe("Optional message body when sending without a draft id. raw must be base64url-encoded RFC 2822, not plain text.")}),pt=s.object({userId:s.string().optional(),q:s.string().optional(),maxResults:s.number().optional(),pageToken:s.string().optional(),labelIds:s.array(s.string()).optional(),includeSpamTrash:s.boolean().optional()}),gt=s.object({userId:s.string().optional(),id:s.string(),format:s.enum(["minimal","full","metadata"]).optional(),metadataHeaders:s.array(s.string()).optional()}),ct=s.object({userId:s.string().optional(),id:s.string(),addLabelIds:s.array(s.string()).optional(),removeLabelIds:s.array(s.string()).optional()}),ut=s.object({userId:s.string().optional(),id:s.string()}),ht=s.object({userId:s.string().optional(),id:s.string()}),ft=s.object({userId:s.string().optional(),id:s.string()}),bt=s.object({userId:s.string().optional()}),u={messagesList:ze,messagesGet:Ve,messagesSend:Ke,messagesDelete:Ye,messagesModify:Ze,messagesBatchModify:Je,messagesTrash:Xe,messagesUntrash:Qe,labelsList:et,labelsGet:tt,labelsCreate:st,labelsUpdate:at,labelsDelete:ot,draftsList:it,draftsGet:nt,draftsCreate:rt,draftsUpdate:dt,draftsDelete:lt,draftsSend:mt,threadsList:pt,threadsGet:gt,threadsModify:ct,threadsDelete:ut,threadsTrash:ht,threadsUntrash:ft,usersGetProfile:bt},yt=s.object({name:s.string().optional(),value:s.string().optional()}),Et=s.object({attachmentId:s.string().optional(),size:s.number().optional(),data:s.string().optional()}),Gt=s.object({partId:s.string().optional(),mimeType:s.string().optional(),filename:s.string().optional(),headers:s.array(yt).optional(),body:Et.optional()}),Ee=Gt.extend({parts:s.lazy(()=>s.array(Ee).optional())}),E=s.object({id:s.string().optional(),threadId:s.string().optional(),labelIds:s.array(s.string()).optional(),snippet:s.string().optional(),historyId:s.string().optional(),internalDate:s.union([s.string(),s.number(),s.date()]).transform(e=>{if(e instanceof Date)return e;if(typeof e=="number")return new Date(e);if(typeof e=="string"){let t=Number(e);return isNaN(t)?null:new Date(t)}return null}).nullable().optional(),sizeEstimate:s.number().optional(),payload:Ee.optional(),raw:s.string().optional().describe("Full RFC 2822 message in base64url encoding (when format=raw). Not plain text \u2014 decode base64url before reading headers/body.")}),It=s.object({messages:s.array(E).optional(),nextPageToken:s.string().optional(),resultSizeEstimate:s.number().optional()}),wt=s.object({textColor:s.string().optional(),backgroundColor:s.string().optional()}),x=s.object({id:s.string().optional(),name:s.string().optional(),messageListVisibility:s.enum(["show","hide"]).optional(),labelListVisibility:s.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),type:s.enum(["system","user"]).optional(),messagesTotal:s.number().optional(),messagesUnread:s.number().optional(),threadsTotal:s.number().optional(),threadsUnread:s.number().optional(),color:wt.optional()}),Tt=s.object({labels:s.array(x).optional()}),R=s.object({id:s.string().optional(),message:E.optional()}),Mt=s.object({drafts:s.array(R).optional(),nextPageToken:s.string().optional(),resultSizeEstimate:s.number().optional()}),P=s.object({id:s.string().optional(),snippet:s.string().optional(),historyId:s.string().optional(),messages:s.array(E).optional()}),St=s.object({threads:s.array(P).optional(),nextPageToken:s.string().optional(),resultSizeEstimate:s.number().optional()}),Lt=s.object({emailAddress:s.string().optional(),messagesTotal:s.number().optional(),threadsTotal:s.number().optional(),historyId:s.string().optional()}),h={messagesList:It,messagesGet:E,messagesSend:E,messagesDelete:s.void(),messagesModify:E,messagesBatchModify:s.void(),messagesTrash:E,messagesUntrash:E,labelsList:Tt,labelsGet:x,labelsCreate:x,labelsUpdate:x,labelsDelete:s.void(),draftsList:Mt,draftsGet:R,draftsCreate:R,draftsUpdate:R,draftsDelete:s.void(),draftsSend:E,threadsList:St,threadsGet:P,threadsModify:P,threadsDelete:s.void(),threadsTrash:P,threadsUntrash:P,usersGetProfile:Lt};var G={list:oe,get:ie,send:ne,delete:re,modify:de,batchModify:le,trash:me,untrash:pe},L={list:X,get:Q,create:ee,update:te,delete:se},w={list:z,get:V,create:K,update:Y,delete:Z,send:J},T={list:ge,get:ce,modify:ue,delete:he,trash:fe,untrash:be};import{z as C}from"zod";import{z as r}from"zod";var kt=r.object({name:r.string().optional(),value:r.string().optional()}),vt=r.object({attachmentId:r.string().optional(),size:r.number().optional(),data:r.string().optional()}),Ge=r.lazy(()=>r.object({partId:r.string().optional(),mimeType:r.string().optional(),filename:r.string().optional(),headers:r.array(kt).optional(),body:vt.optional(),parts:r.array(Ge).optional()})),Ie=r.object({id:r.string(),threadId:r.string().optional(),labelIds:r.array(r.string()).optional(),snippet:r.string().optional(),historyId:r.string().optional(),internalDate:r.string().optional(),sizeEstimate:r.number().optional(),payload:Ge.optional(),raw:r.string().optional(),subject:r.string().optional(),body:r.string().optional(),from:r.string().optional(),to:r.string().optional(),createdAt:r.coerce.date().nullable().optional()}),we=r.object({id:r.string(),name:r.string().optional(),messageListVisibility:r.enum(["show","hide"]).optional(),labelListVisibility:r.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),type:r.enum(["system","user"]).optional(),messagesTotal:r.number().optional(),messagesUnread:r.number().optional(),threadsTotal:r.number().optional(),threadsUnread:r.number().optional(),createdAt:r.coerce.date().nullable().optional()}),Te=r.object({id:r.string(),messageId:r.string().optional(),createdAt:r.coerce.date().nullable().optional()}),Me=r.object({id:r.string(),snippet:r.string().optional(),historyId:r.string().optional(),createdAt:r.coerce.date().nullable().optional()});var fs=C.object({clientId:C.string(),clientSecret:C.string(),accessToken:C.string(),refreshToken:C.string()}),_={version:"1.0.0",entities:{messages:Ie,labels:we,drafts:Te,threads:Me}};import{logEventFromContext as D}from"corsair/core";import{z as l}from"zod";var Pt=l.object({data:l.string().optional(),attributes:l.record(l.string(),l.string()).optional(),messageId:l.string().optional(),publishTime:l.string().optional()}),Se=l.object({message:Pt.optional(),subscription:l.string().optional(),event:l.unknown().optional()}),Es=l.object({emailAddress:l.string().optional(),historyId:l.string().optional()}),Ct=l.object({type:l.literal("messageReceived"),emailAddress:l.string(),historyId:l.string(),message:l.custom()}),Dt=l.object({type:l.literal("messageDeleted"),emailAddress:l.string(),historyId:l.string(),message:l.custom()}),xt=l.object({type:l.literal("messageLabelChanged"),emailAddress:l.string(),historyId:l.string(),message:l.custom(),labelsAdded:l.array(l.string()).optional(),labelsRemoved:l.array(l.string()).optional()}),Le=l.union([Ct,Dt,xt]);function k(e){let t=Buffer.from(e,"base64").toString("utf-8");return JSON.parse(t)}function N(e){return t=>{let a=t.body;if(!a.message?.data)return!1;try{let o=k(a.message.data);return!!o.historyId&&!!o.emailAddress}catch{return!1}}}var Rt=100,At=10,Ot=10;function W(e,t){return e?.headers?e.headers.find(o=>o.name?.toLowerCase()===t.toLowerCase())?.value:void 0}function jt(e){if(e.payload)return W(e.payload,"Subject")}function Bt(e){if(e.payload)return W(e.payload,"From")}function Ut(e){if(e.payload)return W(e.payload,"To")}function Pe(e){if(!e)return;let t,a;if(e.body?.data)try{let o=Buffer.from(e.body.data,"base64").toString("utf-8");e.mimeType==="text/plain"?t=o:e.mimeType==="text/html"&&(a=o)}catch{}if(e.parts&&e.parts.length>0)for(let o of e.parts){let n=Pe(o);n&&(o.mimeType==="text/plain"?t=n:o.mimeType==="text/html"&&!t&&(a=n))}return t||a}function $t(e){if(e.payload)return Pe(e.payload)}function _t(e){let t=[],a=[],o=[];if(!e)return{added:t,deleted:a,modified:o};for(let n of e){if(n.messagesAdded)for(let i of n.messagesAdded)i.message?.id&&t.push(i.message.id);if(n.messagesDeleted)for(let i of n.messagesDeleted)i.message?.id&&a.push(i.message.id);if(n.labelsAdded||n.labelsRemoved){if(n.labelsAdded)for(let i of n.labelsAdded)i.message?.id&&o.push(i.message.id);if(n.labelsRemoved)for(let i of n.labelsRemoved)i.message?.id&&o.push(i.message.id)}}return{added:[...new Set(t)],deleted:[...new Set(a)],modified:[...new Set(o)]}}async function q(e,t,a){let[o,n]=await Promise.all([y(`/users/${t}/messages/${a}`,e,{method:"GET",query:{format:"full"}}),y(`/users/${t}/messages/${a}`,e,{method:"GET",query:{format:"raw"}}).catch(()=>null)]);return{...o,raw:n?.raw}}async function Nt(e,t,a,o){return y(`/users/${t}/messages/${a}/attachments/${o}`,e,{method:"GET"})}async function Ce(e,t,a){if(!a.payload)return a;let o=async i=>{if(!i)return i;if(i.body?.attachmentId)try{let d=await Nt(e,t,a.id,i.body.attachmentId);return{...i,body:{...i.body,data:d.data,size:d.size}}}catch(d){return console.warn(`Failed to fetch attachment ${i.body.attachmentId} for message ${a.id}:`,d),i}if(i.parts&&i.parts.length>0){let d=await Promise.all(i.parts.map(o));return{...i,parts:d.filter(m=>m!==void 0)}}return i},n=await o(a.payload);return{...a,payload:n}}function Wt(e){let t=Number(e);return t>1?String(t-1):e}async function De(e,t){return!e.db?.messages||!t.id?"":(await e.db.messages.upsertByEntityId(t.id,{...t,id:t.id,subject:jt(t),body:$t(t),from:Bt(t),to:Ut(t),createdAt:new Date}))?.id??""}async function qt(e,t,a,o){let n=await y(`/users/${a}/messages`,t,{method:"GET",query:{maxResults:At}}),i=[],d=[];if(!n.messages?.length)return{added:i,modified:d};let m=Number(o);for(let p of n.messages)if(p.id)try{let g=await q(t,a,p.id);(g.historyId?Number(g.historyId):0)>=m-Ot&&(e.db?.messages&&await e.db.messages.findByEntityId(p.id)?d.push(p.id):i.push(p.id))}catch{}return{added:i,modified:d}}async function ke(e,t,a,o){let n=null,i="";for(let d of o)try{let m=await q(t,a,d),p=await Ce(t,a,m);n||(n=p);try{let g=await De(e,p);!i&&g&&(i=g)}catch(g){throw console.error(`Failed to save message ${p.id} to database:`,g),g}}catch(m){console.warn(`Failed to process message ${d}:`,m)}return{message:n,corsairEntityId:i}}async function Ft(e,t,a,o){let n=null,i="";if(!e.db?.messages)return{message:null,corsairEntityId:i};for(let d of o)try{let m=null;try{m=await y(`/users/${a}/messages/${d}`,t,{method:"GET",query:{format:"full"}})}catch(p){if(p?.statusCode===404)continue}if(!n&&m&&(n=m),!i){let p=await e.db.messages.findByEntityId(d);p&&(i=p.id)}await e.db.messages.deleteByEntityId(d)}catch(m){console.warn(`Failed to delete message ${d} from database:`,m)}return{message:n,corsairEntityId:i}}async function ve(e,t,a,o){let n=null,i="";if(!e.db?.messages)return{message:null,corsairEntityId:i};for(let d of o)try{let m=await q(t,a,d),p=await Ce(t,a,m);n||(n=p);try{let g=await De(e,p);!i&&g&&(i=g)}catch(g){throw console.error(`Failed to update message ${p.id} in database:`,g),g}}catch(m){console.warn(`Failed to process message ${d}:`,m)}return{message:n,corsairEntityId:i}}var xe={match:N("messageChanged"),handler:async(e,t)=>{let a=t.payload;if(!a.message?.data)return{success:!1,error:"No message data in notification"};let o=k(a.message.data);if(!o.historyId||!o.emailAddress)return{success:!1,error:"Invalid push notification format"};let n=e.key,i=o.emailAddress,d=o.historyId;try{let m=Wt(d),p=await y(`/users/${i}/history`,n,{method:"GET",query:{startHistoryId:m,maxResults:Rt}}),{added:g,deleted:A,modified:O}=_t(p.history);if(O.length>0){let f=await ve(e,n,i,O),b={type:"messageLabelChanged",emailAddress:i,historyId:d,message:f.message??{}};return await D(e,"gmail.webhook.messageLabelChanged",{...b},"completed"),{success:!0,corsairEntityId:f.corsairEntityId,data:b}}if(g.length>0){let f=await ke(e,n,i,g),b={type:"messageReceived",emailAddress:i,historyId:d,message:f.message??{}};return await D(e,"gmail.webhook.messageReceived",{...b},"completed"),{success:!0,corsairEntityId:f.corsairEntityId,data:b}}if(A.length>0){let f=await Ft(e,n,i,A),b={type:"messageDeleted",emailAddress:i,historyId:d,message:f.message??{}};return await D(e,"gmail.webhook.messageDeleted",{...b},"completed"),{success:!0,corsairEntityId:f.corsairEntityId,data:b}}let{added:F,modified:H}=await qt(e,n,i,d);if(H.length>0){let f=await ve(e,n,i,H),b={type:"messageLabelChanged",emailAddress:i,historyId:d,message:f.message??{}};return await D(e,"gmail.webhook.messageLabelChanged",{...b},"completed"),{success:!0,corsairEntityId:f.corsairEntityId,data:b}}if(F.length>0){let f=await ke(e,n,i,F),b={type:"messageReceived",emailAddress:i,historyId:d,message:f.message??{}};return await D(e,"gmail.webhook.messageReceived",{...b},"completed"),{success:!0,corsairEntityId:f.corsairEntityId,data:b}}return{success:!0,corsairEntityId:"",data:{type:"messageReceived",emailAddress:i,historyId:d,message:{}}}}catch(m){return console.error("Failed to process Gmail webhook:",m),{success:!1,error:`Failed to process message: ${m instanceof Error?m.message:"Unknown error"}`}}}};var Re={messageChanged:xe};var Ht={oauth_2:{integration:["topic_id"]}},zt={messages:{list:G.list,get:G.get,send:G.send,delete:G.delete,modify:G.modify,batchModify:G.batchModify,trash:G.trash,untrash:G.untrash},labels:{list:L.list,get:L.get,create:L.create,update:L.update,delete:L.delete},drafts:{list:w.list,get:w.get,create:w.create,update:w.update,delete:w.delete,send:w.send},threads:{list:T.list,get:T.get,modify:T.modify,delete:T.delete,trash:T.trash,untrash:T.untrash}},Vt={"messages.list":{input:u.messagesList,output:h.messagesList},"messages.get":{input:u.messagesGet,output:h.messagesGet},"messages.send":{input:u.messagesSend,output:h.messagesSend},"messages.delete":{input:u.messagesDelete,output:h.messagesDelete},"messages.modify":{input:u.messagesModify,output:h.messagesModify},"messages.batchModify":{input:u.messagesBatchModify,output:h.messagesBatchModify},"messages.trash":{input:u.messagesTrash,output:h.messagesTrash},"messages.untrash":{input:u.messagesUntrash,output:h.messagesUntrash},"labels.list":{input:u.labelsList,output:h.labelsList},"labels.get":{input:u.labelsGet,output:h.labelsGet},"labels.create":{input:u.labelsCreate,output:h.labelsCreate},"labels.update":{input:u.labelsUpdate,output:h.labelsUpdate},"labels.delete":{input:u.labelsDelete,output:h.labelsDelete},"drafts.list":{input:u.draftsList,output:h.draftsList},"drafts.get":{input:u.draftsGet,output:h.draftsGet},"drafts.create":{input:u.draftsCreate,output:h.draftsCreate},"drafts.update":{input:u.draftsUpdate,output:h.draftsUpdate},"drafts.delete":{input:u.draftsDelete,output:h.draftsDelete},"drafts.send":{input:u.draftsSend,output:h.draftsSend},"threads.list":{input:u.threadsList,output:h.threadsList},"threads.get":{input:u.threadsGet,output:h.threadsGet},"threads.modify":{input:u.threadsModify,output:h.threadsModify},"threads.delete":{input:u.threadsDelete,output:h.threadsDelete},"threads.trash":{input:u.threadsTrash,output:h.threadsTrash},"threads.untrash":{input:u.threadsUntrash,output:h.threadsUntrash}},Kt={messageChanged:Re.messageChanged},Yt={messageChanged:{description:"A Gmail message was received, deleted, or had its labels changed",payload:Se,response:Le}},Zt="oauth_2",Jt={"messages.list":{riskLevel:"read",description:"List messages in a mailbox"},"messages.get":{riskLevel:"read",description:"Get a specific message"},"messages.send":{riskLevel:"write",description:"Send an email to one or more recipients"},"messages.delete":{riskLevel:"destructive",irreversible:!0,description:"Permanently delete a message [DESTRUCTIVE \xB7 IRREVERSIBLE]"},"messages.modify":{riskLevel:"write",description:"Add or remove labels from a message"},"messages.batchModify":{riskLevel:"write",description:"Add or remove labels from multiple messages in bulk"},"messages.trash":{riskLevel:"write",description:"Move a message to the trash"},"messages.untrash":{riskLevel:"write",description:"Restore a message from the trash"},"labels.list":{riskLevel:"read",description:"List all labels in the mailbox"},"labels.get":{riskLevel:"read",description:"Get a specific label"},"labels.create":{riskLevel:"write",description:"Create a new label"},"labels.update":{riskLevel:"write",description:"Update an existing label"},"labels.delete":{riskLevel:"destructive",description:"Delete a label [DESTRUCTIVE]"},"drafts.list":{riskLevel:"read",description:"List drafts in the mailbox"},"drafts.get":{riskLevel:"read",description:"Get a specific draft"},"drafts.create":{riskLevel:"write",description:"Create a new draft"},"drafts.update":{riskLevel:"write",description:"Update an existing draft"},"drafts.delete":{riskLevel:"destructive",description:"Delete a draft [DESTRUCTIVE]"},"drafts.send":{riskLevel:"write",description:"Send a draft as an email"},"threads.list":{riskLevel:"read",description:"List threads in the mailbox"},"threads.get":{riskLevel:"read",description:"Get a specific thread"},"threads.modify":{riskLevel:"write",description:"Add or remove labels from a thread"},"threads.delete":{riskLevel:"destructive",irreversible:!0,description:"Permanently delete a thread [DESTRUCTIVE \xB7 IRREVERSIBLE]"},"threads.trash":{riskLevel:"write",description:"Move a thread to the trash"},"threads.untrash":{riskLevel:"write",description:"Restore a thread from the trash"}};function As(e={}){let t={...e,authType:e.authType??Zt};return{id:"gmail",schema:_,options:t,authConfig:Ht,oauthConfig:{providerName:"Google",authUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.labels","https://www.googleapis.com/auth/gmail.send","https://www.googleapis.com/auth/gmail.compose"],authParams:{access_type:"offline",prompt:"consent"}},hooks:t.hooks,webhookHooks:t.webhookHooks,endpoints:zt,webhooks:Kt,endpointMeta:Jt,endpointSchemas:Vt,webhookSchemas:Yt,keyBuilder:async a=>{let o=a.authType;if(t.key)return t.key;if(a.authType==="oauth_2"){let[n,i,d]=await Promise.all([a.keys.get_access_token(),a.keys.get_expires_at(),a.keys.get_refresh_token()]);if(!d)throw new Error("[auth-missing:gmail:refresh_token]: Gmail refresh token is missing");let m=await a.keys.get_integration_credentials();if(!m.client_id||!m.client_secret)throw new Error("[auth-missing:gmail:client_credentials]: Gmail client credentials are missing");let p;try{p=await B({accessToken:n,expiresAt:i,refreshToken:d,clientId:m.client_id,clientSecret:m.client_secret})}catch(g){throw new Error(`[corsair:gmail] Failed to obtain valid access token: ${g instanceof Error?g.message:String(g)}`)}if(p.refreshed)try{await a.keys.set_access_token(p.accessToken),await a.keys.set_expires_at(String(p.expiresAt))}catch(g){throw new Error(`[corsair:gmail] Token was refreshed but failed to persist new credentials: ${g instanceof Error?g.message:String(g)}`)}return a._refreshAuth=async()=>{let g=await B({accessToken:null,expiresAt:null,refreshToken:d,clientId:m.client_id,clientSecret:m.client_secret,forceRefresh:!0});return await a.keys.set_access_token(g.accessToken),await a.keys.set_expires_at(String(g.expiresAt)),g.accessToken},p.accessToken}throw new Error(`[auth-missing:gmail:${o}]: Gmail key is missing`)},pluginWebhookMatcher:a=>{let o=a.headers;if(!(o.from==="noreply@google.com"||typeof o["user-agent"]=="string"&&o["user-agent"].includes("APIs-Google")))return!1;let i=a.body;if(!i?.message?.data)return!1;try{let d=k(i.message.data);return!!d.emailAddress&&!!d.historyId}catch{return!1}}}}export{_ as GmailSchema,N as createGmailWebhookMatcher,k as decodePubSubMessage,As as gmail,Ht as gmailAuthConfig,Vt as gmailEndpointSchemas,zt as gmailEndpointsNested,Kt as gmailWebhooksNested};
1
+ import{AuthMissingError as us,getOAuthAccessToken as gs}from"corsair/core";import{logEventFromContext as S}from"corsair/core";import{request as Ve}from"corsair/http";var B="https://gmail.googleapis.com/gmail/v1";async function y(e,t,a={}){let{method:o="GET",body:n,query:i}=a;return await Ve({BASE:B,VERSION:"1.0.0",WITH_CREDENTIALS:!1,CREDENTIALS:"omit",TOKEN:t,HEADERS:{"Content-Type":"application/json"}},{method:o,url:e,body:o==="POST"||o==="PUT"||o==="PATCH"?n:void 0,mediaType:"application/json",query:o==="GET"?i:void 0})}function Ke(e){return e instanceof Error&&"status"in e&&e.status===401}async function p(e,t,a={}){try{return await y(e,t.key,a)}catch(o){if(Ke(o)&&t._refreshAuth){let n=await t._refreshAuth();return await y(e,n,a)}throw o}}var Y=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/drafts`,e,{method:"GET",query:{maxResults:t.maxResults,pageToken:t.pageToken,q:t.q}});if(a.drafts&&e.db.drafts)try{for(let o of a.drafts)o.id&&await e.db.drafts.upsertByEntityId(o.id,{...o,id:o.id,messageId:o.message?.id,createdAt:new Date})}catch(o){console.warn("Failed to save drafts to database:",o)}return await S(e,"gmail.drafts.list",{...t},"completed"),a},Z=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/drafts/${t.id}`,e,{method:"GET",query:{format:t.format}});if(a.id&&e.db.drafts)try{await e.db.drafts.upsertByEntityId(a.id,{...a,id:a.id,messageId:a.message?.id,createdAt:new Date})}catch(o){console.warn("Failed to save draft to database:",o)}return await S(e,"gmail.drafts.get",{...t},"completed"),a},Q=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/drafts`,e,{method:"POST",body:t.draft});return a.id&&await e.endpoints.drafts.get({id:a.id,userId:t.userId}),await S(e,"gmail.drafts.create",{...t},"completed"),a},ee=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/drafts/${t.id}`,e,{method:"PUT",body:t.draft});return a.id&&await e.endpoints.drafts.get({id:a.id,userId:t.userId}),await S(e,"gmail.drafts.update",{...t},"completed"),a},te=async(e,t)=>{if(await p(`/users/${t.userId||"me"}/drafts/${t.id}`,e,{method:"DELETE"}),e.db.drafts)try{await e.db.drafts.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete draft from database:",a)}await S(e,"gmail.drafts.delete",{...t},"completed")},se=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/drafts/send`,e,{method:"POST",body:{id:t.id,message:t.message}});return await S(e,"gmail.drafts.send",{...t},"completed"),a};import{logEventFromContext as D}from"corsair/core";var ae=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/labels`,e,{method:"GET"});if(a.labels&&e.db.labels)try{for(let o of a.labels)o.id&&await e.db.labels.upsertByEntityId(o.id,{...o,id:o.id,createdAt:new Date})}catch(o){console.warn("Failed to save labels to database:",o)}return await D(e,"gmail.labels.list",{...t},"completed"),a},oe=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/labels/${t.id}`,e,{method:"GET"});if(a.id&&e.db.labels)try{await e.db.labels.upsertByEntityId(a.id,{id:a.id,name:a.name,messageListVisibility:a.messageListVisibility,labelListVisibility:a.labelListVisibility,type:a.type,messagesTotal:a.messagesTotal,messagesUnread:a.messagesUnread,threadsTotal:a.threadsTotal,threadsUnread:a.threadsUnread,createdAt:new Date})}catch(o){console.warn("Failed to save label to database:",o)}return await D(e,"gmail.labels.get",{...t},"completed"),a},ie=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/labels`,e,{method:"POST",body:t.label});return a.id&&await e.endpoints.labels.get({id:a.id,userId:t.userId}),await D(e,"gmail.labels.create",{...t},"completed"),a},ne=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/labels/${t.id}`,e,{method:"PUT",body:t.label});return a.id&&await e.endpoints.labels.get({id:a.id,userId:t.userId}),await D(e,"gmail.labels.update",{...t},"completed"),a},re=async(e,t)=>{if(await p(`/users/${t.userId||"me"}/labels/${t.id}`,e,{method:"DELETE"}),e.db.labels)try{await e.db.labels.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete label from database:",a)}await D(e,"gmail.labels.delete",{...t},"completed")};import{logEventFromContext as I}from"corsair/core";function F(e,t){return e?.headers?e.headers.find(o=>o.name?.toLowerCase()===t.toLowerCase())?.value:void 0}function Ye(e){if(e.payload)return F(e.payload,"Subject")}function Ze(e){if(e.payload)return F(e.payload,"From")}function Qe(e){if(e.payload)return F(e.payload,"To")}function de(e){if(!e)return;let t,a;if(e.body?.data)try{let o=Buffer.from(e.body.data,"base64").toString("utf-8");e.mimeType==="text/plain"?t=o:e.mimeType==="text/html"&&(a=o)}catch{}if(e.parts&&e.parts.length>0)for(let o of e.parts){let n=de(o);n&&(o.mimeType==="text/plain"?t=n:o.mimeType==="text/html"&&!t&&(a=n))}return t||a}function et(e){if(e.payload)return de(e.payload)}var le=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/messages`,e,{method:"GET",query:{q:t.q,maxResults:t.maxResults,pageToken:t.pageToken,labelIds:t.labelIds?.join(","),includeSpamTrash:t.includeSpamTrash}});if(a.messages&&e.db.messages)try{for(let o of a.messages)o.id&&await e.db.messages.upsertByEntityId(o.id,{...o,id:o.id,createdAt:new Date})}catch(o){console.warn("Failed to save messages to database:",o)}return await I(e,"gmail.messages.list",{...t},"completed"),a},me=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/messages/${t.id}`,e,{method:"GET",query:{format:t.format,metadataHeaders:t.metadataHeaders?.join(",")}});if(a.id&&e.db.messages)try{let o=Ye(a),n=et(a),i=Ze(a),d=Qe(a);await e.db.messages.upsertByEntityId(a.id,{...a,subject:o,body:n,from:i,to:d,id:a.id,createdAt:new Date})}catch(o){console.warn("Failed to save message to database:",o)}return await I(e,"gmail.messages.get",{...t},"completed"),a},pe=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/messages/send`,e,{method:"POST",body:{raw:t.raw,threadId:t.threadId}});return a.id&&await e.endpoints.messages.get({id:a.id,userId:t.userId}),await I(e,"gmail.messages.send",{...t},"completed"),a},ue=async(e,t)=>{if(await p(`/users/${t.userId||"me"}/messages/${t.id}`,e,{method:"DELETE"}),e.db.messages)try{await e.db.messages.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete message from database:",a)}await I(e,"gmail.messages.delete",{...t},"completed")},ge=async(e,t)=>{let a={};t.addLabelIds&&t.addLabelIds.length>0&&(a.addLabelIds=t.addLabelIds),t.removeLabelIds&&t.removeLabelIds.length>0&&(a.removeLabelIds=t.removeLabelIds);let o=await p(`/users/${t.userId||"me"}/messages/${t.id}/modify`,e,{method:"POST",body:a});return o.id&&await e.endpoints.messages.get({id:o.id,userId:t.userId}),await I(e,"gmail.messages.modify",{...t},"completed"),o},ce=async(e,t)=>{let a={ids:t.ids};t.addLabelIds&&t.addLabelIds.length>0&&(a.addLabelIds=t.addLabelIds),t.removeLabelIds&&t.removeLabelIds.length>0&&(a.removeLabelIds=t.removeLabelIds),await p(`/users/${t.userId||"me"}/messages/batchModify`,e,{method:"POST",body:a}),await I(e,"gmail.messages.batchModify",{...t},"completed")},he=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/messages/${t.id}/trash`,e,{method:"POST"});return a.id&&await e.endpoints.messages.get({id:a.id,userId:t.userId}),await I(e,"gmail.messages.trash",{...t},"completed"),a},fe=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/messages/${t.id}/untrash`,e,{method:"POST"});return a.id&&await e.endpoints.messages.get({id:a.id,userId:t.userId}),await I(e,"gmail.messages.untrash",{...t},"completed"),a};import{logEventFromContext as L}from"corsair/core";var be=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/threads`,e,{method:"GET",query:{q:t.q,maxResults:t.maxResults,pageToken:t.pageToken,labelIds:t.labelIds?.join(","),includeSpamTrash:t.includeSpamTrash}});if(a.threads&&e.db.threads)try{for(let o of a.threads)o.id&&await e.db.threads.upsertByEntityId(o.id,{...o,id:o.id,createdAt:new Date})}catch(o){console.warn("Failed to save threads to database:",o)}return await L(e,"gmail.threads.list",{...t},"completed"),a},ye=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/threads/${t.id}`,e,{method:"GET",query:{format:t.format,metadataHeaders:t.metadataHeaders?.join(",")}});if(a.id&&e.db.threads)try{await e.db.threads.upsertByEntityId(a.id,{...a,id:a.id,createdAt:new Date})}catch(o){console.warn("Failed to save thread to database:",o)}return await L(e,"gmail.threads.get",{...t},"completed"),a},Ee=async(e,t)=>{let a={};t.addLabelIds&&t.addLabelIds.length>0&&(a.addLabelIds=t.addLabelIds),t.removeLabelIds&&t.removeLabelIds.length>0&&(a.removeLabelIds=t.removeLabelIds);let o=await p(`/users/${t.userId||"me"}/threads/${t.id}/modify`,e,{method:"POST",body:a});return o.id&&await e.endpoints.threads.get({id:o.id,userId:t.userId}),await L(e,"gmail.threads.modify",{...t},"completed"),o},Ge=async(e,t)=>{if(await p(`/users/${t.userId||"me"}/threads/${t.id}`,e,{method:"DELETE"}),e.db.threads)try{await e.db.threads.deleteByEntityId(t.id)}catch(a){console.warn("Failed to delete thread from database:",a)}await L(e,"gmail.threads.delete",{...t},"completed")},Ie=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/threads/${t.id}/trash`,e,{method:"POST"});return a.id&&await e.endpoints.threads.get({id:a.id,userId:t.userId}),await L(e,"gmail.threads.trash",{...t},"completed"),a},we=async(e,t)=>{let a=await p(`/users/${t.userId||"me"}/threads/${t.id}/untrash`,e,{method:"POST"});return a.id&&await e.endpoints.threads.get({id:a.id,userId:t.userId}),await L(e,"gmail.threads.untrash",{...t},"completed"),a};import{z as s}from"zod";var Te="Base64url-encoded RFC 2822 email \u2014 do NOT pass plain email text. Build the MIME message (From, To, Subject, Content-Type headers, blank line, body; lines separated by \\r\\n), then base64url-encode: standard base64, replace + with -, / with _, remove trailing =.",q=s.object({raw:s.string().optional().describe(Te),threadId:s.string().optional()}),at=s.object({userId:s.string().optional(),q:s.string().optional(),maxResults:s.number().optional(),pageToken:s.string().optional(),labelIds:s.array(s.string()).optional(),includeSpamTrash:s.boolean().optional()}),ot=s.object({userId:s.string().optional(),id:s.string(),format:s.enum(["minimal","full","raw","metadata"]).optional(),metadataHeaders:s.array(s.string()).optional()}),it=s.object({userId:s.string().optional(),raw:s.string().describe(Te),threadId:s.string().optional()}),nt=s.object({userId:s.string().optional(),id:s.string()}),rt=s.object({userId:s.string().optional(),id:s.string(),addLabelIds:s.array(s.string()).optional(),removeLabelIds:s.array(s.string()).optional()}),dt=s.object({userId:s.string().optional(),ids:s.array(s.string()).optional(),addLabelIds:s.array(s.string()).optional(),removeLabelIds:s.array(s.string()).optional()}),lt=s.object({userId:s.string().optional(),id:s.string()}),mt=s.object({userId:s.string().optional(),id:s.string()}),pt=s.object({userId:s.string().optional()}),ut=s.object({userId:s.string().optional(),id:s.string()}),gt=s.object({userId:s.string().optional(),label:s.object({name:s.string().optional(),messageListVisibility:s.enum(["show","hide"]).optional(),labelListVisibility:s.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),color:s.object({textColor:s.string().optional(),backgroundColor:s.string().optional()}).optional()})}),ct=s.object({userId:s.string().optional(),id:s.string(),label:s.object({name:s.string().optional(),messageListVisibility:s.enum(["show","hide"]).optional(),labelListVisibility:s.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),color:s.object({textColor:s.string().optional(),backgroundColor:s.string().optional()}).optional()})}),ht=s.object({userId:s.string().optional(),id:s.string()}),ft=s.object({userId:s.string().optional(),maxResults:s.number().optional(),pageToken:s.string().optional(),q:s.string().optional()}),bt=s.object({userId:s.string().optional(),id:s.string(),format:s.enum(["minimal","full","raw","metadata"]).optional()}),yt=s.object({userId:s.string().optional(),draft:s.object({message:q.optional()}).optional().describe("Draft payload. message.raw must be a base64url-encoded RFC 2822 email, not plain text.")}),Et=s.object({userId:s.string().optional(),id:s.string(),draft:s.object({message:q.optional()}).optional().describe("Updated draft payload. message.raw must be a base64url-encoded RFC 2822 email, not plain text.")}),Gt=s.object({userId:s.string().optional(),id:s.string()}),It=s.object({userId:s.string().optional(),id:s.string().optional(),message:q.optional().describe("Optional message body when sending without a draft id. raw must be base64url-encoded RFC 2822, not plain text.")}),wt=s.object({userId:s.string().optional(),q:s.string().optional(),maxResults:s.number().optional(),pageToken:s.string().optional(),labelIds:s.array(s.string()).optional(),includeSpamTrash:s.boolean().optional()}),Tt=s.object({userId:s.string().optional(),id:s.string(),format:s.enum(["minimal","full","metadata"]).optional(),metadataHeaders:s.array(s.string()).optional()}),Mt=s.object({userId:s.string().optional(),id:s.string(),addLabelIds:s.array(s.string()).optional(),removeLabelIds:s.array(s.string()).optional()}),St=s.object({userId:s.string().optional(),id:s.string()}),Lt=s.object({userId:s.string().optional(),id:s.string()}),kt=s.object({userId:s.string().optional(),id:s.string()}),vt=s.object({userId:s.string().optional()}),g={messagesList:at,messagesGet:ot,messagesSend:it,messagesDelete:nt,messagesModify:rt,messagesBatchModify:dt,messagesTrash:lt,messagesUntrash:mt,labelsList:pt,labelsGet:ut,labelsCreate:gt,labelsUpdate:ct,labelsDelete:ht,draftsList:ft,draftsGet:bt,draftsCreate:yt,draftsUpdate:Et,draftsDelete:Gt,draftsSend:It,threadsList:wt,threadsGet:Tt,threadsModify:Mt,threadsDelete:St,threadsTrash:Lt,threadsUntrash:kt,usersGetProfile:vt},Pt=s.object({name:s.string().optional(),value:s.string().optional()}),Ct=s.object({attachmentId:s.string().optional(),size:s.number().optional(),data:s.string().optional()}),Dt=s.object({partId:s.string().optional(),mimeType:s.string().optional(),filename:s.string().optional(),headers:s.array(Pt).optional(),body:Ct.optional()}),Me=Dt.extend({parts:s.lazy(()=>s.array(Me).optional())}),E=s.object({id:s.string().optional(),threadId:s.string().optional(),labelIds:s.array(s.string()).optional(),snippet:s.string().optional(),historyId:s.string().optional(),internalDate:s.union([s.string(),s.number(),s.date()]).transform(e=>{if(e instanceof Date)return e;if(typeof e=="number")return new Date(e);if(typeof e=="string"){let t=Number(e);return isNaN(t)?null:new Date(t)}return null}).nullable().optional(),sizeEstimate:s.number().optional(),payload:Me.optional(),raw:s.string().optional().describe("Full RFC 2822 message in base64url encoding (when format=raw). Not plain text \u2014 decode base64url before reading headers/body.")}),Rt=s.object({messages:s.array(E).optional(),nextPageToken:s.string().optional(),resultSizeEstimate:s.number().optional()}),xt=s.object({textColor:s.string().optional(),backgroundColor:s.string().optional()}),N=s.object({id:s.string().optional(),name:s.string().optional(),messageListVisibility:s.enum(["show","hide"]).optional(),labelListVisibility:s.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),type:s.enum(["system","user"]).optional(),messagesTotal:s.number().optional(),messagesUnread:s.number().optional(),threadsTotal:s.number().optional(),threadsUnread:s.number().optional(),color:xt.optional()}),At=s.object({labels:s.array(N).optional()}),U=s.object({id:s.string().optional(),message:E.optional()}),Ot=s.object({drafts:s.array(U).optional(),nextPageToken:s.string().optional(),resultSizeEstimate:s.number().optional()}),R=s.object({id:s.string().optional(),snippet:s.string().optional(),historyId:s.string().optional(),messages:s.array(E).optional()}),jt=s.object({threads:s.array(R).optional(),nextPageToken:s.string().optional(),resultSizeEstimate:s.number().optional()}),Bt=s.object({emailAddress:s.string().optional(),messagesTotal:s.number().optional(),threadsTotal:s.number().optional(),historyId:s.string().optional()}),c={messagesList:Rt,messagesGet:E,messagesSend:E,messagesDelete:s.void(),messagesModify:E,messagesBatchModify:s.void(),messagesTrash:E,messagesUntrash:E,labelsList:At,labelsGet:N,labelsCreate:N,labelsUpdate:N,labelsDelete:s.void(),draftsList:Ot,draftsGet:U,draftsCreate:U,draftsUpdate:U,draftsDelete:s.void(),draftsSend:E,threadsList:jt,threadsGet:R,threadsModify:R,threadsDelete:s.void(),threadsTrash:R,threadsUntrash:R,usersGetProfile:Bt};var G={list:le,get:me,send:pe,delete:ue,modify:ge,batchModify:ce,trash:he,untrash:fe},k={list:ae,get:oe,create:ie,update:ne,delete:re},w={list:Y,get:Z,create:Q,update:ee,delete:te,send:se},T={list:be,get:ye,modify:Ee,delete:Ge,trash:Ie,untrash:we};import{z as x}from"zod";import{z as r}from"zod";var Nt=r.object({name:r.string().optional(),value:r.string().optional()}),Ut=r.object({attachmentId:r.string().optional(),size:r.number().optional(),data:r.string().optional()}),Se=r.lazy(()=>r.object({partId:r.string().optional(),mimeType:r.string().optional(),filename:r.string().optional(),headers:r.array(Nt).optional(),body:Ut.optional(),parts:r.array(Se).optional()})),Le=r.object({id:r.string(),threadId:r.string().optional(),labelIds:r.array(r.string()).optional(),snippet:r.string().optional(),historyId:r.string().optional(),internalDate:r.string().optional(),sizeEstimate:r.number().optional(),payload:Se.optional(),raw:r.string().optional(),subject:r.string().optional(),body:r.string().optional(),from:r.string().optional(),to:r.string().optional(),createdAt:r.coerce.date().nullable().optional()}),ke=r.object({id:r.string(),name:r.string().optional(),messageListVisibility:r.enum(["show","hide"]).optional(),labelListVisibility:r.enum(["labelShow","labelShowIfUnread","labelHide"]).optional(),type:r.enum(["system","user"]).optional(),messagesTotal:r.number().optional(),messagesUnread:r.number().optional(),threadsTotal:r.number().optional(),threadsUnread:r.number().optional(),createdAt:r.coerce.date().nullable().optional()}),ve=r.object({id:r.string(),messageId:r.string().optional(),createdAt:r.coerce.date().nullable().optional()}),Pe=r.object({id:r.string(),snippet:r.string().optional(),historyId:r.string().optional(),createdAt:r.coerce.date().nullable().optional()});var $s=x.object({clientId:x.string(),clientSecret:x.string(),accessToken:x.string(),refreshToken:x.string()}),H={version:"1.0.0",entities:{messages:Le,labels:ke,drafts:ve,threads:Pe}};var Ce=2e4;async function De(e,t){let a=await e.keys.get_access_token();if(!a)return null;let o=await e.keys.get_integration_credentials();if(!o.topic_id)return null;let n={authorization:`Bearer ${a}`},i=await fetch(`${B}/users/me/watch`,{method:"POST",signal:AbortSignal.timeout(Ce),headers:{...n,"content-type":"application/json"},body:JSON.stringify({topicName:o.topic_id,labelIds:["INBOX"]})});if(!i.ok)throw new Error(`Gmail watch failed (${i.status}): ${await i.text()}`);let d=await fetch(`${B}/users/me/profile`,{headers:n,signal:AbortSignal.timeout(Ce)});if(!d.ok)throw new Error(`Gmail profile fetch failed (${d.status}): ${await d.text()}`);let{emailAddress:u}=await d.json();return u?{webhookLink:{linkType:"email_address",externalId:u},webhookSecret:o.pubsub_audience??void 0}:null}import{logEventFromContext as V}from"corsair/core";import{z as m}from"zod";var $t=m.object({data:m.string().optional(),attributes:m.record(m.string(),m.string()).optional(),messageId:m.string().optional(),publishTime:m.string().optional()}),Re=m.object({message:$t.optional(),subscription:m.string().optional(),event:m.unknown().optional()}),Wt=m.object({emailAddress:m.string().optional(),historyId:m.coerce.string().optional()}),_t=m.object({type:m.literal("messageReceived"),emailAddress:m.string(),historyId:m.string(),message:m.custom()}),Ft=m.object({type:m.literal("messageDeleted"),emailAddress:m.string(),historyId:m.string(),message:m.custom()}),qt=m.object({type:m.literal("messageLabelChanged"),emailAddress:m.string(),historyId:m.string(),message:m.custom(),labelsAdded:m.array(m.string()).optional(),labelsRemoved:m.array(m.string()).optional()}),xe=m.union([_t,Ft,qt]);function v(e){let t=Buffer.from(e,"base64").toString("utf-8");return Wt.parse(JSON.parse(t))}function z(e){return t=>{let a=t.body;if(!a.message?.data)return!1;try{let o=v(a.message.data);return!!o.historyId&&!!o.emailAddress}catch{return!1}}}var Ht=100,zt=10,Vt=10;function K(e,t){let a=e.options?.webhookEvents;return a?a.includes(t):!0}async function Ae(e,t,a){let o=[],n;do{let i=await y(`/users/${t}/history`,e,{method:"GET",query:{startHistoryId:a,maxResults:Ht,...n?{pageToken:n}:{}}});i.history&&o.push(...i.history),n=i.nextPageToken}while(n);return o}async function Kt(e,t,a){return y(`/users/${t}/messages/${a}`,e,{method:"GET",query:{format:"minimal"}})}function J(e,t){return e?.headers?e.headers.find(o=>o.name?.toLowerCase()===t.toLowerCase())?.value:void 0}function Jt(e){if(e.payload)return J(e.payload,"Subject")}function Xt(e){if(e.payload)return J(e.payload,"From")}function Yt(e){if(e.payload)return J(e.payload,"To")}function Oe(e){if(!e)return;let t,a;if(e.body?.data)try{let o=Buffer.from(e.body.data,"base64").toString("utf-8");e.mimeType==="text/plain"?t=o:e.mimeType==="text/html"&&(a=o)}catch{}if(e.parts&&e.parts.length>0)for(let o of e.parts){let n=Oe(o);n&&(o.mimeType==="text/plain"?t=n:o.mimeType==="text/html"&&!t&&(a=n))}return t||a}function Zt(e){if(e.payload)return Oe(e.payload)}function Qt(e){let t=[],a=[],o=[];if(!e)return{added:t,deleted:a,modified:o};for(let n of e){if(n.messagesAdded)for(let i of n.messagesAdded)i.message?.id&&t.push(i.message.id);if(n.messagesDeleted)for(let i of n.messagesDeleted)i.message?.id&&a.push(i.message.id);if(n.labelsAdded||n.labelsRemoved){if(n.labelsAdded)for(let i of n.labelsAdded)i.message?.id&&o.push(i.message.id);if(n.labelsRemoved)for(let i of n.labelsRemoved)i.message?.id&&o.push(i.message.id)}}return{added:[...new Set(t)],deleted:[...new Set(a)],modified:[...new Set(o)]}}async function je(e,t,a){let[o,n]=await Promise.all([y(`/users/${t}/messages/${a}`,e,{method:"GET",query:{format:"full"}}),y(`/users/${t}/messages/${a}`,e,{method:"GET",query:{format:"raw"}}).catch(()=>null)]);return{...o,raw:n?.raw}}async function es(e,t,a,o){return y(`/users/${t}/messages/${a}/attachments/${o}`,e,{method:"GET"})}async function Be(e,t,a){if(!a.payload)return a;let o=async i=>{if(!i)return i;if(i.body?.attachmentId)try{let d=await es(e,t,a.id,i.body.attachmentId);return{...i,body:{...i.body,data:d.data,size:d.size}}}catch(d){return console.warn(`Failed to fetch attachment ${i.body.attachmentId} for message ${a.id}:`,d),i}if(i.parts&&i.parts.length>0){let d=await Promise.all(i.parts.map(o));return{...i,parts:d.filter(u=>u!==void 0)}}return i},n=await o(a.payload);return{...a,payload:n}}function $(e){let t=Number(e);return t>1?String(t-1):e}function Ne(e){return typeof e!="object"||e===null?!1:"status"in e&&e.status===404?!0:"statusCode"in e&&e.statusCode===404}async function ts(e){try{return await e.keys?.get_last_history_id?.()||null}catch{return null}}async function W(e,t,a){let o=Number(t),n=a?Number(a):Number.NaN;if(!(Number.isFinite(o)&&Number.isFinite(n)&&o<=n))try{await e.keys?.set_last_history_id?.(t)}catch(i){console.warn("Failed to persist Gmail webhook history cursor:",i)}}function ss(e){let t=0;for(let a of e){let o=a.id?Number(a.id):Number.NaN;Number.isFinite(o)&&o>t&&(t=o)}return t>0?String(t):null}async function Ue(e,t){return!e.db?.messages||!t.id?"":(await e.db.messages.upsertByEntityId(t.id,{...t,id:t.id,subject:Jt(t),body:Zt(t),from:Xt(t),to:Yt(t),createdAt:new Date}))?.id??""}async function as(e,t,a,o){let n=await y(`/users/${a}/messages`,t,{method:"GET",query:{maxResults:zt}}),i=[],d=[];if(!n.messages?.length)return{added:i,modified:d};let u=Number(o);for(let l of n.messages)if(l.id)try{let f=await Kt(t,a,l.id);(f.historyId?Number(f.historyId):0)>=u-Vt&&(e.db?.messages&&await e.db.messages.existsByEntityId(l.id)?d.push(l.id):i.push(l.id))}catch{}return{added:i,modified:d}}async function os(e,t,a,o){let n=null,i="",d=0;for(let u of o)try{let l=await je(t,a,u),f=await Be(t,a,l);n||(n=f);try{let b=await Ue(e,f);!i&&b&&(i=b)}catch(b){throw console.error(`Failed to save message ${f.id} to database:`,b),b}}catch(l){d++,console.warn(`Failed to process message ${u}:`,l)}return{message:n,corsairEntityId:i,failedCount:d}}async function is(e,t,a,o){let n=null,i="",d=0;if(!e.db?.messages)return{message:null,corsairEntityId:i,failedCount:d};for(let u of o)try{let l=null;try{l=await y(`/users/${a}/messages/${u}`,t,{method:"GET",query:{format:"full"}})}catch(f){if(!Ne(f))throw f}if(!n&&l&&(n=l),!i){let f=await e.db.messages.findIdByEntityId(u);f&&(i=f)}await e.db.messages.deleteByEntityId(u)}catch(l){d++,console.warn(`Failed to delete message ${u} from database:`,l)}return{message:n,corsairEntityId:i,failedCount:d}}async function ns(e,t,a,o){let n=null,i="",d=0;if(!e.db?.messages)return{message:null,corsairEntityId:i,failedCount:d};for(let u of o)try{let l=await je(t,a,u),f=await Be(t,a,l);n||(n=f);try{let b=await Ue(e,f);!i&&b&&(i=b)}catch(b){throw console.error(`Failed to update message ${f.id} in database:`,b),b}}catch(l){d++,console.warn(`Failed to process message ${u}:`,l)}return{message:n,corsairEntityId:i,failedCount:d}}var $e={match:z("messageChanged"),handler:async(e,t)=>{let o=t.payload.message?.data;if(!o)return{success:!1,error:"No message data in notification"};let n;try{n=v(o)}catch{return{success:!1,error:"Invalid push notification format"}}if(!n.historyId||!n.emailAddress)return{success:!1,error:"Invalid push notification format"};let i=e.key,d=n.emailAddress,u=n.historyId;try{let l=await ts(e),f=l??$(u),b;try{b=await Ae(i,d,f)}catch(h){if(l&&Ne(h))b=await Ae(i,d,$(u));else throw h}let M=Qt(b),qe=new Set(M.added),He=new Set(M.deleted),P=M.added,_=M.deleted,C=M.modified.filter(h=>!qe.has(h)&&!He.has(h)),ze=P.length>0||_.length>0||C.length>0,X=!1;if(!ze&&!l){let h=await as(e,i,d,u);P=h.added,C=h.modified,X=!0}let A=P.length>0&&K(e,"messageReceived")?await os(e,i,d,P):null,O=_.length>0&&K(e,"messageDeleted")?await is(e,i,d,_):null,j=C.length>0&&K(e,"messageLabelChanged")?await ns(e,i,d,C):null;if((A?.failedCount??0)+(O?.failedCount??0)+(j?.failedCount??0)>0)l||await W(e,$(u),l);else{let h=ss(b);h?await W(e,h,l):X&&(P.length>0||C.length>0)?await W(e,u,l):l||await W(e,$(u),l)}if(A){let h={type:"messageReceived",emailAddress:d,historyId:u,message:A.message??{}};return await V(e,"gmail.webhook.messageReceived",{...h},"completed"),{success:!0,corsairEntityId:A.corsairEntityId,data:h}}if(O){let h={type:"messageDeleted",emailAddress:d,historyId:u,message:O.message??{}};return await V(e,"gmail.webhook.messageDeleted",{...h},"completed"),{success:!0,corsairEntityId:O.corsairEntityId,data:h}}if(j){let h={type:"messageLabelChanged",emailAddress:d,historyId:u,message:j.message??{}};return await V(e,"gmail.webhook.messageLabelChanged",{...h},"completed"),{success:!0,corsairEntityId:j.corsairEntityId,data:h}}return{success:!0,corsairEntityId:"",data:void 0}}catch(l){return console.error("Failed to process Gmail webhook:",l),{success:!1,error:`Failed to process message: ${l instanceof Error?l.message:"Unknown error"}`}}}};var We={messageChanged:$e};import{toExternalId as rs}from"corsair/core";async function _e(e){let t=e.access_token;if(!t)return null;let a=await fetch("https://gmail.googleapis.com/gmail/v1/users/me/profile",{headers:{Authorization:`Bearer ${t}`}});if(!a.ok)return null;let o=await a.json(),n=rs(o.emailAddress);return n?{linkType:"email_address",externalId:n}:null}import{asRecord as ds,decodePubSubData as ls,firstString as ms,readBodyRecord as ps}from"corsair/core";function Fe(e){let t=ps(e);if(!t)return null;let a=ds(ls(t)),o=ms([a?.emailAddress]);return o?{linkType:"email_address",externalId:o}:null}var cs={oauth_2:{integration:["topic_id","pubsub_audience"],account:["email_address","last_history_id"]}},hs={messages:{list:G.list,get:G.get,send:G.send,delete:G.delete,modify:G.modify,batchModify:G.batchModify,trash:G.trash,untrash:G.untrash},labels:{list:k.list,get:k.get,create:k.create,update:k.update,delete:k.delete},drafts:{list:w.list,get:w.get,create:w.create,update:w.update,delete:w.delete,send:w.send},threads:{list:T.list,get:T.get,modify:T.modify,delete:T.delete,trash:T.trash,untrash:T.untrash}},fs={"messages.list":{input:g.messagesList,output:c.messagesList},"messages.get":{input:g.messagesGet,output:c.messagesGet},"messages.send":{input:g.messagesSend,output:c.messagesSend},"messages.delete":{input:g.messagesDelete,output:c.messagesDelete},"messages.modify":{input:g.messagesModify,output:c.messagesModify},"messages.batchModify":{input:g.messagesBatchModify,output:c.messagesBatchModify},"messages.trash":{input:g.messagesTrash,output:c.messagesTrash},"messages.untrash":{input:g.messagesUntrash,output:c.messagesUntrash},"labels.list":{input:g.labelsList,output:c.labelsList},"labels.get":{input:g.labelsGet,output:c.labelsGet},"labels.create":{input:g.labelsCreate,output:c.labelsCreate},"labels.update":{input:g.labelsUpdate,output:c.labelsUpdate},"labels.delete":{input:g.labelsDelete,output:c.labelsDelete},"drafts.list":{input:g.draftsList,output:c.draftsList},"drafts.get":{input:g.draftsGet,output:c.draftsGet},"drafts.create":{input:g.draftsCreate,output:c.draftsCreate},"drafts.update":{input:g.draftsUpdate,output:c.draftsUpdate},"drafts.delete":{input:g.draftsDelete,output:c.draftsDelete},"drafts.send":{input:g.draftsSend,output:c.draftsSend},"threads.list":{input:g.threadsList,output:c.threadsList},"threads.get":{input:g.threadsGet,output:c.threadsGet},"threads.modify":{input:g.threadsModify,output:c.threadsModify},"threads.delete":{input:g.threadsDelete,output:c.threadsDelete},"threads.trash":{input:g.threadsTrash,output:c.threadsTrash},"threads.untrash":{input:g.threadsUntrash,output:c.threadsUntrash}},bs={messageChanged:We.messageChanged},ys={messageChanged:{description:"A Gmail message was received, deleted, or had its labels changed",payload:Re,response:xe}},Es="oauth_2",Gs={"messages.list":{riskLevel:"read",description:"List messages in a mailbox"},"messages.get":{riskLevel:"read",description:"Get a specific message"},"messages.send":{riskLevel:"write",description:"Send an email to one or more recipients"},"messages.delete":{riskLevel:"destructive",irreversible:!0,description:"Permanently delete a message [DESTRUCTIVE \xB7 IRREVERSIBLE]"},"messages.modify":{riskLevel:"write",description:"Add or remove labels from a message"},"messages.batchModify":{riskLevel:"write",description:"Add or remove labels from multiple messages in bulk"},"messages.trash":{riskLevel:"write",description:"Move a message to the trash"},"messages.untrash":{riskLevel:"write",description:"Restore a message from the trash"},"labels.list":{riskLevel:"read",description:"List all labels in the mailbox"},"labels.get":{riskLevel:"read",description:"Get a specific label"},"labels.create":{riskLevel:"write",description:"Create a new label"},"labels.update":{riskLevel:"write",description:"Update an existing label"},"labels.delete":{riskLevel:"destructive",description:"Delete a label [DESTRUCTIVE]"},"drafts.list":{riskLevel:"read",description:"List drafts in the mailbox"},"drafts.get":{riskLevel:"read",description:"Get a specific draft"},"drafts.create":{riskLevel:"write",description:"Create a new draft"},"drafts.update":{riskLevel:"write",description:"Update an existing draft"},"drafts.delete":{riskLevel:"destructive",description:"Delete a draft [DESTRUCTIVE]"},"drafts.send":{riskLevel:"write",description:"Send a draft as an email"},"threads.list":{riskLevel:"read",description:"List threads in the mailbox"},"threads.get":{riskLevel:"read",description:"Get a specific thread"},"threads.modify":{riskLevel:"write",description:"Add or remove labels from a thread"},"threads.delete":{riskLevel:"destructive",irreversible:!0,description:"Permanently delete a thread [DESTRUCTIVE \xB7 IRREVERSIBLE]"},"threads.trash":{riskLevel:"write",description:"Move a thread to the trash"},"threads.untrash":{riskLevel:"write",description:"Restore a thread from the trash"}};function ua(e={}){let t={...e,authType:e.authType??Es};return{id:"gmail",schema:H,options:t,authConfig:cs,oauthConfig:{providerName:"Google",authUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/gmail.modify","https://www.googleapis.com/auth/gmail.labels","https://www.googleapis.com/auth/gmail.send","https://www.googleapis.com/auth/gmail.compose"],authParams:{access_type:"offline",prompt:"consent"}},hooks:t.hooks,webhookHooks:t.webhookHooks,endpoints:hs,webhooks:bs,endpointMeta:Gs,endpointSchemas:fs,webhookSchemas:ys,keyBuilder:async a=>{let o=a.authType;if(t.key)return t.key;if(a.authType==="oauth_2")return gs(a,{plugin:"gmail",tokenUrl:"https://oauth2.googleapis.com/token"});throw new us("gmail","oauth_2")},pluginWebhookMatcher:a=>{let o=a.headers;if(!(o.from==="noreply@google.com"||typeof o["user-agent"]=="string"&&o["user-agent"].includes("APIs-Google")))return!1;let i=a.body;if(!i?.message?.data)return!1;try{let d=v(i.message.data);return!!d.emailAddress&&!!d.historyId}catch{return!1}},pluginTenantWebhookMatcher:Fe,oauthWebhookTenantLinkResolver:_e,subscribe:De}}export{H as GmailSchema,z as createGmailWebhookMatcher,v as decodePubSubMessage,ua as gmail,cs as gmailAuthConfig,fs as gmailEndpointSchemas,hs as gmailEndpointsNested,bs as gmailWebhooksNested};
@@ -0,0 +1,22 @@
1
+ import type { CorsairPluginSubscribeResult } from 'corsair/core';
2
+ /** Minimal shape we need from the account key manager (ctx.keys). */
3
+ type SubscribeCtx = {
4
+ keys: {
5
+ get_access_token: () => Promise<string | null | undefined>;
6
+ get_integration_credentials: () => Promise<Record<string, string | null | undefined>>;
7
+ };
8
+ };
9
+ /**
10
+ * BYO subscribe for Gmail: arms `users.watch` on the customer's Pub/Sub topic
11
+ * and returns the routing link (email address) + the push subscription's OIDC
12
+ * identity (service-account email or audience) as the verification secret —
13
+ * Hub's verifyPubsub checks the push JWT against it. Unlike Outlook there is
14
+ * no webhook_signature persist: Gmail notifications are verified by Hub only
15
+ * (the plugin's webhook keyBuilder has no verify branch), and delivery rides
16
+ * the customer's Pub/Sub push subscription, not `webhookUrl` directly.
17
+ */
18
+ export declare function gmailSubscribe(ctx: SubscribeCtx, _input: {
19
+ webhookUrl: string;
20
+ }): Promise<CorsairPluginSubscribeResult | null>;
21
+ export {};
22
+ //# sourceMappingURL=subscribe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe.d.ts","sourceRoot":"","sources":["../subscribe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAKjE,qEAAqE;AACrE,KAAK,YAAY,GAAG;IACnB,IAAI,EAAE;QACL,gBAAgB,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;QAC3D,2BAA2B,EAAE,MAAM,OAAO,CACzC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CACzC,CAAC;KACF,CAAC;CACF,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CACnC,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5B,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CA8C9C"}
@@ -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":""}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../webhooks/messages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0d9C,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,gBAAgB,CAkN1D,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../webhooks/messages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAmmB9C,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,gBAAgB,CAkO1D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=messages.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.test.d.ts","sourceRoot":"","sources":["../../webhooks/messages.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { TokenResponse, WebhookTenantMatch } from 'corsair/core';
2
+ export declare function resolveGmailOAuthWebhookTenantLink(tokens: TokenResponse): Promise<WebhookTenantMatch | null>;
3
+ //# sourceMappingURL=oauth-tenant-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-tenant-link.d.ts","sourceRoot":"","sources":["../../webhooks/oauth-tenant-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGtE,wBAAsB,kCAAkC,CACvD,MAAM,EAAE,aAAa,GACnB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAiBpC"}
@@ -0,0 +1,3 @@
1
+ import type { RawWebhookRequest, WebhookTenantMatch } from 'corsair/core';
2
+ export declare function matchGmailTenantWebhook(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;AAU1E,wBAAgB,uBAAuB,CACtC,OAAO,EAAE,iBAAiB,GACxB,kBAAkB,GAAG,IAAI,CAS3B"}
@@ -23,7 +23,7 @@ export type PubSubNotification<TEvent = unknown> = Omit<z.infer<typeof PubSubNot
23
23
  };
24
24
  export declare const GmailPushNotificationSchema: z.ZodObject<{
25
25
  emailAddress: z.ZodOptional<z.ZodString>;
26
- historyId: z.ZodOptional<z.ZodString>;
26
+ historyId: z.ZodOptional<z.ZodCoercedString<unknown>>;
27
27
  }, z.core.$strip>;
28
28
  export type GmailPushNotification = z.infer<typeof GmailPushNotificationSchema>;
29
29
  export declare const MessageReceivedEventSchema: z.ZodObject<{
@@ -69,6 +69,7 @@ export declare const GmailWebhookEventSchema: z.ZodUnion<readonly [z.ZodObject<{
69
69
  }, z.core.$strip>]>;
70
70
  export type GmailWebhookEvent = z.infer<typeof GmailWebhookEventSchema>;
71
71
  export type GmailEventName = 'messageChanged';
72
+ export type GmailWebhookEventType = 'messageReceived' | 'messageDeleted' | 'messageLabelChanged';
72
73
  export type GmailWebhookPayload<TEvent = unknown> = PubSubNotification<TEvent>;
73
74
  export type GmailWebhookOutputs = {
74
75
  messageChanged: MessageReceivedEvent | MessageDeletedEvent | MessageLabelChangedEvent;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../webhooks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAqB,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAMxC,eAAO,MAAM,mBAAmB;;;;;iBAK9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,wBAAwB;;;;;;;;;iBAInC,CAAC;AACH,MAAM,MAAM,kBAAkB,CAAC,MAAM,GAAG,OAAO,IAAI,IAAI,CACtD,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,EACxC,OAAO,CACP,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvB,eAAO,MAAM,2BAA2B;;;iBAGtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAKhF,eAAO,MAAM,0BAA0B;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,yBAAyB;;;;;iBAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,8BAA8B;;;;;;;iBAOzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,8BAA8B,CACrC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;mBAIlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE9C,MAAM,MAAM,mBAAmB,CAAC,MAAM,GAAG,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE/E,MAAM,MAAM,mBAAmB,GAAG;IACjC,cAAc,EACX,oBAAoB,GACpB,mBAAmB,GACnB,wBAAwB,CAAC;CAC5B,CAAC;AAMF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAGvE;AAED,wBAAgB,yBAAyB,CACxC,SAAS,EAAE,cAAc,GACvB,qBAAqB,CAcvB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../webhooks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAqB,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAMxC,eAAO,MAAM,mBAAmB;;;;;iBAK9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,wBAAwB;;;;;;;;;iBAInC,CAAC;AACH,MAAM,MAAM,kBAAkB,CAAC,MAAM,GAAG,OAAO,IAAI,IAAI,CACtD,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,EACxC,OAAO,CACP,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvB,eAAO,MAAM,2BAA2B;;;iBAKtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAKhF,eAAO,MAAM,0BAA0B;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,yBAAyB;;;;;iBAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,8BAA8B;;;;;;;iBAOzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC7C,OAAO,8BAA8B,CACrC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;mBAIlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE9C,MAAM,MAAM,qBAAqB,GAC9B,iBAAiB,GACjB,gBAAgB,GAChB,qBAAqB,CAAC;AAEzB,MAAM,MAAM,mBAAmB,CAAC,MAAM,GAAG,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAE/E,MAAM,MAAM,mBAAmB,GAAG;IACjC,cAAc,EACX,oBAAoB,GACpB,mBAAmB,GACnB,wBAAwB,CAAC;CAC5B,CAAC;AAMF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAGvE;AAED,wBAAgB,yBAAyB,CACxC,SAAS,EAAE,cAAc,GACvB,qBAAqB,CAcvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corsair-dev/gmail",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Gmail 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": {
@@ -27,7 +27,8 @@
27
27
  "tsup": "^8.0.1",
28
28
  "typescript": "^5.9.3",
29
29
  "zod": "^4.1.13",
30
- "corsair": "0.1.70"
30
+ "jest": "^29.7.0",
31
+ "corsair": "0.1.120"
31
32
  },
32
33
  "keywords": [
33
34
  "corsair",
@@ -39,9 +40,6 @@
39
40
  "files": [
40
41
  "dist"
41
42
  ],
42
- "dependencies": {
43
- "jest": "^29.7.0"
44
- },
45
43
  "scripts": {
46
44
  "build": "rm -rf dist && tsc --build --force && tsup",
47
45
  "typecheck": "tsc --noEmit",