integrate-sdk 0.9.13-dev.0 → 0.9.14-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +1,4 @@
1
- import { createRequire } from "node:module";
2
- var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
1
  var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
17
- };
18
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
2
  var __export = (target, all) => {
20
3
  for (var name in all)
21
4
  __defProp(target, name, {
@@ -26,7 +9,6 @@ var __export = (target, all) => {
26
9
  });
27
10
  };
28
11
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
29
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
12
 
31
13
  // session-detector.ts
32
14
  var exports_session_detector = {};
@@ -169,6 +151,3639 @@ async function detectSessionContext(request) {
169
151
  }
170
152
  return;
171
153
  }
154
+
155
+ // context-cookie.ts
156
+ var exports_context_cookie = {};
157
+ __export(exports_context_cookie, {
158
+ readContextCookie: () => readContextCookie,
159
+ getSetCookieHeader: () => getSetCookieHeader,
160
+ getContextCookieFromRequest: () => getContextCookieFromRequest,
161
+ getClearCookieHeader: () => getClearCookieHeader,
162
+ createContextCookie: () => createContextCookie,
163
+ CONTEXT_COOKIE_NAME: () => CONTEXT_COOKIE_NAME,
164
+ CONTEXT_COOKIE_MAX_AGE: () => CONTEXT_COOKIE_MAX_AGE
165
+ });
166
+ async function deriveKey(secret) {
167
+ const encoder = new TextEncoder;
168
+ const secretData = encoder.encode(secret);
169
+ const keyMaterial = await crypto.subtle.importKey("raw", secretData, { name: "PBKDF2" }, false, ["deriveBits", "deriveKey"]);
170
+ const salt = encoder.encode("integrate-oauth-context-v1");
171
+ return await crypto.subtle.deriveKey({
172
+ name: "PBKDF2",
173
+ salt,
174
+ iterations: 1e5,
175
+ hash: "SHA-256"
176
+ }, keyMaterial, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"]);
177
+ }
178
+ async function encryptPayload(payload, secret) {
179
+ const key = await deriveKey(secret);
180
+ const iv = crypto.getRandomValues(new Uint8Array(12));
181
+ const encoder = new TextEncoder;
182
+ const data = encoder.encode(JSON.stringify(payload));
183
+ const encrypted = await crypto.subtle.encrypt({
184
+ name: "AES-GCM",
185
+ iv
186
+ }, key, data);
187
+ const combined = new Uint8Array(iv.length + encrypted.byteLength);
188
+ combined.set(iv, 0);
189
+ combined.set(new Uint8Array(encrypted), iv.length);
190
+ return base64UrlEncode(combined);
191
+ }
192
+ async function decryptPayload(cookieValue, secret) {
193
+ try {
194
+ const combined = base64UrlDecode(cookieValue);
195
+ const iv = combined.slice(0, 12);
196
+ const encrypted = combined.slice(12);
197
+ const key = await deriveKey(secret);
198
+ const decrypted = await crypto.subtle.decrypt({
199
+ name: "AES-GCM",
200
+ iv
201
+ }, key, encrypted);
202
+ const decoder = new TextDecoder;
203
+ const json = decoder.decode(decrypted);
204
+ const payload = JSON.parse(json);
205
+ const age = Date.now() - payload.timestamp;
206
+ if (age > CONTEXT_COOKIE_MAX_AGE * 1000) {
207
+ return;
208
+ }
209
+ return payload;
210
+ } catch (error) {
211
+ return;
212
+ }
213
+ }
214
+ function base64UrlEncode(data) {
215
+ const base64 = btoa(String.fromCharCode(...data));
216
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
217
+ }
218
+ function base64UrlDecode(str) {
219
+ let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
220
+ const padding = base64.length % 4;
221
+ if (padding) {
222
+ base64 += "=".repeat(4 - padding);
223
+ }
224
+ const binary = atob(base64);
225
+ const bytes = new Uint8Array(binary.length);
226
+ for (let i = 0;i < binary.length; i++) {
227
+ bytes[i] = binary.charCodeAt(i);
228
+ }
229
+ return bytes;
230
+ }
231
+ async function createContextCookie(context, provider, secret) {
232
+ const payload = {
233
+ context,
234
+ provider,
235
+ timestamp: Date.now()
236
+ };
237
+ return await encryptPayload(payload, secret);
238
+ }
239
+ async function readContextCookie(cookieValue, secret) {
240
+ const payload = await decryptPayload(cookieValue, secret);
241
+ if (!payload) {
242
+ return;
243
+ }
244
+ return {
245
+ context: payload.context,
246
+ provider: payload.provider
247
+ };
248
+ }
249
+ function getSetCookieHeader(cookieValue, maxAge = CONTEXT_COOKIE_MAX_AGE) {
250
+ const attributes = [
251
+ `${CONTEXT_COOKIE_NAME}=${cookieValue}`,
252
+ `Max-Age=${maxAge}`,
253
+ "HttpOnly",
254
+ "Secure",
255
+ "SameSite=Lax",
256
+ "Path=/"
257
+ ];
258
+ return attributes.join("; ");
259
+ }
260
+ function getClearCookieHeader() {
261
+ const attributes = [
262
+ `${CONTEXT_COOKIE_NAME}=`,
263
+ "Max-Age=0",
264
+ "HttpOnly",
265
+ "Secure",
266
+ "SameSite=Lax",
267
+ "Path=/"
268
+ ];
269
+ return attributes.join("; ");
270
+ }
271
+ function getContextCookieFromRequest(request) {
272
+ const cookieHeader = request.headers.get("cookie");
273
+ if (!cookieHeader) {
274
+ return;
275
+ }
276
+ const cookies = cookieHeader.split(";");
277
+ for (const cookie of cookies) {
278
+ const [name, ...valueParts] = cookie.split("=");
279
+ if (name && name.trim() === CONTEXT_COOKIE_NAME) {
280
+ return valueParts.join("=").trim();
281
+ }
282
+ }
283
+ return;
284
+ }
285
+ var CONTEXT_COOKIE_NAME = "__integrate_oauth_ctx", CONTEXT_COOKIE_MAX_AGE = 300;
286
+
287
+ // ../utils/logger.ts
288
+ function shouldLog(level, context) {
289
+ return logLevelHierarchy[level] <= logLevelHierarchy[contextLogLevels[context]];
290
+ }
291
+ function createLogger(namespace, context = "client") {
292
+ const prefix = `[${namespace}]`;
293
+ return {
294
+ debug: (...args) => {
295
+ if (shouldLog("debug", context)) {
296
+ console.log(prefix, ...args);
297
+ }
298
+ },
299
+ info: (...args) => {
300
+ if (shouldLog("info", context)) {
301
+ console.log(prefix, ...args);
302
+ }
303
+ },
304
+ warn: (...args) => {
305
+ if (shouldLog("warn", context)) {
306
+ console.warn(prefix, ...args);
307
+ }
308
+ },
309
+ error: (...args) => {
310
+ if (shouldLog("error", context)) {
311
+ console.error(prefix, ...args);
312
+ }
313
+ }
314
+ };
315
+ }
316
+ var contextLogLevels, logLevelHierarchy;
317
+ var init_logger = __esm(() => {
318
+ contextLogLevels = {
319
+ client: "error",
320
+ server: "error"
321
+ };
322
+ logLevelHierarchy = {
323
+ none: 0,
324
+ error: 1,
325
+ warn: 2,
326
+ info: 3,
327
+ debug: 4
328
+ };
329
+ });
330
+
331
+ // ../oauth/email-fetcher.ts
332
+ async function fetchUserEmail(provider, tokenData) {
333
+ try {
334
+ switch (provider.toLowerCase()) {
335
+ case "github":
336
+ return await fetchGitHubEmail(tokenData.accessToken);
337
+ case "gmail":
338
+ case "google":
339
+ return await fetchGoogleEmail(tokenData.accessToken);
340
+ case "notion":
341
+ return await fetchNotionEmail(tokenData.accessToken);
342
+ default:
343
+ return tokenData.email;
344
+ }
345
+ } catch (error) {
346
+ logger.error(`Failed to fetch email for ${provider}:`, error);
347
+ return;
348
+ }
349
+ }
350
+ async function fetchGitHubEmail(accessToken) {
351
+ try {
352
+ const userResponse = await fetch("https://api.github.com/user", {
353
+ headers: {
354
+ Authorization: `Bearer ${accessToken}`,
355
+ Accept: "application/vnd.github.v3+json"
356
+ }
357
+ });
358
+ if (!userResponse.ok) {
359
+ return;
360
+ }
361
+ const user = await userResponse.json();
362
+ if (user.email) {
363
+ return user.email;
364
+ }
365
+ const emailsResponse = await fetch("https://api.github.com/user/emails", {
366
+ headers: {
367
+ Authorization: `Bearer ${accessToken}`,
368
+ Accept: "application/vnd.github.v3+json"
369
+ }
370
+ });
371
+ if (!emailsResponse.ok) {
372
+ return;
373
+ }
374
+ const emails = await emailsResponse.json();
375
+ const primaryEmail = emails.find((e) => e.primary && e.verified);
376
+ if (primaryEmail) {
377
+ return primaryEmail.email;
378
+ }
379
+ const verifiedEmail = emails.find((e) => e.verified);
380
+ if (verifiedEmail) {
381
+ return verifiedEmail.email;
382
+ }
383
+ if (emails.length > 0 && emails[0]?.email) {
384
+ return emails[0].email;
385
+ }
386
+ return;
387
+ } catch (error) {
388
+ logger.error("Failed to fetch GitHub email:", error);
389
+ return;
390
+ }
391
+ }
392
+ async function fetchGoogleEmail(accessToken) {
393
+ try {
394
+ const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
395
+ headers: {
396
+ Authorization: `Bearer ${accessToken}`
397
+ }
398
+ });
399
+ if (!response.ok) {
400
+ return;
401
+ }
402
+ const user = await response.json();
403
+ return user.email;
404
+ } catch (error) {
405
+ logger.error("Failed to fetch Google email:", error);
406
+ return;
407
+ }
408
+ }
409
+ async function fetchNotionEmail(accessToken) {
410
+ try {
411
+ const response = await fetch("https://api.notion.com/v1/users/me", {
412
+ headers: {
413
+ Authorization: `Bearer ${accessToken}`,
414
+ "Notion-Version": "2022-06-28"
415
+ }
416
+ });
417
+ if (!response.ok) {
418
+ return;
419
+ }
420
+ const user = await response.json();
421
+ return user.person?.email;
422
+ } catch (error) {
423
+ logger.error("Failed to fetch Notion email:", error);
424
+ return;
425
+ }
426
+ }
427
+ var logger;
428
+ var init_email_fetcher = __esm(() => {
429
+ init_logger();
430
+ logger = createLogger("EmailFetcher");
431
+ });
432
+
433
+ // base-handler.ts
434
+ class OAuthHandler {
435
+ config;
436
+ serverUrl;
437
+ apiKey;
438
+ constructor(config) {
439
+ this.config = config;
440
+ if (!config || !config.providers) {
441
+ throw new Error("OAuthHandler requires a valid config with providers");
442
+ }
443
+ this.serverUrl = config.serverUrl || MCP_SERVER_URL;
444
+ this.apiKey = config.apiKey;
445
+ }
446
+ handleIntegrations() {
447
+ const integrations = this.config.integrations || [];
448
+ return {
449
+ integrations: integrations.map((integration) => ({
450
+ id: integration.id,
451
+ name: integration.name || integration.id,
452
+ logoUrl: integration.logoUrl,
453
+ tools: integration.tools,
454
+ hasOAuth: !!integration.oauth,
455
+ scopes: integration.oauth?.scopes,
456
+ optionalScopes: integration.oauth?.optionalScopes,
457
+ provider: integration.oauth?.provider
458
+ }))
459
+ };
460
+ }
461
+ getHeaders(additionalHeaders) {
462
+ const headers = {
463
+ ...additionalHeaders
464
+ };
465
+ if (this.apiKey) {
466
+ headers["X-API-KEY"] = this.apiKey;
467
+ }
468
+ return headers;
469
+ }
470
+ hasDatabaseCallbacks() {
471
+ return !!this.config.setProviderToken;
472
+ }
473
+ async handleAuthorize(request) {
474
+ let webRequest;
475
+ let authorizeRequest;
476
+ if (request instanceof Request) {
477
+ webRequest = request;
478
+ authorizeRequest = await request.json();
479
+ } else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
480
+ authorizeRequest = await request.json();
481
+ } else {
482
+ authorizeRequest = request;
483
+ }
484
+ const providerConfig = this.config.providers[authorizeRequest.provider];
485
+ if (!providerConfig) {
486
+ throw new Error(`Provider ${authorizeRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
487
+ }
488
+ if (!providerConfig.clientId || !providerConfig.clientSecret) {
489
+ throw new Error(`Missing OAuth credentials for ${authorizeRequest.provider}. Check your environment variables.`);
490
+ }
491
+ const url = new URL("/oauth/authorize", this.serverUrl);
492
+ url.searchParams.set("provider", authorizeRequest.provider);
493
+ url.searchParams.set("client_id", providerConfig.clientId);
494
+ url.searchParams.set("client_secret", providerConfig.clientSecret);
495
+ const scopes = authorizeRequest.scopes || providerConfig.scopes || [];
496
+ if (scopes.length > 0) {
497
+ url.searchParams.set("scope", scopes.join(","));
498
+ }
499
+ const optionalScopes = authorizeRequest.optionalScopes || providerConfig.optionalScopes || [];
500
+ if (optionalScopes.length > 0) {
501
+ url.searchParams.set("optional_scope", optionalScopes.join(","));
502
+ }
503
+ url.searchParams.set("state", authorizeRequest.state);
504
+ url.searchParams.set("code_challenge", authorizeRequest.codeChallenge);
505
+ url.searchParams.set("code_challenge_method", authorizeRequest.codeChallengeMethod);
506
+ const redirectUri = providerConfig.redirectUri;
507
+ if (redirectUri) {
508
+ url.searchParams.set("redirect_uri", redirectUri);
509
+ }
510
+ const OAUTH_FIELDS = new Set([
511
+ "clientId",
512
+ "clientSecret",
513
+ "scopes",
514
+ "optionalScopes",
515
+ "redirectUri",
516
+ "client_id",
517
+ "client_secret",
518
+ "scope",
519
+ "optional_scope",
520
+ "redirect_uri",
521
+ "provider"
522
+ ]);
523
+ if (providerConfig.config) {
524
+ for (const [key, value] of Object.entries(providerConfig.config)) {
525
+ if (value !== undefined && value !== null && !OAUTH_FIELDS.has(key)) {
526
+ url.searchParams.set(key, String(value));
527
+ }
528
+ }
529
+ }
530
+ const response = await fetch(url.toString(), {
531
+ method: "GET",
532
+ headers: this.getHeaders()
533
+ });
534
+ if (!response.ok) {
535
+ const error = await response.text();
536
+ throw new Error(`MCP server failed to generate authorization URL: ${error}`);
537
+ }
538
+ const data = await response.json();
539
+ const result = data;
540
+ if (!result.authorizationUrl) {
541
+ throw new Error("MCP server failed to return authorization URL");
542
+ }
543
+ if (authorizeRequest.codeVerifier) {
544
+ try {
545
+ const serverImport = new Function("s", "return import(s)");
546
+ const { storeCodeVerifier } = await serverImport("../server.js");
547
+ storeCodeVerifier(authorizeRequest.state, authorizeRequest.codeVerifier, authorizeRequest.provider, authorizeRequest.frontendOrigin);
548
+ } catch (error) {}
549
+ } else {}
550
+ if (webRequest) {
551
+ try {
552
+ const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
553
+ const { createContextCookie: createContextCookie2, getSetCookieHeader: getSetCookieHeader2 } = await Promise.resolve().then(() => exports_context_cookie);
554
+ let context;
555
+ if (this.config.getSessionContext) {
556
+ context = await this.config.getSessionContext(webRequest);
557
+ }
558
+ if (!context || !context.userId) {
559
+ context = await detectSessionContext2(webRequest);
560
+ }
561
+ if (context && context.userId) {
562
+ const secret = this.apiKey || providerConfig.clientSecret;
563
+ const cookieValue = await createContextCookie2(context, authorizeRequest.provider, secret);
564
+ result.setCookie = getSetCookieHeader2(cookieValue);
565
+ }
566
+ } catch (error) {}
567
+ }
568
+ return result;
569
+ }
570
+ async handleCallback(request) {
571
+ let webRequest;
572
+ let callbackRequest;
573
+ if (request instanceof Request) {
574
+ webRequest = request;
575
+ callbackRequest = await request.json();
576
+ } else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
577
+ callbackRequest = await request.json();
578
+ } else {
579
+ callbackRequest = request;
580
+ }
581
+ const providerConfig = this.config.providers[callbackRequest.provider];
582
+ if (!providerConfig) {
583
+ throw new Error(`Provider ${callbackRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
584
+ }
585
+ if (!providerConfig.clientId || !providerConfig.clientSecret) {
586
+ throw new Error(`Missing OAuth credentials for ${callbackRequest.provider}. Check your environment variables.`);
587
+ }
588
+ let context;
589
+ if (webRequest) {
590
+ try {
591
+ const { getContextCookieFromRequest: getContextCookieFromRequest2, readContextCookie: readContextCookie2 } = await Promise.resolve().then(() => exports_context_cookie);
592
+ const cookieValue = getContextCookieFromRequest2(webRequest);
593
+ if (cookieValue) {
594
+ const secret = this.apiKey || providerConfig.clientSecret;
595
+ const contextData = await readContextCookie2(cookieValue, secret);
596
+ if (contextData && contextData.provider === callbackRequest.provider) {
597
+ context = contextData.context;
598
+ }
599
+ }
600
+ } catch (error) {}
601
+ }
602
+ const url = new URL("/oauth/callback", this.serverUrl);
603
+ const response = await fetch(url.toString(), {
604
+ method: "POST",
605
+ headers: this.getHeaders({
606
+ "Content-Type": "application/json"
607
+ }),
608
+ body: JSON.stringify({
609
+ provider: callbackRequest.provider,
610
+ code: callbackRequest.code,
611
+ code_verifier: callbackRequest.codeVerifier,
612
+ state: callbackRequest.state,
613
+ client_id: providerConfig.clientId,
614
+ client_secret: providerConfig.clientSecret,
615
+ redirect_uri: providerConfig.redirectUri
616
+ })
617
+ });
618
+ if (!response.ok) {
619
+ const error = await response.text();
620
+ throw new Error(`MCP server failed to exchange authorization code: ${error}`);
621
+ }
622
+ const data = await response.json();
623
+ const result = data;
624
+ if (this.config.setProviderToken) {
625
+ try {
626
+ const tokenData = {
627
+ accessToken: result.accessToken,
628
+ refreshToken: result.refreshToken,
629
+ tokenType: result.tokenType,
630
+ expiresIn: result.expiresIn,
631
+ expiresAt: result.expiresAt,
632
+ scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
633
+ };
634
+ const email = result.email || await fetchUserEmail(callbackRequest.provider, tokenData);
635
+ if (email) {
636
+ tokenData.email = email;
637
+ }
638
+ await this.config.setProviderToken(callbackRequest.provider, tokenData, email, context);
639
+ } catch (error) {}
640
+ }
641
+ if (webRequest) {
642
+ const { getClearCookieHeader: getClearCookieHeader2 } = await Promise.resolve().then(() => exports_context_cookie);
643
+ result.clearCookie = getClearCookieHeader2();
644
+ }
645
+ return result;
646
+ }
647
+ async handleStatus(provider, accessToken) {
648
+ const url = new URL("/oauth/status", this.serverUrl);
649
+ url.searchParams.set("provider", provider);
650
+ const response = await fetch(url.toString(), {
651
+ method: "GET",
652
+ headers: this.getHeaders({
653
+ Authorization: `Bearer ${accessToken}`
654
+ })
655
+ });
656
+ if (!response.ok) {
657
+ if (response.status === 401) {
658
+ return {
659
+ authorized: false
660
+ };
661
+ }
662
+ const error = await response.text();
663
+ throw new Error(`MCP server failed to check authorization status: ${error}`);
664
+ }
665
+ const data = await response.json();
666
+ return data;
667
+ }
668
+ async handleDisconnect(request, accessToken, webRequest) {
669
+ if (!accessToken) {
670
+ throw new Error("No access token provided. Cannot disconnect provider.");
671
+ }
672
+ if (webRequest && this.config.removeProviderToken) {
673
+ try {
674
+ let context;
675
+ if (this.config.getSessionContext) {
676
+ context = await this.config.getSessionContext(webRequest);
677
+ }
678
+ if (!context || !context.userId) {
679
+ const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
680
+ context = await detectSessionContext2(webRequest);
681
+ }
682
+ if (context) {
683
+ try {
684
+ await this.config.removeProviderToken(request.provider, undefined, context);
685
+ } catch (error) {
686
+ logger2.error(`Failed to delete token for ${request.provider} from database via removeProviderToken:`, error);
687
+ }
688
+ }
689
+ } catch (error) {
690
+ logger2.error(`Failed to extract context for disconnect:`, error);
691
+ }
692
+ }
693
+ const url = new URL("/oauth/disconnect", this.serverUrl);
694
+ const response = await fetch(url.toString(), {
695
+ method: "POST",
696
+ headers: this.getHeaders({
697
+ "Content-Type": "application/json",
698
+ Authorization: `Bearer ${accessToken}`
699
+ }),
700
+ body: JSON.stringify({
701
+ provider: request.provider
702
+ })
703
+ });
704
+ if (!response.ok) {
705
+ const error = await response.text();
706
+ throw new Error(`MCP server failed to disconnect provider: ${error}`);
707
+ }
708
+ const data = await response.json();
709
+ return data;
710
+ }
711
+ async handleRefresh(request) {
712
+ let webRequest;
713
+ let refreshRequest;
714
+ if (request instanceof Request) {
715
+ webRequest = request;
716
+ refreshRequest = await request.json();
717
+ } else if (typeof request === "object" && "json" in request && typeof request.json === "function") {
718
+ refreshRequest = await request.json();
719
+ } else {
720
+ refreshRequest = request;
721
+ }
722
+ const providerConfig = this.config.providers[refreshRequest.provider];
723
+ if (!providerConfig) {
724
+ throw new Error(`Provider ${refreshRequest.provider} not configured. Add OAuth credentials to your API route configuration.`);
725
+ }
726
+ let context;
727
+ if (webRequest) {
728
+ try {
729
+ if (this.config.getSessionContext) {
730
+ context = await this.config.getSessionContext(webRequest);
731
+ }
732
+ if (!context || !context.userId) {
733
+ const { detectSessionContext: detectSessionContext2 } = await Promise.resolve().then(() => exports_session_detector);
734
+ context = await detectSessionContext2(webRequest);
735
+ }
736
+ } catch (error) {}
737
+ }
738
+ const body = {
739
+ provider: refreshRequest.provider,
740
+ refresh_token: refreshRequest.refreshToken,
741
+ client_id: providerConfig.clientId
742
+ };
743
+ if (providerConfig.clientSecret) {
744
+ body.client_secret = providerConfig.clientSecret;
745
+ }
746
+ if (providerConfig.config?.subdomain) {
747
+ body.subdomain = providerConfig.config.subdomain;
748
+ }
749
+ const url = new URL("/oauth/refresh", this.serverUrl);
750
+ const response = await fetch(url.toString(), {
751
+ method: "POST",
752
+ headers: this.getHeaders({
753
+ "Content-Type": "application/json"
754
+ }),
755
+ body: JSON.stringify(body)
756
+ });
757
+ if (!response.ok) {
758
+ const error = await response.text();
759
+ const lowerError = error.toLowerCase();
760
+ if (lowerError.includes("not supported") || lowerError.includes("unsupported")) {
761
+ throw new Error(`Token refresh not supported: ${error}`);
762
+ }
763
+ throw new Error(`Token refresh failed: ${error}`);
764
+ }
765
+ const data = await response.json();
766
+ const result = data;
767
+ if (this.config.setProviderToken) {
768
+ try {
769
+ const tokenData = {
770
+ accessToken: result.accessToken,
771
+ refreshToken: result.refreshToken,
772
+ tokenType: result.tokenType,
773
+ expiresIn: result.expiresIn,
774
+ expiresAt: result.expiresAt,
775
+ scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
776
+ };
777
+ const email = result.email || await fetchUserEmail(refreshRequest.provider, tokenData);
778
+ if (email) {
779
+ tokenData.email = email;
780
+ }
781
+ await this.config.setProviderToken(refreshRequest.provider, tokenData, email, context);
782
+ } catch (error) {}
783
+ }
784
+ return result;
785
+ }
786
+ async handleToolCall(request, authHeader, integrationsHeader) {
787
+ const url = this.serverUrl;
788
+ const headers = this.getHeaders({
789
+ "Content-Type": "application/json"
790
+ });
791
+ if (authHeader) {
792
+ const normalized = authHeader.replace(/^bearer\s+/i, "Bearer ");
793
+ if (normalized.startsWith("Bearer ")) {
794
+ headers["Authorization"] = normalized;
795
+ }
796
+ }
797
+ if (integrationsHeader) {
798
+ headers["X-Integrations"] = integrationsHeader;
799
+ }
800
+ const jsonRpcRequest = {
801
+ jsonrpc: "2.0",
802
+ id: Date.now() + Math.random(),
803
+ method: "tools/call",
804
+ params: {
805
+ name: request.name,
806
+ arguments: request.arguments || {}
807
+ }
808
+ };
809
+ const response = await fetch(url, {
810
+ method: "POST",
811
+ headers,
812
+ body: JSON.stringify(jsonRpcRequest)
813
+ });
814
+ if (!response.ok) {
815
+ const error = await response.text();
816
+ throw new Error(`MCP server failed to execute tool call: ${error}`);
817
+ }
818
+ const jsonRpcResponse = await response.json();
819
+ if (jsonRpcResponse.error) {
820
+ const error = new Error(jsonRpcResponse.error.message || "Tool call failed");
821
+ error.code = jsonRpcResponse.error.code;
822
+ error.data = jsonRpcResponse.error.data;
823
+ throw error;
824
+ }
825
+ return jsonRpcResponse.result;
826
+ }
827
+ }
828
+ var SERVER_LOG_CONTEXT = "server", logger2, MCP_SERVER_URL = "https://mcp.integrate.dev/api/v1/mcp";
829
+ var init_base_handler = __esm(() => {
830
+ init_email_fetcher();
831
+ init_logger();
832
+ logger2 = createLogger("OAuthHandler", SERVER_LOG_CONTEXT);
833
+ });
834
+
835
+ // ../oauth/pkce.ts
836
+ var exports_pkce = {};
837
+ __export(exports_pkce, {
838
+ parseState: () => parseState,
839
+ generateStateWithReturnUrl: () => generateStateWithReturnUrl,
840
+ generateState: () => generateState,
841
+ generateCodeVerifier: () => generateCodeVerifier,
842
+ generateCodeChallenge: () => generateCodeChallenge
843
+ });
844
+ function generateCodeVerifier() {
845
+ const array = new Uint8Array(32);
846
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
847
+ crypto.getRandomValues(array);
848
+ } else if (typeof globalThis !== "undefined" && globalThis.crypto) {
849
+ globalThis.crypto.getRandomValues(array);
850
+ } else {
851
+ throw new Error("crypto.getRandomValues is not available. Please use Node.js 19+ or a modern browser.");
852
+ }
853
+ return base64UrlEncode2(array);
854
+ }
855
+ async function generateCodeChallenge(verifier) {
856
+ const encoder = new TextEncoder;
857
+ const data = encoder.encode(verifier);
858
+ let hashBuffer;
859
+ if (typeof crypto !== "undefined" && crypto.subtle) {
860
+ hashBuffer = await crypto.subtle.digest("SHA-256", data);
861
+ } else if (typeof globalThis !== "undefined" && globalThis.crypto?.subtle) {
862
+ hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", data);
863
+ } else {
864
+ throw new Error("crypto.subtle.digest is not available. Please use Node.js 19+ or a modern browser.");
865
+ }
866
+ return base64UrlEncode2(new Uint8Array(hashBuffer));
867
+ }
868
+ function generateState() {
869
+ const array = new Uint8Array(16);
870
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
871
+ crypto.getRandomValues(array);
872
+ } else if (typeof globalThis !== "undefined" && globalThis.crypto) {
873
+ globalThis.crypto.getRandomValues(array);
874
+ } else {
875
+ throw new Error("crypto.getRandomValues is not available. Please use Node.js 19+ or a modern browser.");
876
+ }
877
+ return base64UrlEncode2(array);
878
+ }
879
+ function generateStateWithReturnUrl(returnUrl) {
880
+ const csrf = generateState();
881
+ const stateData = returnUrl ? { csrf, returnUrl } : { csrf };
882
+ const encoder = new TextEncoder;
883
+ const jsonBytes = encoder.encode(JSON.stringify(stateData));
884
+ return base64UrlEncode2(jsonBytes);
885
+ }
886
+ function parseState(state) {
887
+ try {
888
+ const decoded = base64UrlDecode2(state);
889
+ const parsed = JSON.parse(decoded);
890
+ if (typeof parsed === "string") {
891
+ return { csrf: parsed };
892
+ } else if (parsed && typeof parsed === "object") {
893
+ return {
894
+ csrf: parsed.csrf || state,
895
+ returnUrl: parsed.returnUrl
896
+ };
897
+ }
898
+ return { csrf: state };
899
+ } catch {
900
+ return { csrf: state };
901
+ }
902
+ }
903
+ function base64UrlEncode2(array) {
904
+ let base64 = "";
905
+ if (typeof Buffer !== "undefined") {
906
+ base64 = Buffer.from(array).toString("base64");
907
+ } else {
908
+ const binary = String.fromCharCode(...array);
909
+ base64 = btoa(binary);
910
+ }
911
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
912
+ }
913
+ function base64UrlDecode2(str) {
914
+ let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
915
+ while (base64.length % 4 !== 0) {
916
+ base64 += "=";
917
+ }
918
+ if (typeof Buffer !== "undefined") {
919
+ return Buffer.from(base64, "base64").toString("utf-8");
920
+ } else {
921
+ const binary = atob(base64);
922
+ const bytes = new Uint8Array(binary.length);
923
+ for (let i = 0;i < binary.length; i++) {
924
+ bytes[i] = binary.charCodeAt(i);
925
+ }
926
+ const decoder = new TextDecoder;
927
+ return decoder.decode(bytes);
928
+ }
929
+ }
930
+
931
+ // ../errors.ts
932
+ var exports_errors = {};
933
+ __export(exports_errors, {
934
+ parseServerError: () => parseServerError,
935
+ isTokenExpiredError: () => isTokenExpiredError,
936
+ isAuthorizationError: () => isAuthorizationError,
937
+ isAuthError: () => isAuthError,
938
+ ToolCallError: () => ToolCallError,
939
+ TokenExpiredError: () => TokenExpiredError,
940
+ IntegrateSDKError: () => IntegrateSDKError,
941
+ ConnectionError: () => ConnectionError,
942
+ AuthorizationError: () => AuthorizationError,
943
+ AuthenticationError: () => AuthenticationError
944
+ });
945
+ function isAuthError(error) {
946
+ return error instanceof AuthenticationError;
947
+ }
948
+ function isTokenExpiredError(error) {
949
+ return error instanceof TokenExpiredError;
950
+ }
951
+ function isAuthorizationError(error) {
952
+ return error instanceof AuthorizationError;
953
+ }
954
+ function parseServerError(error, context) {
955
+ if (error && typeof error === "object" && "jsonrpcError" in error) {
956
+ const jsonrpcError = error.jsonrpcError;
957
+ if (jsonrpcError && typeof jsonrpcError === "object") {
958
+ return parseServerError(jsonrpcError, context);
959
+ }
960
+ }
961
+ if (error && typeof error === "object" && "code" in error && "message" in error) {
962
+ const code = error.code;
963
+ const message = error.message || "Unknown error";
964
+ if (code === -32600) {
965
+ return new IntegrateSDKError(`Invalid request: ${message}`);
966
+ }
967
+ if (code === -32601) {
968
+ return new IntegrateSDKError(`Method not found: ${message}`);
969
+ }
970
+ if (code === -32602) {
971
+ return new IntegrateSDKError(`Invalid params: ${message}`);
972
+ }
973
+ if (code === 401 || code === -32001) {
974
+ if (message.toLowerCase().includes("expired") || message.toLowerCase().includes("token")) {
975
+ return new TokenExpiredError(message, context?.provider);
976
+ }
977
+ return new AuthenticationError(message, 401, context?.provider);
978
+ }
979
+ if (code === 403 || code === -32002) {
980
+ return new AuthorizationError(message, 403);
981
+ }
982
+ if (context?.toolName) {
983
+ return new ToolCallError(message, context.toolName, error);
984
+ }
985
+ return new IntegrateSDKError(message);
986
+ }
987
+ if (error instanceof Error) {
988
+ const message = error.message;
989
+ const statusCode = error.statusCode;
990
+ if (statusCode === 401) {
991
+ if (message.toLowerCase().includes("expired") || message.toLowerCase().includes("token")) {
992
+ return new TokenExpiredError(message, context?.provider);
993
+ }
994
+ return new AuthenticationError(message, 401, context?.provider);
995
+ }
996
+ if (statusCode === 403) {
997
+ return new AuthorizationError(message, 403);
998
+ }
999
+ if (message.includes("401") || message.includes("Unauthorized") || message.includes("unauthenticated")) {
1000
+ if (message.toLowerCase().includes("expired") || message.toLowerCase().includes("token")) {
1001
+ return new TokenExpiredError(message, context?.provider);
1002
+ }
1003
+ return new AuthenticationError(message, 401, context?.provider);
1004
+ }
1005
+ if (message.includes("403") || message.includes("Forbidden") || message.includes("unauthorized")) {
1006
+ return new AuthorizationError(message, 403);
1007
+ }
1008
+ if (context?.toolName) {
1009
+ return new ToolCallError(message, context.toolName, error);
1010
+ }
1011
+ return new IntegrateSDKError(message);
1012
+ }
1013
+ return new IntegrateSDKError(String(error));
1014
+ }
1015
+ var IntegrateSDKError, AuthenticationError, AuthorizationError, TokenExpiredError, ConnectionError, ToolCallError;
1016
+ var init_errors = __esm(() => {
1017
+ IntegrateSDKError = class IntegrateSDKError extends Error {
1018
+ constructor(message) {
1019
+ super(message);
1020
+ this.name = "IntegrateSDKError";
1021
+ }
1022
+ };
1023
+ AuthenticationError = class AuthenticationError extends IntegrateSDKError {
1024
+ statusCode;
1025
+ provider;
1026
+ constructor(message, statusCode, provider) {
1027
+ super(message);
1028
+ this.name = "AuthenticationError";
1029
+ this.statusCode = statusCode;
1030
+ this.provider = provider;
1031
+ }
1032
+ };
1033
+ AuthorizationError = class AuthorizationError extends IntegrateSDKError {
1034
+ statusCode;
1035
+ requiredScopes;
1036
+ constructor(message, statusCode, requiredScopes) {
1037
+ super(message);
1038
+ this.name = "AuthorizationError";
1039
+ this.statusCode = statusCode;
1040
+ this.requiredScopes = requiredScopes;
1041
+ }
1042
+ };
1043
+ TokenExpiredError = class TokenExpiredError extends AuthenticationError {
1044
+ constructor(message, provider) {
1045
+ super(message, 401, provider);
1046
+ this.name = "TokenExpiredError";
1047
+ }
1048
+ };
1049
+ ConnectionError = class ConnectionError extends IntegrateSDKError {
1050
+ statusCode;
1051
+ constructor(message, statusCode) {
1052
+ super(message);
1053
+ this.name = "ConnectionError";
1054
+ this.statusCode = statusCode;
1055
+ }
1056
+ };
1057
+ ToolCallError = class ToolCallError extends IntegrateSDKError {
1058
+ toolName;
1059
+ originalError;
1060
+ constructor(message, toolName, originalError) {
1061
+ super(message);
1062
+ this.name = "ToolCallError";
1063
+ this.toolName = toolName;
1064
+ this.originalError = originalError;
1065
+ }
1066
+ };
1067
+ });
1068
+
1069
+ // ../utils/naming.ts
1070
+ function camelToSnake(str) {
1071
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
1072
+ }
1073
+ function methodToToolName(methodName, integrationId) {
1074
+ const snakeCaseMethod = camelToSnake(methodName);
1075
+ return `${integrationId}_${snakeCaseMethod}`;
1076
+ }
1077
+
1078
+ // ../utils/concurrency.ts
1079
+ var exports_concurrency = {};
1080
+ __export(exports_concurrency, {
1081
+ parallelWithLimit: () => parallelWithLimit
1082
+ });
1083
+ async function parallelWithLimit(items, fn, limit = 3) {
1084
+ const results = [];
1085
+ const executing = [];
1086
+ for (let i = 0;i < items.length; i++) {
1087
+ const item = items[i];
1088
+ const index = i;
1089
+ const promise = fn(item).then((result) => {
1090
+ results[index] = result;
1091
+ }).catch(() => {
1092
+ results[index] = undefined;
1093
+ });
1094
+ executing.push(promise);
1095
+ if (executing.length >= limit) {
1096
+ const completedIndex = await Promise.race(executing.map((p, idx) => p.then(() => idx).catch(() => idx)));
1097
+ executing.splice(completedIndex, 1);
1098
+ }
1099
+ }
1100
+ await Promise.all(executing);
1101
+ return results;
1102
+ }
1103
+ // ../triggers/utils.ts
1104
+ var init_utils = () => {};
1105
+
1106
+ // ../code-mode/type-generator.ts
1107
+ var RESERVED_TS;
1108
+ var init_type_generator = __esm(() => {
1109
+ RESERVED_TS = new Set([
1110
+ "break",
1111
+ "case",
1112
+ "catch",
1113
+ "class",
1114
+ "const",
1115
+ "continue",
1116
+ "debugger",
1117
+ "default",
1118
+ "delete",
1119
+ "do",
1120
+ "else",
1121
+ "enum",
1122
+ "export",
1123
+ "extends",
1124
+ "false",
1125
+ "finally",
1126
+ "for",
1127
+ "function",
1128
+ "if",
1129
+ "import",
1130
+ "in",
1131
+ "instanceof",
1132
+ "new",
1133
+ "null",
1134
+ "return",
1135
+ "super",
1136
+ "switch",
1137
+ "this",
1138
+ "throw",
1139
+ "true",
1140
+ "try",
1141
+ "typeof",
1142
+ "var",
1143
+ "void",
1144
+ "while",
1145
+ "with",
1146
+ "as",
1147
+ "implements",
1148
+ "interface",
1149
+ "let",
1150
+ "package",
1151
+ "private",
1152
+ "protected",
1153
+ "public",
1154
+ "static",
1155
+ "yield"
1156
+ ]);
1157
+ });
1158
+ // ../code-mode/executor.ts
1159
+ var init_executor = () => {};
1160
+
1161
+ // ../code-mode/tool-builder.ts
1162
+ var DEFAULT_INSTRUCTIONS, warnedCodeModeReasons;
1163
+ var init_tool_builder = __esm(() => {
1164
+ init_type_generator();
1165
+ init_executor();
1166
+ DEFAULT_INSTRUCTIONS = [
1167
+ "You are given a single tool: `execute_code`. Instead of calling individual MCP tools,",
1168
+ "you write a short async TypeScript/JavaScript snippet that uses the typed `client`",
1169
+ "object below, and the snippet runs in an isolated sandbox which dispatches the actual",
1170
+ "tool calls. Chain multiple operations together in one snippet whenever possible —",
1171
+ "that is the whole point of this tool.",
1172
+ "",
1173
+ "Rules:",
1174
+ "- The snippet is the body of an `async` function. Use `await` freely.",
1175
+ "- Use `return <value>` at the end to hand a structured result back to the caller;",
1176
+ " the caller receives it as JSON.",
1177
+ "- Use `console.log(...)` for intermediate observations you want to read later.",
1178
+ "- Throw / let errors propagate; the runtime will surface them with a non-zero exit.",
1179
+ "- Each method call returns an object of shape `ToolResult` (see types below).",
1180
+ " The payload usually lives in `result.content[0].text` as JSON — parse it if needed.",
1181
+ "- You cannot import npm packages. Only the pre-imported `client` and standard",
1182
+ " globals (`fetch`, `console`, `JSON`, ...) are available.",
1183
+ "",
1184
+ "API surface:"
1185
+ ].join(`
1186
+ `);
1187
+ warnedCodeModeReasons = new Set;
1188
+ });
1189
+
1190
+ // nextjs.ts
1191
+ init_base_handler();
1192
+ init_logger();
1193
+ var SERVER_LOG_CONTEXT2 = "server";
1194
+ var logger3 = createLogger("NextJSOAuth", SERVER_LOG_CONTEXT2);
1195
+ function createNextOAuthHandler(config) {
1196
+ const handler = new OAuthHandler(config);
1197
+ const handlers = {
1198
+ async authorize(req) {
1199
+ try {
1200
+ const result = await handler.handleAuthorize(req);
1201
+ const response = Response.json(result);
1202
+ if (result.setCookie) {
1203
+ response.headers.set("Set-Cookie", result.setCookie);
1204
+ }
1205
+ if (handler.hasDatabaseCallbacks()) {
1206
+ response.headers.set("X-Integrate-Use-Database", "true");
1207
+ }
1208
+ return response;
1209
+ } catch (error) {
1210
+ logger3.error("[OAuth Authorize] Error:", error);
1211
+ return Response.json({ error: error.message || "Failed to get authorization URL" }, { status: 500 });
1212
+ }
1213
+ },
1214
+ async callback(req) {
1215
+ try {
1216
+ const result = await handler.handleCallback(req);
1217
+ const response = Response.json(result);
1218
+ if (result.clearCookie) {
1219
+ response.headers.set("Set-Cookie", result.clearCookie);
1220
+ }
1221
+ if (handler.hasDatabaseCallbacks()) {
1222
+ response.headers.set("X-Integrate-Use-Database", "true");
1223
+ }
1224
+ return response;
1225
+ } catch (error) {
1226
+ logger3.error("[OAuth Callback] Error:", error);
1227
+ return Response.json({ error: error.message || "Failed to exchange authorization code" }, { status: 500 });
1228
+ }
1229
+ },
1230
+ async status(req) {
1231
+ try {
1232
+ const provider = req.nextUrl.searchParams.get("provider");
1233
+ const authHeader = req.headers.get("authorization");
1234
+ if (!provider) {
1235
+ return Response.json({ error: "Missing provider query parameter" }, { status: 400 });
1236
+ }
1237
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
1238
+ return Response.json({ error: "Missing or invalid Authorization header" }, { status: 400 });
1239
+ }
1240
+ const accessToken = authHeader.substring(7);
1241
+ const result = await handler.handleStatus(provider, accessToken);
1242
+ const response = Response.json(result);
1243
+ if (handler.hasDatabaseCallbacks()) {
1244
+ response.headers.set("X-Integrate-Use-Database", "true");
1245
+ }
1246
+ return response;
1247
+ } catch (error) {
1248
+ logger3.error("[OAuth Status] Error:", error);
1249
+ return Response.json({ error: error.message || "Failed to check authorization status" }, { status: 500 });
1250
+ }
1251
+ },
1252
+ async disconnect(req) {
1253
+ try {
1254
+ const authHeader = req.headers.get("authorization");
1255
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
1256
+ return Response.json({ error: "Missing or invalid Authorization header" }, { status: 400 });
1257
+ }
1258
+ const accessToken = authHeader.substring(7);
1259
+ const body = await req.json();
1260
+ const { provider } = body;
1261
+ if (!provider) {
1262
+ return Response.json({ error: "Missing provider in request body" }, { status: 400 });
1263
+ }
1264
+ const result = await handler.handleDisconnect({ provider }, accessToken, req);
1265
+ const response = Response.json(result);
1266
+ if (handler.hasDatabaseCallbacks()) {
1267
+ response.headers.set("X-Integrate-Use-Database", "true");
1268
+ }
1269
+ return response;
1270
+ } catch (error) {
1271
+ logger3.error("[OAuth Disconnect] Error:", error);
1272
+ return Response.json({ error: error.message || "Failed to disconnect provider" }, { status: 500 });
1273
+ }
1274
+ },
1275
+ async refresh(req) {
1276
+ try {
1277
+ const result = await handler.handleRefresh(req);
1278
+ const response = Response.json(result);
1279
+ if (handler.hasDatabaseCallbacks()) {
1280
+ response.headers.set("X-Integrate-Use-Database", "true");
1281
+ }
1282
+ return response;
1283
+ } catch (error) {
1284
+ if (error.message?.toLowerCase().includes("not supported")) {
1285
+ logger3.info("[OAuth Refresh] Not supported for this provider:", error.message);
1286
+ } else {
1287
+ logger3.error("[OAuth Refresh] Error:", error);
1288
+ }
1289
+ return Response.json({ error: error.message || "Failed to refresh token" }, { status: 500 });
1290
+ }
1291
+ },
1292
+ createRoutes() {
1293
+ return {
1294
+ async POST(req, context) {
1295
+ const params = context.params instanceof Promise ? await context.params : context.params;
1296
+ const action = params.action;
1297
+ if (action === "authorize") {
1298
+ return handlers.authorize(req);
1299
+ }
1300
+ if (action === "callback") {
1301
+ return handlers.callback(req);
1302
+ }
1303
+ if (action === "disconnect") {
1304
+ return handlers.disconnect(req);
1305
+ }
1306
+ if (action === "refresh") {
1307
+ return handlers.refresh(req);
1308
+ }
1309
+ if (action === "mcp") {
1310
+ return handlers.mcp(req);
1311
+ }
1312
+ return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
1313
+ },
1314
+ async GET(req, context) {
1315
+ const params = context.params instanceof Promise ? await context.params : context.params;
1316
+ const action = params.action;
1317
+ if (action === "status") {
1318
+ return handlers.status(req);
1319
+ }
1320
+ return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
1321
+ }
1322
+ };
1323
+ },
1324
+ async mcp(req) {
1325
+ try {
1326
+ const body = await req.json();
1327
+ const authHeader = req.headers.get("authorization");
1328
+ const integrationsHeader = req.headers.get("x-integrations");
1329
+ const result = await handler.handleToolCall(body, authHeader, integrationsHeader);
1330
+ return Response.json(result);
1331
+ } catch (error) {
1332
+ logger3.error("[MCP Tool Call] Error:", error);
1333
+ return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
1334
+ }
1335
+ },
1336
+ toNextJsHandler(redirectConfig) {
1337
+ const defaultRedirectUrl = redirectConfig?.redirectUrl || "/";
1338
+ const errorRedirectUrl = redirectConfig?.errorRedirectUrl || "/auth-error";
1339
+ return {
1340
+ async POST(req, context) {
1341
+ const params = context.params instanceof Promise ? await context.params : context.params;
1342
+ const segments = params.all || [];
1343
+ if (segments.length === 2 && segments[0] === "oauth") {
1344
+ const action = segments[1];
1345
+ if (action === "authorize") {
1346
+ return handlers.authorize(req);
1347
+ }
1348
+ if (action === "callback") {
1349
+ return handlers.callback(req);
1350
+ }
1351
+ if (action === "disconnect") {
1352
+ return handlers.disconnect(req);
1353
+ }
1354
+ if (action === "refresh") {
1355
+ return handlers.refresh(req);
1356
+ }
1357
+ return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
1358
+ }
1359
+ if (segments.length === 1 && segments[0] === "mcp") {
1360
+ return handlers.mcp(req);
1361
+ }
1362
+ return Response.json({ error: `Invalid route: /${segments.join("/")}` }, { status: 404 });
1363
+ },
1364
+ async GET(req, context) {
1365
+ const params = context.params instanceof Promise ? await context.params : context.params;
1366
+ const segments = params.all || [];
1367
+ if (segments.length === 2 && segments[0] === "oauth") {
1368
+ const action = segments[1];
1369
+ if (action === "status") {
1370
+ return handlers.status(req);
1371
+ }
1372
+ if (action === "callback") {
1373
+ const { searchParams } = new URL(req.url);
1374
+ const code = searchParams.get("code");
1375
+ const state = searchParams.get("state");
1376
+ const error = searchParams.get("error");
1377
+ const errorDescription = searchParams.get("error_description");
1378
+ if (error) {
1379
+ const errorMsg = errorDescription || error;
1380
+ logger3.error("[OAuth Redirect] Error:", errorMsg);
1381
+ return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent(errorMsg)}`, req.url));
1382
+ }
1383
+ if (!code || !state) {
1384
+ logger3.error("[OAuth Redirect] Missing code or state parameter");
1385
+ return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent("Invalid OAuth callback")}`, req.url));
1386
+ }
1387
+ let returnUrl = defaultRedirectUrl;
1388
+ try {
1389
+ const { parseState: parseState2 } = await Promise.resolve().then(() => exports_pkce);
1390
+ const stateData = parseState2(state);
1391
+ if (stateData.returnUrl) {
1392
+ returnUrl = stateData.returnUrl;
1393
+ }
1394
+ } catch (e) {
1395
+ try {
1396
+ const referrer = req.headers?.get?.("referer") || req.headers?.get?.("referrer");
1397
+ if (referrer) {
1398
+ const referrerUrl = new URL(referrer);
1399
+ const currentUrl = new URL(req.url);
1400
+ if (referrerUrl.origin === currentUrl.origin) {
1401
+ returnUrl = referrerUrl.pathname + referrerUrl.search;
1402
+ }
1403
+ }
1404
+ } catch {}
1405
+ }
1406
+ const targetUrl = new URL(returnUrl, req.url);
1407
+ targetUrl.hash = `oauth_callback=${encodeURIComponent(JSON.stringify({ code, state }))}`;
1408
+ return Response.redirect(targetUrl);
1409
+ }
1410
+ return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
1411
+ }
1412
+ if (segments.length === 1 && segments[0] === "integrations") {
1413
+ const result = handler.handleIntegrations();
1414
+ return Response.json(result);
1415
+ }
1416
+ return Response.json({ error: `Invalid route: /${segments.join("/")}` }, { status: 404 });
1417
+ }
1418
+ };
1419
+ }
1420
+ };
1421
+ return handlers;
1422
+ }
1423
+
1424
+ // node.ts
1425
+ function fromNodeHeaders(nodeHeaders) {
1426
+ const webHeaders = new Headers;
1427
+ for (const [key, value] of Object.entries(nodeHeaders)) {
1428
+ if (value !== undefined) {
1429
+ if (Array.isArray(value)) {
1430
+ value.forEach((v) => webHeaders.append(key, v));
1431
+ } else {
1432
+ webHeaders.set(key, value);
1433
+ }
1434
+ }
1435
+ }
1436
+ return webHeaders;
1437
+ }
1438
+ async function toWebRequest(req) {
1439
+ const protocol = req.socket?.encrypted ? "https" : "http";
1440
+ const host = req.headers.host || "localhost";
1441
+ const url = `${protocol}://${host}${req.url || ""}`;
1442
+ const headers = fromNodeHeaders(req.headers);
1443
+ let body;
1444
+ if (req.method && ["POST", "PUT", "PATCH"].includes(req.method)) {
1445
+ body = await new Promise((resolve, reject) => {
1446
+ let data = "";
1447
+ req.on("data", (chunk) => data += chunk);
1448
+ req.on("end", () => resolve(data));
1449
+ req.on("error", reject);
1450
+ });
1451
+ }
1452
+ return new Request(url, {
1453
+ method: req.method,
1454
+ headers,
1455
+ body: body || undefined
1456
+ });
1457
+ }
1458
+ async function sendWebResponse(webRes, nodeRes) {
1459
+ nodeRes.statusCode = webRes.status;
1460
+ webRes.headers.forEach((value, key) => {
1461
+ nodeRes.setHeader(key, value);
1462
+ });
1463
+ const body = await webRes.text();
1464
+ nodeRes.end(body);
1465
+ }
1466
+
1467
+ // ../protocol/jsonrpc.ts
1468
+ function parseMessage(message) {
1469
+ try {
1470
+ return JSON.parse(message);
1471
+ } catch (error) {
1472
+ throw new Error(`Failed to parse JSON-RPC message: ${error}`);
1473
+ }
1474
+ }
1475
+
1476
+ // ../transport/http-session.ts
1477
+ init_logger();
1478
+ var logger4 = createLogger("HTTPSession");
1479
+
1480
+ class HttpSessionTransport {
1481
+ url;
1482
+ headers;
1483
+ timeout;
1484
+ messageHandlers = new Set;
1485
+ sessionId;
1486
+ sseController;
1487
+ connected = false;
1488
+ constructor(options) {
1489
+ this.url = options.url;
1490
+ this.headers = options.headers || {};
1491
+ this.timeout = options.timeout || 30000;
1492
+ }
1493
+ async connect() {
1494
+ if (this.connected) {
1495
+ return;
1496
+ }
1497
+ this.connected = true;
1498
+ }
1499
+ async sendRequest(method, params) {
1500
+ if (!this.connected) {
1501
+ throw new Error("Not connected to server");
1502
+ }
1503
+ const request = {
1504
+ jsonrpc: "2.0",
1505
+ id: Date.now() + Math.random(),
1506
+ method,
1507
+ params
1508
+ };
1509
+ const headers = {
1510
+ ...this.headers,
1511
+ "Content-Type": "application/json"
1512
+ };
1513
+ if (this.sessionId) {
1514
+ headers["mcp-session-id"] = this.sessionId;
1515
+ }
1516
+ try {
1517
+ const controller = new AbortController;
1518
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1519
+ const response = await fetch(this.url, {
1520
+ method: "POST",
1521
+ headers,
1522
+ body: JSON.stringify(request),
1523
+ signal: controller.signal
1524
+ });
1525
+ clearTimeout(timeoutId);
1526
+ if (!response.ok) {
1527
+ const error = new Error(`Request failed: ${response.statusText}`);
1528
+ error.statusCode = response.status;
1529
+ throw error;
1530
+ }
1531
+ if (!this.sessionId) {
1532
+ const sid = response.headers.get("mcp-session-id");
1533
+ if (sid) {
1534
+ this.sessionId = sid;
1535
+ logger4.debug("Session established:", sid);
1536
+ this.startSSEListener();
1537
+ }
1538
+ }
1539
+ const jsonResponse = await response.json();
1540
+ if ("error" in jsonResponse) {
1541
+ const error = new Error(`JSON-RPC Error ${jsonResponse.error.code}: ${jsonResponse.error.message}`);
1542
+ error.code = jsonResponse.error.code;
1543
+ if (jsonResponse.error.data) {
1544
+ error.data = jsonResponse.error.data;
1545
+ }
1546
+ error.jsonrpcError = jsonResponse.error;
1547
+ throw error;
1548
+ }
1549
+ return jsonResponse.result;
1550
+ } catch (error) {
1551
+ if (error instanceof Error) {
1552
+ if (error.name === "AbortError") {
1553
+ const timeoutError = new Error("Request timeout");
1554
+ timeoutError.code = -32000;
1555
+ throw timeoutError;
1556
+ }
1557
+ throw error;
1558
+ }
1559
+ throw new Error(String(error));
1560
+ }
1561
+ }
1562
+ async startSSEListener() {
1563
+ if (!this.sessionId || this.sseController) {
1564
+ return;
1565
+ }
1566
+ this.sseController = new AbortController;
1567
+ try {
1568
+ const response = await fetch(this.url, {
1569
+ method: "GET",
1570
+ headers: {
1571
+ ...this.headers,
1572
+ Accept: "text/event-stream",
1573
+ "mcp-session-id": this.sessionId
1574
+ },
1575
+ signal: this.sseController.signal
1576
+ });
1577
+ if (!response.ok || !response.body) {
1578
+ return;
1579
+ }
1580
+ this.processSSEStream(response.body);
1581
+ } catch (error) {
1582
+ if (error instanceof Error && error.name === "AbortError") {
1583
+ return;
1584
+ }
1585
+ logger4.error("SSE connection error:", error);
1586
+ }
1587
+ }
1588
+ async processSSEStream(body) {
1589
+ const reader = body.getReader();
1590
+ const decoder = new TextDecoder;
1591
+ let buffer = "";
1592
+ try {
1593
+ while (true) {
1594
+ const { done, value } = await reader.read();
1595
+ if (done)
1596
+ break;
1597
+ buffer += decoder.decode(value, { stream: true });
1598
+ const lines = buffer.split(`
1599
+ `);
1600
+ buffer = lines.pop() || "";
1601
+ for (const line of lines) {
1602
+ if (line.startsWith("data: ")) {
1603
+ const data = line.slice(6).trim();
1604
+ if (data) {
1605
+ this.handleNotification(data);
1606
+ }
1607
+ }
1608
+ }
1609
+ }
1610
+ } catch (error) {
1611
+ if (error instanceof Error && error.name === "AbortError") {
1612
+ return;
1613
+ }
1614
+ logger4.error("SSE stream error:", error);
1615
+ } finally {
1616
+ reader.releaseLock();
1617
+ }
1618
+ }
1619
+ handleNotification(data) {
1620
+ try {
1621
+ const message = parseMessage(data);
1622
+ this.messageHandlers.forEach((handler) => {
1623
+ try {
1624
+ handler(message);
1625
+ } catch (error) {
1626
+ logger4.error("Error in message handler:", error);
1627
+ }
1628
+ });
1629
+ } catch (error) {
1630
+ logger4.error("Failed to parse notification:", error);
1631
+ }
1632
+ }
1633
+ onMessage(handler) {
1634
+ this.messageHandlers.add(handler);
1635
+ return () => {
1636
+ this.messageHandlers.delete(handler);
1637
+ };
1638
+ }
1639
+ async disconnect() {
1640
+ if (!this.connected) {
1641
+ return;
1642
+ }
1643
+ if (this.sseController) {
1644
+ this.sseController.abort();
1645
+ this.sseController = undefined;
1646
+ }
1647
+ this.messageHandlers.clear();
1648
+ this.sessionId = undefined;
1649
+ this.connected = false;
1650
+ }
1651
+ isConnected() {
1652
+ return this.connected;
1653
+ }
1654
+ getSessionId() {
1655
+ return this.sessionId;
1656
+ }
1657
+ setHeader(key, value) {
1658
+ this.headers[key] = value;
1659
+ }
1660
+ removeHeader(key) {
1661
+ delete this.headers[key];
1662
+ }
1663
+ getHeaders() {
1664
+ return { ...this.headers };
1665
+ }
1666
+ }
1667
+
1668
+ // ../client.ts
1669
+ init_errors();
1670
+ init_logger();
1671
+
1672
+ // ../triggers/client.ts
1673
+ class TriggerClient {
1674
+ config;
1675
+ constructor(config) {
1676
+ this.config = config;
1677
+ }
1678
+ async create(params) {
1679
+ return this.request("POST", "/triggers", params);
1680
+ }
1681
+ async list(params) {
1682
+ let path = "/triggers";
1683
+ if (params) {
1684
+ const searchParams = new URLSearchParams;
1685
+ if (params.status)
1686
+ searchParams.set("status", params.status);
1687
+ if (params.toolName)
1688
+ searchParams.set("toolName", params.toolName);
1689
+ if (params.limit !== undefined)
1690
+ searchParams.set("limit", params.limit.toString());
1691
+ if (params.offset !== undefined)
1692
+ searchParams.set("offset", params.offset.toString());
1693
+ const query = searchParams.toString();
1694
+ if (query)
1695
+ path += `?${query}`;
1696
+ }
1697
+ return this.request("GET", path);
1698
+ }
1699
+ async get(triggerId) {
1700
+ return this.request("GET", `/triggers/${triggerId}`);
1701
+ }
1702
+ async update(triggerId, params) {
1703
+ return this.request("PATCH", `/triggers/${triggerId}`, params);
1704
+ }
1705
+ async delete(triggerId) {
1706
+ await this.request("DELETE", `/triggers/${triggerId}`);
1707
+ }
1708
+ async pause(triggerId) {
1709
+ return this.request("POST", `/triggers/${triggerId}/pause`);
1710
+ }
1711
+ async resume(triggerId) {
1712
+ return this.request("POST", `/triggers/${triggerId}/resume`);
1713
+ }
1714
+ async run(triggerId) {
1715
+ return this.request("POST", `/triggers/${triggerId}/run`);
1716
+ }
1717
+ async request(method, path, body) {
1718
+ const url = this.config.apiBaseUrl ? `${this.config.apiBaseUrl}${this.config.apiRouteBase}${path}` : `${this.config.apiRouteBase}${path}`;
1719
+ const options = {
1720
+ method,
1721
+ headers: {
1722
+ "Content-Type": "application/json",
1723
+ ...this.config.getHeaders()
1724
+ }
1725
+ };
1726
+ if (body !== undefined) {
1727
+ options.body = JSON.stringify(body);
1728
+ }
1729
+ const response = await fetch(url, options);
1730
+ if (!response.ok) {
1731
+ let errorMessage = `Request failed: ${response.statusText}`;
1732
+ try {
1733
+ const errorData = await response.json();
1734
+ if (errorData.error) {
1735
+ errorMessage = typeof errorData.error === "string" ? errorData.error : errorData.error.message || errorMessage;
1736
+ }
1737
+ } catch {}
1738
+ throw new Error(errorMessage);
1739
+ }
1740
+ if (method === "DELETE" && response.status === 204) {
1741
+ return;
1742
+ }
1743
+ return response.json();
1744
+ }
1745
+ }
1746
+ // ../oauth/window-manager.ts
1747
+ init_logger();
1748
+ var logger5 = createLogger("OAuthWindowManager");
1749
+ function isBrowser() {
1750
+ return typeof window !== "undefined" && typeof window.document !== "undefined";
1751
+ }
1752
+
1753
+ class OAuthWindowManager {
1754
+ popupWindow = null;
1755
+ popupCheckInterval = null;
1756
+ popupCheckTimeout = null;
1757
+ openPopup(url, options) {
1758
+ if (!isBrowser()) {
1759
+ throw new Error("OAuthWindowManager.openPopup() can only be used in browser environments");
1760
+ }
1761
+ const width = options?.width || 600;
1762
+ const height = options?.height || 700;
1763
+ const left = window.screenX + (window.outerWidth - width) / 2;
1764
+ const top = window.screenY + (window.outerHeight - height) / 2;
1765
+ const features = [
1766
+ `popup=yes`,
1767
+ `width=${width}`,
1768
+ `height=${height}`,
1769
+ `left=${left}`,
1770
+ `top=${top}`,
1771
+ "toolbar=no",
1772
+ "location=no",
1773
+ "directories=no",
1774
+ "status=no",
1775
+ "menubar=no",
1776
+ "scrollbars=yes",
1777
+ "resizable=yes",
1778
+ "copyhistory=no",
1779
+ "noopener=no"
1780
+ ].join(",");
1781
+ const windowName = `oauth_popup_${Date.now()}`;
1782
+ this.popupWindow = window.open(url, windowName, features);
1783
+ if (!this.popupWindow) {
1784
+ logger5.warn("Popup was blocked by the browser. Please allow popups for this site.");
1785
+ return null;
1786
+ }
1787
+ this.popupWindow.focus();
1788
+ return this.popupWindow;
1789
+ }
1790
+ openRedirect(url) {
1791
+ if (!isBrowser()) {
1792
+ throw new Error("OAuthWindowManager.openRedirect() can only be used in browser environments");
1793
+ }
1794
+ logger5.debug("[OAuthWindowManager] Redirecting to:", url.substring(0, 100) + (url.length > 100 ? "..." : ""));
1795
+ window.location.href = url;
1796
+ }
1797
+ listenForCallback(mode, timeoutMs = 5 * 60 * 1000) {
1798
+ if (mode === "popup") {
1799
+ return this.listenForPopupCallback(timeoutMs);
1800
+ } else {
1801
+ return this.listenForRedirectCallback();
1802
+ }
1803
+ }
1804
+ listenForPopupCallback(timeoutMs) {
1805
+ if (!isBrowser()) {
1806
+ return Promise.reject(new Error("OAuth popup callback can only be used in browser environments"));
1807
+ }
1808
+ return new Promise((resolve, reject) => {
1809
+ const timeout = setTimeout(() => {
1810
+ this.cleanup();
1811
+ reject(new Error("OAuth authorization timed out"));
1812
+ }, timeoutMs);
1813
+ const messageHandler = (event) => {
1814
+ if (event.data && event.data.type === "oauth_callback") {
1815
+ clearTimeout(timeout);
1816
+ if (this.popupCheckTimeout) {
1817
+ clearTimeout(this.popupCheckTimeout);
1818
+ this.popupCheckTimeout = null;
1819
+ }
1820
+ window.removeEventListener("message", messageHandler);
1821
+ const { code, state, error } = event.data;
1822
+ if (error) {
1823
+ this.cleanup();
1824
+ reject(new Error(`OAuth error: ${error}`));
1825
+ return;
1826
+ }
1827
+ if (!code || !state) {
1828
+ this.cleanup();
1829
+ reject(new Error("Invalid OAuth callback: missing code or state"));
1830
+ return;
1831
+ }
1832
+ this.cleanup();
1833
+ resolve({ code, state });
1834
+ }
1835
+ };
1836
+ window.addEventListener("message", messageHandler);
1837
+ this.popupCheckTimeout = setTimeout(() => {
1838
+ this.popupCheckTimeout = null;
1839
+ this.popupCheckInterval = setInterval(() => {
1840
+ if (this.popupWindow?.closed) {
1841
+ clearTimeout(timeout);
1842
+ clearInterval(this.popupCheckInterval);
1843
+ window.removeEventListener("message", messageHandler);
1844
+ this.cleanup();
1845
+ reject(new Error("OAuth popup was closed by user"));
1846
+ }
1847
+ }, 500);
1848
+ }, 2000);
1849
+ });
1850
+ }
1851
+ listenForRedirectCallback() {
1852
+ if (!isBrowser()) {
1853
+ return Promise.reject(new Error("OAuth redirect callback can only be used in browser environments"));
1854
+ }
1855
+ return new Promise((resolve, reject) => {
1856
+ const params = new URLSearchParams(window.location.search);
1857
+ let code = params.get("code");
1858
+ let state = params.get("state");
1859
+ let error = params.get("error");
1860
+ let errorDescription = params.get("error_description");
1861
+ if (!code && !error && window.location.hash) {
1862
+ try {
1863
+ const hash = window.location.hash.substring(1);
1864
+ const hashParams = new URLSearchParams(hash);
1865
+ const oauthCallback = hashParams.get("oauth_callback");
1866
+ if (oauthCallback) {
1867
+ const parsed = JSON.parse(decodeURIComponent(oauthCallback));
1868
+ code = parsed.code;
1869
+ state = parsed.state;
1870
+ window.history.replaceState(null, "", window.location.pathname + window.location.search);
1871
+ }
1872
+ } catch (e) {
1873
+ logger5.error("Failed to parse OAuth callback params from hash:", e);
1874
+ }
1875
+ }
1876
+ if (!code && !error) {
1877
+ try {
1878
+ const stored = sessionStorage.getItem("oauth_callback_params");
1879
+ if (stored) {
1880
+ const parsed = JSON.parse(stored);
1881
+ code = parsed.code;
1882
+ state = parsed.state;
1883
+ sessionStorage.removeItem("oauth_callback_params");
1884
+ }
1885
+ } catch (e) {
1886
+ logger5.error("Failed to parse OAuth callback params from sessionStorage:", e);
1887
+ }
1888
+ }
1889
+ if (error) {
1890
+ const errorMsg = errorDescription || error;
1891
+ reject(new Error(`OAuth error: ${errorMsg}`));
1892
+ return;
1893
+ }
1894
+ if (!code || !state) {
1895
+ reject(new Error("Invalid OAuth callback: missing code or state in URL"));
1896
+ return;
1897
+ }
1898
+ resolve({ code, state });
1899
+ });
1900
+ }
1901
+ cleanup() {
1902
+ if (this.popupWindow && !this.popupWindow.closed) {
1903
+ this.popupWindow.close();
1904
+ }
1905
+ this.popupWindow = null;
1906
+ if (this.popupCheckInterval) {
1907
+ clearInterval(this.popupCheckInterval);
1908
+ this.popupCheckInterval = null;
1909
+ }
1910
+ if (this.popupCheckTimeout) {
1911
+ clearTimeout(this.popupCheckTimeout);
1912
+ this.popupCheckTimeout = null;
1913
+ }
1914
+ }
1915
+ close() {
1916
+ this.cleanup();
1917
+ }
1918
+ }
1919
+
1920
+ // ../oauth/indexeddb-storage.ts
1921
+ var DB_NAME = "integrate_oauth_tokens";
1922
+ var DB_VERSION = 1;
1923
+ var STORE_NAME = "tokens";
1924
+
1925
+ class IndexedDBStorage {
1926
+ db = null;
1927
+ initPromise = null;
1928
+ async init() {
1929
+ if (this.db) {
1930
+ return this.db;
1931
+ }
1932
+ if (this.initPromise) {
1933
+ return this.initPromise;
1934
+ }
1935
+ this.initPromise = new Promise((resolve, reject) => {
1936
+ if (typeof window === "undefined" || !window.indexedDB) {
1937
+ reject(new Error("IndexedDB is not available in this environment"));
1938
+ return;
1939
+ }
1940
+ const request = window.indexedDB.open(DB_NAME, DB_VERSION);
1941
+ request.onerror = () => {
1942
+ this.initPromise = null;
1943
+ reject(new Error(`Failed to open IndexedDB: ${request.error?.message}`));
1944
+ };
1945
+ request.onsuccess = () => {
1946
+ this.db = request.result;
1947
+ this.initPromise = null;
1948
+ resolve(this.db);
1949
+ };
1950
+ request.onupgradeneeded = (event) => {
1951
+ const db = event.target.result;
1952
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
1953
+ const store = db.createObjectStore(STORE_NAME, { keyPath: "accountId" });
1954
+ store.createIndex("provider", "provider", { unique: false });
1955
+ store.createIndex("email", "email", { unique: false });
1956
+ store.createIndex("provider_email", ["provider", "email"], { unique: true });
1957
+ }
1958
+ };
1959
+ });
1960
+ return this.initPromise;
1961
+ }
1962
+ generateAccountId(provider, email) {
1963
+ const str = `${provider}:${email}`;
1964
+ let hash = 0;
1965
+ for (let i = 0;i < str.length; i++) {
1966
+ const char = str.charCodeAt(i);
1967
+ hash = (hash << 5) - hash + char;
1968
+ hash = hash & hash;
1969
+ }
1970
+ return `${provider}_${Math.abs(hash).toString(36)}`;
1971
+ }
1972
+ async saveToken(provider, email, tokenData) {
1973
+ const db = await this.init();
1974
+ const accountId = this.generateAccountId(provider, email);
1975
+ const now = Date.now();
1976
+ const entry = {
1977
+ provider,
1978
+ email,
1979
+ accountId,
1980
+ tokenData,
1981
+ createdAt: now,
1982
+ updatedAt: now
1983
+ };
1984
+ return new Promise((resolve, reject) => {
1985
+ const transaction = db.transaction([STORE_NAME], "readwrite");
1986
+ const store = transaction.objectStore(STORE_NAME);
1987
+ const getRequest = store.get(accountId);
1988
+ getRequest.onsuccess = () => {
1989
+ const existing = getRequest.result;
1990
+ if (existing) {
1991
+ entry.createdAt = existing.createdAt;
1992
+ }
1993
+ const putRequest = store.put(entry);
1994
+ putRequest.onsuccess = () => resolve();
1995
+ putRequest.onerror = () => reject(new Error(`Failed to save token: ${putRequest.error?.message}`));
1996
+ };
1997
+ getRequest.onerror = () => reject(new Error(`Failed to check existing token: ${getRequest.error?.message}`));
1998
+ });
1999
+ }
2000
+ async getToken(provider, email) {
2001
+ const db = await this.init();
2002
+ const accountId = this.generateAccountId(provider, email);
2003
+ return new Promise((resolve, reject) => {
2004
+ const transaction = db.transaction([STORE_NAME], "readonly");
2005
+ const store = transaction.objectStore(STORE_NAME);
2006
+ const request = store.get(accountId);
2007
+ request.onsuccess = () => {
2008
+ const entry = request.result;
2009
+ resolve(entry?.tokenData);
2010
+ };
2011
+ request.onerror = () => reject(new Error(`Failed to get token: ${request.error?.message}`));
2012
+ });
2013
+ }
2014
+ async getTokensByProvider(provider) {
2015
+ const db = await this.init();
2016
+ const tokens = new Map;
2017
+ return new Promise((resolve, reject) => {
2018
+ const transaction = db.transaction([STORE_NAME], "readonly");
2019
+ const store = transaction.objectStore(STORE_NAME);
2020
+ const index = store.index("provider");
2021
+ const request = index.getAll(provider);
2022
+ request.onsuccess = () => {
2023
+ const entries = request.result;
2024
+ for (const entry of entries) {
2025
+ tokens.set(entry.email, entry.tokenData);
2026
+ }
2027
+ resolve(tokens);
2028
+ };
2029
+ request.onerror = () => reject(new Error(`Failed to get tokens: ${request.error?.message}`));
2030
+ });
2031
+ }
2032
+ async listAccounts(provider) {
2033
+ const db = await this.init();
2034
+ return new Promise((resolve, reject) => {
2035
+ const transaction = db.transaction([STORE_NAME], "readonly");
2036
+ const store = transaction.objectStore(STORE_NAME);
2037
+ const index = store.index("provider");
2038
+ const request = index.getAll(provider);
2039
+ request.onsuccess = () => {
2040
+ const entries = request.result;
2041
+ const accounts = entries.map((entry) => ({
2042
+ email: entry.email,
2043
+ accountId: entry.accountId,
2044
+ expiresAt: entry.tokenData.expiresAt,
2045
+ scopes: entry.tokenData.scopes,
2046
+ createdAt: entry.createdAt
2047
+ }));
2048
+ resolve(accounts);
2049
+ };
2050
+ request.onerror = () => reject(new Error(`Failed to list accounts: ${request.error?.message}`));
2051
+ });
2052
+ }
2053
+ async deleteToken(provider, email) {
2054
+ const db = await this.init();
2055
+ const accountId = this.generateAccountId(provider, email);
2056
+ return new Promise((resolve, reject) => {
2057
+ const transaction = db.transaction([STORE_NAME], "readwrite");
2058
+ const store = transaction.objectStore(STORE_NAME);
2059
+ const request = store.delete(accountId);
2060
+ request.onsuccess = () => resolve();
2061
+ request.onerror = () => reject(new Error(`Failed to delete token: ${request.error?.message}`));
2062
+ });
2063
+ }
2064
+ async deleteTokensByProvider(provider) {
2065
+ const db = await this.init();
2066
+ return new Promise((resolve, reject) => {
2067
+ const transaction = db.transaction([STORE_NAME], "readwrite");
2068
+ const store = transaction.objectStore(STORE_NAME);
2069
+ const index = store.index("provider");
2070
+ const request = index.getAll(provider);
2071
+ request.onsuccess = () => {
2072
+ const entries = request.result;
2073
+ const deletePromises = entries.map((entry) => {
2074
+ return new Promise((resolveDelete, rejectDelete) => {
2075
+ const deleteRequest = store.delete(entry.accountId);
2076
+ deleteRequest.onsuccess = () => resolveDelete();
2077
+ deleteRequest.onerror = () => rejectDelete(deleteRequest.error);
2078
+ });
2079
+ });
2080
+ Promise.all(deletePromises).then(() => resolve()).catch((error) => reject(error));
2081
+ };
2082
+ request.onerror = () => reject(new Error(`Failed to delete tokens: ${request.error?.message}`));
2083
+ });
2084
+ }
2085
+ async clearAll() {
2086
+ const db = await this.init();
2087
+ return new Promise((resolve, reject) => {
2088
+ const transaction = db.transaction([STORE_NAME], "readwrite");
2089
+ const store = transaction.objectStore(STORE_NAME);
2090
+ const request = store.clear();
2091
+ request.onsuccess = () => resolve();
2092
+ request.onerror = () => reject(new Error(`Failed to clear tokens: ${request.error?.message}`));
2093
+ });
2094
+ }
2095
+ }
2096
+
2097
+ // ../oauth/manager.ts
2098
+ init_email_fetcher();
2099
+ init_logger();
2100
+ var logger6 = createLogger("OAuth");
2101
+
2102
+ class OAuthManager {
2103
+ pendingAuths = new Map;
2104
+ providerTokens = new Map;
2105
+ windowManager;
2106
+ flowConfig;
2107
+ oauthApiBase;
2108
+ apiBaseUrl;
2109
+ getTokenCallback;
2110
+ setTokenCallback;
2111
+ removeTokenCallback;
2112
+ indexedDBStorage;
2113
+ skipLocalStorage = false;
2114
+ constructor(oauthApiBase, flowConfig, apiBaseUrl, tokenCallbacks) {
2115
+ this.oauthApiBase = oauthApiBase;
2116
+ this.apiBaseUrl = apiBaseUrl;
2117
+ this.windowManager = new OAuthWindowManager;
2118
+ this.flowConfig = {
2119
+ mode: flowConfig?.mode || "redirect",
2120
+ popupOptions: flowConfig?.popupOptions,
2121
+ onAuthCallback: flowConfig?.onAuthCallback
2122
+ };
2123
+ this.getTokenCallback = tokenCallbacks?.getProviderToken;
2124
+ this.setTokenCallback = tokenCallbacks?.setProviderToken;
2125
+ this.removeTokenCallback = tokenCallbacks?.removeProviderToken;
2126
+ this.indexedDBStorage = new IndexedDBStorage;
2127
+ this.cleanupExpiredPendingAuths();
2128
+ }
2129
+ async initiateFlow(provider, config, returnUrl) {
2130
+ const codeVerifier = generateCodeVerifier();
2131
+ const codeChallenge = await generateCodeChallenge(codeVerifier);
2132
+ const state = generateStateWithReturnUrl(returnUrl);
2133
+ const pendingAuth = {
2134
+ provider,
2135
+ state,
2136
+ codeVerifier,
2137
+ codeChallenge,
2138
+ redirectUri: config.redirectUri,
2139
+ returnUrl,
2140
+ initiatedAt: Date.now()
2141
+ };
2142
+ this.pendingAuths.set(state, pendingAuth);
2143
+ this.savePendingAuthToStorage(state, pendingAuth);
2144
+ const authUrl = await this.getAuthorizationUrl(provider, state, codeChallenge, config.redirectUri, codeVerifier);
2145
+ if (!authUrl || authUrl.trim() === "") {
2146
+ throw new Error("Received empty authorization URL from server");
2147
+ }
2148
+ if (this.flowConfig.mode === "popup") {
2149
+ this.windowManager.openPopup(authUrl, this.flowConfig.popupOptions);
2150
+ try {
2151
+ const callbackParams = await this.windowManager.listenForCallback("popup");
2152
+ await this.handleCallback(callbackParams.code, callbackParams.state);
2153
+ } catch (error) {
2154
+ this.pendingAuths.delete(state);
2155
+ throw error;
2156
+ }
2157
+ } else {
2158
+ this.windowManager.openRedirect(authUrl);
2159
+ }
2160
+ }
2161
+ async handleCallbackWithToken(_code, state, tokenData) {
2162
+ let pendingAuth = this.pendingAuths.get(state);
2163
+ if (!pendingAuth) {
2164
+ pendingAuth = this.loadPendingAuthFromStorage(state);
2165
+ }
2166
+ if (!pendingAuth) {
2167
+ throw new Error("Invalid state parameter: no matching OAuth flow found");
2168
+ }
2169
+ const fiveMinutes = 5 * 60 * 1000;
2170
+ if (Date.now() - pendingAuth.initiatedAt > fiveMinutes) {
2171
+ this.pendingAuths.delete(state);
2172
+ this.removePendingAuthFromStorage(state);
2173
+ throw new Error("OAuth flow expired: please try again");
2174
+ }
2175
+ const provider = tokenData.provider || pendingAuth.provider;
2176
+ const tokenDataToStore = {
2177
+ accessToken: tokenData.accessToken,
2178
+ refreshToken: tokenData.refreshToken,
2179
+ tokenType: tokenData.tokenType,
2180
+ expiresIn: tokenData.expiresIn,
2181
+ expiresAt: tokenData.expiresAt,
2182
+ scopes: tokenData.scopes
2183
+ };
2184
+ const email = await fetchUserEmail(provider, tokenDataToStore);
2185
+ if (email) {
2186
+ tokenDataToStore.email = email;
2187
+ }
2188
+ this.providerTokens.set(provider, tokenDataToStore);
2189
+ await this.saveProviderToken(provider, tokenDataToStore, email);
2190
+ this.pendingAuths.delete(state);
2191
+ this.removePendingAuthFromStorage(state);
2192
+ return { ...tokenDataToStore, provider };
2193
+ }
2194
+ async handleCallback(code, state) {
2195
+ let pendingAuth = this.pendingAuths.get(state);
2196
+ if (!pendingAuth) {
2197
+ pendingAuth = this.loadPendingAuthFromStorage(state);
2198
+ }
2199
+ if (!pendingAuth) {
2200
+ throw new Error("Invalid state parameter: no matching OAuth flow found");
2201
+ }
2202
+ const fiveMinutes = 5 * 60 * 1000;
2203
+ if (Date.now() - pendingAuth.initiatedAt > fiveMinutes) {
2204
+ this.pendingAuths.delete(state);
2205
+ this.removePendingAuthFromStorage(state);
2206
+ throw new Error("OAuth flow expired: please try again");
2207
+ }
2208
+ if (this.flowConfig.onAuthCallback) {
2209
+ try {
2210
+ await this.flowConfig.onAuthCallback(pendingAuth.provider, code, state);
2211
+ } catch (error) {
2212
+ logger6.error("Custom OAuth callback handler failed:", error);
2213
+ }
2214
+ }
2215
+ try {
2216
+ const response = await this.exchangeCodeForToken(pendingAuth.provider, code, pendingAuth.codeVerifier, state);
2217
+ const tokenData = {
2218
+ accessToken: response.accessToken,
2219
+ refreshToken: response.refreshToken,
2220
+ tokenType: response.tokenType,
2221
+ expiresIn: response.expiresIn,
2222
+ expiresAt: response.expiresAt,
2223
+ scopes: response.scopes
2224
+ };
2225
+ const email = response.email || await fetchUserEmail(pendingAuth.provider, tokenData);
2226
+ if (email) {
2227
+ tokenData.email = email;
2228
+ }
2229
+ this.providerTokens.set(pendingAuth.provider, tokenData);
2230
+ await this.saveProviderToken(pendingAuth.provider, tokenData, email);
2231
+ this.pendingAuths.delete(state);
2232
+ this.removePendingAuthFromStorage(state);
2233
+ return { ...tokenData, provider: pendingAuth.provider };
2234
+ } catch (error) {
2235
+ this.pendingAuths.delete(state);
2236
+ this.removePendingAuthFromStorage(state);
2237
+ throw error;
2238
+ }
2239
+ }
2240
+ async checkAuthStatus(provider, email) {
2241
+ const tokenData = await this.getProviderToken(provider, email);
2242
+ if (!tokenData) {
2243
+ return {
2244
+ authorized: false,
2245
+ provider
2246
+ };
2247
+ }
2248
+ return {
2249
+ authorized: true,
2250
+ provider,
2251
+ scopes: tokenData.scopes,
2252
+ expiresAt: tokenData.expiresAt
2253
+ };
2254
+ }
2255
+ async disconnectAccount(provider, email, context) {
2256
+ if (this.removeTokenCallback) {
2257
+ try {
2258
+ await this.removeTokenCallback(provider, email, context);
2259
+ } catch (error) {
2260
+ logger6.error(`Failed to delete token for ${provider} (${email}) from database:`, error);
2261
+ }
2262
+ } else if (this.setTokenCallback) {
2263
+ try {
2264
+ await this.setTokenCallback(provider, null, email, context);
2265
+ } catch (error) {
2266
+ logger6.error(`Failed to delete token for ${provider} (${email}) from database:`, error);
2267
+ }
2268
+ }
2269
+ if (!this.setTokenCallback && !this.removeTokenCallback) {
2270
+ try {
2271
+ await this.indexedDBStorage.deleteToken(provider, email);
2272
+ } catch (error) {
2273
+ logger6.error(`Failed to delete token from IndexedDB for ${provider} (${email}):`, error);
2274
+ }
2275
+ }
2276
+ this.providerTokens.delete(provider);
2277
+ }
2278
+ async disconnectProvider(provider, context) {
2279
+ if (this.removeTokenCallback) {
2280
+ try {
2281
+ await this.removeTokenCallback(provider, undefined, context);
2282
+ } catch (error) {
2283
+ logger6.error(`Failed to delete tokens for ${provider} from database:`, error);
2284
+ }
2285
+ } else if (this.setTokenCallback) {
2286
+ try {
2287
+ await this.setTokenCallback(provider, null, undefined, context);
2288
+ } catch (error) {
2289
+ logger6.error(`Failed to delete tokens for ${provider} from database:`, error);
2290
+ }
2291
+ }
2292
+ if (!this.setTokenCallback && !this.removeTokenCallback) {
2293
+ try {
2294
+ await this.indexedDBStorage.deleteTokensByProvider(provider);
2295
+ } catch (error) {
2296
+ if (typeof window !== "undefined" && window.localStorage) {
2297
+ try {
2298
+ const key = `integrate_token_${provider}`;
2299
+ window.localStorage.removeItem(key);
2300
+ } catch (localStorageError) {}
2301
+ }
2302
+ }
2303
+ }
2304
+ if (!this.setTokenCallback && !this.removeTokenCallback) {
2305
+ if (typeof window !== "undefined" && window.localStorage) {
2306
+ try {
2307
+ const key = `integrate_token_${provider}`;
2308
+ window.localStorage.removeItem(key);
2309
+ } catch (localStorageError) {}
2310
+ }
2311
+ }
2312
+ this.providerTokens.delete(provider);
2313
+ }
2314
+ async listAccounts(provider) {
2315
+ if (this.getTokenCallback) {
2316
+ return [];
2317
+ }
2318
+ if (!this.getTokenCallback) {
2319
+ try {
2320
+ return await this.indexedDBStorage.listAccounts(provider);
2321
+ } catch (error) {
2322
+ logger6.error(`Failed to list accounts for ${provider}:`, error);
2323
+ return [];
2324
+ }
2325
+ }
2326
+ return [];
2327
+ }
2328
+ async getProviderToken(provider, email, context) {
2329
+ if (this.getTokenCallback) {
2330
+ try {
2331
+ const tokenData = await this.getTokenCallback(provider, email, context);
2332
+ if (tokenData) {
2333
+ this.providerTokens.set(provider, tokenData);
2334
+ }
2335
+ return tokenData;
2336
+ } catch (error) {
2337
+ logger6.error(`Failed to get token for ${provider} via callback:`, error);
2338
+ return;
2339
+ }
2340
+ }
2341
+ if (email && !this.getTokenCallback) {
2342
+ try {
2343
+ const tokenData = await this.indexedDBStorage.getToken(provider, email);
2344
+ if (tokenData) {
2345
+ this.providerTokens.set(provider, tokenData);
2346
+ }
2347
+ return tokenData;
2348
+ } catch (error) {
2349
+ logger6.error(`Failed to get token from IndexedDB for ${provider}:`, error);
2350
+ }
2351
+ }
2352
+ return this.providerTokens.get(provider);
2353
+ }
2354
+ getAllProviderTokens() {
2355
+ return new Map(this.providerTokens);
2356
+ }
2357
+ getProviderTokenFromCache(provider) {
2358
+ return this.providerTokens.get(provider);
2359
+ }
2360
+ async setProviderToken(provider, tokenData, email, context) {
2361
+ const tokenEmail = email || tokenData?.email;
2362
+ if (tokenData === null) {
2363
+ if (tokenEmail) {
2364
+ this.providerTokens.delete(provider);
2365
+ } else {
2366
+ this.providerTokens.delete(provider);
2367
+ }
2368
+ } else {
2369
+ this.providerTokens.set(provider, tokenData);
2370
+ }
2371
+ await this.saveProviderToken(provider, tokenData, tokenEmail, context);
2372
+ }
2373
+ clearProviderToken(provider) {
2374
+ this.providerTokens.delete(provider);
2375
+ if (!this.setTokenCallback && !this.removeTokenCallback && !this.skipLocalStorage) {
2376
+ this.indexedDBStorage.deleteTokensByProvider(provider).catch((error) => {
2377
+ logger6.error(`Failed to clear tokens for ${provider} from IndexedDB:`, error);
2378
+ });
2379
+ }
2380
+ }
2381
+ clearAllProviderTokens() {
2382
+ this.providerTokens.clear();
2383
+ if (!this.setTokenCallback && !this.removeTokenCallback && !this.skipLocalStorage) {
2384
+ if (typeof window !== "undefined" && window.localStorage) {
2385
+ try {
2386
+ const keysToRemove = [];
2387
+ for (let i = 0;i < window.localStorage.length; i++) {
2388
+ const key = window.localStorage.key(i);
2389
+ if (key && key.startsWith("integrate_token_")) {
2390
+ keysToRemove.push(key);
2391
+ }
2392
+ }
2393
+ keysToRemove.forEach((key) => window.localStorage.removeItem(key));
2394
+ } catch (localStorageError) {}
2395
+ }
2396
+ this.indexedDBStorage.clearAll().catch((error) => {
2397
+ logger6.error("Failed to clear all tokens from IndexedDB:", error);
2398
+ });
2399
+ }
2400
+ }
2401
+ clearAllPendingAuths() {
2402
+ this.pendingAuths.clear();
2403
+ if (typeof window !== "undefined" && window.localStorage) {
2404
+ try {
2405
+ const prefix = "integrate_oauth_pending_";
2406
+ const keysToRemove = [];
2407
+ for (let i = 0;i < window.localStorage.length; i++) {
2408
+ const key = window.localStorage.key(i);
2409
+ if (key && key.startsWith(prefix)) {
2410
+ keysToRemove.push(key);
2411
+ }
2412
+ }
2413
+ keysToRemove.forEach((key) => window.localStorage.removeItem(key));
2414
+ } catch (error) {
2415
+ logger6.error("Failed to clear pending auths from localStorage:", error);
2416
+ }
2417
+ }
2418
+ }
2419
+ async saveProviderToken(provider, tokenData, email, context) {
2420
+ if (this.setTokenCallback) {
2421
+ try {
2422
+ await this.setTokenCallback(provider, tokenData, email, context);
2423
+ } catch (error) {
2424
+ logger6.error(`Failed to ${tokenData === null ? "delete" : "save"} token for ${provider} via callback:`, error);
2425
+ throw error;
2426
+ }
2427
+ return;
2428
+ }
2429
+ if (this.skipLocalStorage) {
2430
+ return;
2431
+ }
2432
+ if (tokenData === null) {
2433
+ if (email) {
2434
+ if (!this.setTokenCallback && !this.removeTokenCallback) {
2435
+ await this.indexedDBStorage.deleteToken(provider, email).catch(() => {
2436
+ if (typeof window !== "undefined" && window.localStorage) {
2437
+ try {
2438
+ const key = `integrate_token_${provider}`;
2439
+ window.localStorage.removeItem(key);
2440
+ } catch (localStorageError) {}
2441
+ }
2442
+ });
2443
+ }
2444
+ } else {
2445
+ this.clearProviderToken(provider);
2446
+ if (typeof window !== "undefined" && window.localStorage) {
2447
+ try {
2448
+ const key = `integrate_token_${provider}`;
2449
+ window.localStorage.removeItem(key);
2450
+ } catch (localStorageError) {}
2451
+ }
2452
+ }
2453
+ return;
2454
+ }
2455
+ const tokenEmail = email || tokenData.email;
2456
+ if (tokenEmail) {
2457
+ try {
2458
+ await this.indexedDBStorage.saveToken(provider, tokenEmail, tokenData);
2459
+ } catch (error) {
2460
+ if (typeof window !== "undefined" && window.localStorage) {
2461
+ try {
2462
+ const key = `integrate_token_${provider}`;
2463
+ window.localStorage.setItem(key, JSON.stringify(tokenData));
2464
+ } catch (localStorageError) {
2465
+ logger6.error(`Failed to save token for ${provider} to localStorage:`, localStorageError);
2466
+ }
2467
+ } else {
2468
+ logger6.error(`Failed to save token for ${provider} to IndexedDB:`, error);
2469
+ }
2470
+ }
2471
+ } else {
2472
+ if (typeof window !== "undefined" && window.localStorage) {
2473
+ try {
2474
+ const key = `integrate_token_${provider}`;
2475
+ window.localStorage.setItem(key, JSON.stringify(tokenData));
2476
+ } catch (localStorageError) {
2477
+ logger6.error(`Failed to save token for ${provider} to localStorage:`, localStorageError);
2478
+ }
2479
+ }
2480
+ }
2481
+ }
2482
+ async loadProviderToken(provider, email, context) {
2483
+ if (this.getTokenCallback) {
2484
+ try {
2485
+ return await this.getTokenCallback(provider, email, context);
2486
+ } catch (error) {
2487
+ logger6.error(`Failed to load token for ${provider} via callback:`, error);
2488
+ return;
2489
+ }
2490
+ }
2491
+ if (this.skipLocalStorage) {
2492
+ return this.providerTokens.get(provider);
2493
+ }
2494
+ if (email) {
2495
+ try {
2496
+ return await this.indexedDBStorage.getToken(provider, email);
2497
+ } catch (error) {
2498
+ if (typeof window !== "undefined" && window.localStorage) {
2499
+ try {
2500
+ const key = `integrate_token_${provider}`;
2501
+ const stored = window.localStorage.getItem(key);
2502
+ if (stored) {
2503
+ return JSON.parse(stored);
2504
+ }
2505
+ } catch (localStorageError) {}
2506
+ }
2507
+ return;
2508
+ }
2509
+ } else {
2510
+ try {
2511
+ const tokens = await this.indexedDBStorage.getTokensByProvider(provider);
2512
+ if (tokens.size > 0) {
2513
+ return tokens.values().next().value;
2514
+ }
2515
+ } catch (error) {
2516
+ if (typeof window !== "undefined" && window.localStorage) {
2517
+ try {
2518
+ const key = `integrate_token_${provider}`;
2519
+ const stored = window.localStorage.getItem(key);
2520
+ if (stored) {
2521
+ return JSON.parse(stored);
2522
+ }
2523
+ } catch (localStorageError) {}
2524
+ }
2525
+ }
2526
+ }
2527
+ return;
2528
+ }
2529
+ async loadAllProviderTokens(providers) {
2530
+ for (const provider of providers) {
2531
+ const tokenData = await this.loadProviderToken(provider, undefined, undefined);
2532
+ if (tokenData) {
2533
+ this.providerTokens.set(provider, tokenData);
2534
+ }
2535
+ }
2536
+ }
2537
+ loadAllProviderTokensSync(providers) {
2538
+ if (this.getTokenCallback) {
2539
+ return;
2540
+ }
2541
+ if (this.skipLocalStorage) {
2542
+ return;
2543
+ }
2544
+ if (typeof window !== "undefined" && window.localStorage) {
2545
+ for (const provider of providers) {
2546
+ try {
2547
+ const key = `integrate_token_${provider}`;
2548
+ const stored = window.localStorage.getItem(key);
2549
+ if (stored) {
2550
+ const tokenData = JSON.parse(stored);
2551
+ this.providerTokens.set(provider, tokenData);
2552
+ }
2553
+ } catch {}
2554
+ }
2555
+ }
2556
+ this.loadAllProviderTokens(providers).catch(() => {});
2557
+ }
2558
+ savePendingAuthToStorage(state, pendingAuth) {
2559
+ if (typeof window !== "undefined" && window.localStorage) {
2560
+ try {
2561
+ const key = `integrate_oauth_pending_${state}`;
2562
+ window.localStorage.setItem(key, JSON.stringify(pendingAuth));
2563
+ } catch (error) {
2564
+ logger6.error("Failed to save pending auth to localStorage:", error);
2565
+ }
2566
+ }
2567
+ }
2568
+ loadPendingAuthFromStorage(state) {
2569
+ if (typeof window !== "undefined" && window.localStorage) {
2570
+ try {
2571
+ const key = `integrate_oauth_pending_${state}`;
2572
+ const stored = window.localStorage.getItem(key);
2573
+ if (stored) {
2574
+ return JSON.parse(stored);
2575
+ }
2576
+ } catch (error) {
2577
+ logger6.error("Failed to load pending auth from localStorage:", error);
2578
+ }
2579
+ }
2580
+ return;
2581
+ }
2582
+ removePendingAuthFromStorage(state) {
2583
+ if (typeof window !== "undefined" && window.localStorage) {
2584
+ try {
2585
+ const key = `integrate_oauth_pending_${state}`;
2586
+ window.localStorage.removeItem(key);
2587
+ } catch (error) {
2588
+ logger6.error("Failed to remove pending auth from localStorage:", error);
2589
+ }
2590
+ }
2591
+ }
2592
+ cleanupExpiredPendingAuths() {
2593
+ if (typeof window !== "undefined" && window.localStorage) {
2594
+ try {
2595
+ const prefix = "integrate_oauth_pending_";
2596
+ const fiveMinutes = 5 * 60 * 1000;
2597
+ const now = Date.now();
2598
+ const keysToRemove = [];
2599
+ for (let i = 0;i < window.localStorage.length; i++) {
2600
+ const key = window.localStorage.key(i);
2601
+ if (key && key.startsWith(prefix)) {
2602
+ try {
2603
+ const stored = window.localStorage.getItem(key);
2604
+ if (stored) {
2605
+ const pendingAuth = JSON.parse(stored);
2606
+ if (now - pendingAuth.initiatedAt > fiveMinutes) {
2607
+ keysToRemove.push(key);
2608
+ }
2609
+ }
2610
+ } catch (error) {
2611
+ keysToRemove.push(key);
2612
+ }
2613
+ }
2614
+ }
2615
+ keysToRemove.forEach((key) => window.localStorage.removeItem(key));
2616
+ } catch (error) {
2617
+ logger6.error("Failed to cleanup expired pending auths:", error);
2618
+ }
2619
+ }
2620
+ }
2621
+ async getAuthorizationUrl(provider, state, codeChallenge, redirectUri, codeVerifier) {
2622
+ const url = this.apiBaseUrl ? `${this.apiBaseUrl}${this.oauthApiBase}/authorize` : `${this.oauthApiBase}/authorize`;
2623
+ const response = await fetch(url, {
2624
+ method: "POST",
2625
+ headers: {
2626
+ "Content-Type": "application/json"
2627
+ },
2628
+ body: JSON.stringify({
2629
+ provider,
2630
+ state,
2631
+ codeChallenge,
2632
+ codeChallengeMethod: "S256",
2633
+ redirectUri,
2634
+ codeVerifier: this.flowConfig.mode === "redirect" ? codeVerifier : undefined,
2635
+ frontendOrigin: this.apiBaseUrl && this.flowConfig.mode === "redirect" && typeof window !== "undefined" ? window.location.origin : undefined
2636
+ })
2637
+ });
2638
+ if (response.headers.get("X-Integrate-Use-Database") === "true") {
2639
+ this.setSkipLocalStorage(true);
2640
+ }
2641
+ if (!response.ok) {
2642
+ const error = await response.text();
2643
+ throw new Error(`Failed to get authorization URL: ${error}`);
2644
+ }
2645
+ const data = await response.json();
2646
+ if (!data.authorizationUrl) {
2647
+ throw new Error("Authorization URL is missing from server response");
2648
+ }
2649
+ if (typeof data.authorizationUrl !== "string" || data.authorizationUrl.trim() === "") {
2650
+ throw new Error("Invalid authorization URL received from server");
2651
+ }
2652
+ return data.authorizationUrl;
2653
+ }
2654
+ async exchangeCodeForToken(provider, code, codeVerifier, state) {
2655
+ const url = this.apiBaseUrl ? `${this.apiBaseUrl}${this.oauthApiBase}/callback` : `${this.oauthApiBase}/callback`;
2656
+ const response = await fetch(url, {
2657
+ method: "POST",
2658
+ headers: {
2659
+ "Content-Type": "application/json"
2660
+ },
2661
+ body: JSON.stringify({
2662
+ provider,
2663
+ code,
2664
+ codeVerifier,
2665
+ state
2666
+ })
2667
+ });
2668
+ if (response.headers.get("X-Integrate-Use-Database") === "true") {
2669
+ this.setSkipLocalStorage(true);
2670
+ }
2671
+ if (!response.ok) {
2672
+ const error = await response.text();
2673
+ throw new Error(`Failed to exchange code for token: ${error}`);
2674
+ }
2675
+ const data = await response.json();
2676
+ return data;
2677
+ }
2678
+ setSkipLocalStorage(value) {
2679
+ this.skipLocalStorage = value;
2680
+ }
2681
+ close() {
2682
+ this.windowManager.close();
2683
+ }
2684
+ }
2685
+
2686
+ // ../client.ts
2687
+ var CLIENT_LOG_CONTEXT = "client";
2688
+
2689
+ class SimpleEventEmitter {
2690
+ handlers = new Map;
2691
+ on(event, handler) {
2692
+ if (!this.handlers.has(event)) {
2693
+ this.handlers.set(event, new Set);
2694
+ }
2695
+ this.handlers.get(event).add(handler);
2696
+ }
2697
+ off(event, handler) {
2698
+ const handlers = this.handlers.get(event);
2699
+ if (handlers) {
2700
+ handlers.delete(handler);
2701
+ }
2702
+ }
2703
+ emit(event, payload) {
2704
+ const handlers = this.handlers.get(event);
2705
+ if (handlers) {
2706
+ handlers.forEach((handler) => {
2707
+ try {
2708
+ handler(payload);
2709
+ } catch (error) {
2710
+ logger7.error(`Error in event handler for ${event}:`, error);
2711
+ }
2712
+ });
2713
+ }
2714
+ }
2715
+ removeAllListeners(event) {
2716
+ if (event) {
2717
+ this.handlers.delete(event);
2718
+ } else {
2719
+ this.handlers.clear();
2720
+ }
2721
+ }
2722
+ }
2723
+ var MCP_SERVER_URL2 = "https://mcp.integrate.dev/api/v1/mcp";
2724
+ var logger7 = createLogger("MCPClient", CLIENT_LOG_CONTEXT);
2725
+ var clientCache = new Map;
2726
+ var cleanupClients = new Set;
2727
+ class MCPClientBase {
2728
+ transport;
2729
+ integrations;
2730
+ availableTools = new Map;
2731
+ enabledToolNames = new Set;
2732
+ initialized = false;
2733
+ clientInfo;
2734
+ onReauthRequired;
2735
+ maxReauthRetries;
2736
+ authState = new Map;
2737
+ oauthManager;
2738
+ eventEmitter = new SimpleEventEmitter;
2739
+ apiRouteBase;
2740
+ apiBaseUrl;
2741
+ databaseDetected = false;
2742
+ _connectingPromise = null;
2743
+ __configuredIntegrations;
2744
+ __useServerConfig;
2745
+ oauthCallbackPromise;
2746
+ server;
2747
+ trigger;
2748
+ constructor(config) {
2749
+ this.transport = new HttpSessionTransport({
2750
+ url: config.serverUrl || MCP_SERVER_URL2,
2751
+ headers: config.headers,
2752
+ timeout: config.timeout
2753
+ });
2754
+ const oauthApiBase = config.oauthApiBase || "/api/integrate/oauth";
2755
+ this.apiRouteBase = config.apiRouteBase || "/api/integrate";
2756
+ this.apiBaseUrl = config.apiBaseUrl;
2757
+ const defaultRedirectUri = this.getDefaultRedirectUri(oauthApiBase, this.apiBaseUrl);
2758
+ this.integrations = config.integrations.map((integration) => {
2759
+ if (integration.oauth && !integration.oauth.redirectUri) {
2760
+ return {
2761
+ ...integration,
2762
+ oauth: {
2763
+ ...integration.oauth,
2764
+ redirectUri: defaultRedirectUri
2765
+ }
2766
+ };
2767
+ }
2768
+ return integration;
2769
+ });
2770
+ this.__configuredIntegrations = this.integrations;
2771
+ this.__useServerConfig = config.useServerConfig ?? false;
2772
+ this.clientInfo = config.clientInfo || {
2773
+ name: "integrate-sdk",
2774
+ version: "0.1.0"
2775
+ };
2776
+ this.onReauthRequired = config.onReauthRequired;
2777
+ this.maxReauthRetries = config.maxReauthRetries ?? 1;
2778
+ this.oauthManager = new OAuthManager(oauthApiBase, config.oauthFlow, this.apiBaseUrl, {
2779
+ getProviderToken: config.getProviderToken,
2780
+ setProviderToken: config.setProviderToken,
2781
+ removeProviderToken: config.removeProviderToken
2782
+ });
2783
+ for (const integration of this.integrations) {
2784
+ for (const toolName of integration.tools) {
2785
+ this.enabledToolNames.add(toolName);
2786
+ }
2787
+ if (integration.oauth) {
2788
+ const provider = integration.oauth.provider;
2789
+ this.authState.set(provider, { authenticated: false });
2790
+ }
2791
+ }
2792
+ const integrationHeaderValue = this.getIntegrationHeaderValue();
2793
+ if (integrationHeaderValue && this.transport.setHeader) {
2794
+ this.transport.setHeader("X-Integrations", integrationHeaderValue);
2795
+ }
2796
+ const providers = this.integrations.filter((p) => p.oauth).map((p) => p.oauth.provider);
2797
+ const usingDatabaseCallbacks = !!config.getProviderToken;
2798
+ if (usingDatabaseCallbacks) {
2799
+ this.oauthManager.loadAllProviderTokens(providers).then(async () => {
2800
+ for (const integration of this.integrations) {
2801
+ if (integration.oauth) {
2802
+ const provider = integration.oauth.provider;
2803
+ try {
2804
+ const tokenData = await this.oauthManager.getProviderToken(provider);
2805
+ const currentState = this.authState.get(provider);
2806
+ if (currentState && !currentState.authenticated && !currentState.lastError) {
2807
+ this.authState.set(provider, { authenticated: !!tokenData });
2808
+ }
2809
+ } catch (error) {
2810
+ logger7.error(`Failed to check token for ${provider}:`, error);
2811
+ const currentState = this.authState.get(provider);
2812
+ if (currentState && !currentState.authenticated && !currentState.lastError) {
2813
+ this.authState.set(provider, { authenticated: false });
2814
+ }
2815
+ }
2816
+ }
2817
+ }
2818
+ }).catch((error) => {
2819
+ logger7.error("Failed to load provider tokens:", error);
2820
+ });
2821
+ } else {
2822
+ this.oauthManager.loadAllProviderTokensSync(providers);
2823
+ for (const integration of this.integrations) {
2824
+ if (integration.oauth) {
2825
+ const provider = integration.oauth.provider;
2826
+ const tokenData = this.oauthManager.getProviderTokenFromCache(provider);
2827
+ if (tokenData) {
2828
+ this.authState.set(provider, { authenticated: true });
2829
+ }
2830
+ }
2831
+ }
2832
+ }
2833
+ const integrationIds = this.integrations.map((i) => i.id);
2834
+ if (integrationIds.includes("github")) {
2835
+ this.github = this.createIntegrationProxy("github");
2836
+ }
2837
+ if (integrationIds.includes("gmail")) {
2838
+ this.gmail = this.createIntegrationProxy("gmail");
2839
+ }
2840
+ if (integrationIds.includes("notion")) {
2841
+ this.notion = this.createIntegrationProxy("notion");
2842
+ }
2843
+ if (integrationIds.includes("slack")) {
2844
+ this.slack = this.createIntegrationProxy("slack");
2845
+ }
2846
+ if (integrationIds.includes("linear")) {
2847
+ this.linear = this.createIntegrationProxy("linear");
2848
+ }
2849
+ if (integrationIds.includes("vercel")) {
2850
+ this.vercel = this.createIntegrationProxy("vercel");
2851
+ }
2852
+ if (integrationIds.includes("zendesk")) {
2853
+ this.zendesk = this.createIntegrationProxy("zendesk");
2854
+ }
2855
+ if (integrationIds.includes("stripe")) {
2856
+ this.stripe = this.createIntegrationProxy("stripe");
2857
+ }
2858
+ if (integrationIds.includes("gcal")) {
2859
+ this.gcal = this.createIntegrationProxy("gcal");
2860
+ }
2861
+ if (integrationIds.includes("outlook")) {
2862
+ this.outlook = this.createIntegrationProxy("outlook");
2863
+ }
2864
+ if (integrationIds.includes("airtable")) {
2865
+ this.airtable = this.createIntegrationProxy("airtable");
2866
+ }
2867
+ if (integrationIds.includes("todoist")) {
2868
+ this.todoist = this.createIntegrationProxy("todoist");
2869
+ }
2870
+ this.server = this.createServerProxy();
2871
+ this.trigger = new TriggerClient({
2872
+ apiRouteBase: this.apiRouteBase,
2873
+ apiBaseUrl: this.apiBaseUrl,
2874
+ getHeaders: () => ({
2875
+ "X-Integrations": this.getIntegrationHeaderValue()
2876
+ })
2877
+ });
2878
+ this.initializeIntegrations();
2879
+ }
2880
+ getDefaultRedirectUri(oauthApiBase, apiBaseUrl) {
2881
+ const normalizedPath = oauthApiBase.replace(/\/$/, "");
2882
+ const callbackPath = `${normalizedPath}/callback`;
2883
+ if (apiBaseUrl) {
2884
+ const normalizedApiBaseUrl = apiBaseUrl.replace(/\/$/, "");
2885
+ return `${normalizedApiBaseUrl}${callbackPath}`;
2886
+ }
2887
+ if (typeof window === "undefined" || !window.location) {
2888
+ return "http://localhost:3000/api/integrate/oauth/callback";
2889
+ }
2890
+ const origin = window.location.origin;
2891
+ return `${origin}${callbackPath}`;
2892
+ }
2893
+ createIntegrationProxy(integrationId) {
2894
+ const hasIntegration = this.integrations.some((integration) => integration.id === integrationId);
2895
+ if (!hasIntegration) {
2896
+ return;
2897
+ }
2898
+ return new Proxy({}, {
2899
+ get: (_target, methodName) => {
2900
+ return async (args, options) => {
2901
+ const toolName = methodToToolName(methodName, integrationId);
2902
+ return await this.callToolWithRetry(toolName, args, 0, options);
2903
+ };
2904
+ }
2905
+ });
2906
+ }
2907
+ getIntegrationHeaderValue() {
2908
+ return this.integrations.map((integration) => integration.id).join(",");
2909
+ }
2910
+ createServerProxy() {
2911
+ return new Proxy({}, {
2912
+ get: (_target, methodName) => {
2913
+ if (methodName === "listConfiguredIntegrations") {
2914
+ return async (options) => {
2915
+ const transportHeaders = this.transport.headers || {};
2916
+ const hasApiKey = !!transportHeaders["X-API-KEY"];
2917
+ const serverConfig = this.__oauthConfig;
2918
+ const localIntegrations = serverConfig?.integrations || this.__configuredIntegrations;
2919
+ const formatLocalIntegrations = (integrations) => ({
2920
+ integrations: integrations.map((integration) => ({
2921
+ id: integration.id,
2922
+ name: integration.name || integration.id,
2923
+ logoUrl: integration.logoUrl,
2924
+ tools: integration.tools,
2925
+ hasOAuth: !!integration.oauth,
2926
+ scopes: integration.oauth?.scopes,
2927
+ provider: integration.oauth?.provider
2928
+ }))
2929
+ });
2930
+ if (hasApiKey || !this.__useServerConfig) {
2931
+ if (options?.includeToolMetadata && hasApiKey) {
2932
+ await this.ensureConnected();
2933
+ const integrationsWithMetadata = localIntegrations.map((integration) => {
2934
+ const toolMetadata = integration.tools.map((toolName) => this.availableTools.get(toolName)).filter((tool) => !!tool);
2935
+ return {
2936
+ id: integration.id,
2937
+ name: integration.name || integration.id,
2938
+ logoUrl: integration.logoUrl,
2939
+ tools: integration.tools,
2940
+ hasOAuth: !!integration.oauth,
2941
+ scopes: integration.oauth?.scopes,
2942
+ provider: integration.oauth?.provider,
2943
+ toolMetadata
2944
+ };
2945
+ });
2946
+ return { integrations: integrationsWithMetadata };
2947
+ }
2948
+ if (options?.includeToolMetadata && !hasApiKey) {
2949
+ const { parallelWithLimit: parallelWithLimit2 } = await Promise.resolve().then(() => exports_concurrency);
2950
+ const integrationsWithMetadata = await parallelWithLimit2(localIntegrations, async (integration) => {
2951
+ try {
2952
+ const response = await this.callServerToolInternal("list_tools_by_integration", {
2953
+ integration: integration.id
2954
+ });
2955
+ let toolMetadata = [];
2956
+ if (response.content && Array.isArray(response.content)) {
2957
+ for (const item of response.content) {
2958
+ if (item.type === "text" && item.text) {
2959
+ try {
2960
+ const parsed = JSON.parse(item.text);
2961
+ if (Array.isArray(parsed)) {
2962
+ toolMetadata = parsed;
2963
+ } else if (parsed.tools && Array.isArray(parsed.tools)) {
2964
+ toolMetadata = parsed.tools;
2965
+ }
2966
+ } catch {}
2967
+ }
2968
+ }
2969
+ }
2970
+ return {
2971
+ id: integration.id,
2972
+ name: integration.name || integration.id,
2973
+ logoUrl: integration.logoUrl,
2974
+ tools: integration.tools,
2975
+ hasOAuth: !!integration.oauth,
2976
+ scopes: integration.oauth?.scopes,
2977
+ provider: integration.oauth?.provider,
2978
+ toolMetadata
2979
+ };
2980
+ } catch (error) {
2981
+ logger7.error(`Failed to fetch tool metadata for ${integration.id}:`, error);
2982
+ return {
2983
+ id: integration.id,
2984
+ name: integration.name || integration.id,
2985
+ logoUrl: integration.logoUrl,
2986
+ tools: integration.tools,
2987
+ hasOAuth: !!integration.oauth,
2988
+ scopes: integration.oauth?.scopes,
2989
+ provider: integration.oauth?.provider,
2990
+ toolMetadata: []
2991
+ };
2992
+ }
2993
+ }, 3);
2994
+ return { integrations: integrationsWithMetadata };
2995
+ }
2996
+ return formatLocalIntegrations(localIntegrations);
2997
+ }
2998
+ const url = this.apiBaseUrl ? `${this.apiBaseUrl}${this.apiRouteBase}/integrations` : `${this.apiRouteBase}/integrations`;
2999
+ try {
3000
+ const response = await fetch(url, {
3001
+ method: "GET",
3002
+ headers: {
3003
+ "Content-Type": "application/json"
3004
+ }
3005
+ });
3006
+ if (!response.ok) {
3007
+ logger7.error("Failed to fetch integrations from server, falling back to local config");
3008
+ return formatLocalIntegrations(localIntegrations);
3009
+ }
3010
+ const result = await response.json();
3011
+ if (options?.includeToolMetadata && result.integrations) {
3012
+ const { parallelWithLimit: parallelWithLimit2 } = await Promise.resolve().then(() => exports_concurrency);
3013
+ const integrationsWithMetadata = await parallelWithLimit2(result.integrations, async (integration) => {
3014
+ try {
3015
+ const metadataResponse = await this.callServerToolInternal("list_tools_by_integration", {
3016
+ integration: integration.id
3017
+ });
3018
+ let toolMetadata = [];
3019
+ if (metadataResponse.content && Array.isArray(metadataResponse.content)) {
3020
+ for (const item of metadataResponse.content) {
3021
+ if (item.type === "text" && item.text) {
3022
+ try {
3023
+ const parsed = JSON.parse(item.text);
3024
+ if (Array.isArray(parsed)) {
3025
+ toolMetadata = parsed;
3026
+ } else if (parsed.tools && Array.isArray(parsed.tools)) {
3027
+ toolMetadata = parsed.tools;
3028
+ }
3029
+ } catch {}
3030
+ }
3031
+ }
3032
+ }
3033
+ return {
3034
+ ...integration,
3035
+ toolMetadata
3036
+ };
3037
+ } catch (error) {
3038
+ logger7.error(`Failed to fetch tool metadata for ${integration.id}:`, error);
3039
+ return {
3040
+ ...integration,
3041
+ toolMetadata: []
3042
+ };
3043
+ }
3044
+ }, 3);
3045
+ return { integrations: integrationsWithMetadata };
3046
+ }
3047
+ return result;
3048
+ } catch (error) {
3049
+ logger7.error("Failed to fetch integrations from server, falling back to local config:", error);
3050
+ return formatLocalIntegrations(localIntegrations);
3051
+ }
3052
+ };
3053
+ }
3054
+ return async (args, options) => {
3055
+ const toolName = methodToToolName(methodName, "");
3056
+ const finalToolName = toolName.startsWith("_") ? toolName.substring(1) : toolName;
3057
+ return await this.callServerToolInternal(finalToolName, args, options);
3058
+ };
3059
+ }
3060
+ });
3061
+ }
3062
+ async callServerToolInternal(name, args, options) {
3063
+ try {
3064
+ const response = await this.callToolThroughHandler(name, args, undefined, options);
3065
+ return response;
3066
+ } catch (error) {
3067
+ const parsedError = parseServerError(error, { toolName: name });
3068
+ throw parsedError;
3069
+ }
3070
+ }
3071
+ async ensureConnected() {
3072
+ if (this.isConnected()) {
3073
+ return;
3074
+ }
3075
+ if (!this._connectingPromise) {
3076
+ this._connectingPromise = this.connect().finally(() => {
3077
+ this._connectingPromise = null;
3078
+ });
3079
+ }
3080
+ return this._connectingPromise;
3081
+ }
3082
+ async initializeIntegrations() {
3083
+ for (const integration of this.integrations) {
3084
+ if (integration.onInit) {
3085
+ await integration.onInit(this);
3086
+ }
3087
+ }
3088
+ }
3089
+ async connect() {
3090
+ for (const integration of this.integrations) {
3091
+ if (integration.onBeforeConnect) {
3092
+ await integration.onBeforeConnect(this);
3093
+ }
3094
+ }
3095
+ await this.transport.connect();
3096
+ await this.initialize();
3097
+ await this.discoverTools();
3098
+ for (const integration of this.integrations) {
3099
+ if (integration.onAfterConnect) {
3100
+ await integration.onAfterConnect(this);
3101
+ }
3102
+ }
3103
+ }
3104
+ async initialize() {
3105
+ const params = {
3106
+ protocolVersion: "2024-11-05",
3107
+ capabilities: {
3108
+ tools: {}
3109
+ },
3110
+ clientInfo: this.clientInfo
3111
+ };
3112
+ const response = await this.transport.sendRequest("initialize" /* INITIALIZE */, params);
3113
+ this.initialized = true;
3114
+ return response;
3115
+ }
3116
+ async discoverTools() {
3117
+ let cursor;
3118
+ let totalDiscovered = 0;
3119
+ do {
3120
+ const response = await this.transport.sendRequest("tools/list" /* TOOLS_LIST */, cursor ? { cursor } : undefined);
3121
+ for (const tool of response.tools) {
3122
+ this.availableTools.set(tool.name, tool);
3123
+ }
3124
+ totalDiscovered += response.tools.length;
3125
+ cursor = response.nextCursor;
3126
+ } while (cursor);
3127
+ const enabledCount = Array.from(this.availableTools.keys()).filter((name) => this.enabledToolNames.has(name)).length;
3128
+ logger7.debug(`Discovered ${totalDiscovered} tools, ${enabledCount} enabled by integrations`);
3129
+ }
3130
+ async _callToolByName(name, args, options) {
3131
+ return await this.callToolWithRetry(name, args, 0, options);
3132
+ }
3133
+ async callServerTool(name, args) {
3134
+ try {
3135
+ const response = await this.callToolThroughHandler(name, args);
3136
+ return response;
3137
+ } catch (error) {
3138
+ const parsedError = parseServerError(error, { toolName: name });
3139
+ throw parsedError;
3140
+ }
3141
+ }
3142
+ async callToolThroughHandler(name, args, provider, options) {
3143
+ const transportHeaders = this.transport.headers || {};
3144
+ const hasApiKey = !!transportHeaders["X-API-KEY"];
3145
+ if (hasApiKey) {
3146
+ await this.ensureConnected();
3147
+ if (provider) {
3148
+ const tokenData = await this.oauthManager.getProviderToken(provider, undefined, options?.context);
3149
+ if (tokenData && this.transport.setHeader) {
3150
+ const previousAuthHeader = transportHeaders["Authorization"];
3151
+ try {
3152
+ this.transport.setHeader("Authorization", `Bearer ${tokenData.accessToken}`);
3153
+ const result3 = await this.transport.sendRequest("tools/call", {
3154
+ name,
3155
+ arguments: args || {}
3156
+ });
3157
+ return result3;
3158
+ } finally {
3159
+ if (previousAuthHeader && this.transport.setHeader) {
3160
+ this.transport.setHeader("Authorization", previousAuthHeader);
3161
+ } else if (this.transport.removeHeader) {
3162
+ this.transport.removeHeader("Authorization");
3163
+ }
3164
+ }
3165
+ }
3166
+ }
3167
+ const result2 = await this.transport.sendRequest("tools/call", {
3168
+ name,
3169
+ arguments: args || {}
3170
+ });
3171
+ return result2;
3172
+ }
3173
+ const url = this.apiBaseUrl ? `${this.apiBaseUrl}${this.apiRouteBase}/mcp` : `${this.apiRouteBase}/mcp`;
3174
+ const headers = {
3175
+ "Content-Type": "application/json"
3176
+ };
3177
+ const integrationsHeader = this.getIntegrationHeaderValue();
3178
+ if (integrationsHeader) {
3179
+ headers["X-Integrations"] = integrationsHeader;
3180
+ }
3181
+ if (provider) {
3182
+ const tokenData = await this.oauthManager.getProviderToken(provider, undefined, options?.context);
3183
+ if (tokenData) {
3184
+ headers["Authorization"] = `Bearer ${tokenData.accessToken}`;
3185
+ }
3186
+ }
3187
+ const response = await fetch(url, {
3188
+ method: "POST",
3189
+ headers,
3190
+ body: JSON.stringify({
3191
+ name,
3192
+ arguments: args
3193
+ })
3194
+ });
3195
+ if (!this.databaseDetected && response.headers.get("X-Integrate-Use-Database") === "true") {
3196
+ this.oauthManager.setSkipLocalStorage(true);
3197
+ this.databaseDetected = true;
3198
+ }
3199
+ if (!response.ok) {
3200
+ let errorMessage = `Request failed: ${response.statusText}`;
3201
+ const error = new Error(errorMessage);
3202
+ error.statusCode = response.status;
3203
+ try {
3204
+ const errorData = await response.json();
3205
+ if (errorData.error) {
3206
+ errorMessage = typeof errorData.error === "string" ? errorData.error : errorData.error.message || errorMessage;
3207
+ error.message = errorMessage;
3208
+ }
3209
+ if (errorData.code) {
3210
+ error.code = errorData.code;
3211
+ }
3212
+ if (errorData.data) {
3213
+ error.data = errorData.data;
3214
+ }
3215
+ if (errorData.error && typeof errorData.error === "object") {
3216
+ error.jsonrpcError = errorData.error;
3217
+ }
3218
+ } catch {}
3219
+ throw error;
3220
+ }
3221
+ const result = await response.json();
3222
+ return result;
3223
+ }
3224
+ async callToolWithRetry(name, args, retryCount = 0, options) {
3225
+ if (!this.enabledToolNames.has(name)) {
3226
+ throw new Error(`Tool "${name}" is not enabled. Enable it by adding the appropriate integration.`);
3227
+ }
3228
+ const provider = this.getProviderForTool(name);
3229
+ try {
3230
+ const response = await this.callToolThroughHandler(name, args, provider, options);
3231
+ if (provider) {
3232
+ this.authState.set(provider, { authenticated: true });
3233
+ }
3234
+ return response;
3235
+ } catch (error) {
3236
+ const parsedError = parseServerError(error, { toolName: name, provider });
3237
+ if (isAuthError(parsedError) && retryCount < this.maxReauthRetries) {
3238
+ if (provider) {
3239
+ this.authState.set(provider, {
3240
+ authenticated: false,
3241
+ lastError: parsedError
3242
+ });
3243
+ }
3244
+ if (this.onReauthRequired && provider) {
3245
+ const reauthSuccess = await this.onReauthRequired({
3246
+ provider,
3247
+ error: parsedError,
3248
+ toolName: name
3249
+ });
3250
+ if (reauthSuccess) {
3251
+ return await this.callToolWithRetry(name, args, retryCount + 1);
3252
+ }
3253
+ }
3254
+ }
3255
+ throw parsedError;
3256
+ }
3257
+ }
3258
+ getProviderForTool(toolName) {
3259
+ for (const integration of this.integrations) {
3260
+ if (integration.tools.includes(toolName) && integration.oauth) {
3261
+ return integration.oauth.provider;
3262
+ }
3263
+ }
3264
+ return;
3265
+ }
3266
+ getTool(name) {
3267
+ return this.availableTools.get(name);
3268
+ }
3269
+ getAvailableTools() {
3270
+ return Array.from(this.availableTools.values());
3271
+ }
3272
+ setRequestHeader(key, value) {
3273
+ this.transport.setHeader(key, value);
3274
+ }
3275
+ getEnabledTools() {
3276
+ return Array.from(this.availableTools.values()).filter((tool) => this.enabledToolNames.has(tool.name));
3277
+ }
3278
+ async getEnabledToolsAsync() {
3279
+ if (this.isConnected() && this.availableTools.size > 0) {
3280
+ return this.getEnabledTools();
3281
+ }
3282
+ if (this.availableTools.size > 0) {
3283
+ return this.getEnabledTools();
3284
+ }
3285
+ const tools = [];
3286
+ const integrationIds = new Set;
3287
+ for (const integration of this.integrations) {
3288
+ integrationIds.add(integration.id);
3289
+ }
3290
+ const { parallelWithLimit: parallelWithLimit2 } = await Promise.resolve().then(() => exports_concurrency);
3291
+ const integrationToolsResults = await parallelWithLimit2(Array.from(integrationIds), async (integrationId) => {
3292
+ try {
3293
+ const response = await this.callServerToolInternal("list_tools_by_integration", {
3294
+ integration: integrationId
3295
+ });
3296
+ const integrationTools = [];
3297
+ if (response.content && Array.isArray(response.content)) {
3298
+ for (const item of response.content) {
3299
+ if (item.type === "text" && item.text) {
3300
+ try {
3301
+ const parsed = JSON.parse(item.text);
3302
+ if (Array.isArray(parsed)) {
3303
+ for (const tool of parsed) {
3304
+ if (tool.name && tool.inputSchema) {
3305
+ integrationTools.push({
3306
+ name: tool.name,
3307
+ description: tool.description,
3308
+ inputSchema: tool.inputSchema
3309
+ });
3310
+ }
3311
+ }
3312
+ } else if (parsed.tools && Array.isArray(parsed.tools)) {
3313
+ for (const tool of parsed.tools) {
3314
+ if (tool.name && tool.inputSchema) {
3315
+ integrationTools.push({
3316
+ name: tool.name,
3317
+ description: tool.description,
3318
+ inputSchema: tool.inputSchema
3319
+ });
3320
+ }
3321
+ }
3322
+ }
3323
+ } catch {}
3324
+ }
3325
+ }
3326
+ }
3327
+ return integrationTools;
3328
+ } catch (error) {
3329
+ logger7.error(`Failed to fetch tools for integration ${integrationId}:`, error);
3330
+ return [];
3331
+ }
3332
+ }, 3);
3333
+ for (const integrationTools of integrationToolsResults) {
3334
+ tools.push(...integrationTools);
3335
+ }
3336
+ for (const tool of tools) {
3337
+ this.availableTools.set(tool.name, tool);
3338
+ }
3339
+ return tools.filter((tool) => this.enabledToolNames.has(tool.name));
3340
+ }
3341
+ getOAuthConfig(integrationId) {
3342
+ const integration = this.integrations.find((p) => p.id === integrationId);
3343
+ return integration?.oauth;
3344
+ }
3345
+ getAllOAuthConfigs() {
3346
+ const configs = new Map;
3347
+ for (const integration of this.integrations) {
3348
+ if (integration.oauth) {
3349
+ configs.set(integration.id, integration.oauth);
3350
+ }
3351
+ }
3352
+ return configs;
3353
+ }
3354
+ onMessage(handler) {
3355
+ return this.transport.onMessage(handler);
3356
+ }
3357
+ on(event, handler) {
3358
+ this.eventEmitter.on(event, handler);
3359
+ }
3360
+ off(event, handler) {
3361
+ this.eventEmitter.off(event, handler);
3362
+ }
3363
+ clearSessionToken() {
3364
+ this.oauthManager.clearAllProviderTokens();
3365
+ for (const integration of this.integrations) {
3366
+ if (integration.oauth) {
3367
+ const provider = integration.oauth.provider;
3368
+ this.authState.set(provider, { authenticated: false });
3369
+ }
3370
+ }
3371
+ }
3372
+ async disconnectProvider(provider, context) {
3373
+ const integration = this.integrations.find((p) => p.oauth?.provider === provider);
3374
+ if (!integration?.oauth) {
3375
+ throw new Error(`No OAuth configuration found for provider: ${provider}`);
3376
+ }
3377
+ try {
3378
+ await this.oauthManager.disconnectProvider(provider, context);
3379
+ this.authState.set(provider, { authenticated: false });
3380
+ this.eventEmitter.emit("auth:disconnect", { provider });
3381
+ } catch (error) {
3382
+ this.eventEmitter.emit("auth:error", {
3383
+ provider,
3384
+ error
3385
+ });
3386
+ throw error;
3387
+ }
3388
+ }
3389
+ async disconnectAccount(provider, email, context) {
3390
+ const integration = this.integrations.find((p) => p.oauth?.provider === provider);
3391
+ if (!integration?.oauth) {
3392
+ throw new Error(`No OAuth configuration found for provider: ${provider}`);
3393
+ }
3394
+ try {
3395
+ await this.oauthManager.disconnectAccount(provider, email, context);
3396
+ const accounts = await this.oauthManager.listAccounts(provider);
3397
+ if (accounts.length === 0) {
3398
+ this.authState.set(provider, { authenticated: false });
3399
+ }
3400
+ this.eventEmitter.emit("auth:disconnect", { provider });
3401
+ } catch (error) {
3402
+ this.eventEmitter.emit("auth:error", {
3403
+ provider,
3404
+ error
3405
+ });
3406
+ throw error;
3407
+ }
3408
+ }
3409
+ async listAccounts(provider) {
3410
+ return await this.oauthManager.listAccounts(provider);
3411
+ }
3412
+ async logout() {
3413
+ this.clearSessionToken();
3414
+ this.oauthManager.clearAllPendingAuths();
3415
+ this.authState.clear();
3416
+ for (const integration of this.integrations) {
3417
+ if (integration.oauth) {
3418
+ this.authState.set(integration.oauth.provider, { authenticated: false });
3419
+ }
3420
+ }
3421
+ this.eventEmitter.emit("auth:logout", {});
3422
+ }
3423
+ async disconnect() {
3424
+ for (const integration of this.integrations) {
3425
+ if (integration.onDisconnect) {
3426
+ await integration.onDisconnect(this);
3427
+ }
3428
+ }
3429
+ await this.transport.disconnect();
3430
+ this.initialized = false;
3431
+ }
3432
+ isConnected() {
3433
+ return this.transport.isConnected();
3434
+ }
3435
+ isInitialized() {
3436
+ return this.initialized;
3437
+ }
3438
+ getAuthState(provider) {
3439
+ return this.authState.get(provider);
3440
+ }
3441
+ isProviderAuthenticated(provider) {
3442
+ return this.authState.get(provider)?.authenticated ?? false;
3443
+ }
3444
+ async isAuthorized(provider, email, context) {
3445
+ if (this.oauthCallbackPromise) {
3446
+ await this.oauthCallbackPromise;
3447
+ this.oauthCallbackPromise = null;
3448
+ }
3449
+ try {
3450
+ const tokenData = await this.oauthManager.getProviderToken(provider, email, context);
3451
+ const isAuthenticated = !!tokenData;
3452
+ const currentState = this.authState.get(provider);
3453
+ if (currentState) {
3454
+ currentState.authenticated = isAuthenticated;
3455
+ if (isAuthenticated) {
3456
+ currentState.lastError = undefined;
3457
+ }
3458
+ } else {
3459
+ this.authState.set(provider, { authenticated: isAuthenticated });
3460
+ }
3461
+ return isAuthenticated;
3462
+ } catch (error) {
3463
+ const currentState = this.authState.get(provider);
3464
+ if (currentState) {
3465
+ currentState.authenticated = false;
3466
+ } else {
3467
+ this.authState.set(provider, { authenticated: false });
3468
+ }
3469
+ return false;
3470
+ }
3471
+ }
3472
+ async authorizedProviders() {
3473
+ if (this.oauthCallbackPromise) {
3474
+ await this.oauthCallbackPromise;
3475
+ this.oauthCallbackPromise = null;
3476
+ }
3477
+ const authorized = [];
3478
+ for (const integration of this.integrations) {
3479
+ if (integration.oauth) {
3480
+ const provider = integration.oauth.provider;
3481
+ if (this.authState.get(provider)?.authenticated) {
3482
+ authorized.push(provider);
3483
+ }
3484
+ }
3485
+ }
3486
+ return authorized;
3487
+ }
3488
+ async getAuthorizationStatus(provider, email) {
3489
+ return await this.oauthManager.checkAuthStatus(provider, email);
3490
+ }
3491
+ async authorize(provider, options) {
3492
+ const integration = this.integrations.find((p) => p.oauth?.provider === provider);
3493
+ if (!integration?.oauth) {
3494
+ const error = new Error(`No OAuth configuration found for provider: ${provider}`);
3495
+ this.eventEmitter.emit("auth:error", { provider, error });
3496
+ throw error;
3497
+ }
3498
+ if (options?.useExistingConnection) {
3499
+ const authStatus = await this.oauthManager.checkAuthStatus(provider);
3500
+ if (authStatus.authorized) {
3501
+ const tokenData = await this.oauthManager.getProviderToken(provider);
3502
+ if (tokenData) {
3503
+ this.eventEmitter.emit("auth:complete", {
3504
+ provider,
3505
+ accessToken: tokenData.accessToken,
3506
+ expiresAt: tokenData.expiresAt
3507
+ });
3508
+ this.authState.set(provider, { authenticated: true });
3509
+ }
3510
+ return;
3511
+ }
3512
+ }
3513
+ this.eventEmitter.emit("auth:started", { provider });
3514
+ try {
3515
+ await this.oauthManager.initiateFlow(provider, integration.oauth, options?.returnUrl);
3516
+ const tokenData = await this.oauthManager.getProviderToken(provider);
3517
+ if (tokenData) {
3518
+ this.eventEmitter.emit("auth:complete", {
3519
+ provider,
3520
+ accessToken: tokenData.accessToken,
3521
+ expiresAt: tokenData.expiresAt
3522
+ });
3523
+ }
3524
+ this.authState.set(provider, { authenticated: true });
3525
+ } catch (error) {
3526
+ this.eventEmitter.emit("auth:error", { provider, error });
3527
+ throw error;
3528
+ }
3529
+ }
3530
+ async handleOAuthCallback(params) {
3531
+ try {
3532
+ const result = params.tokenData ? await this.oauthManager.handleCallbackWithToken(params.code, params.state, params.tokenData) : await this.oauthManager.handleCallback(params.code, params.state);
3533
+ this.authState.set(result.provider, { authenticated: true });
3534
+ this.eventEmitter.emit("auth:complete", {
3535
+ provider: result.provider,
3536
+ accessToken: result.accessToken,
3537
+ expiresAt: result.expiresAt
3538
+ });
3539
+ } catch (error) {
3540
+ this.eventEmitter.emit("auth:error", {
3541
+ provider: "unknown",
3542
+ error
3543
+ });
3544
+ throw error;
3545
+ }
3546
+ }
3547
+ async getProviderToken(provider, email, context) {
3548
+ return await this.oauthManager.getProviderToken(provider, email, context);
3549
+ }
3550
+ async setProviderToken(provider, tokenData, email, context) {
3551
+ await this.oauthManager.setProviderToken(provider, tokenData, email, context);
3552
+ if (tokenData === null) {
3553
+ this.authState.set(provider, { authenticated: false });
3554
+ } else {
3555
+ this.authState.set(provider, { authenticated: true });
3556
+ }
3557
+ }
3558
+ getAllProviderTokens() {
3559
+ const tokens = {};
3560
+ const allTokens = this.oauthManager.getAllProviderTokens();
3561
+ for (const [provider, tokenData] of allTokens.entries()) {
3562
+ tokens[provider] = tokenData.accessToken;
3563
+ }
3564
+ return tokens;
3565
+ }
3566
+ async reauthenticate(provider) {
3567
+ const state = this.authState.get(provider);
3568
+ if (!state) {
3569
+ throw new Error(`Provider "${provider}" not found in configured integrations`);
3570
+ }
3571
+ if (!this.onReauthRequired) {
3572
+ throw new Error("No re-authentication handler configured. Set onReauthRequired in client config.");
3573
+ }
3574
+ const lastError = state.lastError || new (await Promise.resolve().then(() => (init_errors(), exports_errors))).AuthenticationError("Manual re-authentication requested", undefined, provider);
3575
+ const success = await this.onReauthRequired({
3576
+ provider,
3577
+ error: lastError
3578
+ });
3579
+ if (success) {
3580
+ this.authState.set(provider, { authenticated: true });
3581
+ }
3582
+ return success;
3583
+ }
3584
+ }
3585
+ // ../server.ts
3586
+ init_logger();
3587
+
3588
+ // ../integrations/github.ts
3589
+ init_logger();
3590
+ var logger8 = createLogger("GitHub");
3591
+ // ../integrations/gmail.ts
3592
+ init_logger();
3593
+ var logger9 = createLogger("Gmail");
3594
+ // ../integrations/notion.ts
3595
+ init_logger();
3596
+ var logger10 = createLogger("Notion");
3597
+ // ../integrations/slack.ts
3598
+ init_logger();
3599
+ var logger11 = createLogger("Slack");
3600
+ // ../integrations/linear.ts
3601
+ init_logger();
3602
+ var logger12 = createLogger("Linear");
3603
+ // ../integrations/vercel.ts
3604
+ init_logger();
3605
+ var logger13 = createLogger("Vercel");
3606
+ // ../integrations/zendesk.ts
3607
+ init_logger();
3608
+ var logger14 = createLogger("Zendesk");
3609
+ // ../integrations/stripe.ts
3610
+ init_logger();
3611
+ var logger15 = createLogger("Stripe");
3612
+ // ../integrations/gcal.ts
3613
+ init_logger();
3614
+ var logger16 = createLogger("Google Calendar");
3615
+ // ../integrations/outlook.ts
3616
+ init_logger();
3617
+ var logger17 = createLogger("Outlook");
3618
+ // ../integrations/airtable.ts
3619
+ init_logger();
3620
+ var logger18 = createLogger("Airtable");
3621
+ // ../integrations/todoist.ts
3622
+ init_logger();
3623
+ var logger19 = createLogger("Todoist");
3624
+ // ../integrations/whatsapp.ts
3625
+ init_logger();
3626
+ var logger20 = createLogger("WhatsApp");
3627
+ // ../integrations/calcom.ts
3628
+ init_logger();
3629
+ var logger21 = createLogger("Cal.com");
3630
+ // ../integrations/ramp.ts
3631
+ init_logger();
3632
+ var logger22 = createLogger("Ramp");
3633
+ // ../integrations/onedrive.ts
3634
+ init_logger();
3635
+ var logger23 = createLogger("OneDrive");
3636
+ // ../integrations/gworkspace.ts
3637
+ init_logger();
3638
+ var logger24 = createLogger("Google Workspace");
3639
+ // ../integrations/polar.ts
3640
+ init_logger();
3641
+ var logger25 = createLogger("Polar");
3642
+ // ../integrations/figma.ts
3643
+ init_logger();
3644
+ var logger26 = createLogger("Figma");
3645
+ // ../integrations/intercom.ts
3646
+ init_logger();
3647
+ var logger27 = createLogger("Intercom");
3648
+ // ../integrations/hubspot.ts
3649
+ init_logger();
3650
+ var logger28 = createLogger("HubSpot");
3651
+ // ../integrations/youtube.ts
3652
+ init_logger();
3653
+ var logger29 = createLogger("YouTube");
3654
+ // ../integrations/cursor.ts
3655
+ init_logger();
3656
+ var logger30 = createLogger("Cursor");
3657
+ // ../ai/trigger-tools.ts
3658
+ init_utils();
3659
+
3660
+ // ../ai/vercel-ai.ts
3661
+ init_tool_builder();
3662
+ // ../ai/openai.ts
3663
+ init_tool_builder();
3664
+
3665
+ // ../../node_modules/zod-to-json-schema/dist/esm/Options.js
3666
+ var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
3667
+ // ../../node_modules/zod-to-json-schema/dist/esm/parsers/string.js
3668
+ var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
3669
+ // ../ai/anthropic.ts
3670
+ init_tool_builder();
3671
+ // ../ai/google.ts
3672
+ init_tool_builder();
3673
+ // ../server.ts
3674
+ var SERVER_LOG_CONTEXT3 = "server";
3675
+ var logger31 = createLogger("MCPServer", SERVER_LOG_CONTEXT3);
3676
+ var codeVerifierStorage = new Map;
3677
+ function toSolidStartHandler(clientOrHandlerOrOptions, _redirectOptions) {
3678
+ if (clientOrHandlerOrOptions && clientOrHandlerOrOptions.handler && typeof clientOrHandlerOrOptions.handler === "function") {
3679
+ const baseHandler = clientOrHandlerOrOptions.handler;
3680
+ const handler2 = async (event) => {
3681
+ return baseHandler(event.request);
3682
+ };
3683
+ return {
3684
+ GET: handler2,
3685
+ POST: handler2,
3686
+ PATCH: handler2,
3687
+ PUT: handler2,
3688
+ DELETE: handler2
3689
+ };
3690
+ }
3691
+ if (typeof clientOrHandlerOrOptions === "function") {
3692
+ const baseHandler = clientOrHandlerOrOptions;
3693
+ const handler2 = async (event) => {
3694
+ return baseHandler(event.request);
3695
+ };
3696
+ return {
3697
+ GET: handler2,
3698
+ POST: handler2,
3699
+ PATCH: handler2,
3700
+ PUT: handler2,
3701
+ DELETE: handler2
3702
+ };
3703
+ }
3704
+ const options = clientOrHandlerOrOptions;
3705
+ if (!options.providers || Object.keys(options.providers).length === 0) {
3706
+ throw new Error("toSolidStartHandler requires either a handler function or a providers config object");
3707
+ }
3708
+ const { providers, serverUrl, apiKey, redirectUrl, errorRedirectUrl } = options;
3709
+ const nextHandler = createNextOAuthHandler({
3710
+ providers,
3711
+ serverUrl,
3712
+ apiKey
3713
+ });
3714
+ const routes = nextHandler.toNextJsHandler({
3715
+ redirectUrl: redirectUrl || "/",
3716
+ errorRedirectUrl: errorRedirectUrl || "/auth-error"
3717
+ });
3718
+ const handler = async (event) => {
3719
+ const method = event.request.method.toUpperCase();
3720
+ const url = new URL(event.request.url);
3721
+ const pathParts = url.pathname.split("/").filter(Boolean);
3722
+ const integrateIndex = pathParts.indexOf("integrate");
3723
+ const segments = integrateIndex >= 0 ? pathParts.slice(integrateIndex + 1) : [];
3724
+ const context = {
3725
+ params: segments
3726
+ };
3727
+ if (method === "POST") {
3728
+ return routes.POST(event.request, { params: { all: context.params } });
3729
+ } else if (method === "GET") {
3730
+ return routes.GET(event.request, { params: { all: context.params } });
3731
+ } else {
3732
+ return Response.json({ error: `Method ${method} not allowed` }, { status: 405 });
3733
+ }
3734
+ };
3735
+ return {
3736
+ GET: handler,
3737
+ POST: handler,
3738
+ PATCH: handler,
3739
+ PUT: handler,
3740
+ DELETE: handler
3741
+ };
3742
+ }
3743
+ function toSvelteKitHandler(clientOrHandlerOrOptions, _redirectOptions) {
3744
+ if (clientOrHandlerOrOptions && clientOrHandlerOrOptions.handler && typeof clientOrHandlerOrOptions.handler === "function") {
3745
+ const baseHandler = clientOrHandlerOrOptions.handler;
3746
+ return async (event) => {
3747
+ const all = event.params?.all;
3748
+ return baseHandler(event.request, { params: { all } });
3749
+ };
3750
+ }
3751
+ if (typeof clientOrHandlerOrOptions === "function") {
3752
+ const baseHandler = clientOrHandlerOrOptions;
3753
+ return async (event) => {
3754
+ const all = event.params?.all;
3755
+ return baseHandler(event.request, { params: { all } });
3756
+ };
3757
+ }
3758
+ const options = clientOrHandlerOrOptions;
3759
+ if (!options.providers || Object.keys(options.providers).length === 0) {
3760
+ throw new Error("toSvelteKitHandler requires either a handler function or a providers config object");
3761
+ }
3762
+ const { providers, serverUrl, apiKey, redirectUrl, errorRedirectUrl } = options;
3763
+ const nextHandler = createNextOAuthHandler({
3764
+ providers,
3765
+ serverUrl,
3766
+ apiKey
3767
+ });
3768
+ const routes = nextHandler.toNextJsHandler({
3769
+ redirectUrl: redirectUrl || "/",
3770
+ errorRedirectUrl: errorRedirectUrl || "/auth-error"
3771
+ });
3772
+ return async (event) => {
3773
+ const method = event.request.method.toUpperCase();
3774
+ const all = event.params?.all;
3775
+ const context = {
3776
+ params: Array.isArray(all) ? all : all ? all.split("/").filter(Boolean) : []
3777
+ };
3778
+ if (method === "POST") {
3779
+ return routes.POST(event.request, { params: { all: context.params } });
3780
+ } else if (method === "GET") {
3781
+ return routes.GET(event.request, { params: { all: context.params } });
3782
+ } else {
3783
+ return Response.json({ error: `Method ${method} not allowed` }, { status: 405 });
3784
+ }
3785
+ };
3786
+ }
172
3787
  export {
173
3788
  toSolidStartHandler
174
3789
  };