@reverbia/sdk 1.0.0-next.20251218225706 → 1.0.0-next.20251219092050

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.
@@ -38,18 +38,24 @@ var __decorateClass = (decorators, target, key, kind) => {
38
38
  // src/react/index.ts
39
39
  var index_exports = {};
40
40
  __export(index_exports, {
41
+ BACKUP_DRIVE_CONVERSATIONS_FOLDER: () => DEFAULT_CONVERSATIONS_FOLDER,
42
+ BACKUP_DRIVE_ROOT_FOLDER: () => DEFAULT_ROOT_FOLDER,
43
+ BackupAuthProvider: () => BackupAuthProvider,
41
44
  ChatConversation: () => Conversation,
42
45
  ChatMessage: () => Message,
43
46
  DEFAULT_BACKUP_FOLDER: () => DEFAULT_BACKUP_FOLDER,
44
47
  DEFAULT_DRIVE_CONVERSATIONS_FOLDER: () => DEFAULT_CONVERSATIONS_FOLDER,
45
48
  DEFAULT_DRIVE_ROOT_FOLDER: () => DEFAULT_ROOT_FOLDER,
49
+ DEFAULT_DROPBOX_FOLDER: () => DEFAULT_BACKUP_FOLDER,
46
50
  DEFAULT_TOOL_SELECTOR_MODEL: () => DEFAULT_TOOL_SELECTOR_MODEL,
47
51
  DropboxAuthProvider: () => DropboxAuthProvider,
52
+ GoogleDriveAuthProvider: () => GoogleDriveAuthProvider,
48
53
  StoredMemoryModel: () => Memory,
49
54
  StoredModelPreferenceModel: () => ModelPreference,
50
55
  chatStorageMigrations: () => chatStorageMigrations,
51
56
  chatStorageSchema: () => chatStorageSchema,
52
57
  clearDropboxToken: () => clearToken,
58
+ clearGoogleDriveToken: () => clearGoogleDriveToken,
53
59
  createMemoryContextSystemMessage: () => createMemoryContextSystemMessage,
54
60
  decryptData: () => decryptData,
55
61
  decryptDataBytes: () => decryptDataBytes,
@@ -60,8 +66,10 @@ __export(index_exports, {
60
66
  generateCompositeKey: () => generateCompositeKey,
61
67
  generateConversationId: () => generateConversationId,
62
68
  generateUniqueKey: () => generateUniqueKey,
63
- getDropboxToken: () => getStoredToken,
69
+ getGoogleDriveStoredToken: () => getGoogleDriveStoredToken,
70
+ hasDropboxCredentials: () => hasDropboxCredentials,
64
71
  hasEncryptionKey: () => hasEncryptionKey,
72
+ hasGoogleDriveCredentials: () => hasGoogleDriveCredentials,
65
73
  memoryStorageSchema: () => memoryStorageSchema,
66
74
  requestEncryptionKey: () => requestEncryptionKey,
67
75
  sdkMigrations: () => sdkMigrations,
@@ -69,12 +77,14 @@ __export(index_exports, {
69
77
  sdkSchema: () => sdkSchema,
70
78
  selectTool: () => selectTool,
71
79
  settingsStorageSchema: () => settingsStorageSchema,
72
- storeDropboxToken: () => storeToken,
80
+ useBackup: () => useBackup,
81
+ useBackupAuth: () => useBackupAuth,
73
82
  useChat: () => useChat,
74
83
  useChatStorage: () => useChatStorage,
75
84
  useDropboxAuth: () => useDropboxAuth,
76
85
  useDropboxBackup: () => useDropboxBackup,
77
86
  useEncryption: () => useEncryption,
87
+ useGoogleDriveAuth: () => useGoogleDriveAuth,
78
88
  useGoogleDriveBackup: () => useGoogleDriveBackup,
79
89
  useImageGeneration: () => useImageGeneration,
80
90
  useMemoryStorage: () => useMemoryStorage,
@@ -3065,6 +3075,36 @@ var postApiV1Search = (options) => {
3065
3075
  }
3066
3076
  });
3067
3077
  };
3078
+ var postAuthOauthByProviderExchange = (options) => {
3079
+ return (options.client ?? client).post({
3080
+ url: "/auth/oauth/{provider}/exchange",
3081
+ ...options,
3082
+ headers: {
3083
+ "Content-Type": "application/json",
3084
+ ...options.headers
3085
+ }
3086
+ });
3087
+ };
3088
+ var postAuthOauthByProviderRefresh = (options) => {
3089
+ return (options.client ?? client).post({
3090
+ url: "/auth/oauth/{provider}/refresh",
3091
+ ...options,
3092
+ headers: {
3093
+ "Content-Type": "application/json",
3094
+ ...options.headers
3095
+ }
3096
+ });
3097
+ };
3098
+ var postAuthOauthByProviderRevoke = (options) => {
3099
+ return (options.client ?? client).post({
3100
+ url: "/auth/oauth/{provider}/revoke",
3101
+ ...options,
3102
+ headers: {
3103
+ "Content-Type": "application/json",
3104
+ ...options.headers
3105
+ }
3106
+ });
3107
+ };
3068
3108
 
3069
3109
  // src/lib/memory/constants.ts
3070
3110
  var DEFAULT_LOCAL_EMBEDDING_MODEL = "Snowflake/snowflake-arctic-embed-xs";
@@ -4608,116 +4648,196 @@ async function performDropboxImport(userAddress, token, deps, onProgress, backup
4608
4648
  // src/react/useDropboxAuth.ts
4609
4649
  var import_react10 = require("react");
4610
4650
 
4611
- // src/lib/backup/dropbox/auth.ts
4612
- var DROPBOX_AUTH_URL = "https://www.dropbox.com/oauth2/authorize";
4613
- var DROPBOX_TOKEN_URL = "https://api.dropboxapi.com/oauth2/token";
4614
- var TOKEN_STORAGE_KEY = "dropbox_access_token";
4615
- var VERIFIER_STORAGE_KEY = "dropbox_code_verifier";
4616
- function generateCodeVerifier() {
4617
- const array = new Uint8Array(32);
4618
- crypto.getRandomValues(array);
4619
- return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
4651
+ // src/lib/backup/oauth/storage.ts
4652
+ var STORAGE_KEY_PREFIX = "oauth_token_";
4653
+ function getStorageKey2(provider) {
4654
+ return `${STORAGE_KEY_PREFIX}${provider}`;
4620
4655
  }
4621
- async function generateCodeChallenge(verifier) {
4622
- const encoder = new TextEncoder();
4623
- const data = encoder.encode(verifier);
4624
- const hash = await crypto.subtle.digest("SHA-256", data);
4625
- const base64 = btoa(String.fromCharCode(...new Uint8Array(hash)));
4626
- return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
4627
- }
4628
- function getStoredToken() {
4656
+ function getStoredTokenData(provider) {
4629
4657
  if (typeof window === "undefined") return null;
4630
- return sessionStorage.getItem(TOKEN_STORAGE_KEY);
4658
+ try {
4659
+ const stored = localStorage.getItem(getStorageKey2(provider));
4660
+ if (!stored) return null;
4661
+ const data = JSON.parse(stored);
4662
+ if (!data.accessToken) return null;
4663
+ return data;
4664
+ } catch {
4665
+ return null;
4666
+ }
4631
4667
  }
4632
- function storeToken(token) {
4668
+ function storeTokenData(provider, data) {
4633
4669
  if (typeof window === "undefined") return;
4634
- sessionStorage.setItem(TOKEN_STORAGE_KEY, token);
4670
+ localStorage.setItem(getStorageKey2(provider), JSON.stringify(data));
4635
4671
  }
4636
- function clearToken() {
4672
+ function clearTokenData(provider) {
4637
4673
  if (typeof window === "undefined") return;
4638
- sessionStorage.removeItem(TOKEN_STORAGE_KEY);
4674
+ localStorage.removeItem(getStorageKey2(provider));
4639
4675
  }
4640
- function getStoredVerifier() {
4641
- if (typeof window === "undefined") return null;
4642
- return sessionStorage.getItem(VERIFIER_STORAGE_KEY);
4676
+ function isTokenExpired(data, bufferSeconds = 60) {
4677
+ if (!data) return true;
4678
+ if (!data.expiresAt) return false;
4679
+ const now = Date.now();
4680
+ const bufferMs = bufferSeconds * 1e3;
4681
+ return data.expiresAt - bufferMs <= now;
4643
4682
  }
4644
- function storeVerifier(verifier) {
4645
- if (typeof window === "undefined") return;
4646
- sessionStorage.setItem(VERIFIER_STORAGE_KEY, verifier);
4683
+ function getValidAccessToken(provider) {
4684
+ const data = getStoredTokenData(provider);
4685
+ if (!data) return null;
4686
+ if (data.expiresAt && isTokenExpired(data)) {
4687
+ return null;
4688
+ }
4689
+ return data.accessToken;
4647
4690
  }
4648
- function clearVerifier() {
4649
- if (typeof window === "undefined") return;
4650
- sessionStorage.removeItem(VERIFIER_STORAGE_KEY);
4691
+ function getRefreshToken(provider) {
4692
+ const data = getStoredTokenData(provider);
4693
+ return data?.refreshToken ?? null;
4694
+ }
4695
+ function tokenResponseToStoredData(accessToken, expiresIn, refreshToken, scope) {
4696
+ const data = {
4697
+ accessToken,
4698
+ refreshToken,
4699
+ scope
4700
+ };
4701
+ if (expiresIn) {
4702
+ data.expiresAt = Date.now() + expiresIn * 1e3;
4703
+ }
4704
+ return data;
4651
4705
  }
4706
+
4707
+ // src/lib/backup/dropbox/auth.ts
4708
+ var PROVIDER = "dropbox";
4709
+ var STATE_STORAGE_KEY = "dropbox_oauth_state";
4710
+ var DROPBOX_AUTH_URL = "https://www.dropbox.com/oauth2/authorize";
4652
4711
  function getRedirectUri(callbackPath) {
4653
4712
  if (typeof window === "undefined") return "";
4654
4713
  return `${window.location.origin}${callbackPath}`;
4655
4714
  }
4656
- async function handleDropboxCallback(appKey, callbackPath) {
4715
+ function generateState() {
4716
+ const array = new Uint8Array(16);
4717
+ crypto.getRandomValues(array);
4718
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join(
4719
+ ""
4720
+ );
4721
+ }
4722
+ function storeOAuthState(state) {
4723
+ if (typeof window === "undefined") return;
4724
+ sessionStorage.setItem(STATE_STORAGE_KEY, state);
4725
+ }
4726
+ function getAndClearOAuthState() {
4727
+ if (typeof window === "undefined") return null;
4728
+ const state = sessionStorage.getItem(STATE_STORAGE_KEY);
4729
+ sessionStorage.removeItem(STATE_STORAGE_KEY);
4730
+ return state;
4731
+ }
4732
+ function isDropboxCallback() {
4733
+ if (typeof window === "undefined") return false;
4734
+ const url = new URL(window.location.href);
4735
+ const code = url.searchParams.get("code");
4736
+ const state = url.searchParams.get("state");
4737
+ const storedState = sessionStorage.getItem(STATE_STORAGE_KEY);
4738
+ return !!code && !!state && state === storedState;
4739
+ }
4740
+ async function handleDropboxCallback(callbackPath, apiClient) {
4657
4741
  if (typeof window === "undefined") return null;
4658
4742
  const url = new URL(window.location.href);
4659
4743
  const code = url.searchParams.get("code");
4660
4744
  const state = url.searchParams.get("state");
4661
- if (!code || state !== "dropbox_auth") return null;
4662
- const verifier = getStoredVerifier();
4663
- if (!verifier) return null;
4745
+ const storedState = getAndClearOAuthState();
4746
+ if (!code || !state || state !== storedState) {
4747
+ return null;
4748
+ }
4664
4749
  try {
4665
- const response = await fetch(DROPBOX_TOKEN_URL, {
4666
- method: "POST",
4667
- headers: {
4668
- "Content-Type": "application/x-www-form-urlencoded"
4669
- },
4670
- body: new URLSearchParams({
4750
+ const response = await postAuthOauthByProviderExchange({
4751
+ client: apiClient,
4752
+ path: { provider: PROVIDER },
4753
+ body: {
4671
4754
  code,
4672
- grant_type: "authorization_code",
4673
- client_id: appKey,
4674
- redirect_uri: getRedirectUri(callbackPath),
4675
- code_verifier: verifier
4676
- })
4755
+ redirect_uri: getRedirectUri(callbackPath)
4756
+ }
4677
4757
  });
4678
- if (!response.ok) {
4679
- throw new Error("Token exchange failed");
4680
- }
4681
- const data = await response.json();
4682
- const token = data.access_token;
4683
- if (typeof token !== "string" || token.trim() === "") {
4684
- throw new Error("Invalid token response: access_token is missing or empty");
4758
+ if (!response.data?.access_token) {
4759
+ throw new Error("No access token in response");
4685
4760
  }
4686
- storeToken(token);
4687
- clearVerifier();
4761
+ const tokenData = tokenResponseToStoredData(
4762
+ response.data.access_token,
4763
+ response.data.expires_in,
4764
+ response.data.refresh_token,
4765
+ response.data.scope
4766
+ );
4767
+ storeTokenData(PROVIDER, tokenData);
4688
4768
  window.history.replaceState({}, "", window.location.pathname);
4689
- return token;
4769
+ return response.data.access_token;
4690
4770
  } catch {
4691
- clearVerifier();
4692
4771
  return null;
4693
4772
  }
4694
4773
  }
4774
+ async function refreshDropboxToken(apiClient) {
4775
+ const refreshToken = getRefreshToken(PROVIDER);
4776
+ if (!refreshToken) return null;
4777
+ try {
4778
+ const response = await postAuthOauthByProviderRefresh({
4779
+ client: apiClient,
4780
+ path: { provider: PROVIDER },
4781
+ body: { refresh_token: refreshToken }
4782
+ });
4783
+ if (!response.data?.access_token) {
4784
+ throw new Error("No access token in refresh response");
4785
+ }
4786
+ const currentData = getStoredTokenData(PROVIDER);
4787
+ const tokenData = tokenResponseToStoredData(
4788
+ response.data.access_token,
4789
+ response.data.expires_in,
4790
+ response.data.refresh_token ?? currentData?.refreshToken,
4791
+ response.data.scope ?? currentData?.scope
4792
+ );
4793
+ storeTokenData(PROVIDER, tokenData);
4794
+ return response.data.access_token;
4795
+ } catch {
4796
+ clearTokenData(PROVIDER);
4797
+ return null;
4798
+ }
4799
+ }
4800
+ async function revokeDropboxToken(apiClient) {
4801
+ const tokenData = getStoredTokenData(PROVIDER);
4802
+ if (!tokenData) return;
4803
+ try {
4804
+ const tokenToRevoke = tokenData.refreshToken ?? tokenData.accessToken;
4805
+ await postAuthOauthByProviderRevoke({
4806
+ client: apiClient,
4807
+ path: { provider: PROVIDER },
4808
+ body: { token: tokenToRevoke }
4809
+ });
4810
+ } catch {
4811
+ } finally {
4812
+ clearTokenData(PROVIDER);
4813
+ }
4814
+ }
4815
+ async function getDropboxAccessToken(apiClient) {
4816
+ const validToken = getValidAccessToken(PROVIDER);
4817
+ if (validToken) return validToken;
4818
+ return refreshDropboxToken(apiClient);
4819
+ }
4695
4820
  async function startDropboxAuth(appKey, callbackPath) {
4696
- const verifier = generateCodeVerifier();
4697
- const challenge = await generateCodeChallenge(verifier);
4698
- storeVerifier(verifier);
4821
+ const state = generateState();
4822
+ storeOAuthState(state);
4699
4823
  const params = new URLSearchParams({
4700
4824
  client_id: appKey,
4701
4825
  redirect_uri: getRedirectUri(callbackPath),
4702
4826
  response_type: "code",
4703
- code_challenge: challenge,
4704
- code_challenge_method: "S256",
4705
- state: "dropbox_auth",
4827
+ state,
4706
4828
  token_access_type: "offline"
4829
+ // Request refresh token
4707
4830
  });
4708
4831
  window.location.href = `${DROPBOX_AUTH_URL}?${params.toString()}`;
4709
4832
  return new Promise(() => {
4710
4833
  });
4711
4834
  }
4712
- async function requestDropboxAccess(appKey, callbackPath) {
4713
- if (!appKey) {
4714
- throw new Error("Dropbox is not configured");
4715
- }
4716
- const storedToken = getStoredToken();
4717
- if (storedToken) {
4718
- return storedToken;
4719
- }
4720
- return startDropboxAuth(appKey, callbackPath);
4835
+ function clearToken() {
4836
+ clearTokenData(PROVIDER);
4837
+ }
4838
+ function hasDropboxCredentials() {
4839
+ const data = getStoredTokenData(PROVIDER);
4840
+ return !!(data?.accessToken || data?.refreshToken);
4721
4841
  }
4722
4842
 
4723
4843
  // src/react/useDropboxAuth.ts
@@ -4725,26 +4845,41 @@ var DropboxAuthContext = (0, import_react10.createContext)(null);
4725
4845
  function DropboxAuthProvider({
4726
4846
  appKey,
4727
4847
  callbackPath = "/auth/dropbox/callback",
4848
+ apiClient,
4728
4849
  children
4729
4850
  }) {
4730
4851
  const [accessToken, setAccessToken] = (0, import_react10.useState)(null);
4731
4852
  const isConfigured = !!appKey;
4732
4853
  (0, import_react10.useEffect)(() => {
4733
- const storedToken = getStoredToken();
4734
- if (storedToken) {
4735
- setAccessToken(storedToken);
4736
- }
4737
- }, []);
4854
+ const checkStoredToken = async () => {
4855
+ if (hasDropboxCredentials()) {
4856
+ const token = await getDropboxAccessToken(apiClient);
4857
+ if (token) {
4858
+ setAccessToken(token);
4859
+ }
4860
+ }
4861
+ };
4862
+ checkStoredToken();
4863
+ }, [apiClient]);
4738
4864
  (0, import_react10.useEffect)(() => {
4739
- if (!isConfigured || !appKey) return;
4865
+ if (!isConfigured) return;
4740
4866
  const handleCallback = async () => {
4741
- const token = await handleDropboxCallback(appKey, callbackPath);
4742
- if (token) {
4743
- setAccessToken(token);
4867
+ if (isDropboxCallback()) {
4868
+ const token = await handleDropboxCallback(callbackPath, apiClient);
4869
+ if (token) {
4870
+ setAccessToken(token);
4871
+ }
4744
4872
  }
4745
4873
  };
4746
4874
  handleCallback();
4747
- }, [appKey, callbackPath, isConfigured]);
4875
+ }, [callbackPath, isConfigured, apiClient]);
4876
+ const refreshTokenFn = (0, import_react10.useCallback)(async () => {
4877
+ const token = await getDropboxAccessToken(apiClient);
4878
+ if (token) {
4879
+ setAccessToken(token);
4880
+ }
4881
+ return token;
4882
+ }, [apiClient]);
4748
4883
  const requestAccess = (0, import_react10.useCallback)(async () => {
4749
4884
  if (!isConfigured || !appKey) {
4750
4885
  throw new Error("Dropbox is not configured");
@@ -4752,17 +4887,17 @@ function DropboxAuthProvider({
4752
4887
  if (accessToken) {
4753
4888
  return accessToken;
4754
4889
  }
4755
- const storedToken = getStoredToken();
4890
+ const storedToken = await getDropboxAccessToken(apiClient);
4756
4891
  if (storedToken) {
4757
4892
  setAccessToken(storedToken);
4758
4893
  return storedToken;
4759
4894
  }
4760
- return requestDropboxAccess(appKey, callbackPath);
4761
- }, [accessToken, appKey, callbackPath, isConfigured]);
4762
- const logout = (0, import_react10.useCallback)(() => {
4763
- clearToken();
4895
+ return startDropboxAuth(appKey, callbackPath);
4896
+ }, [accessToken, appKey, callbackPath, isConfigured, apiClient]);
4897
+ const logout = (0, import_react10.useCallback)(async () => {
4898
+ await revokeDropboxToken(apiClient);
4764
4899
  setAccessToken(null);
4765
- }, []);
4900
+ }, [apiClient]);
4766
4901
  return (0, import_react10.createElement)(
4767
4902
  DropboxAuthContext.Provider,
4768
4903
  {
@@ -4771,7 +4906,8 @@ function DropboxAuthProvider({
4771
4906
  isAuthenticated: !!accessToken,
4772
4907
  isConfigured,
4773
4908
  requestAccess,
4774
- logout
4909
+ logout,
4910
+ refreshToken: refreshTokenFn
4775
4911
  }
4776
4912
  },
4777
4913
  children
@@ -4798,25 +4934,25 @@ function useDropboxBackup(options) {
4798
4934
  const {
4799
4935
  accessToken: dropboxToken,
4800
4936
  isConfigured: isDropboxConfigured,
4801
- requestAccess: requestDropboxAccess2
4937
+ requestAccess: requestDropboxAccess
4802
4938
  } = useDropboxAuth();
4803
4939
  const deps = (0, import_react11.useMemo)(
4804
4940
  () => ({
4805
- requestDropboxAccess: requestDropboxAccess2,
4941
+ requestDropboxAccess,
4806
4942
  requestEncryptionKey: requestEncryptionKey2,
4807
4943
  exportConversation,
4808
4944
  importConversation
4809
4945
  }),
4810
- [requestDropboxAccess2, requestEncryptionKey2, exportConversation, importConversation]
4946
+ [requestDropboxAccess, requestEncryptionKey2, exportConversation, importConversation]
4811
4947
  );
4812
4948
  const ensureToken = (0, import_react11.useCallback)(async () => {
4813
4949
  if (dropboxToken) return dropboxToken;
4814
4950
  try {
4815
- return await requestDropboxAccess2();
4951
+ return await requestDropboxAccess();
4816
4952
  } catch {
4817
4953
  return null;
4818
4954
  }
4819
- }, [dropboxToken, requestDropboxAccess2]);
4955
+ }, [dropboxToken, requestDropboxAccess]);
4820
4956
  const backup = (0, import_react11.useCallback)(
4821
4957
  async (backupOptions) => {
4822
4958
  if (!userAddress) {
@@ -4876,9 +5012,241 @@ function useDropboxBackup(options) {
4876
5012
  };
4877
5013
  }
4878
5014
 
4879
- // src/react/useGoogleDriveBackup.ts
5015
+ // src/react/useGoogleDriveAuth.ts
4880
5016
  var import_react12 = require("react");
4881
5017
 
5018
+ // src/lib/backup/google/auth.ts
5019
+ var PROVIDER2 = "google-drive";
5020
+ var CODE_STORAGE_KEY = "google_oauth_state";
5021
+ var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
5022
+ var DRIVE_SCOPES = [
5023
+ "https://www.googleapis.com/auth/drive.file"
5024
+ // Access to files created by the app
5025
+ ].join(" ");
5026
+ function getRedirectUri2(callbackPath) {
5027
+ if (typeof window === "undefined") return "";
5028
+ return `${window.location.origin}${callbackPath}`;
5029
+ }
5030
+ function generateState2() {
5031
+ const array = new Uint8Array(16);
5032
+ crypto.getRandomValues(array);
5033
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join(
5034
+ ""
5035
+ );
5036
+ }
5037
+ function storeOAuthState2(state) {
5038
+ if (typeof window === "undefined") return;
5039
+ sessionStorage.setItem(CODE_STORAGE_KEY, state);
5040
+ }
5041
+ function getAndClearOAuthState2() {
5042
+ if (typeof window === "undefined") return null;
5043
+ const state = sessionStorage.getItem(CODE_STORAGE_KEY);
5044
+ sessionStorage.removeItem(CODE_STORAGE_KEY);
5045
+ return state;
5046
+ }
5047
+ function isGoogleDriveCallback() {
5048
+ if (typeof window === "undefined") return false;
5049
+ const url = new URL(window.location.href);
5050
+ const code = url.searchParams.get("code");
5051
+ const state = url.searchParams.get("state");
5052
+ const storedState = sessionStorage.getItem(CODE_STORAGE_KEY);
5053
+ return !!code && !!state && state === storedState;
5054
+ }
5055
+ async function handleGoogleDriveCallback(callbackPath, apiClient) {
5056
+ if (typeof window === "undefined") return null;
5057
+ const url = new URL(window.location.href);
5058
+ const code = url.searchParams.get("code");
5059
+ const state = url.searchParams.get("state");
5060
+ const storedState = getAndClearOAuthState2();
5061
+ if (!code || !state || state !== storedState) {
5062
+ return null;
5063
+ }
5064
+ try {
5065
+ const response = await postAuthOauthByProviderExchange({
5066
+ client: apiClient,
5067
+ path: { provider: PROVIDER2 },
5068
+ body: {
5069
+ code,
5070
+ redirect_uri: getRedirectUri2(callbackPath)
5071
+ }
5072
+ });
5073
+ if (!response.data?.access_token) {
5074
+ throw new Error("No access token in response");
5075
+ }
5076
+ const tokenData = tokenResponseToStoredData(
5077
+ response.data.access_token,
5078
+ response.data.expires_in,
5079
+ response.data.refresh_token,
5080
+ response.data.scope
5081
+ );
5082
+ storeTokenData(PROVIDER2, tokenData);
5083
+ window.history.replaceState({}, "", window.location.pathname);
5084
+ return response.data.access_token;
5085
+ } catch {
5086
+ return null;
5087
+ }
5088
+ }
5089
+ async function refreshGoogleDriveToken(apiClient) {
5090
+ const refreshToken = getRefreshToken(PROVIDER2);
5091
+ if (!refreshToken) return null;
5092
+ try {
5093
+ const response = await postAuthOauthByProviderRefresh({
5094
+ client: apiClient,
5095
+ path: { provider: PROVIDER2 },
5096
+ body: { refresh_token: refreshToken }
5097
+ });
5098
+ if (!response.data?.access_token) {
5099
+ throw new Error("No access token in refresh response");
5100
+ }
5101
+ const currentData = getStoredTokenData(PROVIDER2);
5102
+ const tokenData = tokenResponseToStoredData(
5103
+ response.data.access_token,
5104
+ response.data.expires_in,
5105
+ response.data.refresh_token ?? currentData?.refreshToken,
5106
+ response.data.scope ?? currentData?.scope
5107
+ );
5108
+ storeTokenData(PROVIDER2, tokenData);
5109
+ return response.data.access_token;
5110
+ } catch {
5111
+ clearTokenData(PROVIDER2);
5112
+ return null;
5113
+ }
5114
+ }
5115
+ async function revokeGoogleDriveToken(apiClient) {
5116
+ const tokenData = getStoredTokenData(PROVIDER2);
5117
+ if (!tokenData) return;
5118
+ try {
5119
+ const tokenToRevoke = tokenData.refreshToken ?? tokenData.accessToken;
5120
+ await postAuthOauthByProviderRevoke({
5121
+ client: apiClient,
5122
+ path: { provider: PROVIDER2 },
5123
+ body: { token: tokenToRevoke }
5124
+ });
5125
+ } catch {
5126
+ } finally {
5127
+ clearTokenData(PROVIDER2);
5128
+ }
5129
+ }
5130
+ async function getGoogleDriveAccessToken(apiClient) {
5131
+ const validToken = getValidAccessToken(PROVIDER2);
5132
+ if (validToken) return validToken;
5133
+ return refreshGoogleDriveToken(apiClient);
5134
+ }
5135
+ async function startGoogleDriveAuth(clientId, callbackPath) {
5136
+ const state = generateState2();
5137
+ storeOAuthState2(state);
5138
+ const params = new URLSearchParams({
5139
+ client_id: clientId,
5140
+ redirect_uri: getRedirectUri2(callbackPath),
5141
+ response_type: "code",
5142
+ scope: DRIVE_SCOPES,
5143
+ state,
5144
+ access_type: "offline",
5145
+ // Request refresh token
5146
+ prompt: "consent"
5147
+ // Force consent to always get refresh token
5148
+ });
5149
+ window.location.href = `${GOOGLE_AUTH_URL}?${params.toString()}`;
5150
+ return new Promise(() => {
5151
+ });
5152
+ }
5153
+ function getGoogleDriveStoredToken() {
5154
+ return getValidAccessToken(PROVIDER2);
5155
+ }
5156
+ function clearGoogleDriveToken() {
5157
+ clearTokenData(PROVIDER2);
5158
+ }
5159
+ function hasGoogleDriveCredentials() {
5160
+ const data = getStoredTokenData(PROVIDER2);
5161
+ return !!(data?.accessToken || data?.refreshToken);
5162
+ }
5163
+
5164
+ // src/react/useGoogleDriveAuth.ts
5165
+ var GoogleDriveAuthContext = (0, import_react12.createContext)(null);
5166
+ function GoogleDriveAuthProvider({
5167
+ clientId,
5168
+ callbackPath = "/auth/google/callback",
5169
+ apiClient,
5170
+ children
5171
+ }) {
5172
+ const [accessToken, setAccessToken] = (0, import_react12.useState)(null);
5173
+ const isConfigured = !!clientId;
5174
+ (0, import_react12.useEffect)(() => {
5175
+ const checkStoredToken = async () => {
5176
+ if (hasGoogleDriveCredentials()) {
5177
+ const token = await getGoogleDriveAccessToken(apiClient);
5178
+ if (token) {
5179
+ setAccessToken(token);
5180
+ }
5181
+ }
5182
+ };
5183
+ checkStoredToken();
5184
+ }, [apiClient]);
5185
+ (0, import_react12.useEffect)(() => {
5186
+ if (!isConfigured) return;
5187
+ const handleCallback = async () => {
5188
+ if (isGoogleDriveCallback()) {
5189
+ const token = await handleGoogleDriveCallback(callbackPath, apiClient);
5190
+ if (token) {
5191
+ setAccessToken(token);
5192
+ }
5193
+ }
5194
+ };
5195
+ handleCallback();
5196
+ }, [callbackPath, isConfigured, apiClient]);
5197
+ const refreshTokenFn = (0, import_react12.useCallback)(async () => {
5198
+ const token = await getGoogleDriveAccessToken(apiClient);
5199
+ if (token) {
5200
+ setAccessToken(token);
5201
+ }
5202
+ return token;
5203
+ }, [apiClient]);
5204
+ const requestAccess = (0, import_react12.useCallback)(async () => {
5205
+ if (!isConfigured || !clientId) {
5206
+ throw new Error("Google Drive is not configured");
5207
+ }
5208
+ if (accessToken) {
5209
+ return accessToken;
5210
+ }
5211
+ const storedToken = await getGoogleDriveAccessToken(apiClient);
5212
+ if (storedToken) {
5213
+ setAccessToken(storedToken);
5214
+ return storedToken;
5215
+ }
5216
+ return startGoogleDriveAuth(clientId, callbackPath);
5217
+ }, [accessToken, clientId, callbackPath, isConfigured, apiClient]);
5218
+ const logout = (0, import_react12.useCallback)(async () => {
5219
+ await revokeGoogleDriveToken(apiClient);
5220
+ setAccessToken(null);
5221
+ }, [apiClient]);
5222
+ return (0, import_react12.createElement)(
5223
+ GoogleDriveAuthContext.Provider,
5224
+ {
5225
+ value: {
5226
+ accessToken,
5227
+ isAuthenticated: !!accessToken,
5228
+ isConfigured,
5229
+ requestAccess,
5230
+ logout,
5231
+ refreshToken: refreshTokenFn
5232
+ }
5233
+ },
5234
+ children
5235
+ );
5236
+ }
5237
+ function useGoogleDriveAuth() {
5238
+ const context = (0, import_react12.useContext)(GoogleDriveAuthContext);
5239
+ if (!context) {
5240
+ throw new Error(
5241
+ "useGoogleDriveAuth must be used within GoogleDriveAuthProvider"
5242
+ );
5243
+ }
5244
+ return context;
5245
+ }
5246
+
5247
+ // src/react/useGoogleDriveBackup.ts
5248
+ var import_react13 = require("react");
5249
+
4882
5250
  // src/lib/backup/google/api.ts
4883
5251
  var DRIVE_API_URL = "https://www.googleapis.com/drive/v3";
4884
5252
  var DRIVE_UPLOAD_URL = "https://www.googleapis.com/upload/drive/v3";
@@ -5184,37 +5552,35 @@ function useGoogleDriveBackup(options) {
5184
5552
  const {
5185
5553
  database,
5186
5554
  userAddress,
5187
- accessToken,
5188
- requestDriveAccess,
5189
5555
  requestEncryptionKey: requestEncryptionKey2,
5190
5556
  exportConversation,
5191
5557
  importConversation,
5192
5558
  rootFolder = DEFAULT_ROOT_FOLDER,
5193
5559
  conversationsFolder = DEFAULT_CONVERSATIONS_FOLDER
5194
5560
  } = options;
5195
- const deps = (0, import_react12.useMemo)(
5561
+ const {
5562
+ accessToken: driveToken,
5563
+ isConfigured: isDriveConfigured,
5564
+ requestAccess: requestDriveAccess
5565
+ } = useGoogleDriveAuth();
5566
+ const deps = (0, import_react13.useMemo)(
5196
5567
  () => ({
5197
5568
  requestDriveAccess,
5198
5569
  requestEncryptionKey: requestEncryptionKey2,
5199
5570
  exportConversation,
5200
5571
  importConversation
5201
5572
  }),
5202
- [
5203
- requestDriveAccess,
5204
- requestEncryptionKey2,
5205
- exportConversation,
5206
- importConversation
5207
- ]
5573
+ [requestDriveAccess, requestEncryptionKey2, exportConversation, importConversation]
5208
5574
  );
5209
- const ensureToken = (0, import_react12.useCallback)(async () => {
5210
- if (accessToken) return accessToken;
5575
+ const ensureToken = (0, import_react13.useCallback)(async () => {
5576
+ if (driveToken) return driveToken;
5211
5577
  try {
5212
5578
  return await requestDriveAccess();
5213
5579
  } catch {
5214
5580
  return null;
5215
5581
  }
5216
- }, [accessToken, requestDriveAccess]);
5217
- const backup = (0, import_react12.useCallback)(
5582
+ }, [driveToken, requestDriveAccess]);
5583
+ const backup = (0, import_react13.useCallback)(
5218
5584
  async (backupOptions) => {
5219
5585
  if (!userAddress) {
5220
5586
  return { error: "Please sign in to backup to Google Drive" };
@@ -5241,7 +5607,7 @@ function useGoogleDriveBackup(options) {
5241
5607
  },
5242
5608
  [database, userAddress, ensureToken, deps, rootFolder, conversationsFolder]
5243
5609
  );
5244
- const restore = (0, import_react12.useCallback)(
5610
+ const restore = (0, import_react13.useCallback)(
5245
5611
  async (restoreOptions) => {
5246
5612
  if (!userAddress) {
5247
5613
  return { error: "Please sign in to restore from Google Drive" };
@@ -5270,23 +5636,394 @@ function useGoogleDriveBackup(options) {
5270
5636
  return {
5271
5637
  backup,
5272
5638
  restore,
5273
- isAuthenticated: !!accessToken
5639
+ isConfigured: isDriveConfigured,
5640
+ isAuthenticated: !!driveToken
5641
+ };
5642
+ }
5643
+
5644
+ // src/react/useBackupAuth.ts
5645
+ var import_react14 = require("react");
5646
+ var BackupAuthContext = (0, import_react14.createContext)(null);
5647
+ function BackupAuthProvider({
5648
+ dropboxAppKey,
5649
+ dropboxCallbackPath = "/auth/dropbox/callback",
5650
+ googleClientId,
5651
+ googleCallbackPath = "/auth/google/callback",
5652
+ apiClient,
5653
+ children
5654
+ }) {
5655
+ const [dropboxToken, setDropboxToken] = (0, import_react14.useState)(null);
5656
+ const isDropboxConfigured = !!dropboxAppKey;
5657
+ const [googleToken, setGoogleToken] = (0, import_react14.useState)(null);
5658
+ const isGoogleConfigured = !!googleClientId;
5659
+ (0, import_react14.useEffect)(() => {
5660
+ const checkStoredTokens = async () => {
5661
+ if (hasDropboxCredentials()) {
5662
+ const token = await getDropboxAccessToken(apiClient);
5663
+ if (token) {
5664
+ setDropboxToken(token);
5665
+ }
5666
+ }
5667
+ if (hasGoogleDriveCredentials()) {
5668
+ const token = await getGoogleDriveAccessToken(apiClient);
5669
+ if (token) {
5670
+ setGoogleToken(token);
5671
+ }
5672
+ }
5673
+ };
5674
+ checkStoredTokens();
5675
+ }, [apiClient]);
5676
+ (0, import_react14.useEffect)(() => {
5677
+ if (!isDropboxConfigured) return;
5678
+ const handleCallback = async () => {
5679
+ if (isDropboxCallback()) {
5680
+ const token = await handleDropboxCallback(
5681
+ dropboxCallbackPath,
5682
+ apiClient
5683
+ );
5684
+ if (token) {
5685
+ setDropboxToken(token);
5686
+ }
5687
+ }
5688
+ };
5689
+ handleCallback();
5690
+ }, [dropboxCallbackPath, isDropboxConfigured, apiClient]);
5691
+ (0, import_react14.useEffect)(() => {
5692
+ if (!isGoogleConfigured) return;
5693
+ const handleCallback = async () => {
5694
+ if (isGoogleDriveCallback()) {
5695
+ const token = await handleGoogleDriveCallback(
5696
+ googleCallbackPath,
5697
+ apiClient
5698
+ );
5699
+ if (token) {
5700
+ setGoogleToken(token);
5701
+ }
5702
+ }
5703
+ };
5704
+ handleCallback();
5705
+ }, [googleCallbackPath, isGoogleConfigured, apiClient]);
5706
+ const refreshDropboxTokenFn = (0, import_react14.useCallback)(async () => {
5707
+ const token = await getDropboxAccessToken(apiClient);
5708
+ if (token) {
5709
+ setDropboxToken(token);
5710
+ }
5711
+ return token;
5712
+ }, [apiClient]);
5713
+ const requestDropboxAccess = (0, import_react14.useCallback)(async () => {
5714
+ if (!isDropboxConfigured || !dropboxAppKey) {
5715
+ throw new Error("Dropbox is not configured");
5716
+ }
5717
+ if (dropboxToken) {
5718
+ return dropboxToken;
5719
+ }
5720
+ const storedToken = await getDropboxAccessToken(apiClient);
5721
+ if (storedToken) {
5722
+ setDropboxToken(storedToken);
5723
+ return storedToken;
5724
+ }
5725
+ return startDropboxAuth(dropboxAppKey, dropboxCallbackPath);
5726
+ }, [
5727
+ dropboxToken,
5728
+ dropboxAppKey,
5729
+ dropboxCallbackPath,
5730
+ isDropboxConfigured,
5731
+ apiClient
5732
+ ]);
5733
+ const logoutDropbox = (0, import_react14.useCallback)(async () => {
5734
+ await revokeDropboxToken(apiClient);
5735
+ setDropboxToken(null);
5736
+ }, [apiClient]);
5737
+ const refreshGoogleTokenFn = (0, import_react14.useCallback)(async () => {
5738
+ const token = await getGoogleDriveAccessToken(apiClient);
5739
+ if (token) {
5740
+ setGoogleToken(token);
5741
+ }
5742
+ return token;
5743
+ }, [apiClient]);
5744
+ const requestGoogleAccess = (0, import_react14.useCallback)(async () => {
5745
+ if (!isGoogleConfigured || !googleClientId) {
5746
+ throw new Error("Google Drive is not configured");
5747
+ }
5748
+ if (googleToken) {
5749
+ return googleToken;
5750
+ }
5751
+ const storedToken = await getGoogleDriveAccessToken(apiClient);
5752
+ if (storedToken) {
5753
+ setGoogleToken(storedToken);
5754
+ return storedToken;
5755
+ }
5756
+ return startGoogleDriveAuth(googleClientId, googleCallbackPath);
5757
+ }, [
5758
+ googleToken,
5759
+ googleClientId,
5760
+ googleCallbackPath,
5761
+ isGoogleConfigured,
5762
+ apiClient
5763
+ ]);
5764
+ const logoutGoogle = (0, import_react14.useCallback)(async () => {
5765
+ await revokeGoogleDriveToken(apiClient);
5766
+ setGoogleToken(null);
5767
+ }, [apiClient]);
5768
+ const logoutAll = (0, import_react14.useCallback)(async () => {
5769
+ await Promise.all([
5770
+ isDropboxConfigured ? logoutDropbox() : Promise.resolve(),
5771
+ isGoogleConfigured ? logoutGoogle() : Promise.resolve()
5772
+ ]);
5773
+ }, [isDropboxConfigured, isGoogleConfigured, logoutDropbox, logoutGoogle]);
5774
+ const dropboxState = {
5775
+ accessToken: dropboxToken,
5776
+ isAuthenticated: !!dropboxToken,
5777
+ isConfigured: isDropboxConfigured,
5778
+ requestAccess: requestDropboxAccess,
5779
+ logout: logoutDropbox,
5780
+ refreshToken: refreshDropboxTokenFn
5781
+ };
5782
+ const googleDriveState = {
5783
+ accessToken: googleToken,
5784
+ isAuthenticated: !!googleToken,
5785
+ isConfigured: isGoogleConfigured,
5786
+ requestAccess: requestGoogleAccess,
5787
+ logout: logoutGoogle,
5788
+ refreshToken: refreshGoogleTokenFn
5789
+ };
5790
+ return (0, import_react14.createElement)(
5791
+ BackupAuthContext.Provider,
5792
+ {
5793
+ value: {
5794
+ dropbox: dropboxState,
5795
+ googleDrive: googleDriveState,
5796
+ hasAnyProvider: isDropboxConfigured || isGoogleConfigured,
5797
+ hasAnyAuthentication: !!dropboxToken || !!googleToken,
5798
+ logoutAll
5799
+ }
5800
+ },
5801
+ children
5802
+ );
5803
+ }
5804
+ function useBackupAuth() {
5805
+ const context = (0, import_react14.useContext)(BackupAuthContext);
5806
+ if (!context) {
5807
+ throw new Error("useBackupAuth must be used within BackupAuthProvider");
5808
+ }
5809
+ return context;
5810
+ }
5811
+
5812
+ // src/react/useBackup.ts
5813
+ var import_react15 = require("react");
5814
+ function useBackup(options) {
5815
+ const {
5816
+ database,
5817
+ userAddress,
5818
+ requestEncryptionKey: requestEncryptionKey2,
5819
+ exportConversation,
5820
+ importConversation,
5821
+ dropboxFolder = DEFAULT_BACKUP_FOLDER,
5822
+ googleRootFolder = DEFAULT_ROOT_FOLDER,
5823
+ googleConversationsFolder = DEFAULT_CONVERSATIONS_FOLDER
5824
+ } = options;
5825
+ const {
5826
+ dropbox: dropboxAuth,
5827
+ googleDrive: googleDriveAuth,
5828
+ hasAnyProvider,
5829
+ hasAnyAuthentication,
5830
+ logoutAll
5831
+ } = useBackupAuth();
5832
+ const dropboxDeps = (0, import_react15.useMemo)(
5833
+ () => ({
5834
+ requestDropboxAccess: dropboxAuth.requestAccess,
5835
+ requestEncryptionKey: requestEncryptionKey2,
5836
+ exportConversation,
5837
+ importConversation
5838
+ }),
5839
+ [dropboxAuth.requestAccess, requestEncryptionKey2, exportConversation, importConversation]
5840
+ );
5841
+ const googleDriveDeps = (0, import_react15.useMemo)(
5842
+ () => ({
5843
+ requestDriveAccess: googleDriveAuth.requestAccess,
5844
+ requestEncryptionKey: requestEncryptionKey2,
5845
+ exportConversation,
5846
+ importConversation
5847
+ }),
5848
+ [googleDriveAuth.requestAccess, requestEncryptionKey2, exportConversation, importConversation]
5849
+ );
5850
+ const dropboxBackup = (0, import_react15.useCallback)(
5851
+ async (backupOptions) => {
5852
+ if (!userAddress) {
5853
+ return { error: "Please sign in to backup to Dropbox" };
5854
+ }
5855
+ let token = dropboxAuth.accessToken;
5856
+ if (!token) {
5857
+ try {
5858
+ token = await dropboxAuth.requestAccess();
5859
+ } catch {
5860
+ return { error: "Dropbox access denied" };
5861
+ }
5862
+ }
5863
+ try {
5864
+ return await performDropboxExport(
5865
+ database,
5866
+ userAddress,
5867
+ token,
5868
+ dropboxDeps,
5869
+ backupOptions?.onProgress,
5870
+ dropboxFolder
5871
+ );
5872
+ } catch (err) {
5873
+ return {
5874
+ error: err instanceof Error ? err.message : "Failed to backup to Dropbox"
5875
+ };
5876
+ }
5877
+ },
5878
+ [database, userAddress, dropboxAuth, dropboxDeps, dropboxFolder]
5879
+ );
5880
+ const dropboxRestore = (0, import_react15.useCallback)(
5881
+ async (restoreOptions) => {
5882
+ if (!userAddress) {
5883
+ return { error: "Please sign in to restore from Dropbox" };
5884
+ }
5885
+ let token = dropboxAuth.accessToken;
5886
+ if (!token) {
5887
+ try {
5888
+ token = await dropboxAuth.requestAccess();
5889
+ } catch {
5890
+ return { error: "Dropbox access denied" };
5891
+ }
5892
+ }
5893
+ try {
5894
+ return await performDropboxImport(
5895
+ userAddress,
5896
+ token,
5897
+ dropboxDeps,
5898
+ restoreOptions?.onProgress,
5899
+ dropboxFolder
5900
+ );
5901
+ } catch (err) {
5902
+ return {
5903
+ error: err instanceof Error ? err.message : "Failed to restore from Dropbox"
5904
+ };
5905
+ }
5906
+ },
5907
+ [userAddress, dropboxAuth, dropboxDeps, dropboxFolder]
5908
+ );
5909
+ const googleDriveBackup = (0, import_react15.useCallback)(
5910
+ async (backupOptions) => {
5911
+ if (!userAddress) {
5912
+ return { error: "Please sign in to backup to Google Drive" };
5913
+ }
5914
+ let token = googleDriveAuth.accessToken;
5915
+ if (!token) {
5916
+ try {
5917
+ token = await googleDriveAuth.requestAccess();
5918
+ } catch {
5919
+ return { error: "Google Drive access denied" };
5920
+ }
5921
+ }
5922
+ try {
5923
+ return await performGoogleDriveExport(
5924
+ database,
5925
+ userAddress,
5926
+ token,
5927
+ googleDriveDeps,
5928
+ backupOptions?.onProgress,
5929
+ googleRootFolder,
5930
+ googleConversationsFolder
5931
+ );
5932
+ } catch (err) {
5933
+ return {
5934
+ error: err instanceof Error ? err.message : "Failed to backup to Google Drive"
5935
+ };
5936
+ }
5937
+ },
5938
+ [
5939
+ database,
5940
+ userAddress,
5941
+ googleDriveAuth,
5942
+ googleDriveDeps,
5943
+ googleRootFolder,
5944
+ googleConversationsFolder
5945
+ ]
5946
+ );
5947
+ const googleDriveRestore = (0, import_react15.useCallback)(
5948
+ async (restoreOptions) => {
5949
+ if (!userAddress) {
5950
+ return { error: "Please sign in to restore from Google Drive" };
5951
+ }
5952
+ let token = googleDriveAuth.accessToken;
5953
+ if (!token) {
5954
+ try {
5955
+ token = await googleDriveAuth.requestAccess();
5956
+ } catch {
5957
+ return { error: "Google Drive access denied" };
5958
+ }
5959
+ }
5960
+ try {
5961
+ return await performGoogleDriveImport(
5962
+ userAddress,
5963
+ token,
5964
+ googleDriveDeps,
5965
+ restoreOptions?.onProgress,
5966
+ googleRootFolder,
5967
+ googleConversationsFolder
5968
+ );
5969
+ } catch (err) {
5970
+ return {
5971
+ error: err instanceof Error ? err.message : "Failed to restore from Google Drive"
5972
+ };
5973
+ }
5974
+ },
5975
+ [
5976
+ userAddress,
5977
+ googleDriveAuth,
5978
+ googleDriveDeps,
5979
+ googleRootFolder,
5980
+ googleConversationsFolder
5981
+ ]
5982
+ );
5983
+ const dropboxState = {
5984
+ isConfigured: dropboxAuth.isConfigured,
5985
+ isAuthenticated: dropboxAuth.isAuthenticated,
5986
+ backup: dropboxBackup,
5987
+ restore: dropboxRestore,
5988
+ connect: dropboxAuth.requestAccess,
5989
+ disconnect: dropboxAuth.logout
5990
+ };
5991
+ const googleDriveState = {
5992
+ isConfigured: googleDriveAuth.isConfigured,
5993
+ isAuthenticated: googleDriveAuth.isAuthenticated,
5994
+ backup: googleDriveBackup,
5995
+ restore: googleDriveRestore,
5996
+ connect: googleDriveAuth.requestAccess,
5997
+ disconnect: googleDriveAuth.logout
5998
+ };
5999
+ return {
6000
+ dropbox: dropboxState,
6001
+ googleDrive: googleDriveState,
6002
+ hasAnyProvider,
6003
+ hasAnyAuthentication,
6004
+ disconnectAll: logoutAll
5274
6005
  };
5275
6006
  }
5276
6007
  // Annotate the CommonJS export names for ESM import in node:
5277
6008
  0 && (module.exports = {
6009
+ BACKUP_DRIVE_CONVERSATIONS_FOLDER,
6010
+ BACKUP_DRIVE_ROOT_FOLDER,
6011
+ BackupAuthProvider,
5278
6012
  ChatConversation,
5279
6013
  ChatMessage,
5280
6014
  DEFAULT_BACKUP_FOLDER,
5281
6015
  DEFAULT_DRIVE_CONVERSATIONS_FOLDER,
5282
6016
  DEFAULT_DRIVE_ROOT_FOLDER,
6017
+ DEFAULT_DROPBOX_FOLDER,
5283
6018
  DEFAULT_TOOL_SELECTOR_MODEL,
5284
6019
  DropboxAuthProvider,
6020
+ GoogleDriveAuthProvider,
5285
6021
  StoredMemoryModel,
5286
6022
  StoredModelPreferenceModel,
5287
6023
  chatStorageMigrations,
5288
6024
  chatStorageSchema,
5289
6025
  clearDropboxToken,
6026
+ clearGoogleDriveToken,
5290
6027
  createMemoryContextSystemMessage,
5291
6028
  decryptData,
5292
6029
  decryptDataBytes,
@@ -5297,8 +6034,10 @@ function useGoogleDriveBackup(options) {
5297
6034
  generateCompositeKey,
5298
6035
  generateConversationId,
5299
6036
  generateUniqueKey,
5300
- getDropboxToken,
6037
+ getGoogleDriveStoredToken,
6038
+ hasDropboxCredentials,
5301
6039
  hasEncryptionKey,
6040
+ hasGoogleDriveCredentials,
5302
6041
  memoryStorageSchema,
5303
6042
  requestEncryptionKey,
5304
6043
  sdkMigrations,
@@ -5306,12 +6045,14 @@ function useGoogleDriveBackup(options) {
5306
6045
  sdkSchema,
5307
6046
  selectTool,
5308
6047
  settingsStorageSchema,
5309
- storeDropboxToken,
6048
+ useBackup,
6049
+ useBackupAuth,
5310
6050
  useChat,
5311
6051
  useChatStorage,
5312
6052
  useDropboxAuth,
5313
6053
  useDropboxBackup,
5314
6054
  useEncryption,
6055
+ useGoogleDriveAuth,
5315
6056
  useGoogleDriveBackup,
5316
6057
  useImageGeneration,
5317
6058
  useMemoryStorage,