@rebasepro/client-firebase 0.0.1-canary.4d4fb3e

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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -0
  3. package/dist/components/FirebaseLoginView.d.ts +72 -0
  4. package/dist/components/RebaseFirebaseApp.d.ts +19 -0
  5. package/dist/components/RebaseFirebaseAppProps.d.ts +144 -0
  6. package/dist/components/index.d.ts +3 -0
  7. package/dist/components/social_icons.d.ts +6 -0
  8. package/dist/hooks/index.d.ts +7 -0
  9. package/dist/hooks/useAppCheck.d.ts +20 -0
  10. package/dist/hooks/useFirebaseAuthController.d.ts +15 -0
  11. package/dist/hooks/useFirebaseRealTimeDBDelegate.d.ts +5 -0
  12. package/dist/hooks/useFirebaseStorageSource.d.ts +14 -0
  13. package/dist/hooks/useFirestoreDriver.d.ts +56 -0
  14. package/dist/hooks/useInitialiseFirebase.d.ts +34 -0
  15. package/dist/hooks/useRecaptcha.d.ts +8 -0
  16. package/dist/index.d.ts +4 -0
  17. package/dist/index.es.js +2757 -0
  18. package/dist/index.es.js.map +1 -0
  19. package/dist/index.umd.js +2743 -0
  20. package/dist/index.umd.js.map +1 -0
  21. package/dist/social_icons.d.ts +6 -0
  22. package/dist/types/appcheck.d.ts +10 -0
  23. package/dist/types/auth.d.ts +41 -0
  24. package/dist/types/index.d.ts +3 -0
  25. package/dist/types/text_search.d.ts +39 -0
  26. package/dist/utils/algolia.d.ts +9 -0
  27. package/dist/utils/collections_firestore.d.ts +5 -0
  28. package/dist/utils/database.d.ts +2 -0
  29. package/dist/utils/index.d.ts +7 -0
  30. package/dist/utils/local_text_search_controller.d.ts +2 -0
  31. package/dist/utils/pinecone.d.ts +24 -0
  32. package/dist/utils/rebase_search_controller.d.ts +73 -0
  33. package/dist/utils/text_search_controller.d.ts +13 -0
  34. package/package.json +61 -0
  35. package/src/components/FirebaseLoginView.tsx +703 -0
  36. package/src/components/RebaseFirebaseApp.tsx +275 -0
  37. package/src/components/RebaseFirebaseAppProps.tsx +180 -0
  38. package/src/components/index.ts +3 -0
  39. package/src/components/social_icons.tsx +135 -0
  40. package/src/hooks/index.ts +7 -0
  41. package/src/hooks/useAppCheck.ts +101 -0
  42. package/src/hooks/useFirebaseAuthController.ts +334 -0
  43. package/src/hooks/useFirebaseRealTimeDBDelegate.ts +269 -0
  44. package/src/hooks/useFirebaseStorageSource.ts +208 -0
  45. package/src/hooks/useFirestoreDriver.ts +778 -0
  46. package/src/hooks/useInitialiseFirebase.ts +132 -0
  47. package/src/hooks/useRecaptcha.tsx +28 -0
  48. package/src/index.ts +4 -0
  49. package/src/social_icons.tsx +135 -0
  50. package/src/types/appcheck.ts +11 -0
  51. package/src/types/auth.tsx +74 -0
  52. package/src/types/index.ts +3 -0
  53. package/src/types/text_search.ts +42 -0
  54. package/src/utils/algolia.ts +27 -0
  55. package/src/utils/collections_firestore.ts +149 -0
  56. package/src/utils/database.ts +39 -0
  57. package/src/utils/index.ts +7 -0
  58. package/src/utils/local_text_search_controller.ts +143 -0
  59. package/src/utils/pinecone.ts +75 -0
  60. package/src/utils/rebase_search_controller.ts +356 -0
  61. package/src/utils/text_search_controller.ts +34 -0
