@contractspec/integration.providers-impls 3.8.8 → 3.8.10
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/analytics.js +1 -2
- package/dist/calendar.js +1 -2
- package/dist/database.js +1 -2
- package/dist/email.js +1 -2
- package/dist/embedding.js +1 -2
- package/dist/health.js +1 -2
- package/dist/impls/async-event-queue.js +1 -48
- package/dist/impls/composio-fallback-resolver.js +1 -579
- package/dist/impls/composio-mcp.js +1 -163
- package/dist/impls/composio-proxies.js +1 -310
- package/dist/impls/composio-sdk.js +1 -77
- package/dist/impls/composio-types.js +1 -53
- package/dist/impls/elevenlabs-voice.js +1 -104
- package/dist/impls/fal-voice.js +1 -117
- package/dist/impls/fathom-meeting-recorder.js +2 -289
- package/dist/impls/fathom-meeting-recorder.mapper.js +1 -107
- package/dist/impls/fathom-meeting-recorder.utils.js +1 -74
- package/dist/impls/fathom-meeting-recorder.webhooks.js +1 -31
- package/dist/impls/fireflies-meeting-recorder.js +5 -203
- package/dist/impls/fireflies-meeting-recorder.queries.js +4 -14
- package/dist/impls/fireflies-meeting-recorder.utils.js +1 -44
- package/dist/impls/gcs-storage.js +1 -99
- package/dist/impls/gmail-inbound.js +1 -229
- package/dist/impls/gmail-outbound.js +25 -137
- package/dist/impls/google-calendar.js +1 -193
- package/dist/impls/gradium-voice.js +1 -95
- package/dist/impls/granola-meeting-recorder.js +3 -514
- package/dist/impls/granola-meeting-recorder.mcp.js +1 -280
- package/dist/impls/health/base-health-provider.js +1 -617
- package/dist/impls/health/hybrid-health-providers.js +1 -1089
- package/dist/impls/health/official-health-providers.js +1 -969
- package/dist/impls/health/provider-normalizers.js +1 -288
- package/dist/impls/health/providers.js +1 -1095
- package/dist/impls/health-provider-factory.js +1 -1309
- package/dist/impls/index.js +42 -7448
- package/dist/impls/jira.js +1 -126
- package/dist/impls/linear.js +1 -85
- package/dist/impls/messaging-github.js +1 -111
- package/dist/impls/messaging-slack.js +1 -81
- package/dist/impls/messaging-telegram.js +1 -48
- package/dist/impls/messaging-whatsapp-meta.js +1 -53
- package/dist/impls/messaging-whatsapp-twilio.js +1 -83
- package/dist/impls/mistral-conversational.js +2 -477
- package/dist/impls/mistral-conversational.session.js +2 -207
- package/dist/impls/mistral-embedding.js +1 -45
- package/dist/impls/mistral-llm.js +1 -271
- package/dist/impls/mistral-stt.js +1 -168
- package/dist/impls/notion.js +1 -162
- package/dist/impls/posthog-reader.js +1 -161
- package/dist/impls/posthog-utils.js +1 -40
- package/dist/impls/posthog.js +1 -324
- package/dist/impls/postmark-email.js +1 -62
- package/dist/impls/powens-client.js +1 -197
- package/dist/impls/powens-openbanking.js +1 -428
- package/dist/impls/provider-factory.js +18 -6268
- package/dist/impls/qdrant-vector.js +1 -80
- package/dist/impls/stripe-payments.js +1 -230
- package/dist/impls/supabase-psql.js +1 -152
- package/dist/impls/supabase-vector.js +9 -298
- package/dist/impls/tldv-meeting-recorder.js +2 -147
- package/dist/impls/twilio-sms.js +1 -67
- package/dist/index.js +42 -7495
- package/dist/llm.js +1 -2
- package/dist/meeting-recorder.js +1 -2
- package/dist/messaging.js +1 -2
- package/dist/node/analytics.js +1 -2
- package/dist/node/calendar.js +1 -2
- package/dist/node/database.js +1 -2
- package/dist/node/email.js +1 -2
- package/dist/node/embedding.js +1 -2
- package/dist/node/health.js +1 -2
- package/dist/node/impls/async-event-queue.js +1 -49
- package/dist/node/impls/composio-fallback-resolver.js +1 -580
- package/dist/node/impls/composio-mcp.js +1 -164
- package/dist/node/impls/composio-proxies.js +1 -311
- package/dist/node/impls/composio-sdk.js +1 -78
- package/dist/node/impls/composio-types.js +1 -54
- package/dist/node/impls/elevenlabs-voice.js +1 -105
- package/dist/node/impls/fal-voice.js +1 -118
- package/dist/node/impls/fathom-meeting-recorder.js +2 -290
- package/dist/node/impls/fathom-meeting-recorder.mapper.js +1 -108
- package/dist/node/impls/fathom-meeting-recorder.utils.js +1 -75
- package/dist/node/impls/fathom-meeting-recorder.webhooks.js +1 -32
- package/dist/node/impls/fireflies-meeting-recorder.js +5 -204
- package/dist/node/impls/fireflies-meeting-recorder.queries.js +4 -15
- package/dist/node/impls/fireflies-meeting-recorder.utils.js +1 -45
- package/dist/node/impls/gcs-storage.js +1 -100
- package/dist/node/impls/gmail-inbound.js +1 -230
- package/dist/node/impls/gmail-outbound.js +25 -138
- package/dist/node/impls/google-calendar.js +1 -194
- package/dist/node/impls/gradium-voice.js +1 -96
- package/dist/node/impls/granola-meeting-recorder.js +3 -515
- package/dist/node/impls/granola-meeting-recorder.mcp.js +1 -281
- package/dist/node/impls/health/base-health-provider.js +1 -618
- package/dist/node/impls/health/hybrid-health-providers.js +1 -1090
- package/dist/node/impls/health/official-health-providers.js +1 -970
- package/dist/node/impls/health/provider-normalizers.js +1 -289
- package/dist/node/impls/health/providers.js +1 -1096
- package/dist/node/impls/health-provider-factory.js +1 -1310
- package/dist/node/impls/index.js +42 -7449
- package/dist/node/impls/jira.js +1 -127
- package/dist/node/impls/linear.js +1 -86
- package/dist/node/impls/messaging-github.js +1 -112
- package/dist/node/impls/messaging-slack.js +1 -82
- package/dist/node/impls/messaging-telegram.js +1 -49
- package/dist/node/impls/messaging-whatsapp-meta.js +1 -54
- package/dist/node/impls/messaging-whatsapp-twilio.js +1 -84
- package/dist/node/impls/mistral-conversational.js +2 -478
- package/dist/node/impls/mistral-conversational.session.js +2 -208
- package/dist/node/impls/mistral-embedding.js +1 -46
- package/dist/node/impls/mistral-llm.js +1 -272
- package/dist/node/impls/mistral-stt.js +1 -169
- package/dist/node/impls/notion.js +1 -163
- package/dist/node/impls/posthog-reader.js +1 -162
- package/dist/node/impls/posthog-utils.js +1 -41
- package/dist/node/impls/posthog.js +1 -325
- package/dist/node/impls/postmark-email.js +1 -63
- package/dist/node/impls/powens-client.js +1 -198
- package/dist/node/impls/powens-openbanking.js +1 -429
- package/dist/node/impls/provider-factory.js +18 -6269
- package/dist/node/impls/qdrant-vector.js +1 -81
- package/dist/node/impls/stripe-payments.js +1 -231
- package/dist/node/impls/supabase-psql.js +1 -153
- package/dist/node/impls/supabase-vector.js +9 -299
- package/dist/node/impls/tldv-meeting-recorder.js +2 -148
- package/dist/node/impls/twilio-sms.js +1 -68
- package/dist/node/index.js +42 -7496
- package/dist/node/llm.js +1 -2
- package/dist/node/meeting-recorder.js +1 -2
- package/dist/node/messaging.js +1 -2
- package/dist/node/openbanking.js +1 -2
- package/dist/node/payments.js +1 -2
- package/dist/node/project-management.js +1 -2
- package/dist/node/secrets/provider.js +1 -14
- package/dist/node/sms.js +1 -2
- package/dist/node/storage.js +1 -2
- package/dist/node/vector-store.js +1 -2
- package/dist/node/voice.js +1 -2
- package/dist/openbanking.js +1 -2
- package/dist/payments.js +1 -2
- package/dist/project-management.js +1 -2
- package/dist/secrets/provider.js +1 -13
- package/dist/sms.js +1 -2
- package/dist/storage.js +1 -2
- package/dist/vector-store.js +1 -2
- package/dist/voice.js +1 -2
- package/package.json +17 -17
|
@@ -1,230 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
// src/impls/gmail-inbound.ts
|
|
5
|
-
import { google } from "googleapis";
|
|
6
|
-
|
|
7
|
-
class GmailInboundProvider {
|
|
8
|
-
gmail;
|
|
9
|
-
userId;
|
|
10
|
-
includeSpamTrash;
|
|
11
|
-
auth;
|
|
12
|
-
constructor(options) {
|
|
13
|
-
this.auth = options.auth;
|
|
14
|
-
this.gmail = options.gmail ?? google.gmail({
|
|
15
|
-
version: "v1",
|
|
16
|
-
auth: options.auth
|
|
17
|
-
});
|
|
18
|
-
this.userId = options.userId ?? "me";
|
|
19
|
-
this.includeSpamTrash = options.includeSpamTrash ?? false;
|
|
20
|
-
}
|
|
21
|
-
async listThreads(query) {
|
|
22
|
-
const response = await this.gmail.users.threads.list({
|
|
23
|
-
userId: this.userId,
|
|
24
|
-
maxResults: query?.pageSize,
|
|
25
|
-
pageToken: query?.pageToken,
|
|
26
|
-
q: query?.query,
|
|
27
|
-
labelIds: query?.label ? [query.label] : undefined,
|
|
28
|
-
includeSpamTrash: this.includeSpamTrash,
|
|
29
|
-
auth: this.auth
|
|
30
|
-
});
|
|
31
|
-
const threads = await Promise.all((response.data.threads ?? []).map(async (thread) => {
|
|
32
|
-
if (!thread.id)
|
|
33
|
-
return null;
|
|
34
|
-
return this.getThread(thread.id);
|
|
35
|
-
}));
|
|
36
|
-
return threads.filter((thread) => thread !== null);
|
|
37
|
-
}
|
|
38
|
-
async getThread(threadId) {
|
|
39
|
-
const response = await this.gmail.users.threads.get({
|
|
40
|
-
id: threadId,
|
|
41
|
-
userId: this.userId,
|
|
42
|
-
format: "full",
|
|
43
|
-
auth: this.auth
|
|
44
|
-
});
|
|
45
|
-
const thread = response.data;
|
|
46
|
-
if (!thread)
|
|
47
|
-
return null;
|
|
48
|
-
const messages = thread.messages?.map((message) => this.transformMessage(message)) ?? [];
|
|
49
|
-
const participants = dedupeAddresses(messages.flatMap((message) => [
|
|
50
|
-
message.from,
|
|
51
|
-
...message.to,
|
|
52
|
-
...message.cc ?? []
|
|
53
|
-
]));
|
|
54
|
-
const firstMessage = messages[0];
|
|
55
|
-
const lastMessage = messages[messages.length - 1];
|
|
56
|
-
const updatedAt = lastMessage?.receivedAt ?? lastMessage?.sentAt ?? firstMessage?.receivedAt ?? firstMessage?.sentAt ?? new Date;
|
|
57
|
-
const labels = Array.from(new Set(messages.flatMap((message) => {
|
|
58
|
-
const labelField = message.metadata?.labelIds;
|
|
59
|
-
if (!labelField)
|
|
60
|
-
return [];
|
|
61
|
-
return labelField.split(",").map((label) => label.trim());
|
|
62
|
-
}).filter((label) => Boolean(label))));
|
|
63
|
-
return {
|
|
64
|
-
id: thread.id ?? threadId,
|
|
65
|
-
subject: messages[0]?.subject,
|
|
66
|
-
snippet: thread.snippet ?? "",
|
|
67
|
-
participants,
|
|
68
|
-
messages,
|
|
69
|
-
updatedAt,
|
|
70
|
-
labels,
|
|
71
|
-
metadata: thread.historyId ? { historyId: thread.historyId } : undefined
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
async listMessagesSince(query) {
|
|
75
|
-
const after = query.since ? Math.floor(query.since.getTime() / 1000) : undefined;
|
|
76
|
-
const q = [];
|
|
77
|
-
if (after) {
|
|
78
|
-
q.push(`after:${after}`);
|
|
79
|
-
}
|
|
80
|
-
const response = await this.gmail.users.messages.list({
|
|
81
|
-
userId: this.userId,
|
|
82
|
-
maxResults: query.pageSize,
|
|
83
|
-
pageToken: query.pageToken,
|
|
84
|
-
labelIds: query.label ? [query.label] : undefined,
|
|
85
|
-
q: q.join(" "),
|
|
86
|
-
includeSpamTrash: this.includeSpamTrash,
|
|
87
|
-
auth: this.auth
|
|
88
|
-
});
|
|
89
|
-
const messages = await Promise.all((response.data.messages ?? []).map(async (item) => {
|
|
90
|
-
if (!item.id)
|
|
91
|
-
return null;
|
|
92
|
-
const full = await this.gmail.users.messages.get({
|
|
93
|
-
userId: this.userId,
|
|
94
|
-
id: item.id,
|
|
95
|
-
format: "full",
|
|
96
|
-
auth: this.auth
|
|
97
|
-
});
|
|
98
|
-
if (!full.data)
|
|
99
|
-
return null;
|
|
100
|
-
return this.transformMessage(full.data);
|
|
101
|
-
}));
|
|
102
|
-
return {
|
|
103
|
-
messages: messages.filter((message) => message !== null),
|
|
104
|
-
nextPageToken: response.data.nextPageToken ?? undefined
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
transformMessage(message) {
|
|
108
|
-
const headers = message.payload?.headers ?? [];
|
|
109
|
-
const subject = headerValue(headers, "Subject") ?? "";
|
|
110
|
-
const from = parseAddress(headerValue(headers, "From")) ?? inferFallbackAddress("from", message.id);
|
|
111
|
-
const to = parseAddressList(headerValue(headers, "To"));
|
|
112
|
-
const cc = parseAddressList(headerValue(headers, "Cc"));
|
|
113
|
-
const bcc = parseAddressList(headerValue(headers, "Bcc"));
|
|
114
|
-
const replyTo = parseAddress(headerValue(headers, "Reply-To"));
|
|
115
|
-
const { text, html, attachments } = extractContent(message.payload);
|
|
116
|
-
const timestamp = message.internalDate ? new Date(Number(message.internalDate)) : new Date;
|
|
117
|
-
const metadata = {
|
|
118
|
-
...message.labelIds?.length ? { labelIds: message.labelIds.join(",") } : {},
|
|
119
|
-
...message.historyId ? { historyId: message.historyId } : {}
|
|
120
|
-
};
|
|
121
|
-
return {
|
|
122
|
-
id: message.id ?? "",
|
|
123
|
-
threadId: message.threadId ?? "",
|
|
124
|
-
subject,
|
|
125
|
-
from,
|
|
126
|
-
to,
|
|
127
|
-
cc,
|
|
128
|
-
bcc,
|
|
129
|
-
replyTo: replyTo ?? undefined,
|
|
130
|
-
sentAt: timestamp,
|
|
131
|
-
receivedAt: timestamp,
|
|
132
|
-
textBody: text ?? undefined,
|
|
133
|
-
htmlBody: html ?? undefined,
|
|
134
|
-
attachments,
|
|
135
|
-
headers: Object.fromEntries(headers.map((header) => [header.name ?? "", header.value ?? ""])),
|
|
136
|
-
metadata: Object.keys(metadata).length > 0 ? metadata : undefined
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function headerValue(headers, name) {
|
|
141
|
-
const header = headers.find((candidate) => candidate.name?.toLowerCase() === name.toLowerCase());
|
|
142
|
-
const value = header?.value;
|
|
143
|
-
return typeof value === "string" ? value : undefined;
|
|
144
|
-
}
|
|
145
|
-
function parseAddress(header) {
|
|
146
|
-
const addresses = parseAddressList(header);
|
|
147
|
-
if (addresses.length === 0) {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
const firstAddress = addresses[0];
|
|
151
|
-
return firstAddress || null;
|
|
152
|
-
}
|
|
153
|
-
function inferFallbackAddress(field, messageId) {
|
|
154
|
-
const suffix = messageId ? messageId.replace(/[^\w]/g, "").slice(-8) || "unknown" : "unknown";
|
|
155
|
-
return {
|
|
156
|
-
email: `${field}-${suffix}@mail.local`
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
function parseAddressList(header) {
|
|
160
|
-
if (!header)
|
|
161
|
-
return [];
|
|
162
|
-
return header.split(",").map((part) => part.trim()).filter(Boolean).map((value) => {
|
|
163
|
-
const match = value.match(/^(?:"?([^"]*)"?\s)?<?([^<>]+)>?$/);
|
|
164
|
-
if (!match) {
|
|
165
|
-
return { email: value };
|
|
166
|
-
}
|
|
167
|
-
const name = match[1]?.trim();
|
|
168
|
-
const email = match[2]?.trim();
|
|
169
|
-
if (!email) {
|
|
170
|
-
return { email: value };
|
|
171
|
-
}
|
|
172
|
-
return name ? { email, name } : { email };
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
function dedupeAddresses(addresses) {
|
|
176
|
-
const map = new Map;
|
|
177
|
-
for (const address of addresses) {
|
|
178
|
-
if (!address)
|
|
179
|
-
continue;
|
|
180
|
-
map.set(address.email.toLowerCase(), address);
|
|
181
|
-
}
|
|
182
|
-
return Array.from(map.values());
|
|
183
|
-
}
|
|
184
|
-
function extractContent(payload) {
|
|
185
|
-
if (!payload) {
|
|
186
|
-
return { attachments: [] };
|
|
187
|
-
}
|
|
188
|
-
const attachments = [];
|
|
189
|
-
const visit = (part) => {
|
|
190
|
-
if (!part)
|
|
191
|
-
return {};
|
|
192
|
-
if (part.filename && part.body?.attachmentId) {
|
|
193
|
-
attachments.push({
|
|
194
|
-
id: part.body.attachmentId,
|
|
195
|
-
filename: part.filename,
|
|
196
|
-
contentType: part.mimeType ?? "application/octet-stream",
|
|
197
|
-
sizeBytes: part.body.size ?? undefined
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
const mimeType = part.mimeType ?? "";
|
|
201
|
-
const data = part.body?.data;
|
|
202
|
-
if (mimeType === "text/plain" && data) {
|
|
203
|
-
return { text: decodeBase64Url(data) };
|
|
204
|
-
}
|
|
205
|
-
if (mimeType === "text/html" && data) {
|
|
206
|
-
return { html: decodeBase64Url(data) };
|
|
207
|
-
}
|
|
208
|
-
if (part.parts?.length) {
|
|
209
|
-
return part.parts.reduce((acc, nested) => {
|
|
210
|
-
const value = visit(nested);
|
|
211
|
-
return {
|
|
212
|
-
text: value.text ?? acc.text,
|
|
213
|
-
html: value.html ?? acc.html
|
|
214
|
-
};
|
|
215
|
-
}, {});
|
|
216
|
-
}
|
|
217
|
-
return {};
|
|
218
|
-
};
|
|
219
|
-
const { text, html } = visit(payload);
|
|
220
|
-
return { text, html, attachments };
|
|
221
|
-
}
|
|
222
|
-
function decodeBase64Url(data) {
|
|
223
|
-
const normalized = data.replace(/-/g, "+").replace(/_/g, "/");
|
|
224
|
-
const padding = normalized.length % 4;
|
|
225
|
-
const padded = padding === 0 ? normalized : normalized + "=".repeat(4 - padding);
|
|
226
|
-
return Buffer.from(padded, "base64").toString("utf-8");
|
|
227
|
-
}
|
|
228
|
-
export {
|
|
229
|
-
GmailInboundProvider
|
|
230
|
-
};
|
|
2
|
+
var x=import.meta.require;import{google as y}from"googleapis";class T{gmail;userId;includeSpamTrash;auth;constructor(e){this.auth=e.auth,this.gmail=e.gmail??y.gmail({version:"v1",auth:e.auth}),this.userId=e.userId??"me",this.includeSpamTrash=e.includeSpamTrash??!1}async listThreads(e){let t=await this.gmail.users.threads.list({userId:this.userId,maxResults:e?.pageSize,pageToken:e?.pageToken,q:e?.query,labelIds:e?.label?[e.label]:void 0,includeSpamTrash:this.includeSpamTrash,auth:this.auth});return(await Promise.all((t.data.threads??[]).map(async(s)=>{if(!s.id)return null;return this.getThread(s.id)}))).filter((s)=>s!==null)}async getThread(e){let a=(await this.gmail.users.threads.get({id:e,userId:this.userId,format:"full",auth:this.auth})).data;if(!a)return null;let s=a.messages?.map((i)=>this.transformMessage(i))??[],r=v(s.flatMap((i)=>[i.from,...i.to,...i.cc??[]])),n=s[0],l=s[s.length-1],d=l?.receivedAt??l?.sentAt??n?.receivedAt??n?.sentAt??new Date,m=Array.from(new Set(s.flatMap((i)=>{let o=i.metadata?.labelIds;if(!o)return[];return o.split(",").map((c)=>c.trim())}).filter((i)=>Boolean(i))));return{id:a.id??e,subject:s[0]?.subject,snippet:a.snippet??"",participants:r,messages:s,updatedAt:d,labels:m,metadata:a.historyId?{historyId:a.historyId}:void 0}}async listMessagesSince(e){let t=e.since?Math.floor(e.since.getTime()/1000):void 0,a=[];if(t)a.push(`after:${t}`);let s=await this.gmail.users.messages.list({userId:this.userId,maxResults:e.pageSize,pageToken:e.pageToken,labelIds:e.label?[e.label]:void 0,q:a.join(" "),includeSpamTrash:this.includeSpamTrash,auth:this.auth});return{messages:(await Promise.all((s.data.messages??[]).map(async(n)=>{if(!n.id)return null;let l=await this.gmail.users.messages.get({userId:this.userId,id:n.id,format:"full",auth:this.auth});if(!l.data)return null;return this.transformMessage(l.data)}))).filter((n)=>n!==null),nextPageToken:s.data.nextPageToken??void 0}}transformMessage(e){let t=e.payload?.headers??[],a=u(t,"Subject")??"",s=p(u(t,"From"))??I("from",e.id),r=h(u(t,"To")),n=h(u(t,"Cc")),l=h(u(t,"Bcc")),d=p(u(t,"Reply-To")),{text:m,html:i,attachments:o}=M(e.payload),c=e.internalDate?new Date(Number(e.internalDate)):new Date,g={...e.labelIds?.length?{labelIds:e.labelIds.join(",")}:{},...e.historyId?{historyId:e.historyId}:{}};return{id:e.id??"",threadId:e.threadId??"",subject:a,from:s,to:r,cc:n,bcc:l,replyTo:d??void 0,sentAt:c,receivedAt:c,textBody:m??void 0,htmlBody:i??void 0,attachments:o,headers:Object.fromEntries(t.map((f)=>[f.name??"",f.value??""])),metadata:Object.keys(g).length>0?g:void 0}}}function u(e,t){let s=e.find((r)=>r.name?.toLowerCase()===t.toLowerCase())?.value;return typeof s==="string"?s:void 0}function p(e){let t=h(e);if(t.length===0)return null;return t[0]||null}function I(e,t){let a=t?t.replace(/[^\w]/g,"").slice(-8)||"unknown":"unknown";return{email:`${e}-${a}@mail.local`}}function h(e){if(!e)return[];return e.split(",").map((t)=>t.trim()).filter(Boolean).map((t)=>{let a=t.match(/^(?:"?([^"]*)"?\s)?<?([^<>]+)>?$/);if(!a)return{email:t};let s=a[1]?.trim(),r=a[2]?.trim();if(!r)return{email:t};return s?{email:r,name:s}:{email:r}})}function v(e){let t=new Map;for(let a of e){if(!a)continue;t.set(a.email.toLowerCase(),a)}return Array.from(t.values())}function M(e){if(!e)return{attachments:[]};let t=[],a=(n)=>{if(!n)return{};if(n.filename&&n.body?.attachmentId)t.push({id:n.body.attachmentId,filename:n.filename,contentType:n.mimeType??"application/octet-stream",sizeBytes:n.body.size??void 0});let l=n.mimeType??"",d=n.body?.data;if(l==="text/plain"&&d)return{text:b(d)};if(l==="text/html"&&d)return{html:b(d)};if(n.parts?.length)return n.parts.reduce((m,i)=>{let o=a(i);return{text:o.text??m.text,html:o.html??m.html}},{});return{}},{text:s,html:r}=a(e);return{text:s,html:r,attachments:t}}function b(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),a=t.length%4,s=a===0?t:t+"=".repeat(4-a);return Buffer.from(s,"base64").toString("utf-8")}export{T as GmailInboundProvider};
|
|
@@ -1,142 +1,30 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
constructor(options) {
|
|
12
|
-
this.auth = options.auth;
|
|
13
|
-
this.gmail = options.gmail ?? google.gmail({
|
|
14
|
-
version: "v1",
|
|
15
|
-
auth: options.auth
|
|
16
|
-
});
|
|
17
|
-
this.userId = options.userId ?? "me";
|
|
18
|
-
}
|
|
19
|
-
async sendEmail(message) {
|
|
20
|
-
const raw = encodeMessage(message);
|
|
21
|
-
const response = await this.gmail.users.messages.send({
|
|
22
|
-
userId: this.userId,
|
|
23
|
-
requestBody: {
|
|
24
|
-
raw
|
|
25
|
-
},
|
|
26
|
-
auth: this.auth
|
|
27
|
-
});
|
|
28
|
-
const id = response.data.id ?? "";
|
|
29
|
-
return {
|
|
30
|
-
id,
|
|
31
|
-
providerMessageId: response.data.id ?? undefined,
|
|
32
|
-
queuedAt: new Date
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function encodeMessage(message) {
|
|
37
|
-
const headers = [
|
|
38
|
-
`From: ${formatAddress(message.from)}`,
|
|
39
|
-
`To: ${message.to.map(formatAddress).join(", ")}`,
|
|
40
|
-
`Subject: ${message.subject}`,
|
|
41
|
-
"MIME-Version: 1.0"
|
|
42
|
-
];
|
|
43
|
-
if (message.cc?.length) {
|
|
44
|
-
headers.push(`Cc: ${message.cc.map(formatAddress).join(", ")}`);
|
|
45
|
-
}
|
|
46
|
-
if (message.replyTo) {
|
|
47
|
-
headers.push(`Reply-To: ${formatAddress(message.replyTo)}`);
|
|
48
|
-
}
|
|
49
|
-
Object.entries(message.headers ?? {}).forEach(([key, value]) => {
|
|
50
|
-
headers.push(`${key}: ${value}`);
|
|
51
|
-
});
|
|
52
|
-
const attachments = message.attachments ?? [];
|
|
53
|
-
const hasHtml = Boolean(message.htmlBody);
|
|
54
|
-
const hasText = Boolean(message.textBody);
|
|
55
|
-
const boundaryMain = `mixed_${Date.now()}`;
|
|
56
|
-
const boundaryAlt = `alt_${Date.now()}`;
|
|
57
|
-
let body = "";
|
|
58
|
-
if (attachments.length > 0) {
|
|
59
|
-
headers.push(`Content-Type: multipart/mixed; boundary="${boundaryMain}"`);
|
|
60
|
-
body += `\r
|
|
61
|
-
--${boundaryMain}\r
|
|
62
|
-
`;
|
|
63
|
-
body += buildAlternativePart(hasText, hasHtml, boundaryAlt, message);
|
|
64
|
-
attachments.forEach((attachment) => {
|
|
65
|
-
body += buildAttachmentPart(boundaryMain, attachment);
|
|
66
|
-
});
|
|
67
|
-
body += `\r
|
|
68
|
-
--${boundaryMain}--`;
|
|
69
|
-
} else if (hasText && hasHtml) {
|
|
70
|
-
headers.push(`Content-Type: multipart/alternative; boundary="${boundaryAlt}"`);
|
|
71
|
-
body += `\r
|
|
72
|
-
--${boundaryAlt}\r
|
|
73
|
-
`;
|
|
74
|
-
body += buildTextPart('text/plain; charset="utf-8"', message.textBody || "");
|
|
75
|
-
body += `\r
|
|
76
|
-
--${boundaryAlt}\r
|
|
77
|
-
`;
|
|
78
|
-
body += buildTextPart('text/html; charset="utf-8"', message.htmlBody || "");
|
|
79
|
-
body += `\r
|
|
80
|
-
--${boundaryAlt}--`;
|
|
81
|
-
} else if (hasHtml) {
|
|
82
|
-
headers.push('Content-Type: text/html; charset="utf-8"');
|
|
83
|
-
body += `\r
|
|
2
|
+
var b=import.meta.require;import{google as h}from"googleapis";class p{gmail;userId;auth;constructor(t){this.auth=t.auth,this.gmail=t.gmail??h.gmail({version:"v1",auth:t.auth}),this.userId=t.userId??"me"}async sendEmail(t){let n=f(t),e=await this.gmail.users.messages.send({userId:this.userId,requestBody:{raw:n},auth:this.auth});return{id:e.data.id??"",providerMessageId:e.data.id??void 0,queuedAt:new Date}}}function f(t){let n=[`From: ${l(t.from)}`,`To: ${t.to.map(l).join(", ")}`,`Subject: ${t.subject}`,"MIME-Version: 1.0"];if(t.cc?.length)n.push(`Cc: ${t.cc.map(l).join(", ")}`);if(t.replyTo)n.push(`Reply-To: ${l(t.replyTo)}`);Object.entries(t.headers??{}).forEach(([d,c])=>{n.push(`${d}: ${c}`)});let e=t.attachments??[],a=Boolean(t.htmlBody),i=Boolean(t.textBody),u=`mixed_${Date.now()}`,o=`alt_${Date.now()}`,r="";if(e.length>0)n.push(`Content-Type: multipart/mixed; boundary="${u}"`),r+=`\r
|
|
3
|
+
--${u}\r
|
|
4
|
+
`,r+=$(i,a,o,t),e.forEach((d)=>{r+=y(u,d)}),r+=`\r
|
|
5
|
+
--${u}--`;else if(i&&a)n.push(`Content-Type: multipart/alternative; boundary="${o}"`),r+=`\r
|
|
6
|
+
--${o}\r
|
|
7
|
+
`,r+=s('text/plain; charset="utf-8"',t.textBody||""),r+=`\r
|
|
8
|
+
--${o}\r
|
|
9
|
+
`,r+=s('text/html; charset="utf-8"',t.htmlBody||""),r+=`\r
|
|
10
|
+
--${o}--`;else if(a)n.push('Content-Type: text/html; charset="utf-8"'),r+=`\r
|
|
84
11
|
\r
|
|
85
|
-
${
|
|
86
|
-
} else {
|
|
87
|
-
headers.push('Content-Type: text/plain; charset="utf-8"');
|
|
88
|
-
body += `\r
|
|
12
|
+
${t.htmlBody}`;else n.push('Content-Type: text/plain; charset="utf-8"'),r+=`\r
|
|
89
13
|
\r
|
|
90
|
-
${
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
`;
|
|
100
|
-
content += `\r
|
|
101
|
-
`;
|
|
102
|
-
if (hasText) {
|
|
103
|
-
content += `--${boundary}\r
|
|
104
|
-
`;
|
|
105
|
-
content += buildTextPart('text/plain; charset="utf-8"', message.textBody || "");
|
|
106
|
-
}
|
|
107
|
-
if (hasHtml) {
|
|
108
|
-
content += `\r
|
|
109
|
-
--${boundary}\r
|
|
110
|
-
`;
|
|
111
|
-
content += buildTextPart('text/html; charset="utf-8"', message.htmlBody || "");
|
|
112
|
-
}
|
|
113
|
-
content += `\r
|
|
114
|
-
--${boundary}--`;
|
|
115
|
-
return content;
|
|
116
|
-
}
|
|
117
|
-
function buildTextPart(contentType, content) {
|
|
118
|
-
return `Content-Type: ${contentType}\r
|
|
119
|
-
` + `Content-Transfer-Encoding: 7bit\r
|
|
14
|
+
${t.textBody??""}`;let m=`${n.join(`\r
|
|
15
|
+
`)}${r}`;return Buffer.from(m).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function $(t,n,e,a){let i="";if(i+=`Content-Type: multipart/alternative; boundary="${e}"\r
|
|
16
|
+
`,i+=`\r
|
|
17
|
+
`,t)i+=`--${e}\r
|
|
18
|
+
`,i+=s('text/plain; charset="utf-8"',a.textBody||"");if(n)i+=`\r
|
|
19
|
+
--${e}\r
|
|
20
|
+
`,i+=s('text/html; charset="utf-8"',a.htmlBody||"");return i+=`\r
|
|
21
|
+
--${e}--`,i}function s(t,n){return`Content-Type: ${t}\r
|
|
22
|
+
Content-Transfer-Encoding: 7bit\r
|
|
120
23
|
\r
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return `\r
|
|
127
|
-
--${boundary}\r
|
|
128
|
-
` + `Content-Type: ${attachment.contentType}; name="${attachment.filename}"\r
|
|
129
|
-
` + `Content-Transfer-Encoding: base64\r
|
|
130
|
-
` + `Content-Disposition: attachment; filename="${attachment.filename}"\r
|
|
24
|
+
`+n}function y(t,n){let e=n.data??new Uint8Array,a=e.byteLength>0?Buffer.from(e).toString("base64"):"";return`\r
|
|
25
|
+
--${t}\r
|
|
26
|
+
Content-Type: ${n.contentType}; name="${n.filename}"\r
|
|
27
|
+
Content-Transfer-Encoding: base64\r
|
|
28
|
+
Content-Disposition: attachment; filename="${n.filename}"\r
|
|
131
29
|
\r
|
|
132
|
-
`
|
|
133
|
-
}
|
|
134
|
-
function formatAddress(address) {
|
|
135
|
-
if (address.name) {
|
|
136
|
-
return `"${address.name}" <${address.email}>`;
|
|
137
|
-
}
|
|
138
|
-
return address.email;
|
|
139
|
-
}
|
|
140
|
-
export {
|
|
141
|
-
GmailOutboundProvider
|
|
142
|
-
};
|
|
30
|
+
`+a}function l(t){if(t.name)return`"${t.name}" <${t.email}>`;return t.email}export{p as GmailOutboundProvider};
|
|
@@ -1,194 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
// src/impls/google-calendar.ts
|
|
5
|
-
import { google } from "googleapis";
|
|
6
|
-
|
|
7
|
-
class GoogleCalendarProvider {
|
|
8
|
-
calendar;
|
|
9
|
-
defaultCalendarId;
|
|
10
|
-
auth;
|
|
11
|
-
constructor(options) {
|
|
12
|
-
this.auth = options.auth;
|
|
13
|
-
this.calendar = options.calendar ?? google.calendar({
|
|
14
|
-
version: "v3",
|
|
15
|
-
auth: options.auth
|
|
16
|
-
});
|
|
17
|
-
this.defaultCalendarId = options.calendarId ?? "primary";
|
|
18
|
-
}
|
|
19
|
-
async listEvents(query) {
|
|
20
|
-
const response = await this.calendar.events.list({
|
|
21
|
-
calendarId: query.calendarId ?? this.defaultCalendarId,
|
|
22
|
-
timeMin: query.timeMin?.toISOString(),
|
|
23
|
-
timeMax: query.timeMax?.toISOString(),
|
|
24
|
-
maxResults: query.maxResults,
|
|
25
|
-
pageToken: query.pageToken,
|
|
26
|
-
singleEvents: true,
|
|
27
|
-
orderBy: "startTime",
|
|
28
|
-
auth: this.auth
|
|
29
|
-
});
|
|
30
|
-
const events = response.data.items?.map((item) => this.fromGoogleEvent(query.calendarId ?? this.defaultCalendarId, item)) ?? [];
|
|
31
|
-
return {
|
|
32
|
-
events,
|
|
33
|
-
nextPageToken: response.data.nextPageToken ?? undefined
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
async createEvent(input) {
|
|
37
|
-
const calendarId = input.calendarId ?? this.defaultCalendarId;
|
|
38
|
-
const response = await this.calendar.events.insert({
|
|
39
|
-
calendarId,
|
|
40
|
-
requestBody: this.toGoogleEvent(input),
|
|
41
|
-
conferenceDataVersion: input.conference?.create ? 1 : undefined,
|
|
42
|
-
auth: this.auth
|
|
43
|
-
});
|
|
44
|
-
return this.fromGoogleEvent(calendarId, response.data);
|
|
45
|
-
}
|
|
46
|
-
async updateEvent(calendarId, eventId, input) {
|
|
47
|
-
const response = await this.calendar.events.patch({
|
|
48
|
-
calendarId: calendarId ?? this.defaultCalendarId,
|
|
49
|
-
eventId,
|
|
50
|
-
requestBody: this.toGoogleEvent(input),
|
|
51
|
-
conferenceDataVersion: input.conference?.create ? 1 : undefined,
|
|
52
|
-
auth: this.auth
|
|
53
|
-
});
|
|
54
|
-
return this.fromGoogleEvent(calendarId, response.data);
|
|
55
|
-
}
|
|
56
|
-
async deleteEvent(calendarId, eventId) {
|
|
57
|
-
await this.calendar.events.delete({
|
|
58
|
-
calendarId: calendarId ?? this.defaultCalendarId,
|
|
59
|
-
eventId,
|
|
60
|
-
auth: this.auth
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
fromGoogleEvent(calendarId, event) {
|
|
64
|
-
const start = parseDateTime(event.start);
|
|
65
|
-
const end = parseDateTime(event.end);
|
|
66
|
-
const attendees = event.attendees?.map((attendee) => ({
|
|
67
|
-
email: attendee.email ?? "",
|
|
68
|
-
name: attendee.displayName ?? undefined,
|
|
69
|
-
optional: attendee.optional ?? undefined,
|
|
70
|
-
responseStatus: normalizeResponseStatus(attendee.responseStatus)
|
|
71
|
-
})) ?? [];
|
|
72
|
-
const reminders = event.reminders?.overrides?.map((reminder) => ({
|
|
73
|
-
method: reminder.method ?? "popup",
|
|
74
|
-
minutesBeforeStart: reminder.minutes ?? 0
|
|
75
|
-
})) ?? [];
|
|
76
|
-
const metadata = buildMetadata(event);
|
|
77
|
-
return {
|
|
78
|
-
id: event.id ?? "",
|
|
79
|
-
calendarId,
|
|
80
|
-
title: event.summary ?? "",
|
|
81
|
-
description: event.description ?? undefined,
|
|
82
|
-
location: event.location ?? undefined,
|
|
83
|
-
start,
|
|
84
|
-
end,
|
|
85
|
-
allDay: event.start?.date ? true : undefined,
|
|
86
|
-
attendees,
|
|
87
|
-
reminders,
|
|
88
|
-
conferenceLink: event.hangoutLink ?? event.conferenceData?.entryPoints?.find((entry) => entry.uri)?.uri ?? undefined,
|
|
89
|
-
metadata,
|
|
90
|
-
createdAt: event.created ? new Date(event.created) : undefined,
|
|
91
|
-
updatedAt: event.updated ? new Date(event.updated) : undefined
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
toGoogleEvent(input) {
|
|
95
|
-
const event = {};
|
|
96
|
-
if ("title" in input && input.title)
|
|
97
|
-
event.summary = input.title;
|
|
98
|
-
if (input.description !== undefined)
|
|
99
|
-
event.description = input.description;
|
|
100
|
-
if (input.location !== undefined)
|
|
101
|
-
event.location = input.location;
|
|
102
|
-
if (input.start) {
|
|
103
|
-
event.start = formatDateTime(input.start, input.allDay);
|
|
104
|
-
}
|
|
105
|
-
if (input.end) {
|
|
106
|
-
event.end = formatDateTime(input.end, input.allDay);
|
|
107
|
-
}
|
|
108
|
-
if (input.attendees) {
|
|
109
|
-
event.attendees = input.attendees.map((attendee) => ({
|
|
110
|
-
email: attendee.email,
|
|
111
|
-
displayName: attendee.name,
|
|
112
|
-
optional: attendee.optional,
|
|
113
|
-
responseStatus: attendee.responseStatus
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
if (input.reminders) {
|
|
117
|
-
event.reminders = {
|
|
118
|
-
useDefault: false,
|
|
119
|
-
overrides: input.reminders.map((reminder) => ({
|
|
120
|
-
method: reminder.method,
|
|
121
|
-
minutes: reminder.minutesBeforeStart
|
|
122
|
-
}))
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
if (input.conference?.create) {
|
|
126
|
-
event.conferenceData = {
|
|
127
|
-
createRequest: {
|
|
128
|
-
requestId: `conf-${Date.now()}`
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
if (input.metadata) {
|
|
133
|
-
event.extendedProperties = {
|
|
134
|
-
...event.extendedProperties ?? {},
|
|
135
|
-
private: {
|
|
136
|
-
...event.extendedProperties?.private ?? {},
|
|
137
|
-
...input.metadata
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
return event;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function parseDateTime(time) {
|
|
145
|
-
if (!time)
|
|
146
|
-
return new Date;
|
|
147
|
-
if (time.dateTime)
|
|
148
|
-
return new Date(time.dateTime);
|
|
149
|
-
if (time.date)
|
|
150
|
-
return new Date(`${time.date}T00:00:00`);
|
|
151
|
-
return new Date;
|
|
152
|
-
}
|
|
153
|
-
function formatDateTime(date, allDay) {
|
|
154
|
-
if (allDay) {
|
|
155
|
-
return { date: date.toISOString().slice(0, 10) };
|
|
156
|
-
}
|
|
157
|
-
return { dateTime: date.toISOString() };
|
|
158
|
-
}
|
|
159
|
-
function normalizeResponseStatus(status) {
|
|
160
|
-
if (!status)
|
|
161
|
-
return;
|
|
162
|
-
const allowed = [
|
|
163
|
-
"needsAction",
|
|
164
|
-
"declined",
|
|
165
|
-
"tentative",
|
|
166
|
-
"accepted"
|
|
167
|
-
];
|
|
168
|
-
return allowed.includes(status) ? status : undefined;
|
|
169
|
-
}
|
|
170
|
-
function buildMetadata(event) {
|
|
171
|
-
const metadata = {};
|
|
172
|
-
if (event.status)
|
|
173
|
-
metadata.status = event.status;
|
|
174
|
-
if (event.htmlLink)
|
|
175
|
-
metadata.htmlLink = event.htmlLink;
|
|
176
|
-
if (event.iCalUID)
|
|
177
|
-
metadata.iCalUID = event.iCalUID;
|
|
178
|
-
if (event.etag)
|
|
179
|
-
metadata.etag = event.etag;
|
|
180
|
-
if (event.conferenceData?.conferenceSolution?.name) {
|
|
181
|
-
metadata.conferenceSolution = event.conferenceData.conferenceSolution.name;
|
|
182
|
-
}
|
|
183
|
-
if (event.extendedProperties?.private) {
|
|
184
|
-
Object.entries(event.extendedProperties.private).forEach(([key, value]) => {
|
|
185
|
-
if (typeof value === "string") {
|
|
186
|
-
metadata[`extended.${key}`] = value;
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
191
|
-
}
|
|
192
|
-
export {
|
|
193
|
-
GoogleCalendarProvider
|
|
194
|
-
};
|
|
2
|
+
var p=import.meta.require;import{google as c}from"googleapis";class u{calendar;defaultCalendarId;auth;constructor(e){this.auth=e.auth,this.calendar=e.calendar??c.calendar({version:"v3",auth:e.auth}),this.defaultCalendarId=e.calendarId??"primary"}async listEvents(e){let a=await this.calendar.events.list({calendarId:e.calendarId??this.defaultCalendarId,timeMin:e.timeMin?.toISOString(),timeMax:e.timeMax?.toISOString(),maxResults:e.maxResults,pageToken:e.pageToken,singleEvents:!0,orderBy:"startTime",auth:this.auth});return{events:a.data.items?.map((r)=>this.fromGoogleEvent(e.calendarId??this.defaultCalendarId,r))??[],nextPageToken:a.data.nextPageToken??void 0}}async createEvent(e){let a=e.calendarId??this.defaultCalendarId,t=await this.calendar.events.insert({calendarId:a,requestBody:this.toGoogleEvent(e),conferenceDataVersion:e.conference?.create?1:void 0,auth:this.auth});return this.fromGoogleEvent(a,t.data)}async updateEvent(e,a,t){let r=await this.calendar.events.patch({calendarId:e??this.defaultCalendarId,eventId:a,requestBody:this.toGoogleEvent(t),conferenceDataVersion:t.conference?.create?1:void 0,auth:this.auth});return this.fromGoogleEvent(e,r.data)}async deleteEvent(e,a){await this.calendar.events.delete({calendarId:e??this.defaultCalendarId,eventId:a,auth:this.auth})}fromGoogleEvent(e,a){let t=d(a.start),r=d(a.end),s=a.attendees?.map((n)=>({email:n.email??"",name:n.displayName??void 0,optional:n.optional??void 0,responseStatus:f(n.responseStatus)}))??[],o=a.reminders?.overrides?.map((n)=>({method:n.method??"popup",minutesBeforeStart:n.minutes??0}))??[],l=m(a);return{id:a.id??"",calendarId:e,title:a.summary??"",description:a.description??void 0,location:a.location??void 0,start:t,end:r,allDay:a.start?.date?!0:void 0,attendees:s,reminders:o,conferenceLink:a.hangoutLink??a.conferenceData?.entryPoints?.find((n)=>n.uri)?.uri??void 0,metadata:l,createdAt:a.created?new Date(a.created):void 0,updatedAt:a.updated?new Date(a.updated):void 0}}toGoogleEvent(e){let a={};if("title"in e&&e.title)a.summary=e.title;if(e.description!==void 0)a.description=e.description;if(e.location!==void 0)a.location=e.location;if(e.start)a.start=i(e.start,e.allDay);if(e.end)a.end=i(e.end,e.allDay);if(e.attendees)a.attendees=e.attendees.map((t)=>({email:t.email,displayName:t.name,optional:t.optional,responseStatus:t.responseStatus}));if(e.reminders)a.reminders={useDefault:!1,overrides:e.reminders.map((t)=>({method:t.method,minutes:t.minutesBeforeStart}))};if(e.conference?.create)a.conferenceData={createRequest:{requestId:`conf-${Date.now()}`}};if(e.metadata)a.extendedProperties={...a.extendedProperties??{},private:{...a.extendedProperties?.private??{},...e.metadata}};return a}}function d(e){if(!e)return new Date;if(e.dateTime)return new Date(e.dateTime);if(e.date)return new Date(`${e.date}T00:00:00`);return new Date}function i(e,a){if(a)return{date:e.toISOString().slice(0,10)};return{dateTime:e.toISOString()}}function f(e){if(!e)return;return["needsAction","declined","tentative","accepted"].includes(e)?e:void 0}function m(e){let a={};if(e.status)a.status=e.status;if(e.htmlLink)a.htmlLink=e.htmlLink;if(e.iCalUID)a.iCalUID=e.iCalUID;if(e.etag)a.etag=e.etag;if(e.conferenceData?.conferenceSolution?.name)a.conferenceSolution=e.conferenceData.conferenceSolution.name;if(e.extendedProperties?.private)Object.entries(e.extendedProperties.private).forEach(([t,r])=>{if(typeof r==="string")a[`extended.${t}`]=r});return Object.keys(a).length>0?a:void 0}export{u as GoogleCalendarProvider};
|