@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.
- package/LICENSE +21 -0
- package/README.md +4 -0
- package/dist/components/FirebaseLoginView.d.ts +72 -0
- package/dist/components/RebaseFirebaseApp.d.ts +19 -0
- package/dist/components/RebaseFirebaseAppProps.d.ts +144 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/social_icons.d.ts +6 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/useAppCheck.d.ts +20 -0
- package/dist/hooks/useFirebaseAuthController.d.ts +15 -0
- package/dist/hooks/useFirebaseRealTimeDBDelegate.d.ts +5 -0
- package/dist/hooks/useFirebaseStorageSource.d.ts +14 -0
- package/dist/hooks/useFirestoreDriver.d.ts +56 -0
- package/dist/hooks/useInitialiseFirebase.d.ts +34 -0
- package/dist/hooks/useRecaptcha.d.ts +8 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +2757 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +2743 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/social_icons.d.ts +6 -0
- package/dist/types/appcheck.d.ts +10 -0
- package/dist/types/auth.d.ts +41 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/text_search.d.ts +39 -0
- package/dist/utils/algolia.d.ts +9 -0
- package/dist/utils/collections_firestore.d.ts +5 -0
- package/dist/utils/database.d.ts +2 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/local_text_search_controller.d.ts +2 -0
- package/dist/utils/pinecone.d.ts +24 -0
- package/dist/utils/rebase_search_controller.d.ts +73 -0
- package/dist/utils/text_search_controller.d.ts +13 -0
- package/package.json +61 -0
- package/src/components/FirebaseLoginView.tsx +703 -0
- package/src/components/RebaseFirebaseApp.tsx +275 -0
- package/src/components/RebaseFirebaseAppProps.tsx +180 -0
- package/src/components/index.ts +3 -0
- package/src/components/social_icons.tsx +135 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/useAppCheck.ts +101 -0
- package/src/hooks/useFirebaseAuthController.ts +334 -0
- package/src/hooks/useFirebaseRealTimeDBDelegate.ts +269 -0
- package/src/hooks/useFirebaseStorageSource.ts +208 -0
- package/src/hooks/useFirestoreDriver.ts +778 -0
- package/src/hooks/useInitialiseFirebase.ts +132 -0
- package/src/hooks/useRecaptcha.tsx +28 -0
- package/src/index.ts +4 -0
- package/src/social_icons.tsx +135 -0
- package/src/types/appcheck.ts +11 -0
- package/src/types/auth.tsx +74 -0
- package/src/types/index.ts +3 -0
- package/src/types/text_search.ts +42 -0
- package/src/utils/algolia.ts +27 -0
- package/src/utils/collections_firestore.ts +149 -0
- package/src/utils/database.ts +39 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/local_text_search_controller.ts +143 -0
- package/src/utils/pinecone.ts +75 -0
- package/src/utils/rebase_search_controller.ts +356 -0
- 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
|