@rebasepro/firebase 0.0.1-canary.0

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