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

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