@@ -0,0 +1,2757 @@
1
+ import React, { useState, useCallback, useRef, useEffect } from "react";
2
+ import { deepEqual } from "fast-equals";
3
+ import { getAuth, onAuthStateChanged, GoogleAuthProvider, signInWithPopup, signInWithEmailAndPassword, createUserWithEmailAndPassword, sendPasswordResetEmail, fetchSignInMethodsForEmail, signOut, signInAnonymously, signInWithPhoneNumber, OAuthProvider, FacebookAuthProvider, GithubAuthProvider, TwitterAuthProvider, RecaptchaVerifier, getMultiFactorResolver, PhoneMultiFactorGenerator, PhoneAuthProvider } from "@firebase/auth";
4
+ import { getStorage, ref, deleteObject, list, getDownloadURL, getMetadata, uploadBytesResumable } from "@firebase/storage";
5
+ import { getApps, deleteApp, initializeApp } from "@firebase/app";
6
+ import { getToken, initializeAppCheck } from "@firebase/app-check";
7
+ import { GeoPoint, EntityReference } from "@rebasepro/types";
8
+ import { getFirestore, query, collection, limit, getDocs, onSnapshot, deleteField, doc, GeoPoint as GeoPoint$1, Timestamp, vector, serverTimestamp, VectorValue, DocumentReference, where, orderBy, startAfter, getDoc, getCountFromServer, deleteDoc, setDoc } from "@firebase/firestore";
9
+ import { stripCollectionPath, COLLECTION_PATH_SEPARATOR, sortProperties, buildRebaseData } from "@rebasepro/common";
10
+ import Fuse from "fuse.js";
11
+ import { getFunctions, httpsCallable } from "@firebase/functions";
12
+ import { c } from "react-compiler-runtime";
13
+ import { getDatabase, query as query$1, ref as ref$1, orderByKey, startAt, limitToFirst, get, onValue, push, set, remove, orderByChild } from "@firebase/database";
14
+ import { jsx, Fragment, jsxs } from "react/jsx-runtime";
15
+ import { useModeController, ErrorView, useSnackbarController, RebaseLogo, useBrowserTitleAndIcon, useBuildModeController, useBuildAdminModeController, useBuildLocalConfigurationPersistence, useValidateAuthenticator, RebaseRoutes, Rebase, AdminModeControllerProvider, SnackbarProvider, ModeControllerProvider } from "@rebasepro/core";
16
+ import { useBuildCollectionRegistryController, useBuildUrlController, useBuildNavigationStateController, NavigationStateContext, UrlContext, CollectionRegistryContext, Scaffold, AppBar, Drawer, SideDialogs } from "@rebasepro/cms";
17
+ import { MailIcon, CallIcon, PersonIcon, Button, cls, IconButton, ArrowBackIcon, Typography, TextField, CircularProgress, LoadingButton, CircularProgressCenter, CenteredView } from "@rebasepro/ui";
18
+ import { Routes, Route, Outlet } from "react-router-dom";
19
+ const useFirebaseAuthController = ({
20
+ loading,
21
+ firebaseApp,
22
+ signInOptions,
23
+ onSignOut: onSignOutProp,
24
+ defineRolesFor
25
+ }) => {
26
+ const [loggedUser, setLoggedUser] = useState(void 0);
27
+ const [authError, setAuthError] = useState();
28
+ const [authProviderError, setAuthProviderError] = useState();
29
+ const [initialLoading, setInitialLoading] = useState(true);
30
+ const [authLoading, setAuthLoading] = useState(true);
31
+ const [loginSkipped, setLoginSkipped] = useState(false);
32
+ const [confirmationResult, setConfirmationResult] = useState();
33
+ const [userRoles, _setUserRoles] = useState();
34
+ const [extra, setExtra] = useState();
35
+ const setUserRoles = useCallback((roles) => {
36
+ const currentRoleIds = userRoles?.map((r) => r.id);
37
+ const newRoleIds = roles?.map((r_0) => r_0.id);
38
+ if (!deepEqual(currentRoleIds, newRoleIds)) {
39
+ _setUserRoles(roles);
40
+ }
41
+ }, [userRoles]);
42
+ const authRef = useRef(null);
43
+ const updateUser = useCallback(async (user, initialize) => {
44
+ if (loading) return;
45
+ if (defineRolesFor && user) {
46
+ setUserRoles(await defineRolesFor(user));
47
+ }
48
+ setLoggedUser(user);
49
+ setAuthLoading(false);
50
+ if (initialize) {
51
+ setInitialLoading(false);
52
+ }
53
+ }, [loading]);
54
+ const updateRoles = useCallback(async (user_0) => {
55
+ if (defineRolesFor && user_0) {
56
+ const userRoles_0 = await defineRolesFor(user_0);
57
+ if (!deepEqual(userRoles_0, userRoles_0)) {
58
+ setUserRoles(userRoles_0);
59
+ }
60
+ }
61
+ }, [defineRolesFor, userRoles]);
62
+ useEffect(() => {
63
+ if (updateRoles && loggedUser) {
64
+ updateRoles(loggedUser);
65
+ }
66
+ }, [updateRoles, loggedUser]);
67
+ useEffect(() => {
68
+ if (!firebaseApp) return;
69
+ try {
70
+ const auth = getAuth(firebaseApp);
71
+ authRef.current = auth;
72
+ setAuthError(void 0);
73
+ updateUser(auth.currentUser, false);
74
+ return onAuthStateChanged(auth, async (user_1) => {
75
+ console.debug("User state changed", user_1);
76
+ await updateUser(user_1, true);
77
+ }, (error) => setAuthProviderError(error));
78
+ } catch (e) {
79
+ setAuthError(e);
80
+ setInitialLoading(false);
81
+ return () => {
82
+ };
83
+ }
84
+ }, [firebaseApp, updateUser]);
85
+ useEffect(() => {
86
+ if (!loading && authRef.current) {
87
+ updateUser(authRef.current.currentUser, false);
88
+ }
89
+ }, [loading, updateUser]);
90
+ const getProviderOptions = useCallback((providerId) => {
91
+ return signInOptions?.find((option) => {
92
+ if (option === null) throw Error("useFirebaseAuthController");
93
+ if (typeof option === "object" && option.provider === providerId) return option;
94
+ return void 0;
95
+ });
96
+ }, []);
97
+ const googleLogin = useCallback(() => {
98
+ const provider = new GoogleAuthProvider();
99
+ const options = getProviderOptions("google.com");
100
+ if (options?.scopes) options.scopes.forEach((scope) => provider.addScope(scope));
101
+ if (options?.customParameters) {
102
+ provider.setCustomParameters(options.customParameters);
103
+ } else {
104
+ provider.setCustomParameters({
105
+ prompt: "select_account"
106
+ });
107
+ }
108
+ const auth_0 = authRef.current;
109
+ if (!auth_0) throw Error("No auth");
110
+ signInWithPopup(auth_0, provider).catch(setAuthProviderError);
111
+ }, [getProviderOptions]);
112
+ const getAuthToken = useCallback(async () => {
113
+ if (!loggedUser) throw Error("No client user is logged in");
114
+ if (!loggedUser.getIdToken) {
115
+ throw Error("No getIdToken method available");
116
+ }
117
+ return loggedUser.getIdToken?.();
118
+ }, [loggedUser]);
119
+ const emailPasswordLogin = useCallback((email, password) => {
120
+ const auth_1 = authRef.current;
121
+ if (!auth_1) throw Error("No auth");
122
+ setAuthLoading(true);
123
+ signInWithEmailAndPassword(auth_1, email, password).catch(setAuthProviderError).then(() => setAuthLoading(false));
124
+ }, []);
125
+ const createUserWithEmailAndPassword$1 = useCallback((email_0, password_0) => {
126
+ const auth_2 = authRef.current;
127
+ if (!auth_2) throw Error("No auth");
128
+ setAuthLoading(true);
129
+ createUserWithEmailAndPassword(auth_2, email_0, password_0).catch(setAuthProviderError).then(() => setAuthLoading(false));
130
+ }, []);
131
+ const sendPasswordResetEmail$1 = useCallback((email_1) => {
132
+ const auth_3 = authRef.current;
133
+ if (!auth_3) throw Error("No auth");
134
+ return sendPasswordResetEmail(auth_3, email_1);
135
+ }, []);
136
+ const fetchSignInMethodsForEmail$1 = useCallback((email_2) => {
137
+ const auth_4 = authRef.current;
138
+ if (!auth_4) throw Error("No auth");
139
+ setAuthLoading(true);
140
+ return fetchSignInMethodsForEmail(auth_4, email_2).then((res) => {
141
+ setAuthLoading(false);
142
+ return res;
143
+ });
144
+ }, []);
145
+ const onSignOut = useCallback(async () => {
146
+ const auth_5 = authRef.current;
147
+ if (!auth_5) throw Error("No auth");
148
+ await signOut(auth_5).then((_) => {
149
+ setLoggedUser(null);
150
+ setUserRoles(void 0);
151
+ setAuthProviderError(null);
152
+ onSignOutProp?.();
153
+ });
154
+ setLoginSkipped(false);
155
+ }, [onSignOutProp]);
156
+ const doOauthLogin = useCallback((auth_6, provider_0) => {
157
+ setAuthLoading(true);
158
+ signInWithPopup(auth_6, provider_0).catch(setAuthProviderError).then(() => setAuthLoading(false));
159
+ }, []);
160
+ const anonymousLogin = useCallback(() => {
161
+ const auth_7 = authRef.current;
162
+ if (!auth_7) throw Error("No auth");
163
+ setAuthLoading(true);
164
+ signInAnonymously(auth_7).catch(setAuthProviderError).then(() => setAuthLoading(false));
165
+ }, []);
166
+ const phoneLogin = useCallback((phone, applicationVerifier) => {
167
+ const auth_8 = authRef.current;
168
+ if (!auth_8) throw Error("No auth");
169
+ setAuthLoading(true);
170
+ return signInWithPhoneNumber(auth_8, phone, applicationVerifier).catch(setAuthProviderError).then((res_0) => {
171
+ setAuthLoading(false);
172
+ setConfirmationResult(res_0 ?? void 0);
173
+ });
174
+ }, []);
175
+ const appleLogin = useCallback(() => {
176
+ const provider_1 = new OAuthProvider("apple.com");
177
+ const options_0 = getProviderOptions("apple.com");
178
+ if (options_0?.scopes) options_0.scopes.forEach((scope_0) => provider_1.addScope(scope_0));
179
+ if (options_0?.customParameters) provider_1.setCustomParameters(options_0.customParameters);
180
+ const auth_9 = authRef.current;
181
+ if (!auth_9) throw Error("No auth");
182
+ doOauthLogin(auth_9, provider_1);
183
+ }, [doOauthLogin, getProviderOptions]);
184
+ const facebookLogin = useCallback(() => {
185
+ const provider_2 = new FacebookAuthProvider();
186
+ const options_1 = getProviderOptions("facebook.com");
187
+ if (options_1?.scopes) options_1.scopes.forEach((scope_1) => provider_2.addScope(scope_1));
188
+ if (options_1?.customParameters) provider_2.setCustomParameters(options_1.customParameters);
189
+ const auth_10 = authRef.current;
190
+ if (!auth_10) throw Error("No auth");
191
+ doOauthLogin(auth_10, provider_2);
192
+ }, [doOauthLogin, getProviderOptions]);
193
+ const githubLogin = useCallback(() => {
194
+ const provider_3 = new GithubAuthProvider();
195
+ const options_2 = getProviderOptions("github.com");
196
+ if (options_2?.scopes) options_2.scopes.forEach((scope_2) => provider_3.addScope(scope_2));
197
+ if (options_2?.customParameters) provider_3.setCustomParameters(options_2.customParameters);
198
+ const auth_11 = authRef.current;
199
+ if (!auth_11) throw Error("No auth");
200
+ doOauthLogin(auth_11, provider_3);
201
+ }, [doOauthLogin, getProviderOptions]);
202
+ const microsoftLogin = useCallback(() => {
203
+ const provider_4 = new OAuthProvider("microsoft.com");
204
+ const options_3 = getProviderOptions("microsoft.com");
205
+ if (options_3?.scopes) options_3.scopes.forEach((scope_3) => provider_4.addScope(scope_3));
206
+ if (options_3?.customParameters) provider_4.setCustomParameters(options_3.customParameters);
207
+ const auth_12 = authRef.current;
208
+ if (!auth_12) throw Error("No auth");
209
+ doOauthLogin(auth_12, provider_4);
210
+ }, [doOauthLogin, getProviderOptions]);
211
+ const twitterLogin = useCallback(() => {
212
+ const provider_5 = new TwitterAuthProvider();
213
+ const options_4 = getProviderOptions("twitter.com");
214
+ if (options_4?.customParameters) provider_5.setCustomParameters(options_4.customParameters);
215
+ const auth_13 = authRef.current;
216
+ if (!auth_13) throw Error("No auth");
217
+ doOauthLogin(auth_13, provider_5);
218
+ }, [doOauthLogin, getProviderOptions]);
219
+ const skipLogin = useCallback(() => {
220
+ setLoginSkipped(true);
221
+ setLoggedUser(null);
222
+ setUserRoles(void 0);
223
+ }, []);
224
+ const firebaseUserWrapper = loggedUser ? {
225
+ ...loggedUser,
226
+ roles: userRoles?.map((r_1) => r_1.id),
227
+ // User.roles is string[], keep Role[] internally only
228
+ firebaseUser: loggedUser
229
+ } : null;
230
+ return {
231
+ user: firebaseUserWrapper,
232
+ setUser: updateUser,
233
+ setUserRoles,
234
+ authProviderError,
235
+ authLoading,
236
+ initialLoading: loading || initialLoading,
237
+ signOut: onSignOut,
238
+ getAuthToken,
239
+ googleLogin,
240
+ skipLogin,
241
+ loginSkipped,
242
+ emailPasswordLogin,
243
+ createUserWithEmailAndPassword: createUserWithEmailAndPassword$1,
244
+ sendPasswordResetEmail: sendPasswordResetEmail$1,
245
+ fetchSignInMethodsForEmail: fetchSignInMethodsForEmail$1,
246
+ anonymousLogin,
247
+ phoneLogin,
248
+ appleLogin,
249
+ facebookLogin,
250
+ githubLogin,
251
+ microsoftLogin,
252
+ twitterLogin,
253
+ confirmationResult,
254
+ extra,
255
+ setExtra
256
+ };
257
+ };
258
+ function useFirebaseStorageSource({
259
+ firebaseApp,
260
+ bucketUrl
261
+ }) {
262
+ const projectId = firebaseApp?.options?.projectId;
263
+ const urlsCache = {};
264
+ return {
265
+ uploadFile({
266
+ file,
267
+ fileName,
268
+ path,
269
+ metadata,
270
+ bucket
271
+ }) {
272
+ try {
273
+ if (!firebaseApp) throw Error("useFirebaseStorageSource Firebase not initialised");
274
+ const storageBucketUrl = bucket ?? bucketUrl;
275
+ const storage = getStorage(firebaseApp, storageBucketUrl);
276
+ if (!storage) throw Error("useFirebaseStorageSource Firebase not initialised");
277
+ const usedFilename = fileName ?? file.name;
278
+ const storageRef = ref(storage, `${path}/${usedFilename}`);
279
+ const uploadTask = uploadBytesResumable(storageRef, file, metadata);
280
+ return new Promise((resolve, reject) => {
281
+ let lastProgress = 0;
282
+ let timeoutId = null;
283
+ const clearTimeoutIfExists = () => {
284
+ if (timeoutId) {
285
+ clearTimeout(timeoutId);
286
+ timeoutId = null;
287
+ }
288
+ };
289
+ const setProgressTimeout = () => {
290
+ clearTimeoutIfExists();
291
+ timeoutId = setTimeout(() => {
292
+ uploadTask.cancel();
293
+ reject(new Error(`Upload failed - This is likely a CORS configuration issue. Make sure Firebase Storage is enabled in your project: https://console.firebase.google.com/u/0/project/${projectId}/storage. If it is, check Firebase Storage CORS settings.`));
294
+ }, 5e3);
295
+ };
296
+ setProgressTimeout();
297
+ uploadTask.on("state_changed", (snapshot) => {
298
+ const progress = snapshot.bytesTransferred / snapshot.totalBytes * 100;
299
+ if (progress > lastProgress) {
300
+ lastProgress = progress;
301
+ setProgressTimeout();
302
+ }
303
+ }, (error) => {
304
+ clearTimeoutIfExists();
305
+ console.error("Firebase Storage upload error:", error);
306
+ let errorMessage = "Unknown upload error";
307
+ if (error?.message) {
308
+ errorMessage = error.message;
309
+ } else if (typeof error === "string") {
310
+ errorMessage = error;
311
+ } else if (error?.code) {
312
+ errorMessage = error.code;
313
+ }
314
+ if (error?.code === "storage/unauthorized") {
315
+ reject(new Error("Unauthorized: Check Firebase Storage security rules"));
316
+ } else if (error?.code === "storage/canceled") {
317
+ reject(new Error("Upload canceled"));
318
+ } else if (error?.code === "storage/unknown" || !error?.code) {
319
+ reject(new Error("Upload failed - Check Firebase Storage CORS configuration or network connection"));
320
+ } else if (errorMessage.toLowerCase().includes("network")) {
321
+ reject(new Error("Network error: Check your internet connection"));
322
+ } else {
323
+ const newError = Object.assign(new Error(errorMessage), {
324
+ code: error?.code
325
+ });
326
+ reject(newError);
327
+ }
328
+ }, () => {
329
+ clearTimeoutIfExists();
330
+ const fullPath = uploadTask.snapshot.ref.fullPath;
331
+ const bucketName = uploadTask.snapshot.ref.bucket;
332
+ resolve({
333
+ path: fullPath,
334
+ bucket: bucketName,
335
+ storageUrl: `gs://${bucketName}/${fullPath}`
336
+ });
337
+ });
338
+ });
339
+ } catch (error) {
340
+ return Promise.reject(error);
341
+ }
342
+ },
343
+ async getFile(path, bucket) {
344
+ try {
345
+ if (!firebaseApp) throw Error("useFirebaseStorageSource Firebase not initialised");
346
+ const storageBucketUrl = bucket ?? bucketUrl;
347
+ const storage = getStorage(firebaseApp, storageBucketUrl);
348
+ if (!storage) throw Error("useFirebaseStorageSource Firebase not initialised");
349
+ const fileRef = ref(storage, path);
350
+ const url = await getDownloadURL(fileRef);
351
+ const response = await fetch(url);
352
+ const blob = await response.blob();
353
+ return new File([blob], path);
354
+ } catch (e) {
355
+ if (e?.code === "storage/object-not-found") return null;
356
+ throw e;
357
+ }
358
+ },
359
+ async getDownloadURL(storagePathOrUrl, bucket) {
360
+ if (!firebaseApp) throw Error("useFirebaseStorageSource Firebase not initialised");
361
+ let resolvedPathOrUrl = storagePathOrUrl;
362
+ let resolvedBucket = bucket;
363
+ if (storagePathOrUrl.startsWith("gs://")) {
364
+ const withoutProtocol = storagePathOrUrl.substring("gs://".length);
365
+ const firstSlash = withoutProtocol.indexOf("/");
366
+ if (firstSlash > 0) {
367
+ resolvedBucket = withoutProtocol.substring(0, firstSlash);
368
+ resolvedPathOrUrl = withoutProtocol.substring(firstSlash + 1);
369
+ }
370
+ }
371
+ const storageBucketUrl = resolvedBucket ?? bucketUrl;
372
+ const storage = getStorage(firebaseApp, storageBucketUrl);
373
+ if (!storage) throw Error("useFirebaseStorageSource Firebase not initialised");
374
+ if (urlsCache[storagePathOrUrl]) return urlsCache[storagePathOrUrl];
375
+ try {
376
+ const fileRef = ref(storage, resolvedPathOrUrl);
377
+ const [url, metadata] = await Promise.all([getDownloadURL(fileRef), getMetadata(fileRef)]);
378
+ const result = {
379
+ url,
380
+ metadata
381
+ };
382
+ urlsCache[storagePathOrUrl] = result;
383
+ return result;
384
+ } catch (e) {
385
+ if (e?.code === "storage/object-not-found") return {
386
+ url: null,
387
+ fileNotFound: true
388
+ };
389
+ throw e;
390
+ }
391
+ },
392
+ async list(path, options) {
393
+ if (!firebaseApp) throw Error("useFirebaseStorageSource Firebase not initialised");
394
+ const storageBucketUrl = options?.bucket ?? bucketUrl;
395
+ const storage = getStorage(firebaseApp, storageBucketUrl);
396
+ if (!storage) throw Error("useFirebaseStorageSource Firebase not initialised");
397
+ const folderRef = ref(storage, path);
398
+ return await list(folderRef, {
399
+ maxResults: options?.maxResults,
400
+ pageToken: options?.pageToken
401
+ });
402
+ },
403
+ async deleteFile(path, bucket) {
404
+ if (!firebaseApp) throw Error("useFirebaseStorageSource Firebase not initialised");
405
+ const storageBucketUrl = bucket ?? bucketUrl;
406
+ const storage = getStorage(firebaseApp, storageBucketUrl);
407
+ if (!storage) throw Error("useFirebaseStorageSource Firebase not initialised");
408
+ const fileRef = ref(storage, path);
409
+ return deleteObject(fileRef);
410
+ }
411
+ };
412
+ }
413
+ const hostingError = "It seems like the provided Firebase config is not correct. If you \nare using the credentials provided automatically by Firebase \nHosting, make sure you link your Firebase app to Firebase Hosting. \n";
414
+ function useInitialiseFirebase({
415
+ firebaseConfig,
416
+ fromUrl,
417
+ onFirebaseInit,
418
+ name,
419
+ authDomain
420
+ }) {
421
+ const [firebaseApp, setFirebaseApp] = useState();
422
+ const [firebaseConfigLoading, setFirebaseConfigLoading] = useState(false);
423
+ const [configError, setConfigError] = useState();
424
+ const initFirebase = useCallback((config) => {
425
+ if (config.projectId === firebaseApp?.options.projectId) {
426
+ console.debug("Firebase app already initialised with the same project ID. This should happen only in development mode.");
427
+ setConfigError(void 0);
428
+ setFirebaseConfigLoading(false);
429
+ return;
430
+ }
431
+ try {
432
+ const targetName = name ?? "[DEFAULT]";
433
+ const currentApps = getApps();
434
+ const existingApp = currentApps.find((app) => app.name === targetName);
435
+ if (existingApp) {
436
+ deleteApp(existingApp);
437
+ }
438
+ const initialisedFirebaseApp = initializeApp(config, targetName);
439
+ setConfigError(void 0);
440
+ setFirebaseConfigLoading(false);
441
+ setFirebaseApp(initialisedFirebaseApp);
442
+ } catch (e) {
443
+ console.error("Error initialising Firebase", e);
444
+ setConfigError(hostingError + "\n" + (e.message ?? JSON.stringify(e)));
445
+ }
446
+ }, [name]);
447
+ useEffect(() => {
448
+ if (onFirebaseInit && firebaseConfig && firebaseApp) {
449
+ onFirebaseInit(firebaseConfig, firebaseApp);
450
+ }
451
+ }, [firebaseApp]);
452
+ useEffect(() => {
453
+ setFirebaseConfigLoading(true);
454
+ function fetchFromUrl(url) {
455
+ fetch(url).then(async (response) => {
456
+ console.debug("Firebase init response", response.status);
457
+ if (response && response.status < 300) {
458
+ const config_0 = await response.json();
459
+ if (authDomain) config_0.authDomain = authDomain;
460
+ initFirebase(config_0);
461
+ }
462
+ }).catch((e_0) => {
463
+ setFirebaseConfigLoading(false);
464
+ setConfigError("Could not load Firebase configuration from Firebase hosting. If the app is not deployed in Firebase hosting, you need to specify the configuration manually" + e_0.toString());
465
+ });
466
+ }
467
+ if (firebaseConfig) {
468
+ initFirebase(firebaseConfig);
469
+ } else {
470
+ if (fromUrl) {
471
+ fetchFromUrl(fromUrl);
472
+ } else if (process.env.NODE_ENV === "production") {
473
+ fetchFromUrl("/__/firebase/init.json");
474
+ } else {
475
+ setFirebaseConfigLoading(false);
476
+ setConfigError("You need to deploy the app to Firebase hosting or specify a Firebase configuration object");
477
+ }
478
+ }
479
+ }, []);
480
+ return {
481
+ firebaseApp,
482
+ firebaseConfigLoading,
483
+ configError
484
+ };
485
+ }
486
+ function useAppCheck({
487
+ firebaseApp,
488
+ options
489
+ }) {
490
+ if (options?.debugToken) {
491
+ Object.assign(window, {
492
+ FIREBASE_APPCHECK_DEBUG_TOKEN: options?.debugToken
493
+ });
494
+ }
495
+ const [appCheckLoading, setAppCheckLoading] = React.useState(false);
496
+ const [appCheckVerified, setAppCheckVerified] = React.useState(void 0);
497
+ const [error, setError] = React.useState();
498
+ const initialCheck = useRef(false);
499
+ const verifyToken = useCallback(async (appCheck) => {
500
+ console.debug("Verifying App Check token...", appCheck);
501
+ try {
502
+ const token = await getToken(appCheck, options?.forceRefresh);
503
+ console.debug("App Check token:", token);
504
+ if (!token) {
505
+ setError("App Check failed.");
506
+ setAppCheckVerified(false);
507
+ } else {
508
+ setAppCheckVerified(true);
509
+ console.debug("App Check success.");
510
+ }
511
+ } catch (e) {
512
+ console.error("App Check error:", e);
513
+ setError(e.message);
514
+ }
515
+ }, [options?.forceRefresh]);
516
+ useEffect(() => {
517
+ if (!options) return;
518
+ if (!firebaseApp) return;
519
+ if (appCheckVerified !== void 0) return;
520
+ if (initialCheck.current) return;
521
+ setAppCheckLoading(true);
522
+ const {
523
+ provider,
524
+ isTokenAutoRefreshEnabled
525
+ } = options;
526
+ removeCurrentAppCheckDiv();
527
+ const appCheck_0 = initializeAppCheck(firebaseApp, {
528
+ provider,
529
+ isTokenAutoRefreshEnabled
530
+ });
531
+ verifyToken(appCheck_0).then(() => {
532
+ setAppCheckLoading(false);
533
+ });
534
+ initialCheck.current = true;
535
+ }, [appCheckVerified, firebaseApp, options, verifyToken]);
536
+ return {
537
+ loading: appCheckLoading,
538
+ appCheckVerified,
539
+ error
540
+ };
541
+ }
542
+ function removeCurrentAppCheckDiv() {
543
+ const div = document.getElementById("fire_app_check_[DEFAULT]");
544
+ if (div) {
545
+ div.remove();
546
+ }
547
+ }
548
+ function buildCollectionId(idOrPath, parentCollectionIds) {
549
+ if (!parentCollectionIds) return stripCollectionPath(idOrPath);
550
+ return [...parentCollectionIds.map(stripCollectionPath), stripCollectionPath(idOrPath)].join(COLLECTION_PATH_SEPARATOR);
551
+ }
552
+ const docsToCollectionTree = (docs) => {
553
+ const collectionsMap = docs.map((doc2) => {
554
+ const id = doc2.id;
555
+ const collection2 = docToCollection(doc2);
556
+ return {
557
+ [id]: collection2
558
+ };
559
+ }).reduce((a, b) => ({
560
+ ...a,
561
+ ...b
562
+ }), {});
563
+ const orderedKeys = Object.keys(collectionsMap).sort((a, b) => b.split(COLLECTION_PATH_SEPARATOR).length - a.split(COLLECTION_PATH_SEPARATOR).length);
564
+ orderedKeys.forEach((id) => {
565
+ const collection2 = collectionsMap[id];
566
+ if (id.includes(COLLECTION_PATH_SEPARATOR)) {
567
+ const parentId = id.split(COLLECTION_PATH_SEPARATOR).slice(0, -1).join(COLLECTION_PATH_SEPARATOR);
568
+ const parentCollection = collectionsMap[parentId];
569
+ if (parentCollection) parentCollection.subcollections = () => [...parentCollection.subcollections?.() ?? [], collection2];
570
+ delete collectionsMap[id];
571
+ }
572
+ });
573
+ return Object.values(collectionsMap);
574
+ };
575
+ const docToCollection = (doc2) => {
576
+ const data = doc2.data();
577
+ if (!data) throw Error("Entity collection has not been persisted correctly");
578
+ const propertiesOrder = data.propertiesOrder;
579
+ const properties = data.properties ?? {};
580
+ const normalizedProperties = normalizePropertiesEnumValues(properties, true);
581
+ const sortedProperties = sortProperties(normalizedProperties, propertiesOrder);
582
+ return {
583
+ ...data,
584
+ properties: sortedProperties,
585
+ slug: data.id ?? data.alias ?? data.slug
586
+ };
587
+ };
588
+ function normalizeEnumValuesToArray(enumValues, sortObjectFormat = false) {
589
+ if (Array.isArray(enumValues)) {
590
+ return enumValues;
591
+ } else if (typeof enumValues === "object" && enumValues !== null) {
592
+ const entries = Object.entries(enumValues).map(([id, value]) => typeof value === "string" ? {
593
+ id,
594
+ label: value
595
+ } : {
596
+ ...value,
597
+ id
598
+ });
599
+ if (sortObjectFormat) {
600
+ entries.sort((a, b) => String(a.id).localeCompare(String(b.id)));
601
+ }
602
+ return entries;
603
+ }
604
+ return [];
605
+ }
606
+ function normalizePropertiesEnumValues(properties, sortObjectFormat = false) {
607
+ const result = {};
608
+ Object.entries(properties).forEach(([key, property]) => {
609
+ if (typeof property === "object" && property !== null) {
610
+ const normalizedProperty = {
611
+ ...property
612
+ };
613
+ if (normalizedProperty.enum) {
614
+ normalizedProperty.enum = normalizeEnumValuesToArray(normalizedProperty.enum, sortObjectFormat);
615
+ }
616
+ if (normalizedProperty.dataType === "array" && typeof normalizedProperty.of === "object" && normalizedProperty.of !== null) {
617
+ const ofProp = normalizedProperty.of;
618
+ if (ofProp.enum) {
619
+ normalizedProperty.of = {
620
+ ...ofProp,
621
+ enum: normalizeEnumValuesToArray(ofProp.enum, sortObjectFormat)
622
+ };
623
+ }
624
+ }
625
+ if (normalizedProperty.dataType === "map" && normalizedProperty.properties) {
626
+ normalizedProperty.properties = normalizePropertiesEnumValues(normalizedProperty.properties, sortObjectFormat);
627
+ }
628
+ result[key] = normalizedProperty;
629
+ } else {
630
+ result[key] = property;
631
+ }
632
+ });
633
+ return result;
634
+ }
635
+ async function getFirestoreDataInPath(firebaseApp, path, parentPaths, limit$1) {
636
+ const firestore = getFirestore(firebaseApp);
637
+ if (!parentPaths || parentPaths.length === 0) {
638
+ const q = query(collection(firestore, path), limit(limit$1));
639
+ return getDocs(q).then((querySnapshot) => {
640
+ return querySnapshot.docs.map((doc2) => doc2.data());
641
+ });
642
+ } else {
643
+ let currentDocs = void 0;
644
+ let index = 0;
645
+ const allPaths = parentPaths;
646
+ allPaths.push(path);
647
+ let parentPath = allPaths[0];
648
+ while (parentPath) {
649
+ if (currentDocs) {
650
+ currentDocs = (await Promise.all(currentDocs.map(async (doc2) => {
651
+ const q = query(collection(firestore, doc2.ref.path, parentPath), limit(5));
652
+ return (await getDocs(q)).docs;
653
+ }))).flat();
654
+ } else {
655
+ const q = query(collection(firestore, parentPath), limit(5));
656
+ currentDocs = (await getDocs(q)).docs;
657
+ }
658
+ index++;
659
+ parentPath = index < allPaths.length ? allPaths[index] : void 0;
660
+ }
661
+ return currentDocs ? currentDocs.map((doc2) => doc2.data()) : [];
662
+ }
663
+ }
664
+ function performAlgoliaTextSearch(client, indexName, query2) {
665
+ console.debug("Performing Algolia query", client, query2);
666
+ return client.searchSingleIndex({
667
+ indexName,
668
+ searchParams: {
669
+ query: query2
670
+ }
671
+ }).then(({
672
+ hits
673
+ }) => {
674
+ return hits.map((hit) => hit.objectID);
675
+ }).catch((err) => {
676
+ console.error(err);
677
+ return [];
678
+ });
679
+ }
680
+ const DEFAULT_SERVER = "https://api.rebase.pro";
681
+ async function performPineconeTextSearch({
682
+ host = DEFAULT_SERVER,
683
+ firebaseToken,
684
+ projectId,
685
+ collectionPath,
686
+ query: query2
687
+ }) {
688
+ console.debug("Performing Pinecone query", collectionPath, query2);
689
+ const response = await fetch((host ?? DEFAULT_SERVER) + `/projects/${projectId}/search/${collectionPath}`, {
690
+ // mode: "no-cors",
691
+ method: "POST",
692
+ headers: {
693
+ "Content-Type": "application/json",
694
+ Authorization: `Basic ${firebaseToken}`
695
+ // "x-de-version": version
696
+ },
697
+ body: JSON.stringify({
698
+ query: query2
699
+ })
700
+ });
701
+ const promise = await response.json();
702
+ return promise.data.ids;
703
+ }
704
+ function buildPineconeSearchController({
705
+ isPathSupported,
706
+ search
707
+ }) {
708
+ return (props) => {
709
+ const init = (props2) => {
710
+ return Promise.resolve(isPathSupported(props2.path));
711
+ };
712
+ return {
713
+ init,
714
+ search
715
+ };
716
+ };
717
+ }
718
+ function buildExternalSearchController({
719
+ isPathSupported,
720
+ search
721
+ }) {
722
+ return (props) => {
723
+ const init = (props2) => {
724
+ return Promise.resolve(isPathSupported(props2.path));
725
+ };
726
+ return {
727
+ init,
728
+ search
729
+ };
730
+ };
731
+ }
732
+ const MAX_SEARCH_RESULTS = 80;
733
+ const localSearchControllerBuilder = ({
734
+ firebaseApp
735
+ }) => {
736
+ let currentPath;
737
+ const indexes = {};
738
+ const listeners = {};
739
+ const destroyListener = (path) => {
740
+ if (listeners[path]) {
741
+ listeners[path]();
742
+ delete listeners[path];
743
+ delete indexes[path];
744
+ }
745
+ };
746
+ const init = ({
747
+ path,
748
+ collection: collectionProp,
749
+ databaseId
750
+ }) => {
751
+ if (currentPath && path !== currentPath) {
752
+ destroyListener(currentPath);
753
+ }
754
+ currentPath = path;
755
+ return new Promise(async (resolve, reject) => {
756
+ if (collectionProp) {
757
+ console.debug("Init local search controller", path);
758
+ const firestore = databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp);
759
+ const col = collection(firestore, path);
760
+ listeners[path] = onSnapshot(query(col), {
761
+ next: (snapshot) => {
762
+ if (snapshot.metadata.fromCache && snapshot.metadata.hasPendingWrites) {
763
+ return;
764
+ }
765
+ const docs = snapshot.docs.map((doc2) => ({
766
+ id: doc2.id,
767
+ ...doc2.data()
768
+ }));
769
+ indexes[path] = buildIndex(docs, collectionProp);
770
+ console.debug("Added docs to index", path, docs.length);
771
+ resolve(true);
772
+ },
773
+ error: (e) => {
774
+ console.error("Error initializing local search controller", path);
775
+ console.error(e);
776
+ reject(e);
777
+ }
778
+ });
779
+ }
780
+ });
781
+ };
782
+ const search = async ({
783
+ searchString,
784
+ path
785
+ }) => {
786
+ console.debug("Searching local index", path, searchString);
787
+ const index = indexes[path];
788
+ if (!index) {
789
+ throw new Error(`Index not found for path ${path}`);
790
+ }
791
+ let searchResult = index.search(searchString);
792
+ searchResult = searchResult.splice(0, MAX_SEARCH_RESULTS);
793
+ searchResult = searchResult.sort((a, b) => {
794
+ const aExactMatch = a.item.id === searchString;
795
+ const bExactMatch = b.item.id === searchString;
796
+ if (aExactMatch && !bExactMatch) {
797
+ return -1;
798
+ } else if (!aExactMatch && bExactMatch) {
799
+ return 1;
800
+ } else {
801
+ return (a.score ?? 0) - (b.score ?? 0);
802
+ }
803
+ });
804
+ return searchResult.map((e) => e.item.id);
805
+ };
806
+ return {
807
+ init,
808
+ search
809
+ };
810
+ };
811
+ function buildIndex(list2, collection2) {
812
+ const keys = ["id", ...Object.keys(collection2.properties)];
813
+ const fuseOptions = {
814
+ // isCaseSensitive: false,
815
+ // includeScore: false,
816
+ // shouldSort: true,
817
+ // includeMatches: false,
818
+ // findAllMatches: false,
819
+ // minMatchCharLength: 1,
820
+ // location: 0,
821
+ threshold: 0.6,
822
+ // distance: 100,
823
+ // useExtendedSearch: false,
824
+ // ignoreLocation: false,
825
+ // ignoreFieldNorm: false,
826
+ // fieldNormWeight: 1,
827
+ includeScore: true,
828
+ keys: [{
829
+ name: "title",
830
+ weight: 1
831
+ }, ...keys.map((key) => ({
832
+ name: key,
833
+ weight: 0.5
834
+ }))]
835
+ };
836
+ return new Fuse(list2, fuseOptions);
837
+ }
838
+ function buildRebaseSearchController(options) {
839
+ const region = options?.region || "us-central1";
840
+ const extensionInstanceId = options?.extensionInstanceId || "typesense-search";
841
+ let searchConfig = null;
842
+ let typesenseClient = null;
843
+ let initPromise = null;
844
+ return ({
845
+ firebaseApp
846
+ }) => {
847
+ const initializeClient = async () => {
848
+ if (typesenseClient) return;
849
+ if (options?.customConfig) {
850
+ searchConfig = {
851
+ host: options.customConfig.host,
852
+ port: options.customConfig.port || 443,
853
+ protocol: options.customConfig.protocol || "https",
854
+ apiKey: options.customConfig.apiKey,
855
+ path: options.customConfig.path,
856
+ collectionsToIndex: ["*"]
857
+ };
858
+ } else {
859
+ const functions = getFunctions(firebaseApp, region);
860
+ const getConfig = httpsCallable(functions, `ext-${extensionInstanceId}-getSearchConfig`);
861
+ try {
862
+ const result = await getConfig();
863
+ searchConfig = result.data;
864
+ if (options?.collections && options.collections.length > 0) {
865
+ searchConfig.collectionsToIndex = options.collections;
866
+ }
867
+ } catch (error) {
868
+ console.error("Failed to get search config from extension:", error);
869
+ throw new Error(`Failed to initialize Rebase Search. Make sure the rebase-search extension is installed and configured. Error: ${error.message || error}`);
870
+ }
871
+ }
872
+ if (!searchConfig) {
873
+ throw new Error("Search config not available");
874
+ }
875
+ const Typesense = (await import("typesense")).default;
876
+ typesenseClient = new Typesense.Client({
877
+ nodes: [{
878
+ host: searchConfig.host,
879
+ port: searchConfig.port,
880
+ protocol: searchConfig.protocol,
881
+ path: searchConfig.path || ""
882
+ }],
883
+ apiKey: searchConfig.apiKey,
884
+ connectionTimeoutSeconds: 5,
885
+ retryIntervalSeconds: 0.5,
886
+ numRetries: 2
887
+ });
888
+ };
889
+ const getTypesenseCollectionName = (path) => {
890
+ const pathParts = path.split("/");
891
+ const collectionNames = [];
892
+ for (let i = 0; i < pathParts.length; i += 2) {
893
+ if (pathParts[i]) {
894
+ collectionNames.push(pathParts[i]);
895
+ }
896
+ }
897
+ return collectionNames.join("_");
898
+ };
899
+ const getParentFilter = (path) => {
900
+ const pathParts = path.split("/");
901
+ if (pathParts.length <= 1) return null;
902
+ const filters = [];
903
+ for (let i = 0; i < pathParts.length - 1; i += 2) {
904
+ const collectionName = pathParts[i];
905
+ const docId = pathParts[i + 1];
906
+ if (collectionName && docId) {
907
+ filters.push(`_parent_${collectionName}_id:=${docId}`);
908
+ }
909
+ }
910
+ return filters.length > 0 ? filters.join(" && ") : null;
911
+ };
912
+ const init = async (props) => {
913
+ try {
914
+ if (!initPromise) {
915
+ initPromise = initializeClient();
916
+ }
917
+ await initPromise;
918
+ if (!searchConfig) return false;
919
+ const pathParts = props.path.split("/");
920
+ const collectionNames = [];
921
+ for (let i = 0; i < pathParts.length; i += 2) {
922
+ if (pathParts[i]) collectionNames.push(pathParts[i]);
923
+ }
924
+ const collectionPattern = collectionNames.join("/");
925
+ const rootCollection = collectionNames[0];
926
+ if (searchConfig.collectionsToIndex.includes("*")) {
927
+ return true;
928
+ }
929
+ return searchConfig.collectionsToIndex.includes(collectionPattern) || searchConfig.collectionsToIndex.includes(rootCollection);
930
+ } catch (error) {
931
+ console.error("Failed to initialize Rebase Search:", error);
932
+ return false;
933
+ }
934
+ };
935
+ const schemaCache = /* @__PURE__ */ new Map();
936
+ const getSearchableFieldsFromSchema = async (collectionName) => {
937
+ if (schemaCache.has(collectionName)) {
938
+ return schemaCache.get(collectionName);
939
+ }
940
+ try {
941
+ const collection2 = await typesenseClient.collections(collectionName).retrieve();
942
+ const stringFields = collection2.fields.filter((f) => {
943
+ const isStringType = f.type === "string" || f.type === "string[]" || f.type === "string*" || f.type === "auto";
944
+ const isNotInternal = !f.name.startsWith("_") && f.name !== ".*";
945
+ return isStringType && isNotInternal;
946
+ }).map((f) => f.name);
947
+ schemaCache.set(collectionName, stringFields);
948
+ return stringFields;
949
+ } catch (error) {
950
+ if (error.httpStatus === 404) {
951
+ throw new Error(`Collection "${collectionName}" not found in Typesense. Make sure the collection has been indexed. Try running the backfill function.`);
952
+ }
953
+ throw error;
954
+ }
955
+ };
956
+ const search = async (props) => {
957
+ if (!typesenseClient) {
958
+ if (!initPromise) {
959
+ initPromise = initializeClient();
960
+ }
961
+ await initPromise;
962
+ }
963
+ if (!typesenseClient) {
964
+ throw new Error("Typesense client not initialized. Check extension configuration.");
965
+ }
966
+ const collectionName = getTypesenseCollectionName(props.path);
967
+ const parentFilter = getParentFilter(props.path);
968
+ const searchableFields = await getSearchableFieldsFromSchema(collectionName);
969
+ if (searchableFields.length === 0) {
970
+ throw new Error(`No searchable string fields found in Typesense collection "${collectionName}". Make sure some documents have been indexed with string fields.`);
971
+ }
972
+ const queryBy = searchableFields.join(",");
973
+ try {
974
+ const searchParams = {
975
+ q: props.searchString,
976
+ query_by: queryBy,
977
+ per_page: 100,
978
+ prefix: true,
979
+ // Enable prefix matching
980
+ typo_tokens_threshold: 1
981
+ // Allow some typos
982
+ };
983
+ if (parentFilter) {
984
+ searchParams.filter_by = parentFilter;
985
+ }
986
+ const result = await typesenseClient.collections(collectionName).documents().search(searchParams);
987
+ const ids = result.hits?.map((hit) => hit.document.id) ?? [];
988
+ return ids;
989
+ } catch (error) {
990
+ const message = error.message || error.toString();
991
+ throw new Error(`Search failed: ${message}`);
992
+ }
993
+ };
994
+ return {
995
+ init,
996
+ search
997
+ };
998
+ };
999
+ }
1000
+ function useFirestoreDriver({
1001
+ firebaseApp,
1002
+ textSearchControllerBuilder,
1003
+ firestoreIndexesBuilder,
1004
+ localTextSearchEnabled
1005
+ }) {
1006
+ const searchControllerRef = useRef(void 0);
1007
+ useEffect(() => {
1008
+ if (!searchControllerRef.current && firebaseApp) {
1009
+ if ((textSearchControllerBuilder || localTextSearchEnabled) && !searchControllerRef.current) {
1010
+ searchControllerRef.current = buildTextSearchControllerWithLocalSearch({
1011
+ firebaseApp,
1012
+ textSearchControllerBuilder,
1013
+ localTextSearchEnabled: localTextSearchEnabled ?? false
1014
+ });
1015
+ }
1016
+ }
1017
+ }, [firebaseApp, localTextSearchEnabled, textSearchControllerBuilder]);
1018
+ const buildQuery = useCallback((path, filter, orderBy$1, order, startAfter$1, limit$1, databaseId) => {
1019
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1020
+ const firestore = databaseId ? getFirestore(firebaseApp, databaseId) : getFirestore(firebaseApp);
1021
+ const collectionReference = collection(firestore, path);
1022
+ const queryParams = [];
1023
+ if (filter) {
1024
+ Object.entries(filter).filter(([_, entry]) => !!entry).forEach(([key, filterParameter]) => {
1025
+ const [op, value] = filterParameter;
1026
+ queryParams.push(where(key, op, cmsToFirestoreModel(value, firestore)));
1027
+ });
1028
+ }
1029
+ if (orderBy$1 && order) {
1030
+ queryParams.push(orderBy(orderBy$1, order));
1031
+ }
1032
+ if (startAfter$1) {
1033
+ queryParams.push(startAfter(startAfter$1));
1034
+ }
1035
+ if (limit$1) {
1036
+ queryParams.push(limit(limit$1));
1037
+ }
1038
+ return query(collectionReference, ...queryParams);
1039
+ }, [firebaseApp]);
1040
+ const getAndBuildEntity = useCallback((path_0, entityId, databaseId_0) => {
1041
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1042
+ const firestore_0 = databaseId_0 ? getFirestore(firebaseApp, databaseId_0) : getFirestore(firebaseApp);
1043
+ return getDoc(doc(firestore_0, path_0, String(entityId))).then((docSnapshot) => {
1044
+ if (!docSnapshot.exists()) {
1045
+ return void 0;
1046
+ }
1047
+ return createEntityFromDocument(docSnapshot, databaseId_0);
1048
+ });
1049
+ }, [firebaseApp]);
1050
+ const listenEntity = useCallback(({
1051
+ path: path_1,
1052
+ entityId: entityId_0,
1053
+ collection: collection2,
1054
+ onUpdate,
1055
+ onError
1056
+ }) => {
1057
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1058
+ const databaseId_1 = collection2?.databaseId;
1059
+ const firestore_1 = databaseId_1 ? getFirestore(firebaseApp, databaseId_1) : getFirestore(firebaseApp);
1060
+ const resolvedPath = path_1;
1061
+ return onSnapshot(doc(firestore_1, resolvedPath, String(entityId_0)), {
1062
+ next: (docSnapshot_0) => {
1063
+ onUpdate(createEntityFromDocument(docSnapshot_0, databaseId_1));
1064
+ },
1065
+ error: onError
1066
+ });
1067
+ }, [firebaseApp]);
1068
+ const performTextSearch = useCallback(({
1069
+ path: path_2,
1070
+ databaseId: databaseId_2,
1071
+ searchString,
1072
+ onUpdate: onUpdate_0
1073
+ }) => {
1074
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1075
+ const textSearchController = searchControllerRef.current;
1076
+ if (!textSearchController) throw Error("Trying to make text search without specifying a FirestoreTextSearchController");
1077
+ let subscriptions = [];
1078
+ const auth = getAuth(firebaseApp);
1079
+ const currentUser = auth?.currentUser;
1080
+ const search = textSearchController.search({
1081
+ path: path_2,
1082
+ searchString,
1083
+ currentUser: currentUser ?? void 0,
1084
+ databaseId: databaseId_2
1085
+ });
1086
+ if (!search) {
1087
+ throw Error("The current path is not supported by the specified FirestoreTextSearchController");
1088
+ }
1089
+ search.then((ids) => {
1090
+ if (!ids || ids.length === 0) {
1091
+ subscriptions = [];
1092
+ onUpdate_0([]);
1093
+ }
1094
+ const entities = [];
1095
+ const addedEntitiesSet = /* @__PURE__ */ new Set();
1096
+ subscriptions = (ids ?? []).map((entityId_1) => {
1097
+ return listenEntity({
1098
+ path: path_2,
1099
+ entityId: entityId_1,
1100
+ onUpdate: (entity) => {
1101
+ if (entity?.values) {
1102
+ if (entity.id && !addedEntitiesSet.has(entity.id)) {
1103
+ addedEntitiesSet.add(entity.id);
1104
+ entities.push(entity);
1105
+ onUpdate_0(entities);
1106
+ }
1107
+ } else if (entity?.id) {
1108
+ addedEntitiesSet.delete(entity.id);
1109
+ onUpdate_0([...entities.filter((e) => e.id !== entityId_1)]);
1110
+ }
1111
+ }
1112
+ });
1113
+ });
1114
+ });
1115
+ return () => {
1116
+ subscriptions.forEach((p) => p());
1117
+ };
1118
+ }, [firebaseApp, listenEntity]);
1119
+ return {
1120
+ key: "firestore",
1121
+ currentTime,
1122
+ initialised: Boolean(firebaseApp),
1123
+ initTextSearch: useCallback(async (props) => {
1124
+ console.debug("Init text search controller", searchControllerRef.current, props.path);
1125
+ if (!searchControllerRef.current) {
1126
+ console.warn("You are trying to use text search, but have not provided a text search controller in `useFirestoreDriver`. You can also set the flag `localTextSearchEnabled` to use local search in `useFirestoreDriver`. Local text search can incur in performance issues and higher costs for large datasets.");
1127
+ return false;
1128
+ }
1129
+ try {
1130
+ return searchControllerRef.current.init(props);
1131
+ } catch (e_0) {
1132
+ console.error("Error initializing text search controller", e_0);
1133
+ return false;
1134
+ }
1135
+ }, []),
1136
+ /**
1137
+ * Fetch entities in a Firestore path
1138
+ * @param path
1139
+ * @param collection
1140
+ * @param filter
1141
+ * @param limit
1142
+ * @param startAfter
1143
+ * @param searchString
1144
+ * @param orderBy
1145
+ * @param order
1146
+ * @return Function to cancel subscription
1147
+ * @see useCollectionFetch if you need this functionality implemented as a hook
1148
+ * @group Firestore
1149
+ */
1150
+ fetchCollection: useCallback(async ({
1151
+ path: path_3,
1152
+ filter: filter_0,
1153
+ limit: limit_0,
1154
+ startAfter: startAfter_0,
1155
+ searchString: searchString_0,
1156
+ orderBy: orderBy_0,
1157
+ order: order_0,
1158
+ collection: collection_0
1159
+ }) => {
1160
+ const databaseId_3 = collection_0?.databaseId;
1161
+ const resolvedPath_0 = path_3;
1162
+ console.debug("Fetching collection", {
1163
+ path: path_3,
1164
+ limit: limit_0,
1165
+ filter: filter_0,
1166
+ startAfter: startAfter_0,
1167
+ orderBy: orderBy_0,
1168
+ order: order_0
1169
+ });
1170
+ const query2 = buildQuery(resolvedPath_0, filter_0, orderBy_0, order_0, startAfter_0, limit_0, databaseId_3);
1171
+ const snapshot = await getDocs(query2);
1172
+ return snapshot.docs.map((doc2) => createEntityFromDocument(doc2, databaseId_3));
1173
+ }, [buildQuery]),
1174
+ /**
1175
+ * Listen to a entities in a given path
1176
+ * @param path
1177
+ * @param collection
1178
+ * @param onError
1179
+ * @param filter
1180
+ * @param limit
1181
+ * @param startAfter
1182
+ * @param searchString
1183
+ * @param orderBy
1184
+ * @param order
1185
+ * @param onUpdate
1186
+ * @return Function to cancel subscription
1187
+ * @see useCollectionFetch if you need this functionality implemented as a hook
1188
+ * @group Firestore
1189
+ */
1190
+ listenCollection: useCallback(({
1191
+ path: path_4,
1192
+ filter: filter_1,
1193
+ limit: limit_1,
1194
+ startAfter: startAfter_1,
1195
+ searchString: searchString_1,
1196
+ orderBy: orderBy_1,
1197
+ order: order_1,
1198
+ onUpdate: onUpdate_1,
1199
+ onError: onError_0,
1200
+ collection: collection_1
1201
+ }) => {
1202
+ console.debug("Listening collection", {
1203
+ path: path_4,
1204
+ searchString: searchString_1,
1205
+ limit: limit_1,
1206
+ filter: filter_1,
1207
+ startAfter: startAfter_1,
1208
+ orderBy: orderBy_1,
1209
+ order: order_1,
1210
+ collection: collection_1
1211
+ });
1212
+ if (!firebaseApp) {
1213
+ throw Error("useFirestoreDriver Firebase not initialised");
1214
+ }
1215
+ const databaseId_4 = collection_1?.databaseId;
1216
+ if (searchString_1) {
1217
+ return performTextSearch({
1218
+ path: path_4,
1219
+ searchString: searchString_1,
1220
+ onUpdate: onUpdate_1,
1221
+ databaseId: databaseId_4
1222
+ });
1223
+ }
1224
+ const resolvedPath_1 = path_4;
1225
+ console.debug("Resolved path for listening", {
1226
+ path: path_4,
1227
+ resolvedPath: resolvedPath_1
1228
+ });
1229
+ const query_0 = buildQuery(resolvedPath_1, filter_1, orderBy_1, order_1, startAfter_1, limit_1, databaseId_4);
1230
+ return onSnapshot(query_0, {
1231
+ next: (snapshot_0) => {
1232
+ if (!searchString_1) onUpdate_1(snapshot_0.docs.map((doc_0) => createEntityFromDocument(doc_0, databaseId_4)));
1233
+ },
1234
+ error: onError_0
1235
+ });
1236
+ }, [buildQuery, firebaseApp, performTextSearch]),
1237
+ /**
1238
+ * Retrieve an entity given a path and a collection
1239
+ * @param path
1240
+ * @param entityId
1241
+ * @param collection
1242
+ * @group Firestore
1243
+ */
1244
+ fetchEntity: useCallback(({
1245
+ path: path_5,
1246
+ entityId: entityId_2,
1247
+ collection: collection_2
1248
+ }) => {
1249
+ const resolvedPath_2 = path_5;
1250
+ return getAndBuildEntity(resolvedPath_2, entityId_2, collection_2?.databaseId);
1251
+ }, [getAndBuildEntity]),
1252
+ /**
1253
+ *
1254
+ * @param path
1255
+ * @param entityId
1256
+ * @param collection
1257
+ * @param onUpdate
1258
+ * @param onError
1259
+ * @return Function to cancel subscription
1260
+ * @group Firestore
1261
+ */
1262
+ listenEntity,
1263
+ /**
1264
+ * Save entity to the specified path. Note that Firestore does not allow
1265
+ * undefined values.
1266
+ * @param path
1267
+ * @param entityId
1268
+ * @param values
1269
+ * @param schemaId
1270
+ * @param collection
1271
+ * @param status
1272
+ * @group Firestore
1273
+ */
1274
+ saveEntity: useCallback(({
1275
+ path: path_6,
1276
+ entityId: entityId_3,
1277
+ values: valuesProp,
1278
+ collection: collection_3,
1279
+ status
1280
+ }) => {
1281
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1282
+ console.debug("1", {
1283
+ path: path_6,
1284
+ entityId: entityId_3,
1285
+ values: valuesProp,
1286
+ collection: collection_3
1287
+ });
1288
+ const values = cmsToFirestoreModel(valuesProp, getFirestore(firebaseApp));
1289
+ console.debug("2", {
1290
+ path: path_6,
1291
+ entityId: entityId_3,
1292
+ values: valuesProp,
1293
+ collection: collection_3
1294
+ });
1295
+ const databaseId_5 = collection_3?.databaseId;
1296
+ const firestore_2 = databaseId_5 ? getFirestore(firebaseApp, databaseId_5) : getFirestore(firebaseApp);
1297
+ const collectionReference_0 = collection(firestore_2, path_6);
1298
+ console.debug("Saving entity", {
1299
+ path: path_6,
1300
+ entityId: entityId_3,
1301
+ values,
1302
+ databaseId: databaseId_5
1303
+ });
1304
+ let documentReference;
1305
+ if (entityId_3) {
1306
+ documentReference = doc(collectionReference_0, String(entityId_3));
1307
+ } else {
1308
+ documentReference = doc(collectionReference_0);
1309
+ }
1310
+ return setDoc(documentReference, values, {
1311
+ merge: true
1312
+ }).then(() => {
1313
+ return {
1314
+ id: documentReference.id,
1315
+ path: path_6,
1316
+ values: firestoreToCMSModel(values)
1317
+ };
1318
+ }).catch((error) => {
1319
+ console.error("Error saving entity", error);
1320
+ throw error;
1321
+ });
1322
+ }, [firebaseApp]),
1323
+ /**
1324
+ * Delete an entity
1325
+ * @param entity
1326
+ * @param collection
1327
+ * @group Firestore
1328
+ */
1329
+ deleteEntity: useCallback(({
1330
+ entity: entity_0
1331
+ }) => {
1332
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1333
+ const databaseId_6 = entity_0.databaseId;
1334
+ const firestore_3 = databaseId_6 ? getFirestore(firebaseApp, databaseId_6) : getFirestore(firebaseApp);
1335
+ return deleteDoc(doc(firestore_3, entity_0.path, String(entity_0.id)));
1336
+ }, [firebaseApp]),
1337
+ /**
1338
+ * Check if the given property is unique in the given collection
1339
+ * @param path Collection path
1340
+ * @param name of the property
1341
+ * @param value
1342
+ * @param property
1343
+ * @param entityId
1344
+ * @return `true` if there are no other fields besides the given entity
1345
+ * @group Firestore
1346
+ */
1347
+ checkUniqueField: useCallback(async (path_7, name, value_0, entityId_4, collection_4) => {
1348
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1349
+ const databaseId_7 = collection_4?.databaseId;
1350
+ const firestore_4 = databaseId_7 ? getFirestore(firebaseApp, databaseId_7) : getFirestore(firebaseApp);
1351
+ if (value_0 === void 0 || value_0 === null) {
1352
+ return Promise.resolve(true);
1353
+ }
1354
+ const q = query(collection(firestore_4, path_7), where(name, "==", cmsToFirestoreModel(value_0, firestore_4)));
1355
+ const snapshot_1 = await getDocs(q);
1356
+ return snapshot_1.docs.filter((doc_1) => doc_1.id !== entityId_4).length === 0;
1357
+ }, [firebaseApp]),
1358
+ countEntities: useCallback(async ({
1359
+ path: path_8,
1360
+ filter: filter_2,
1361
+ order: order_2,
1362
+ orderBy: orderBy_2,
1363
+ collection: collection_5
1364
+ }) => {
1365
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1366
+ const databaseId_8 = collection_5?.databaseId;
1367
+ const resolvedPath_4 = path_8;
1368
+ const query_1 = buildQuery(resolvedPath_4, filter_2, orderBy_2, order_2, void 0, void 0, databaseId_8);
1369
+ const snapshot_2 = await getCountFromServer(query_1);
1370
+ return snapshot_2.data().count;
1371
+ }, [firebaseApp]),
1372
+ isFilterCombinationValid: useCallback(({
1373
+ path: path_9,
1374
+ collection: collection_6,
1375
+ filterValues,
1376
+ sortBy
1377
+ }) => {
1378
+ if (!firebaseApp) throw Error("useFirestoreDriver Firebase not initialised");
1379
+ if (firestoreIndexesBuilder === void 0) return true;
1380
+ const resolvedPath_5 = path_9;
1381
+ const indexes = firestoreIndexesBuilder?.({
1382
+ path: resolvedPath_5,
1383
+ collection: collection_6
1384
+ });
1385
+ const sortKey = sortBy ? sortBy[0] : void 0;
1386
+ const sortDirection = sortBy ? sortBy[1] : void 0;
1387
+ const values_0 = Object.values(filterValues);
1388
+ const filterKeys = Object.keys(filterValues);
1389
+ const filtersCount = filterKeys.length;
1390
+ if (!sortKey && values_0.every((v) => v[0] === "==")) {
1391
+ return true;
1392
+ }
1393
+ if (filtersCount === 1 && (!sortKey || sortKey === filterKeys[0])) {
1394
+ return true;
1395
+ }
1396
+ if (!indexes && filtersCount > 1) {
1397
+ return false;
1398
+ }
1399
+ return !!indexes && indexes.filter((compositeIndex) => !sortKey || sortKey in compositeIndex).find((compositeIndex_0) => Object.entries(filterValues).every(([key_0, value_1]) => compositeIndex_0[key_0] !== void 0 && (!sortDirection || compositeIndex_0[key_0] === sortDirection))) !== void 0;
1400
+ }, [firebaseApp])
1401
+ };
1402
+ }
1403
+ const createEntityFromDocument = (docSnap, databaseId) => {
1404
+ const values = firestoreToCMSModel(docSnap.data());
1405
+ const path = getCMSPathFromFirestorePath(docSnap.ref.path);
1406
+ return {
1407
+ id: docSnap.id,
1408
+ path,
1409
+ values,
1410
+ databaseId
1411
+ };
1412
+ };
1413
+ function firestoreToCMSModel(data) {
1414
+ if (data === null || data === void 0) return null;
1415
+ if (deleteField().isEqual(data)) {
1416
+ return void 0;
1417
+ }
1418
+ if (serverTimestamp().isEqual(data)) {
1419
+ return null;
1420
+ }
1421
+ if (data instanceof Timestamp || typeof data.toDate === "function" && data.toDate() instanceof Date) {
1422
+ return data.toDate();
1423
+ }
1424
+ if (data instanceof Date) {
1425
+ return data;
1426
+ }
1427
+ if (typeof data === "object" && "__type__" in data && data.__type__ === "__vector__") {
1428
+ return data;
1429
+ }
1430
+ if (data instanceof VectorValue || typeof data === "object" && data !== null && typeof data.toArray === "function" && data.constructor?.name === "VectorValue") {
1431
+ return {
1432
+ __type__: "__vector__",
1433
+ value: data.toArray()
1434
+ };
1435
+ }
1436
+ if (data instanceof GeoPoint$1) {
1437
+ return new GeoPoint(data.latitude, data.longitude);
1438
+ }
1439
+ if (data instanceof DocumentReference) {
1440
+ const databaseId = data?.firestore?._databaseId?.database;
1441
+ return new EntityReference({
1442
+ id: data.id,
1443
+ path: getCMSPathFromFirestorePath(data.path),
1444
+ databaseId
1445
+ });
1446
+ }
1447
+ if (Array.isArray(data)) {
1448
+ return data.map(firestoreToCMSModel).filter((v) => v !== void 0);
1449
+ }
1450
+ if (typeof data === "object") {
1451
+ const result = {};
1452
+ for (const key of Object.keys(data)) {
1453
+ const childValue = firestoreToCMSModel(data[key]);
1454
+ if (childValue !== void 0) result[key] = childValue;
1455
+ }
1456
+ return result;
1457
+ }
1458
+ return data;
1459
+ }
1460
+ function getCMSPathFromFirestorePath(fsPath) {
1461
+ let to = fsPath.lastIndexOf("/");
1462
+ to = to === -1 ? fsPath.length : to;
1463
+ return fsPath.substring(0, to);
1464
+ }
1465
+ function cmsToFirestoreModel(data, firestore, inArray = false) {
1466
+ if (data === void 0) {
1467
+ return deleteField();
1468
+ } else if (data === null) {
1469
+ return null;
1470
+ } else if (Array.isArray(data)) {
1471
+ return data.filter((v) => v !== void 0).map((v) => cmsToFirestoreModel(v, firestore, true));
1472
+ } else if (data.isEntityReference && data.isEntityReference()) {
1473
+ const targetFirestore = data.databaseId ? getFirestore(firestore.app, data.databaseId) : firestore;
1474
+ return doc(targetFirestore, data.path, data.id);
1475
+ } else if (data instanceof GeoPoint) {
1476
+ return new GeoPoint$1(data.latitude, data.longitude);
1477
+ } else if (data instanceof Date) {
1478
+ return Timestamp.fromDate(data);
1479
+ } else if (data && typeof data === "object" && "__type__" in data && data.__type__ === "__vector__") {
1480
+ return vector(data.value || []);
1481
+ } else if (data && typeof data === "object") {
1482
+ return Object.entries(data).map(([key, v]) => {
1483
+ const firestoreModel = cmsToFirestoreModel(v, firestore);
1484
+ if (firestoreModel !== void 0) return {
1485
+ [key]: firestoreModel
1486
+ };
1487
+ else return {};
1488
+ }).reduce((a, b) => ({
1489
+ ...a,
1490
+ ...b
1491
+ }), {});
1492
+ }
1493
+ return data;
1494
+ }
1495
+ function currentTime() {
1496
+ return serverTimestamp();
1497
+ }
1498
+ function buildTextSearchControllerWithLocalSearch({
1499
+ textSearchControllerBuilder,
1500
+ firebaseApp,
1501
+ localTextSearchEnabled
1502
+ }) {
1503
+ if (!textSearchControllerBuilder && localTextSearchEnabled) {
1504
+ console.debug("Using local search only");
1505
+ return localSearchControllerBuilder({
1506
+ firebaseApp
1507
+ });
1508
+ }
1509
+ if (!localTextSearchEnabled && textSearchControllerBuilder) {
1510
+ console.debug("Using external text search only");
1511
+ return textSearchControllerBuilder({
1512
+ firebaseApp
1513
+ });
1514
+ }
1515
+ if (!textSearchControllerBuilder && !localTextSearchEnabled) {
1516
+ return void 0;
1517
+ }
1518
+ const localSearchController = localSearchControllerBuilder({
1519
+ firebaseApp
1520
+ });
1521
+ const textSearchController = textSearchControllerBuilder({
1522
+ firebaseApp
1523
+ });
1524
+ return {
1525
+ init: async (props) => {
1526
+ const b = await textSearchController.init(props);
1527
+ if (b) {
1528
+ console.debug("External Text search controller supports path", props.path);
1529
+ return true;
1530
+ }
1531
+ if (localTextSearchEnabled) return localSearchController.init(props);
1532
+ return false;
1533
+ },
1534
+ search: async (props) => {
1535
+ const search = await textSearchController.search(props);
1536
+ return search ?? await localSearchController.search(props);
1537
+ }
1538
+ };
1539
+ }
1540
+ function useFirebaseRTDBDelegate(t0) {
1541
+ const $ = c(22);
1542
+ const {
1543
+ firebaseApp
1544
+ } = t0;
1545
+ let t1;
1546
+ if ($[0] !== firebaseApp) {
1547
+ t1 = async (t22) => {
1548
+ const {
1549
+ path,
1550
+ limit: limit2,
1551
+ startAfter: startAfter2
1552
+ } = t22;
1553
+ if (!firebaseApp) {
1554
+ throw new Error("Firebase app not provided");
1555
+ }
1556
+ const database = getDatabase(firebaseApp);
1557
+ let dbQuery = query$1(ref$1(database, path));
1558
+ if (startAfter2 !== void 0) {
1559
+ dbQuery = query$1(dbQuery, orderByKey(), startAt(String(startAfter2)));
1560
+ }
1561
+ if (limit2 !== void 0) {
1562
+ dbQuery = query$1(dbQuery, limitToFirst(limit2));
1563
+ }
1564
+ const snapshot = await get(dbQuery);
1565
+ if (snapshot.exists()) {
1566
+ return Object.entries(snapshot.val()).map((t32) => {
1567
+ const [id, values] = t32;
1568
+ return {
1569
+ id,
1570
+ path,
1571
+ values: delegateToCMSModel(values)
1572
+ };
1573
+ });
1574
+ }
1575
+ return [];
1576
+ };
1577
+ $[0] = firebaseApp;
1578
+ $[1] = t1;
1579
+ } else {
1580
+ t1 = $[1];
1581
+ }
1582
+ const fetchCollection = t1;
1583
+ let t2;
1584
+ if ($[2] !== firebaseApp) {
1585
+ t2 = (t32) => {
1586
+ const {
1587
+ path: path_0,
1588
+ onUpdate
1589
+ } = t32;
1590
+ if (!firebaseApp) {
1591
+ throw new Error("Firebase app not provided");
1592
+ }
1593
+ const database_0 = getDatabase(firebaseApp);
1594
+ const dbRef = ref$1(database_0, path_0);
1595
+ const unsubscribe = onValue(dbRef, (snapshot_0) => {
1596
+ if (snapshot_0.exists()) {
1597
+ const result = Object.entries(snapshot_0.val()).map((t42) => {
1598
+ const [id_0, values_0] = t42;
1599
+ return {
1600
+ id: id_0,
1601
+ path: path_0,
1602
+ values: delegateToCMSModel(values_0)
1603
+ };
1604
+ });
1605
+ onUpdate(result);
1606
+ } else {
1607
+ onUpdate([]);
1608
+ }
1609
+ });
1610
+ return () => unsubscribe();
1611
+ };
1612
+ $[2] = firebaseApp;
1613
+ $[3] = t2;
1614
+ } else {
1615
+ t2 = $[3];
1616
+ }
1617
+ const listenCollection = t2;
1618
+ let t3;
1619
+ if ($[4] !== firebaseApp) {
1620
+ t3 = async (t42) => {
1621
+ const {
1622
+ path: path_1,
1623
+ entityId
1624
+ } = t42;
1625
+ if (!firebaseApp) {
1626
+ throw new Error("Firebase app not provided");
1627
+ }
1628
+ const database_1 = getDatabase(firebaseApp);
1629
+ const snapshot_1 = await get(ref$1(database_1, `${path_1}/${entityId}`));
1630
+ if (snapshot_1.exists()) {
1631
+ return {
1632
+ id: entityId,
1633
+ path: path_1,
1634
+ values: delegateToCMSModel(snapshot_1.val())
1635
+ };
1636
+ }
1637
+ };
1638
+ $[4] = firebaseApp;
1639
+ $[5] = t3;
1640
+ } else {
1641
+ t3 = $[5];
1642
+ }
1643
+ const fetchEntity = t3;
1644
+ let t4;
1645
+ if ($[6] !== firebaseApp) {
1646
+ t4 = (t52) => {
1647
+ const {
1648
+ path: path_2,
1649
+ entityId: entityId_0,
1650
+ onUpdate: onUpdate_0,
1651
+ onError
1652
+ } = t52;
1653
+ if (!firebaseApp) {
1654
+ throw new Error("Firebase app not provided");
1655
+ }
1656
+ const database_2 = getDatabase(firebaseApp);
1657
+ const dbRef_0 = ref$1(database_2, `${path_2}/${entityId_0}`);
1658
+ const unsubscribe_0 = onValue(dbRef_0, (snapshot_2) => {
1659
+ if (snapshot_2.exists()) {
1660
+ onUpdate_0({
1661
+ id: entityId_0,
1662
+ path: path_2,
1663
+ values: delegateToCMSModel(snapshot_2.val())
1664
+ });
1665
+ } else {
1666
+ onError?.(new Error("Entity does not exist"));
1667
+ }
1668
+ });
1669
+ return () => unsubscribe_0();
1670
+ };
1671
+ $[6] = firebaseApp;
1672
+ $[7] = t4;
1673
+ } else {
1674
+ t4 = $[7];
1675
+ }
1676
+ const listenEntity = t4;
1677
+ let t5;
1678
+ if ($[8] !== firebaseApp) {
1679
+ t5 = async (t62) => {
1680
+ const {
1681
+ path: path_3,
1682
+ entityId: entityId_1,
1683
+ values: values_1
1684
+ } = t62;
1685
+ if (!firebaseApp) {
1686
+ throw new Error("Firebase app not provided");
1687
+ }
1688
+ const database_3 = getDatabase(firebaseApp);
1689
+ const finalId = entityId_1 ?? push(ref$1(database_3, path_3)).key;
1690
+ if (!finalId) {
1691
+ throw new Error("Could not generate a new id");
1692
+ }
1693
+ const transformedValues = cmsToRTDBModel(values_1, database_3);
1694
+ await set(ref$1(database_3, `${path_3}/${finalId}`), transformedValues);
1695
+ return {
1696
+ id: finalId,
1697
+ path: path_3,
1698
+ values: values_1
1699
+ };
1700
+ };
1701
+ $[8] = firebaseApp;
1702
+ $[9] = t5;
1703
+ } else {
1704
+ t5 = $[9];
1705
+ }
1706
+ const saveEntity = t5;
1707
+ let t6;
1708
+ if ($[10] !== firebaseApp) {
1709
+ t6 = async (t72) => {
1710
+ const {
1711
+ entity
1712
+ } = t72;
1713
+ if (!firebaseApp) {
1714
+ throw new Error("Firebase app not provided");
1715
+ }
1716
+ const database_4 = getDatabase(firebaseApp);
1717
+ await remove(ref$1(database_4, `${entity.path}/${entity.id}`));
1718
+ };
1719
+ $[10] = firebaseApp;
1720
+ $[11] = t6;
1721
+ } else {
1722
+ t6 = $[11];
1723
+ }
1724
+ const deleteEntity = t6;
1725
+ let t7;
1726
+ if ($[12] !== firebaseApp) {
1727
+ t7 = async (slug, name, value, entityId_2) => {
1728
+ if (!firebaseApp) {
1729
+ throw new Error("Firebase app not provided");
1730
+ }
1731
+ const database_5 = getDatabase(firebaseApp);
1732
+ const dbRef_1 = query$1(ref$1(database_5, slug), orderByChild(name), startAt(value), limitToFirst(1));
1733
+ const snapshot_3 = await get(dbRef_1);
1734
+ if (!snapshot_3.exists()) {
1735
+ return true;
1736
+ }
1737
+ const [key, entityValue] = Object.entries(snapshot_3.val())[0];
1738
+ if (entityValue && typeof entityValue === "object" && entityValue[name] === value && key === entityId_2) {
1739
+ return true;
1740
+ }
1741
+ return false;
1742
+ };
1743
+ $[12] = firebaseApp;
1744
+ $[13] = t7;
1745
+ } else {
1746
+ t7 = $[13];
1747
+ }
1748
+ const checkUniqueField = t7;
1749
+ const isFilterCombinationValid = _temp$2;
1750
+ let t8;
1751
+ if ($[14] !== checkUniqueField || $[15] !== deleteEntity || $[16] !== fetchCollection || $[17] !== fetchEntity || $[18] !== listenCollection || $[19] !== listenEntity || $[20] !== saveEntity) {
1752
+ t8 = {
1753
+ key: "firebase_rtdb",
1754
+ fetchCollection,
1755
+ listenCollection,
1756
+ fetchEntity,
1757
+ listenEntity,
1758
+ saveEntity,
1759
+ deleteEntity,
1760
+ checkUniqueField,
1761
+ isFilterCombinationValid,
1762
+ currentTime: _temp2$1
1763
+ };
1764
+ $[14] = checkUniqueField;
1765
+ $[15] = deleteEntity;
1766
+ $[16] = fetchCollection;
1767
+ $[17] = fetchEntity;
1768
+ $[18] = listenCollection;
1769
+ $[19] = listenEntity;
1770
+ $[20] = saveEntity;
1771
+ $[21] = t8;
1772
+ } else {
1773
+ t8 = $[21];
1774
+ }
1775
+ return t8;
1776
+ }
1777
+ function _temp2$1() {
1778
+ return /* @__PURE__ */ new Date();
1779
+ }
1780
+ function _temp$2(t0) {
1781
+ return false;
1782
+ }
1783
+ function delegateToCMSModel(data) {
1784
+ if (data === null || data === void 0) return null;
1785
+ if (Array.isArray(data)) {
1786
+ return data.map(delegateToCMSModel).filter((v) => v !== void 0);
1787
+ }
1788
+ if (typeof data === "object") {
1789
+ const result = {};
1790
+ for (const key of Object.keys(data)) {
1791
+ const childValue = delegateToCMSModel(data[key]);
1792
+ if (childValue !== void 0) result[key] = childValue;
1793
+ }
1794
+ return result;
1795
+ }
1796
+ return data;
1797
+ }
1798
+ function cmsToRTDBModel(data, database) {
1799
+ if (data === void 0) {
1800
+ return null;
1801
+ } else if (data === null) {
1802
+ return null;
1803
+ } else if (Array.isArray(data)) {
1804
+ return data.filter((v) => v !== void 0).map((v) => cmsToRTDBModel(v, database));
1805
+ } else if (data.isEntityReference && data.isEntityReference()) {
1806
+ return ref$1(database, `${data.slug}/${data.id}`);
1807
+ } else if (data instanceof Date) {
1808
+ return data.toISOString();
1809
+ } else if (data && typeof data === "object") {
1810
+ return Object.entries(data).map(([key, v]) => {
1811
+ const rtdbModel = cmsToRTDBModel(v, database);
1812
+ if (rtdbModel !== void 0) return {
1813
+ [key]: rtdbModel
1814
+ };
1815
+ else return {};
1816
+ }).reduce((a, b) => ({
1817
+ ...a,
1818
+ ...b
1819
+ }), {});
1820
+ }
1821
+ return data;
1822
+ }
1823
+ const RECAPTCHA_CONTAINER_ID = "recaptcha-container";
1824
+ function useRecaptcha() {
1825
+ const $ = c(1);
1826
+ let t0;
1827
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1828
+ t0 = [];
1829
+ $[0] = t0;
1830
+ } else {
1831
+ t0 = $[0];
1832
+ }
1833
+ useEffect(_temp$1, t0);
1834
+ return null;
1835
+ }
1836
+ function _temp$1() {
1837
+ if (!window || window?.recaptchaVerifier) {
1838
+ return;
1839
+ }
1840
+ const auth = getAuth();
1841
+ window.recaptchaVerifier = new RecaptchaVerifier(auth, RECAPTCHA_CONTAINER_ID, {
1842
+ size: "invisible"
1843
+ });
1844
+ }
1845
+ const googleIcon = (mode) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 64 64", width: 32, height: 32, children: [
1846
+ /* @__PURE__ */ jsxs("linearGradient", { id: "95yY7w43Oj6n2vH63j6HJb", x1: "29.401", x2: "29.401", y1: "4.064", y2: "106.734", gradientTransform: "matrix(1 0 0 -1 0 66)", gradientUnits: "userSpaceOnUse", children: [
1847
+ /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#ff5840" }),
1848
+ /* @__PURE__ */ jsx("stop", { offset: ".007", stopColor: "#ff5840" }),
1849
+ /* @__PURE__ */ jsx("stop", { offset: ".989", stopColor: "#fa528c" }),
1850
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#fa528c" })
1851
+ ] }),
1852
+ /* @__PURE__ */ jsx("path", { fill: "url(#95yY7w43Oj6n2vH63j6HJb)", d: "M47.46,15.5l-1.37,1.48c-1.34,1.44-3.5,1.67-5.15,0.6c-2.71-1.75-6.43-3.13-11-2.37 c-4.94,0.83-9.17,3.85-11.64, 7.97l-8.03-6.08C14.99,9.82,23.2,5,32.5,5c5,0,9.94,1.56,14.27,4.46 C48.81,10.83,49.13,13.71,47.46,15.5z" }),
1853
+ /* @__PURE__ */ jsxs("linearGradient", { id: "95yY7w43Oj6n2vH63j6HJc", x1: "12.148", x2: "12.148", y1: ".872", y2: "47.812", gradientTransform: "matrix(1 0 0 -1 0 66)", gradientUnits: "userSpaceOnUse", children: [
1854
+ /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#feaa53" }),
1855
+ /* @__PURE__ */ jsx("stop", { offset: ".612", stopColor: "#ffcd49" }),
1856
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#ffde44" })
1857
+ ] }),
1858
+ /* @__PURE__ */ jsx("path", { fill: "url(#95yY7w43Oj6n2vH63j6HJc)", d: "M16.01,30.91c-0.09,2.47,0.37,4.83,1.27,6.96l-8.21,6.05c-1.35-2.51-2.3-5.28-2.75-8.22 c-1.06-6.88,0.54-13.38, 3.95-18.6l8.03,6.08C16.93,25.47,16.1,28.11,16.01,30.91z" }),
1859
+ /* @__PURE__ */ jsxs("linearGradient", { id: "95yY7w43Oj6n2vH63j6HJd", x1: "29.76", x2: "29.76", y1: "32.149", y2: "-6.939", gradientTransform: "matrix(1 0 0 -1 0 66)", gradientUnits: "userSpaceOnUse", children: [
1860
+ /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#42d778" }),
1861
+ /* @__PURE__ */ jsx("stop", { offset: ".428", stopColor: "#3dca76" }),
1862
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#34b171" })
1863
+ ] }),
1864
+ /* @__PURE__ */ jsx("path", { fill: "url(#95yY7w43Oj6n2vH63j6HJd)", d: "M50.45,51.28c-4.55,4.07-10.61,6.57-17.36,6.71C22.91,58.2,13.66,52.53,9.07,43.92l8.21-6.05 C19.78,43.81, 25.67,48,32.5,48c3.94,0,7.52-1.28,10.33-3.44L50.45,51.28z" }),
1865
+ /* @__PURE__ */ jsxs("linearGradient", { id: "95yY7w43Oj6n2vH63j6HJe", x1: "46", x2: "46", y1: "3.638", y2: "35.593", gradientTransform: "matrix(1 0 0 -1 0 66)", gradientUnits: "userSpaceOnUse", children: [
1866
+ /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#155cde" }),
1867
+ /* @__PURE__ */ jsx("stop", { offset: ".278", stopColor: "#1f7fe5" }),
1868
+ /* @__PURE__ */ jsx("stop", { offset: ".569", stopColor: "#279ceb" }),
1869
+ /* @__PURE__ */ jsx("stop", { offset: ".82", stopColor: "#2cafef" }),
1870
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#2eb5f0" })
1871
+ ] }),
1872
+ /* @__PURE__ */ jsx("path", { fill: "url(#95yY7w43Oj6n2vH63j6HJe)", d: "M59,31.97c0.01,7.73-3.26,14.58-8.55,19.31l-7.62-6.72c2.1-1.61,3.77-3.71,4.84-6.15\n c0.29-0.66-0.2-1.41-0.92-1.41H37c-2.21,0-4-1.79-4-4v-2c0-2.21,1.79-4,4-4h17C56.75,27,59,29.22,59,31.97z" })
1873
+ ] }) });
1874
+ const appleIcon = (mode) => /* @__PURE__ */ jsx("svg", { width: 32, height: 32, viewBox: "0 0 56 56", style: {
1875
+ transform: "scale(2.8)"
1876
+ }, version: "1.1", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("g", { stroke: mode === "light" ? "#424245" : "white", strokeWidth: "0.5", fillRule: "evenodd", children: /* @__PURE__ */ jsx("path", { d: "M28.2226562,20.3846154 C29.0546875,20.3846154 30.0976562,19.8048315 30.71875,19.0317864 C31.28125,18.3312142 31.6914062,17.352829 31.6914062,16.3744437 C31.6914062,16.2415766 31.6796875,16.1087095 31.65625,16 C30.7304687,16.0362365 29.6171875,16.640178 28.9492187,17.4494596 C28.421875,18.06548 27.9414062,19.0317864 27.9414062,20.0222505 C27.9414062,20.1671964 27.9648438,20.3121424 27.9765625,20.3604577 C28.0351562,20.3725366 28.1289062,20.3846154 28.2226562,20.3846154 Z M25.2929688,35 C26.4296875,35 26.9335938,34.214876 28.3515625,34.214876 C29.7929688,34.214876 30.109375,34.9758423 31.375,34.9758423 C32.6171875,34.9758423 33.4492188,33.792117 34.234375,32.6325493 C35.1132812,31.3038779 35.4765625,29.9993643 35.5,29.9389701 C35.4179688,29.9148125 33.0390625,28.9122695 33.0390625,26.0979021 C33.0390625,23.6579784 34.9140625,22.5588048 35.0195312,22.474253 C33.7773438,20.6382708 31.890625,20.5899555 31.375,20.5899555 C29.9804688,20.5899555 28.84375,21.4596313 28.1289062,21.4596313 C27.3554688,21.4596313 26.3359375,20.6382708 25.1289062,20.6382708 C22.8320312,20.6382708 20.5,22.5950413 20.5,26.2911634 C20.5,28.5861411 21.3671875,31.013986 22.4335938,32.5842339 C23.3476562,33.9129053 24.1445312,35 25.2929688,35 Z", fill: mode === "light" ? "#424245" : "white", fillRule: "nonzero" }) }) });
1877
+ const githubIcon = (mode) => /* @__PURE__ */ jsx("svg", { fill: mode === "light" ? "#1c1e21" : "white", role: "img", viewBox: "0 0 24 24", width: 28, height: 28, xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" }) });
1878
+ const facebookIcon = (mode) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: 28, height: 28, viewBox: "0 0 90 90", children: /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx("path", { d: "M90,15.001C90,7.119,82.884,0,75,0H15C7.116,0,0,7.119,0,15.001v59.998 C0,82.881,7.116,90,15.001,90H45V56H34V41h11v-5.844C45,25.077,52.568,16,61.875,16H74v15H61.875C60.548,31,59,32.611,59,35.024V41 h15v15H59v34h16c7.884,0,15-7.119,15-15.001V15.001z", fill: mode === "light" ? "#39569c" : "white" }) }) });
1879
+ const microsoftIcon = (mode) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: 28, height: 28, viewBox: "0 0 480 480", children: /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx("path", { d: "M0.176,224L0.001,67.963l192-26.072V224H0.176z M224.001,37.241L479.937,0v224H224.001V37.241z M479.999,256l-0.062,224 l-255.936-36.008V256H479.999z M192.001,439.918L0.157,413.621L0.147,256h191.854V439.918z", fill: mode === "light" ? "#00a2ed" : "white" }) }) });
1880
+ const twitterIcon = (mode) => /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: 28, height: 28, viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { fill: mode === "light" ? "#00acee" : "white", d: "M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z" }) });
1881
+ function FirebaseLoginView({
1882
+ children,
1883
+ allowSkipLogin,
1884
+ logo,
1885
+ signInOptions,
1886
+ firebaseApp,
1887
+ authController,
1888
+ noUserComponent,
1889
+ disableSignupScreen = false,
1890
+ disableResetPassword = false,
1891
+ disabled = false,
1892
+ additionalComponent,
1893
+ notAllowedError,
1894
+ className
1895
+ }) {
1896
+ const modeState = useModeController();
1897
+ const [passwordLoginSelected, setPasswordLoginSelected] = useState(false);
1898
+ const [phoneLoginSelected, setPhoneLoginSelected] = useState(false);
1899
+ const [fadeIn, setFadeIn] = useState(false);
1900
+ useEffect(() => {
1901
+ const timer = setTimeout(() => {
1902
+ setFadeIn(true);
1903
+ }, 50);
1904
+ return () => clearTimeout(timer);
1905
+ }, []);
1906
+ const resolvedSignInOptions = signInOptions.map((o) => {
1907
+ if (typeof o === "object") {
1908
+ return o.provider;
1909
+ } else return o;
1910
+ });
1911
+ const sendMFASms = useCallback(() => {
1912
+ const auth = getAuth(firebaseApp);
1913
+ const recaptchaVerifier = new RecaptchaVerifier(auth, "recaptcha", {
1914
+ size: "invisible"
1915
+ });
1916
+ const resolver = getMultiFactorResolver(auth, authController.authProviderError);
1917
+ if (resolver.hints[0].factorId === PhoneMultiFactorGenerator.FACTOR_ID) {
1918
+ const phoneInfoOptions = {
1919
+ multiFactorHint: resolver.hints[0],
1920
+ session: resolver.session
1921
+ };
1922
+ const phoneAuthProvider = new PhoneAuthProvider(auth);
1923
+ phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier).then(function(verificationId) {
1924
+ const verificationCode = String(window.prompt("Please enter the verification code that was sent to your mobile device."));
1925
+ const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
1926
+ const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
1927
+ return resolver.resolveSignIn(multiFactorAssertion);
1928
+ });
1929
+ } else {
1930
+ console.warn("Unsupported second factor.");
1931
+ }
1932
+ }, [authController.authProviderError]);
1933
+ function buildErrorView() {
1934
+ let errorView;
1935
+ if (authController.user != null) return errorView;
1936
+ const ignoredCodes = ["auth/popup-closed-by-user", "auth/cancelled-popup-request"];
1937
+ if (authController.authProviderError) {
1938
+ const authError = authController.authProviderError;
1939
+ if (authError.code === "auth/operation-not-allowed" || authError.code === "auth/configuration-not-found") {
1940
+ errorView = /* @__PURE__ */ jsxs(Fragment, { children: [
1941
+ /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(ErrorView, { title: "Firebase Auth not enabled", error: "You need to enable Firebase Auth and the corresponding login provider in your Firebase project" }) }),
1942
+ firebaseApp && /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx("a", { href: `https://console.firebase.google.com/project/${firebaseApp.options.projectId}/authentication/providers`, rel: "noopener noreferrer", target: "_blank", children: /* @__PURE__ */ jsx(Button, { variant: "text", color: "error", children: "Open Firebase configuration" }) }) })
1943
+ ] });
1944
+ } else if (authError.code === "auth/invalid-api-key") {
1945
+ errorView = /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(ErrorView, { title: "Invalid API key", error: "auth/invalid-api-key: Check that your Firebase config is set correctly in your `firebase_config.ts` file" }) });
1946
+ } else if (authError.code === "auth/email-already-in-use") {
1947
+ errorView = /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(ErrorView, { title: "Email already in use", error: "The selected email is already in use by another account" }) });
1948
+ } else if (authError.code === "auth/invalid-credential") {
1949
+ errorView = /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(ErrorView, { title: "Invalid credential", error: "The provided credential is not correct" }) });
1950
+ } else if (!ignoredCodes.includes(authError.code)) {
1951
+ if (authError.code === "auth/multi-factor-auth-required") {
1952
+ sendMFASms();
1953
+ }
1954
+ errorView = /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsx(ErrorView, { error: authController.authProviderError }) });
1955
+ }
1956
+ }
1957
+ return errorView;
1958
+ }
1959
+ let logoComponent;
1960
+ if (logo) {
1961
+ logoComponent = /* @__PURE__ */ jsx("img", { src: logo, style: {
1962
+ height: "100%",
1963
+ width: "100%",
1964
+ objectFit: "contain"
1965
+ }, alt: "Logo" });
1966
+ } else {
1967
+ logoComponent = /* @__PURE__ */ jsx(RebaseLogo, {});
1968
+ }
1969
+ let notAllowedMessage;
1970
+ if (notAllowedError) {
1971
+ if (typeof notAllowedError === "string") {
1972
+ notAllowedMessage = notAllowedError;
1973
+ } else if (notAllowedError instanceof Error) {
1974
+ notAllowedMessage = notAllowedError.message;
1975
+ } else {
1976
+ notAllowedMessage = "It looks like you don't have access to the CMS, based on the specified Authenticator configuration";
1977
+ }
1978
+ }
1979
+ const fadeStyle = {
1980
+ opacity: fadeIn ? 1 : 0,
1981
+ transition: "opacity 0.6s ease-in-out"
1982
+ };
1983
+ return /* @__PURE__ */ jsxs("div", { className: cls("flex flex-col items-center justify-center min-w-full p-4", className), style: fadeStyle, children: [
1984
+ /* @__PURE__ */ jsx("div", { id: "recaptcha" }),
1985
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center w-full max-w-[500px]", children: [
1986
+ /* @__PURE__ */ jsx("div", { className: "p-1 w-64 h-64 m-4", children: logoComponent }),
1987
+ children,
1988
+ notAllowedMessage && /* @__PURE__ */ jsx("div", { className: "p-8", children: /* @__PURE__ */ jsx(ErrorView, { error: notAllowedMessage }) }),
1989
+ buildErrorView(),
1990
+ !passwordLoginSelected && !phoneLoginSelected && /* @__PURE__ */ jsxs("div", { className: "my-4 w-full", children: [
1991
+ buildOauthLoginButtons(authController, resolvedSignInOptions, modeState.mode, disabled),
1992
+ resolvedSignInOptions.includes("password") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Email/password", icon: /* @__PURE__ */ jsx(MailIcon, { size: 28 }), onClick: () => setPasswordLoginSelected(true) }),
1993
+ resolvedSignInOptions.includes("phone") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Phone number", icon: /* @__PURE__ */ jsx(CallIcon, { size: 28 }), onClick: () => setPhoneLoginSelected(true) }),
1994
+ resolvedSignInOptions.includes("anonymous") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Log in anonymously", icon: /* @__PURE__ */ jsx(PersonIcon, { size: 28 }), onClick: authController.anonymousLogin }),
1995
+ allowSkipLogin && /* @__PURE__ */ jsx(Button, { className: "m-1 mb-4", variant: "text", disabled, onClick: authController.skipLogin, children: "Skip login" })
1996
+ ] }),
1997
+ passwordLoginSelected && /* @__PURE__ */ jsx(LoginForm, { authController, onClose: () => setPasswordLoginSelected(false), mode: modeState.mode, noUserComponent, disableSignupScreen, disableResetPassword }),
1998
+ phoneLoginSelected && /* @__PURE__ */ jsx(PhoneLoginForm, { authController, onClose: () => setPhoneLoginSelected(false) }),
1999
+ !passwordLoginSelected && !phoneLoginSelected && additionalComponent
2000
+ ] })
2001
+ ] });
2002
+ }
2003
+ function LoginButton(t0) {
2004
+ const $ = c(15);
2005
+ const {
2006
+ icon,
2007
+ onClick,
2008
+ text,
2009
+ disabled
2010
+ } = t0;
2011
+ const t1 = disabled ? "" : "hover:text-surface-800 hover:dark:text-white";
2012
+ let t2;
2013
+ if ($[0] !== t1) {
2014
+ t2 = cls("w-full bg-white dark:bg-surface-800 text-surface-900 dark:text-surface-100", t1);
2015
+ $[0] = t1;
2016
+ $[1] = t2;
2017
+ } else {
2018
+ t2 = $[1];
2019
+ }
2020
+ let t3;
2021
+ if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2022
+ t3 = {
2023
+ height: "40px",
2024
+ borderRadius: "4px",
2025
+ fontSize: "14px"
2026
+ };
2027
+ $[2] = t3;
2028
+ } else {
2029
+ t3 = $[2];
2030
+ }
2031
+ let t4;
2032
+ if ($[3] !== icon) {
2033
+ t4 = /* @__PURE__ */ jsx("div", { className: "flex flex-col w-8 items-center justify-items-center mr-4", children: icon });
2034
+ $[3] = icon;
2035
+ $[4] = t4;
2036
+ } else {
2037
+ t4 = $[4];
2038
+ }
2039
+ let t5;
2040
+ if ($[5] !== text) {
2041
+ t5 = /* @__PURE__ */ jsx("div", { className: "grow pl-2 text-center", children: text });
2042
+ $[5] = text;
2043
+ $[6] = t5;
2044
+ } else {
2045
+ t5 = $[6];
2046
+ }
2047
+ let t6;
2048
+ if ($[7] !== t4 || $[8] !== t5) {
2049
+ t6 = /* @__PURE__ */ jsxs("div", { className: "p-1 flex h-8 items-center justify-items-center", children: [
2050
+ t4,
2051
+ t5
2052
+ ] });
2053
+ $[7] = t4;
2054
+ $[8] = t5;
2055
+ $[9] = t6;
2056
+ } else {
2057
+ t6 = $[9];
2058
+ }
2059
+ let t7;
2060
+ if ($[10] !== disabled || $[11] !== onClick || $[12] !== t2 || $[13] !== t6) {
2061
+ t7 = /* @__PURE__ */ jsx("div", { className: "my-1 w-full", children: /* @__PURE__ */ jsx(Button, { className: t2, style: t3, disabled, onClick, children: t6 }) });
2062
+ $[10] = disabled;
2063
+ $[11] = onClick;
2064
+ $[12] = t2;
2065
+ $[13] = t6;
2066
+ $[14] = t7;
2067
+ } else {
2068
+ t7 = $[14];
2069
+ }
2070
+ return t7;
2071
+ }
2072
+ function PhoneLoginForm(t0) {
2073
+ const $ = c(33);
2074
+ const {
2075
+ onClose,
2076
+ authController
2077
+ } = t0;
2078
+ useRecaptcha();
2079
+ const [phone, setPhone] = useState();
2080
+ const [code, setCode] = useState();
2081
+ const [isInvalidCode, setIsInvalidCode] = useState(false);
2082
+ let t1;
2083
+ if ($[0] !== authController || $[1] !== code || $[2] !== phone) {
2084
+ t1 = async (event) => {
2085
+ event.preventDefault();
2086
+ if (code && authController.confirmationResult) {
2087
+ setIsInvalidCode(false);
2088
+ authController.confirmationResult.confirm(code).catch((e) => {
2089
+ if (e.code === "auth/invalid-verification-code") {
2090
+ setIsInvalidCode(true);
2091
+ }
2092
+ });
2093
+ } else {
2094
+ if (phone) {
2095
+ authController.phoneLogin(phone, window.recaptchaVerifier);
2096
+ }
2097
+ }
2098
+ };
2099
+ $[0] = authController;
2100
+ $[1] = code;
2101
+ $[2] = phone;
2102
+ $[3] = t1;
2103
+ } else {
2104
+ t1 = $[3];
2105
+ }
2106
+ const handleSubmit = t1;
2107
+ let t2;
2108
+ if ($[4] !== isInvalidCode) {
2109
+ t2 = isInvalidCode && /* @__PURE__ */ jsx("div", { className: "p-8", children: /* @__PURE__ */ jsx(ErrorView, { error: "Invalid confirmation code" }) });
2110
+ $[4] = isInvalidCode;
2111
+ $[5] = t2;
2112
+ } else {
2113
+ t2 = $[5];
2114
+ }
2115
+ let t3;
2116
+ if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2117
+ t3 = /* @__PURE__ */ jsx("div", { id: RECAPTCHA_CONTAINER_ID });
2118
+ $[6] = t3;
2119
+ } else {
2120
+ t3 = $[6];
2121
+ }
2122
+ let t4;
2123
+ if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2124
+ t4 = /* @__PURE__ */ jsx(ArrowBackIcon, { className: "w-5 h-5" });
2125
+ $[7] = t4;
2126
+ } else {
2127
+ t4 = $[7];
2128
+ }
2129
+ let t5;
2130
+ if ($[8] !== onClose) {
2131
+ t5 = /* @__PURE__ */ jsx(IconButton, { onClick: onClose, children: t4 });
2132
+ $[8] = onClose;
2133
+ $[9] = t5;
2134
+ } else {
2135
+ t5 = $[9];
2136
+ }
2137
+ let t6;
2138
+ if ($[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2139
+ t6 = /* @__PURE__ */ jsx("div", { className: "p-1 flex", children: /* @__PURE__ */ jsx(Typography, { align: "center", variant: "subtitle2", children: "Please enter your phone number" }) });
2140
+ $[10] = t6;
2141
+ } else {
2142
+ t6 = $[10];
2143
+ }
2144
+ const t7 = phone ?? "";
2145
+ const t8 = Boolean(phone && (authController.authLoading || authController.confirmationResult));
2146
+ let t9;
2147
+ if ($[11] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2148
+ t9 = (event_0) => setPhone(event_0.target.value);
2149
+ $[11] = t9;
2150
+ } else {
2151
+ t9 = $[11];
2152
+ }
2153
+ let t10;
2154
+ if ($[12] !== t7 || $[13] !== t8) {
2155
+ t10 = /* @__PURE__ */ jsx(TextField, { placeholder: "", value: t7, disabled: t8, type: "phone", onChange: t9 });
2156
+ $[12] = t7;
2157
+ $[13] = t8;
2158
+ $[14] = t10;
2159
+ } else {
2160
+ t10 = $[14];
2161
+ }
2162
+ let t11;
2163
+ if ($[15] !== authController.confirmationResult || $[16] !== code || $[17] !== phone) {
2164
+ t11 = Boolean(phone && authController.confirmationResult) && /* @__PURE__ */ jsxs(Fragment, { children: [
2165
+ /* @__PURE__ */ jsx("div", { className: "mt-2 p-1 flex", children: /* @__PURE__ */ jsx(Typography, { align: "center", variant: "subtitle2", children: "Please enter the confirmation code" }) }),
2166
+ /* @__PURE__ */ jsx(TextField, { placeholder: "", value: code ?? "", type: "text", onChange: (event_1) => setCode(event_1.target.value) })
2167
+ ] });
2168
+ $[15] = authController.confirmationResult;
2169
+ $[16] = code;
2170
+ $[17] = phone;
2171
+ $[18] = t11;
2172
+ } else {
2173
+ t11 = $[18];
2174
+ }
2175
+ let t12;
2176
+ if ($[19] !== authController.authLoading) {
2177
+ t12 = authController.authLoading && /* @__PURE__ */ jsx(CircularProgress, { className: "p-1", size: "small" });
2178
+ $[19] = authController.authLoading;
2179
+ $[20] = t12;
2180
+ } else {
2181
+ t12 = $[20];
2182
+ }
2183
+ let t13;
2184
+ if ($[21] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2185
+ t13 = /* @__PURE__ */ jsx(Button, { type: "submit", children: "Ok" });
2186
+ $[21] = t13;
2187
+ } else {
2188
+ t13 = $[21];
2189
+ }
2190
+ let t14;
2191
+ if ($[22] !== t12) {
2192
+ t14 = /* @__PURE__ */ jsxs("div", { className: "flex justify-end items-center w-full", children: [
2193
+ t12,
2194
+ t13
2195
+ ] });
2196
+ $[22] = t12;
2197
+ $[23] = t14;
2198
+ } else {
2199
+ t14 = $[23];
2200
+ }
2201
+ let t15;
2202
+ if ($[24] !== t10 || $[25] !== t11 || $[26] !== t14 || $[27] !== t5) {
2203
+ t15 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
2204
+ t5,
2205
+ t6,
2206
+ t10,
2207
+ t11,
2208
+ t14
2209
+ ] });
2210
+ $[24] = t10;
2211
+ $[25] = t11;
2212
+ $[26] = t14;
2213
+ $[27] = t5;
2214
+ $[28] = t15;
2215
+ } else {
2216
+ t15 = $[28];
2217
+ }
2218
+ let t16;
2219
+ if ($[29] !== handleSubmit || $[30] !== t15 || $[31] !== t2) {
2220
+ t16 = /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
2221
+ t2,
2222
+ t3,
2223
+ t15
2224
+ ] });
2225
+ $[29] = handleSubmit;
2226
+ $[30] = t15;
2227
+ $[31] = t2;
2228
+ $[32] = t16;
2229
+ } else {
2230
+ t16 = $[32];
2231
+ }
2232
+ return t16;
2233
+ }
2234
+ function LoginForm({
2235
+ onClose,
2236
+ authController,
2237
+ mode,
2238
+ noUserComponent,
2239
+ disableSignupScreen,
2240
+ disableResetPassword
2241
+ }) {
2242
+ const passwordRef = useRef(null);
2243
+ const [loginState, setLoginState] = useState("email");
2244
+ const [email, setEmail] = useState();
2245
+ const [password, setPassword] = useState();
2246
+ const [previouslyUsedMethodsForUser, setPreviouslyUsedMethodsForUser] = useState();
2247
+ const [resettingPassword, setResettingPassword] = useState(false);
2248
+ const snackbarController = useSnackbarController();
2249
+ useEffect(() => {
2250
+ if ((loginState === "password" || loginState === "registration") && passwordRef.current) {
2251
+ passwordRef.current.focus();
2252
+ }
2253
+ }, [loginState]);
2254
+ useEffect(() => {
2255
+ if (!document) return;
2256
+ const escFunction = (event) => {
2257
+ if (event.keyCode === 27) {
2258
+ onClose();
2259
+ }
2260
+ };
2261
+ document.addEventListener("keydown", escFunction, false);
2262
+ return () => {
2263
+ document.removeEventListener("keydown", escFunction, false);
2264
+ };
2265
+ }, [onClose]);
2266
+ function handleEnterEmail() {
2267
+ if (email) {
2268
+ authController.fetchSignInMethodsForEmail(email).then((availableProviders) => {
2269
+ setPreviouslyUsedMethodsForUser(availableProviders.filter((p) => p !== "password"));
2270
+ });
2271
+ setLoginState("password");
2272
+ }
2273
+ }
2274
+ function handleEnterPassword() {
2275
+ if (email && password) {
2276
+ authController.emailPasswordLogin(email, password);
2277
+ }
2278
+ }
2279
+ function handleRegistration() {
2280
+ if (email && password) {
2281
+ authController.createUserWithEmailAndPassword(email, password);
2282
+ }
2283
+ }
2284
+ const onBackPressed = () => {
2285
+ if (loginState === "email") {
2286
+ onClose();
2287
+ } else if (loginState === "password" || loginState === "registration") {
2288
+ setLoginState("email");
2289
+ } else {
2290
+ setPreviouslyUsedMethodsForUser(void 0);
2291
+ }
2292
+ };
2293
+ const handleSubmit = (event_0) => {
2294
+ event_0.preventDefault();
2295
+ if (loginState === "email") {
2296
+ handleEnterEmail();
2297
+ } else if (loginState === "password") {
2298
+ handleEnterPassword();
2299
+ } else if (loginState === "registration") {
2300
+ handleRegistration();
2301
+ }
2302
+ };
2303
+ const label = loginState === "registration" ? "Please enter your email and password to create an account" : loginState === "password" ? "Please enter your password" : "Please enter your email";
2304
+ return /* @__PURE__ */ jsx("form", { className: "w-full", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs("div", { className: "max-w-[480px] w-full flex flex-col gap-4", children: [
2305
+ /* @__PURE__ */ jsx(IconButton, { onClick: onBackPressed, children: /* @__PURE__ */ jsx(ArrowBackIcon, { className: "w-5 h-5" }) }),
2306
+ /* @__PURE__ */ jsx("div", { children: loginState === "registration" && noUserComponent }),
2307
+ /* @__PURE__ */ jsx(Typography, { className: `${loginState === "registration" && disableSignupScreen ? "hidden" : "flex"}`, variant: "subtitle2", children: label }),
2308
+ (loginState === "email" || loginState === "registration") && /* @__PURE__ */ jsx(TextField, { placeholder: "Email", autoFocus: true, value: email ?? "", disabled: authController.authLoading, type: "email", onChange: (event_1) => setEmail(event_1.target.value) }),
2309
+ /* @__PURE__ */ jsx("div", { className: `${loginState === "password" || loginState === "registration" && !disableSignupScreen ? "block" : "hidden"}`, children: /* @__PURE__ */ jsx(TextField, { placeholder: "Password", value: password ?? "", disabled: authController.authLoading, inputRef: passwordRef, type: "password", onChange: (event_2) => setPassword(event_2.target.value) }) }),
2310
+ /* @__PURE__ */ jsxs("div", { className: `${loginState === "registration" && disableSignupScreen ? "hidden" : "flex"} justify-end items-center w-full flex gap-2`, children: [
2311
+ authController.authLoading && /* @__PURE__ */ jsx(CircularProgress, { className: "p-1", size: "small" }),
2312
+ !disableResetPassword && /* @__PURE__ */ jsx(LoadingButton, { variant: "text", loading: resettingPassword, onClick: email ? async () => {
2313
+ setResettingPassword(true);
2314
+ try {
2315
+ try {
2316
+ await authController.sendPasswordResetEmail(email);
2317
+ snackbarController.open({
2318
+ message: "Password reset email sent",
2319
+ type: "success"
2320
+ });
2321
+ } catch (e) {
2322
+ snackbarController.open({
2323
+ message: e.message,
2324
+ type: "error"
2325
+ });
2326
+ }
2327
+ } finally {
2328
+ setResettingPassword(false);
2329
+ }
2330
+ } : void 0, children: "Reset password" }),
2331
+ !disableSignupScreen && loginState === "email" && /* @__PURE__ */ jsx(Button, { variant: "text", onClick: () => setLoginState("registration"), children: "New user" }),
2332
+ /* @__PURE__ */ jsx(Button, { type: "submit", children: loginState === "registration" ? "Create account" : loginState === "password" ? "Login" : "Login" })
2333
+ ] }),
2334
+ previouslyUsedMethodsForUser && previouslyUsedMethodsForUser.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 p-4", children: [
2335
+ /* @__PURE__ */ jsxs("div", { children: [
2336
+ /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", children: "You already have an account" }),
2337
+ /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
2338
+ "You can use one of these methods to login with ",
2339
+ email
2340
+ ] })
2341
+ ] }),
2342
+ /* @__PURE__ */ jsx("div", { children: previouslyUsedMethodsForUser && buildOauthLoginButtons(authController, previouslyUsedMethodsForUser, mode, false) })
2343
+ ] })
2344
+ ] }) });
2345
+ }
2346
+ function buildOauthLoginButtons(authController, providers, mode, disabled) {
2347
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2348
+ providers.includes("google.com") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Sign in with Google", icon: googleIcon(), onClick: authController.googleLogin }),
2349
+ providers.includes("microsoft.com") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Sign in with Microsoft", icon: microsoftIcon(mode), onClick: authController.microsoftLogin }),
2350
+ providers.includes("apple.com") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Sign in with Apple", icon: appleIcon(mode), onClick: authController.appleLogin }),
2351
+ providers.includes("github.com") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Sign in with Github", icon: githubIcon(mode), onClick: authController.githubLogin }),
2352
+ providers.includes("facebook.com") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Sign in with Facebook", icon: facebookIcon(mode), onClick: authController.facebookLogin }),
2353
+ providers.includes("twitter.com") && /* @__PURE__ */ jsx(LoginButton, { disabled, text: "Sign in with Twitter", icon: twitterIcon(mode), onClick: authController.twitterLogin })
2354
+ ] });
2355
+ }
2356
+ const DEFAULT_SIGN_IN_OPTIONS = [GoogleAuthProvider.PROVIDER_ID];
2357
+ function RebaseFirebaseApp(t0) {
2358
+ const $ = c(93);
2359
+ const {
2360
+ name,
2361
+ logo,
2362
+ logoDark,
2363
+ authenticator,
2364
+ collections,
2365
+ views,
2366
+ adminViews,
2367
+ textSearchControllerBuilder,
2368
+ allowSkipLogin,
2369
+ signInOptions: t1,
2370
+ firebaseConfig,
2371
+ onFirebaseInit,
2372
+ appCheckOptions,
2373
+ dateTimeFormat,
2374
+ locale,
2375
+ basePath,
2376
+ baseCollectionPath,
2377
+ onAnalyticsEvent,
2378
+ propertyConfigs: propertyConfigsProp,
2379
+ plugins,
2380
+ autoOpenDrawer,
2381
+ firestoreIndexesBuilder,
2382
+ components,
2383
+ localTextSearchEnabled: t2,
2384
+ userManagement
2385
+ } = t0;
2386
+ const signInOptions = t1 === void 0 ? DEFAULT_SIGN_IN_OPTIONS : t1;
2387
+ const localTextSearchEnabled = t2 === void 0 ? false : t2;
2388
+ useBrowserTitleAndIcon(name, logo);
2389
+ let t3;
2390
+ if ($[0] !== propertyConfigsProp) {
2391
+ t3 = propertyConfigsProp ?? [];
2392
+ $[0] = propertyConfigsProp;
2393
+ $[1] = t3;
2394
+ } else {
2395
+ t3 = $[1];
2396
+ }
2397
+ let t4;
2398
+ if ($[2] !== t3) {
2399
+ t4 = t3.map(_temp).reduce(_temp2, {});
2400
+ $[2] = t3;
2401
+ $[3] = t4;
2402
+ } else {
2403
+ t4 = $[3];
2404
+ }
2405
+ const propertyConfigs = t4;
2406
+ let t5;
2407
+ if ($[4] !== firebaseConfig || $[5] !== onFirebaseInit) {
2408
+ t5 = {
2409
+ onFirebaseInit,
2410
+ firebaseConfig
2411
+ };
2412
+ $[4] = firebaseConfig;
2413
+ $[5] = onFirebaseInit;
2414
+ $[6] = t5;
2415
+ } else {
2416
+ t5 = $[6];
2417
+ }
2418
+ const {
2419
+ firebaseApp,
2420
+ firebaseConfigLoading,
2421
+ configError
2422
+ } = useInitialiseFirebase(t5);
2423
+ const modeController = useBuildModeController();
2424
+ const adminModeController = useBuildAdminModeController();
2425
+ let t6;
2426
+ if ($[7] !== appCheckOptions || $[8] !== firebaseApp) {
2427
+ t6 = {
2428
+ firebaseApp,
2429
+ options: appCheckOptions
2430
+ };
2431
+ $[7] = appCheckOptions;
2432
+ $[8] = firebaseApp;
2433
+ $[9] = t6;
2434
+ } else {
2435
+ t6 = $[9];
2436
+ }
2437
+ const {
2438
+ loading
2439
+ } = useAppCheck(t6);
2440
+ let t7;
2441
+ if ($[10] !== firebaseApp || $[11] !== signInOptions) {
2442
+ t7 = {
2443
+ firebaseApp,
2444
+ signInOptions
2445
+ };
2446
+ $[10] = firebaseApp;
2447
+ $[11] = signInOptions;
2448
+ $[12] = t7;
2449
+ } else {
2450
+ t7 = $[12];
2451
+ }
2452
+ const authController = useFirebaseAuthController(t7);
2453
+ const userConfigPersistence = useBuildLocalConfigurationPersistence();
2454
+ let t8;
2455
+ if ($[13] !== firebaseApp || $[14] !== firestoreIndexesBuilder || $[15] !== localTextSearchEnabled || $[16] !== textSearchControllerBuilder) {
2456
+ t8 = {
2457
+ firebaseApp,
2458
+ textSearchControllerBuilder,
2459
+ firestoreIndexesBuilder,
2460
+ localTextSearchEnabled
2461
+ };
2462
+ $[13] = firebaseApp;
2463
+ $[14] = firestoreIndexesBuilder;
2464
+ $[15] = localTextSearchEnabled;
2465
+ $[16] = textSearchControllerBuilder;
2466
+ $[17] = t8;
2467
+ } else {
2468
+ t8 = $[17];
2469
+ }
2470
+ const firestoreDelegate = useFirestoreDriver(t8);
2471
+ let t9;
2472
+ if ($[18] !== firebaseApp) {
2473
+ t9 = {
2474
+ firebaseApp
2475
+ };
2476
+ $[18] = firebaseApp;
2477
+ $[19] = t9;
2478
+ } else {
2479
+ t9 = $[19];
2480
+ }
2481
+ const storageSource = useFirebaseStorageSource(t9);
2482
+ let t10;
2483
+ if ($[20] !== firestoreDelegate) {
2484
+ t10 = buildRebaseData(firestoreDelegate);
2485
+ $[20] = firestoreDelegate;
2486
+ $[21] = t10;
2487
+ } else {
2488
+ t10 = $[21];
2489
+ }
2490
+ let t11;
2491
+ if ($[22] !== authController || $[23] !== authenticator || $[24] !== storageSource || $[25] !== t10) {
2492
+ t11 = {
2493
+ authController,
2494
+ authenticator,
2495
+ data: t10,
2496
+ storageSource
2497
+ };
2498
+ $[22] = authController;
2499
+ $[23] = authenticator;
2500
+ $[24] = storageSource;
2501
+ $[25] = t10;
2502
+ $[26] = t11;
2503
+ } else {
2504
+ t11 = $[26];
2505
+ }
2506
+ const {
2507
+ authLoading,
2508
+ canAccessMainView,
2509
+ notAllowedError
2510
+ } = useValidateAuthenticator(t11);
2511
+ let t12;
2512
+ if ($[27] !== userConfigPersistence) {
2513
+ t12 = {
2514
+ userConfigPersistence
2515
+ };
2516
+ $[27] = userConfigPersistence;
2517
+ $[28] = t12;
2518
+ } else {
2519
+ t12 = $[28];
2520
+ }
2521
+ const collectionRegistryController = useBuildCollectionRegistryController(t12);
2522
+ const t13 = basePath ?? "/";
2523
+ const t14 = baseCollectionPath ?? "/c";
2524
+ let t15;
2525
+ if ($[29] !== collectionRegistryController || $[30] !== t13 || $[31] !== t14) {
2526
+ t15 = {
2527
+ basePath: t13,
2528
+ baseCollectionPath: t14,
2529
+ collectionRegistryController
2530
+ };
2531
+ $[29] = collectionRegistryController;
2532
+ $[30] = t13;
2533
+ $[31] = t14;
2534
+ $[32] = t15;
2535
+ } else {
2536
+ t15 = $[32];
2537
+ }
2538
+ const urlController = useBuildUrlController(t15);
2539
+ let t16;
2540
+ if ($[33] !== firestoreDelegate) {
2541
+ t16 = buildRebaseData(firestoreDelegate);
2542
+ $[33] = firestoreDelegate;
2543
+ $[34] = t16;
2544
+ } else {
2545
+ t16 = $[34];
2546
+ }
2547
+ let t17;
2548
+ if ($[35] !== adminModeController.mode || $[36] !== adminViews || $[37] !== authController || $[38] !== collectionRegistryController || $[39] !== collections || $[40] !== plugins || $[41] !== t16 || $[42] !== urlController || $[43] !== userManagement || $[44] !== views) {
2549
+ t17 = {
2550
+ collections,
2551
+ views,
2552
+ adminViews,
2553
+ authController,
2554
+ data: t16,
2555
+ plugins,
2556
+ collectionRegistryController,
2557
+ urlController,
2558
+ adminMode: adminModeController.mode,
2559
+ userManagement
2560
+ };
2561
+ $[35] = adminModeController.mode;
2562
+ $[36] = adminViews;
2563
+ $[37] = authController;
2564
+ $[38] = collectionRegistryController;
2565
+ $[39] = collections;
2566
+ $[40] = plugins;
2567
+ $[41] = t16;
2568
+ $[42] = urlController;
2569
+ $[43] = userManagement;
2570
+ $[44] = views;
2571
+ $[45] = t17;
2572
+ } else {
2573
+ t17 = $[45];
2574
+ }
2575
+ const navigationStateController = useBuildNavigationStateController(t17);
2576
+ if (firebaseConfigLoading || !firebaseApp || loading) {
2577
+ let t182;
2578
+ if ($[46] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2579
+ t182 = /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(CircularProgressCenter, {}) });
2580
+ $[46] = t182;
2581
+ } else {
2582
+ t182 = $[46];
2583
+ }
2584
+ return t182;
2585
+ }
2586
+ if (configError) {
2587
+ let t182;
2588
+ if ($[47] !== configError) {
2589
+ t182 = /* @__PURE__ */ jsx(CenteredView, { children: configError });
2590
+ $[47] = configError;
2591
+ $[48] = t182;
2592
+ } else {
2593
+ t182 = $[48];
2594
+ }
2595
+ return t182;
2596
+ }
2597
+ let t18;
2598
+ if ($[49] !== firebaseApp.options.projectId) {
2599
+ t18 = (t192) => {
2600
+ const {
2601
+ entity
2602
+ } = t192;
2603
+ return `https://console.firebase.google.com/project/${firebaseApp.options.projectId}/firestore/data/${entity.path}/${entity.id}`;
2604
+ };
2605
+ $[49] = firebaseApp.options.projectId;
2606
+ $[50] = t18;
2607
+ } else {
2608
+ t18 = $[50];
2609
+ }
2610
+ let t19;
2611
+ if ($[51] !== allowSkipLogin || $[52] !== authController || $[53] !== authLoading || $[54] !== autoOpenDrawer || $[55] !== canAccessMainView || $[56] !== components || $[57] !== firebaseApp || $[58] !== logo || $[59] !== logoDark || $[60] !== modeController || $[61] !== name || $[62] !== notAllowedError || $[63] !== signInOptions) {
2612
+ t19 = (t202) => {
2613
+ const {
2614
+ loading: loading_0
2615
+ } = t202;
2616
+ let component;
2617
+ if (loading_0 || authLoading) {
2618
+ component = /* @__PURE__ */ jsx(CircularProgressCenter, { size: "large" });
2619
+ } else {
2620
+ const usedLogo = modeController.mode === "dark" && logoDark ? logoDark : logo;
2621
+ if (!canAccessMainView) {
2622
+ const LoginViewUsed = components?.LoginView ?? FirebaseLoginView;
2623
+ component = /* @__PURE__ */ jsx(LoginViewUsed, { logo: usedLogo, allowSkipLogin, signInOptions: signInOptions ?? DEFAULT_SIGN_IN_OPTIONS, firebaseApp, authController, notAllowedError });
2624
+ } else {
2625
+ component = /* @__PURE__ */ jsx(Routes, { children: /* @__PURE__ */ jsxs(Route, { element: /* @__PURE__ */ jsxs(Scaffold, { logo: usedLogo, autoOpenDrawer, children: [
2626
+ /* @__PURE__ */ jsx(AppBar, { title: name, logo: usedLogo }),
2627
+ /* @__PURE__ */ jsx(Drawer, {}),
2628
+ /* @__PURE__ */ jsx(Outlet, {}),
2629
+ /* @__PURE__ */ jsx(SideDialogs, {})
2630
+ ] }), children: [
2631
+ components?.HomePage && /* @__PURE__ */ jsx(Route, { path: "/", element: /* @__PURE__ */ jsx(components.HomePage, {}) }),
2632
+ /* @__PURE__ */ jsx(Route, { path: "/c/*", element: /* @__PURE__ */ jsx(RebaseRoutes, {}) })
2633
+ ] }) });
2634
+ }
2635
+ }
2636
+ return component;
2637
+ };
2638
+ $[51] = allowSkipLogin;
2639
+ $[52] = authController;
2640
+ $[53] = authLoading;
2641
+ $[54] = autoOpenDrawer;
2642
+ $[55] = canAccessMainView;
2643
+ $[56] = components;
2644
+ $[57] = firebaseApp;
2645
+ $[58] = logo;
2646
+ $[59] = logoDark;
2647
+ $[60] = modeController;
2648
+ $[61] = name;
2649
+ $[62] = notAllowedError;
2650
+ $[63] = signInOptions;
2651
+ $[64] = t19;
2652
+ } else {
2653
+ t19 = $[64];
2654
+ }
2655
+ let t20;
2656
+ if ($[65] !== authController || $[66] !== dateTimeFormat || $[67] !== firestoreDelegate || $[68] !== locale || $[69] !== onAnalyticsEvent || $[70] !== plugins || $[71] !== propertyConfigs || $[72] !== storageSource || $[73] !== t18 || $[74] !== t19 || $[75] !== userConfigPersistence || $[76] !== userManagement) {
2657
+ t20 = /* @__PURE__ */ jsx(Rebase, { authController, userConfigPersistence, dateTimeFormat, driver: firestoreDelegate, storageSource, userManagement, entityLinkBuilder: t18, locale, onAnalyticsEvent, plugins, propertyConfigs, children: t19 });
2658
+ $[65] = authController;
2659
+ $[66] = dateTimeFormat;
2660
+ $[67] = firestoreDelegate;
2661
+ $[68] = locale;
2662
+ $[69] = onAnalyticsEvent;
2663
+ $[70] = plugins;
2664
+ $[71] = propertyConfigs;
2665
+ $[72] = storageSource;
2666
+ $[73] = t18;
2667
+ $[74] = t19;
2668
+ $[75] = userConfigPersistence;
2669
+ $[76] = userManagement;
2670
+ $[77] = t20;
2671
+ } else {
2672
+ t20 = $[77];
2673
+ }
2674
+ let t21;
2675
+ if ($[78] !== navigationStateController || $[79] !== t20) {
2676
+ t21 = /* @__PURE__ */ jsx(NavigationStateContext.Provider, { value: navigationStateController, children: t20 });
2677
+ $[78] = navigationStateController;
2678
+ $[79] = t20;
2679
+ $[80] = t21;
2680
+ } else {
2681
+ t21 = $[80];
2682
+ }
2683
+ let t22;
2684
+ if ($[81] !== t21 || $[82] !== urlController) {
2685
+ t22 = /* @__PURE__ */ jsx(UrlContext.Provider, { value: urlController, children: t21 });
2686
+ $[81] = t21;
2687
+ $[82] = urlController;
2688
+ $[83] = t22;
2689
+ } else {
2690
+ t22 = $[83];
2691
+ }
2692
+ let t23;
2693
+ if ($[84] !== collectionRegistryController || $[85] !== t22) {
2694
+ t23 = /* @__PURE__ */ jsx(CollectionRegistryContext.Provider, { value: collectionRegistryController, children: t22 });
2695
+ $[84] = collectionRegistryController;
2696
+ $[85] = t22;
2697
+ $[86] = t23;
2698
+ } else {
2699
+ t23 = $[86];
2700
+ }
2701
+ let t24;
2702
+ if ($[87] !== adminModeController || $[88] !== t23) {
2703
+ t24 = /* @__PURE__ */ jsx(AdminModeControllerProvider, { value: adminModeController, children: t23 });
2704
+ $[87] = adminModeController;
2705
+ $[88] = t23;
2706
+ $[89] = t24;
2707
+ } else {
2708
+ t24 = $[89];
2709
+ }
2710
+ let t25;
2711
+ if ($[90] !== modeController || $[91] !== t24) {
2712
+ t25 = /* @__PURE__ */ jsx(SnackbarProvider, { children: /* @__PURE__ */ jsx(ModeControllerProvider, { value: modeController, children: t24 }) });
2713
+ $[90] = modeController;
2714
+ $[91] = t24;
2715
+ $[92] = t25;
2716
+ } else {
2717
+ t25 = $[92];
2718
+ }
2719
+ return t25;
2720
+ }
2721
+ function _temp2(a, b) {
2722
+ return {
2723
+ ...a,
2724
+ ...b
2725
+ };
2726
+ }
2727
+ function _temp(pc) {
2728
+ return {
2729
+ [pc.key]: pc
2730
+ };
2731
+ }
2732
+ export {
2733
+ FirebaseLoginView,
2734
+ LoginButton,
2735
+ RECAPTCHA_CONTAINER_ID,
2736
+ RebaseFirebaseApp,
2737
+ buildCollectionId,
2738
+ buildExternalSearchController,
2739
+ buildPineconeSearchController,
2740
+ buildRebaseSearchController,
2741
+ cmsToFirestoreModel,
2742
+ docToCollection,
2743
+ docsToCollectionTree,
2744
+ firestoreToCMSModel,
2745
+ getFirestoreDataInPath,
2746
+ localSearchControllerBuilder,
2747
+ performAlgoliaTextSearch,
2748
+ performPineconeTextSearch,
2749
+ useAppCheck,
2750
+ useFirebaseAuthController,
2751
+ useFirebaseRTDBDelegate,
2752
+ useFirebaseStorageSource,
2753
+ useFirestoreDriver,
2754
+ useInitialiseFirebase,
2755
+ useRecaptcha
2756
+ };
2757
+ //# sourceMappingURL=index.es.js.map