@marcwelti/mw-core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -0
- package/dist/context/index.d.mts +95 -0
- package/dist/context/index.d.ts +95 -0
- package/dist/context/index.js +280 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/index.mjs +276 -0
- package/dist/context/index.mjs.map +1 -0
- package/dist/firebase/index.d.mts +176 -0
- package/dist/firebase/index.d.ts +176 -0
- package/dist/firebase/index.js +393 -0
- package/dist/firebase/index.js.map +1 -0
- package/dist/firebase/index.mjs +318 -0
- package/dist/firebase/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +97 -0
- package/dist/hooks/index.d.ts +97 -0
- package/dist/hooks/index.js +618 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +611 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +922 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +843 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server/index.d.mts +216 -0
- package/dist/server/index.d.ts +216 -0
- package/dist/server/index.js +309 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +276 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/storage-BU_rfYCi.d.mts +43 -0
- package/dist/storage-BU_rfYCi.d.ts +43 -0
- package/dist/types/index.d.mts +108 -0
- package/dist/types/index.d.ts +108 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/index.mjs +3 -0
- package/dist/types/index.mjs.map +1 -0
- package/package.json +91 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
import { getApps, getApp, initializeApp } from 'firebase/app';
|
|
2
|
+
import { getAuth, signInWithEmailAndPassword, createUserWithEmailAndPassword, updateProfile, signOut as signOut$1, sendPasswordResetEmail, sendEmailVerification, GoogleAuthProvider, signInWithPopup, signInWithRedirect, getRedirectResult, onAuthStateChanged } from 'firebase/auth';
|
|
3
|
+
import { getFirestore, doc, collection, getDoc, query, getDocs, addDoc, serverTimestamp, setDoc, updateDoc, deleteDoc, onSnapshot } from 'firebase/firestore';
|
|
4
|
+
export { limit, orderBy, query, serverTimestamp, startAfter, where } from 'firebase/firestore';
|
|
5
|
+
import { getStorage, ref, uploadBytes, getDownloadURL, uploadBytesResumable, deleteObject, listAll, getMetadata, updateMetadata } from 'firebase/storage';
|
|
6
|
+
import { isSupported, getAnalytics, logEvent } from 'firebase/analytics';
|
|
7
|
+
import { createContext, useState, useEffect, useCallback, useMemo, useContext } from 'react';
|
|
8
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
// src/firebase/config.ts
|
|
11
|
+
function getFirebaseConfig() {
|
|
12
|
+
const config = {
|
|
13
|
+
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY || "",
|
|
14
|
+
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN || "",
|
|
15
|
+
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID || "",
|
|
16
|
+
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET || "",
|
|
17
|
+
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID || "",
|
|
18
|
+
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID || "",
|
|
19
|
+
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID
|
|
20
|
+
};
|
|
21
|
+
const requiredFields = [
|
|
22
|
+
"apiKey",
|
|
23
|
+
"authDomain",
|
|
24
|
+
"projectId",
|
|
25
|
+
"storageBucket",
|
|
26
|
+
"messagingSenderId",
|
|
27
|
+
"appId"
|
|
28
|
+
];
|
|
29
|
+
const missingFields = requiredFields.filter((field) => !config[field]);
|
|
30
|
+
if (missingFields.length > 0) {
|
|
31
|
+
console.warn(
|
|
32
|
+
`[mw-core] Missing Firebase config fields: ${missingFields.join(", ")}. Make sure to set NEXT_PUBLIC_FIREBASE_* environment variables.`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return config;
|
|
36
|
+
}
|
|
37
|
+
function initializeFirebase(config) {
|
|
38
|
+
if (getApps().length > 0) {
|
|
39
|
+
return getApp();
|
|
40
|
+
}
|
|
41
|
+
const firebaseConfig = config || getFirebaseConfig();
|
|
42
|
+
return initializeApp(firebaseConfig);
|
|
43
|
+
}
|
|
44
|
+
var _app = null;
|
|
45
|
+
var _auth = null;
|
|
46
|
+
var _db = null;
|
|
47
|
+
var _storage = null;
|
|
48
|
+
function getFirebaseApp() {
|
|
49
|
+
if (!_app) {
|
|
50
|
+
_app = initializeFirebase();
|
|
51
|
+
}
|
|
52
|
+
return _app;
|
|
53
|
+
}
|
|
54
|
+
function getFirebaseAuth() {
|
|
55
|
+
if (!_auth) {
|
|
56
|
+
_auth = getAuth(getFirebaseApp());
|
|
57
|
+
}
|
|
58
|
+
return _auth;
|
|
59
|
+
}
|
|
60
|
+
function getFirebaseFirestore() {
|
|
61
|
+
if (!_db) {
|
|
62
|
+
_db = getFirestore(getFirebaseApp());
|
|
63
|
+
}
|
|
64
|
+
return _db;
|
|
65
|
+
}
|
|
66
|
+
function getFirebaseStorage() {
|
|
67
|
+
if (!_storage) {
|
|
68
|
+
_storage = getStorage(getFirebaseApp());
|
|
69
|
+
}
|
|
70
|
+
return _storage;
|
|
71
|
+
}
|
|
72
|
+
var app = typeof window !== "undefined" ? getFirebaseApp() : null;
|
|
73
|
+
var auth = typeof window !== "undefined" ? getFirebaseAuth() : null;
|
|
74
|
+
var db = typeof window !== "undefined" ? getFirebaseFirestore() : null;
|
|
75
|
+
var storage = typeof window !== "undefined" ? getFirebaseStorage() : null;
|
|
76
|
+
async function signInWithEmail(email, password) {
|
|
77
|
+
const auth2 = getFirebaseAuth();
|
|
78
|
+
return signInWithEmailAndPassword(auth2, email, password);
|
|
79
|
+
}
|
|
80
|
+
async function signUpWithEmail(email, password, displayName) {
|
|
81
|
+
const auth2 = getFirebaseAuth();
|
|
82
|
+
const credential = await createUserWithEmailAndPassword(auth2, email, password);
|
|
83
|
+
if (displayName && credential.user) {
|
|
84
|
+
await updateProfile(credential.user, { displayName });
|
|
85
|
+
}
|
|
86
|
+
return credential;
|
|
87
|
+
}
|
|
88
|
+
async function signOut() {
|
|
89
|
+
const auth2 = getFirebaseAuth();
|
|
90
|
+
return signOut$1(auth2);
|
|
91
|
+
}
|
|
92
|
+
async function resetPassword(email) {
|
|
93
|
+
const auth2 = getFirebaseAuth();
|
|
94
|
+
return sendPasswordResetEmail(auth2, email);
|
|
95
|
+
}
|
|
96
|
+
async function sendVerificationEmail(user) {
|
|
97
|
+
return sendEmailVerification(user);
|
|
98
|
+
}
|
|
99
|
+
async function updateUserProfile(user, profile) {
|
|
100
|
+
return updateProfile(user, profile);
|
|
101
|
+
}
|
|
102
|
+
async function signInWithGoogle() {
|
|
103
|
+
const auth2 = getFirebaseAuth();
|
|
104
|
+
const provider = new GoogleAuthProvider();
|
|
105
|
+
provider.addScope("email");
|
|
106
|
+
provider.addScope("profile");
|
|
107
|
+
return signInWithPopup(auth2, provider);
|
|
108
|
+
}
|
|
109
|
+
async function signInWithGoogleRedirect() {
|
|
110
|
+
const auth2 = getFirebaseAuth();
|
|
111
|
+
const provider = new GoogleAuthProvider();
|
|
112
|
+
provider.addScope("email");
|
|
113
|
+
provider.addScope("profile");
|
|
114
|
+
return signInWithRedirect(auth2, provider);
|
|
115
|
+
}
|
|
116
|
+
async function getGoogleRedirectResult() {
|
|
117
|
+
const auth2 = getFirebaseAuth();
|
|
118
|
+
return getRedirectResult(auth2);
|
|
119
|
+
}
|
|
120
|
+
function subscribeToAuthState(callback) {
|
|
121
|
+
const auth2 = getFirebaseAuth();
|
|
122
|
+
return onAuthStateChanged(auth2, callback);
|
|
123
|
+
}
|
|
124
|
+
function getCurrentUser() {
|
|
125
|
+
const auth2 = getFirebaseAuth();
|
|
126
|
+
return auth2.currentUser;
|
|
127
|
+
}
|
|
128
|
+
function waitForAuthState() {
|
|
129
|
+
return new Promise((resolve) => {
|
|
130
|
+
const auth2 = getFirebaseAuth();
|
|
131
|
+
const unsubscribe = onAuthStateChanged(auth2, (user) => {
|
|
132
|
+
unsubscribe();
|
|
133
|
+
resolve(user);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function getDocRef(collectionPath, documentId) {
|
|
138
|
+
const db2 = getFirebaseFirestore();
|
|
139
|
+
return doc(db2, collectionPath, documentId);
|
|
140
|
+
}
|
|
141
|
+
function getCollectionRef(collectionPath) {
|
|
142
|
+
const db2 = getFirebaseFirestore();
|
|
143
|
+
return collection(db2, collectionPath);
|
|
144
|
+
}
|
|
145
|
+
async function getDocument(collectionPath, documentId) {
|
|
146
|
+
const docRef = getDocRef(collectionPath, documentId);
|
|
147
|
+
const docSnap = await getDoc(docRef);
|
|
148
|
+
if (docSnap.exists()) {
|
|
149
|
+
return { id: docSnap.id, ...docSnap.data() };
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
async function getCollection(collectionPath, constraints = []) {
|
|
154
|
+
const collectionRef = getCollectionRef(collectionPath);
|
|
155
|
+
const q = query(collectionRef, ...constraints);
|
|
156
|
+
const querySnapshot = await getDocs(q);
|
|
157
|
+
return querySnapshot.docs.map((doc2) => ({
|
|
158
|
+
id: doc2.id,
|
|
159
|
+
...doc2.data()
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
async function addDocument(collectionPath, data) {
|
|
163
|
+
const collectionRef = getCollectionRef(collectionPath);
|
|
164
|
+
const docRef = await addDoc(collectionRef, {
|
|
165
|
+
...data,
|
|
166
|
+
createdAt: serverTimestamp(),
|
|
167
|
+
updatedAt: serverTimestamp()
|
|
168
|
+
});
|
|
169
|
+
return docRef.id;
|
|
170
|
+
}
|
|
171
|
+
async function setDocument(collectionPath, documentId, data, merge = false) {
|
|
172
|
+
const docRef = getDocRef(collectionPath, documentId);
|
|
173
|
+
await setDoc(
|
|
174
|
+
docRef,
|
|
175
|
+
{
|
|
176
|
+
...data,
|
|
177
|
+
updatedAt: serverTimestamp(),
|
|
178
|
+
...merge ? {} : { createdAt: serverTimestamp() }
|
|
179
|
+
},
|
|
180
|
+
{ merge }
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
async function updateDocument(collectionPath, documentId, data) {
|
|
184
|
+
const docRef = getDocRef(collectionPath, documentId);
|
|
185
|
+
await updateDoc(docRef, {
|
|
186
|
+
...data,
|
|
187
|
+
updatedAt: serverTimestamp()
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async function deleteDocument(collectionPath, documentId) {
|
|
191
|
+
const docRef = getDocRef(collectionPath, documentId);
|
|
192
|
+
await deleteDoc(docRef);
|
|
193
|
+
}
|
|
194
|
+
function subscribeToDocument(collectionPath, documentId, callback) {
|
|
195
|
+
const docRef = getDocRef(collectionPath, documentId);
|
|
196
|
+
return onSnapshot(docRef, (docSnap) => {
|
|
197
|
+
if (docSnap.exists()) {
|
|
198
|
+
callback({ id: docSnap.id, ...docSnap.data() });
|
|
199
|
+
} else {
|
|
200
|
+
callback(null);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function subscribeToCollection(collectionPath, callback, constraints = []) {
|
|
205
|
+
const collectionRef = getCollectionRef(collectionPath);
|
|
206
|
+
const q = query(collectionRef, ...constraints);
|
|
207
|
+
return onSnapshot(q, (querySnapshot) => {
|
|
208
|
+
const data = querySnapshot.docs.map((doc2) => ({
|
|
209
|
+
id: doc2.id,
|
|
210
|
+
...doc2.data()
|
|
211
|
+
}));
|
|
212
|
+
callback(data);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
function getStorageRef(path) {
|
|
216
|
+
const storage2 = getFirebaseStorage();
|
|
217
|
+
return ref(storage2, path);
|
|
218
|
+
}
|
|
219
|
+
async function uploadFile(path, file, metadata) {
|
|
220
|
+
const storageRef = getStorageRef(path);
|
|
221
|
+
await uploadBytes(storageRef, file, metadata);
|
|
222
|
+
return getDownloadURL(storageRef);
|
|
223
|
+
}
|
|
224
|
+
function uploadFileWithProgress(path, file, onProgress, metadata) {
|
|
225
|
+
const storageRef = getStorageRef(path);
|
|
226
|
+
const task = uploadBytesResumable(storageRef, file, metadata);
|
|
227
|
+
if (onProgress) {
|
|
228
|
+
task.on("state_changed", (snapshot) => {
|
|
229
|
+
const progress = snapshot.bytesTransferred / snapshot.totalBytes * 100;
|
|
230
|
+
onProgress(progress);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
const promise = new Promise((resolve, reject) => {
|
|
234
|
+
task.on(
|
|
235
|
+
"state_changed",
|
|
236
|
+
null,
|
|
237
|
+
(error) => reject(error),
|
|
238
|
+
async () => {
|
|
239
|
+
const url = await getDownloadURL(task.snapshot.ref);
|
|
240
|
+
resolve(url);
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
});
|
|
244
|
+
return { task, promise };
|
|
245
|
+
}
|
|
246
|
+
async function getFileURL(path) {
|
|
247
|
+
const storageRef = getStorageRef(path);
|
|
248
|
+
return getDownloadURL(storageRef);
|
|
249
|
+
}
|
|
250
|
+
async function deleteFile(path) {
|
|
251
|
+
const storageRef = getStorageRef(path);
|
|
252
|
+
return deleteObject(storageRef);
|
|
253
|
+
}
|
|
254
|
+
async function listFiles(path) {
|
|
255
|
+
const storageRef = getStorageRef(path);
|
|
256
|
+
return listAll(storageRef);
|
|
257
|
+
}
|
|
258
|
+
async function getFileMetadata(path) {
|
|
259
|
+
const storageRef = getStorageRef(path);
|
|
260
|
+
return getMetadata(storageRef);
|
|
261
|
+
}
|
|
262
|
+
async function updateFileMetadata(path, metadata) {
|
|
263
|
+
const storageRef = getStorageRef(path);
|
|
264
|
+
return updateMetadata(storageRef, metadata);
|
|
265
|
+
}
|
|
266
|
+
function generateFilePath(folder, filename, userId) {
|
|
267
|
+
const timestamp = Date.now();
|
|
268
|
+
const extension = filename.split(".").pop() || "";
|
|
269
|
+
const baseName = filename.replace(/\.[^/.]+$/, "");
|
|
270
|
+
const sanitizedName = baseName.replace(/[^a-zA-Z0-9]/g, "_");
|
|
271
|
+
if (userId) {
|
|
272
|
+
return `${folder}/${userId}/${timestamp}_${sanitizedName}.${extension}`;
|
|
273
|
+
}
|
|
274
|
+
return `${folder}/${timestamp}_${sanitizedName}.${extension}`;
|
|
275
|
+
}
|
|
276
|
+
var _analytics = null;
|
|
277
|
+
async function getFirebaseAnalytics() {
|
|
278
|
+
if (typeof window === "undefined") {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
if (_analytics) {
|
|
282
|
+
return _analytics;
|
|
283
|
+
}
|
|
284
|
+
const supported = await isSupported();
|
|
285
|
+
if (!supported) {
|
|
286
|
+
console.warn("[mw-core] Firebase Analytics is not supported in this environment");
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
_analytics = getAnalytics(getFirebaseApp());
|
|
290
|
+
return _analytics;
|
|
291
|
+
}
|
|
292
|
+
async function trackEvent(eventName, eventParams) {
|
|
293
|
+
const analytics = await getFirebaseAnalytics();
|
|
294
|
+
if (analytics) {
|
|
295
|
+
logEvent(analytics, eventName, eventParams);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async function trackPageView(pagePath, pageTitle) {
|
|
299
|
+
await trackEvent("page_view", {
|
|
300
|
+
page_path: pagePath,
|
|
301
|
+
page_title: pageTitle
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
async function trackUserAction(action, category, label, value) {
|
|
305
|
+
await trackEvent(action, {
|
|
306
|
+
event_category: category,
|
|
307
|
+
event_label: label,
|
|
308
|
+
value
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
async function trackSignUp(method) {
|
|
312
|
+
await trackEvent("sign_up", { method });
|
|
313
|
+
}
|
|
314
|
+
async function trackLogin(method) {
|
|
315
|
+
await trackEvent("login", { method });
|
|
316
|
+
}
|
|
317
|
+
function useAuth() {
|
|
318
|
+
const [user, setUser] = useState(null);
|
|
319
|
+
const [loading, setLoading] = useState(true);
|
|
320
|
+
const [error, setError] = useState(null);
|
|
321
|
+
useEffect(() => {
|
|
322
|
+
const unsubscribe = subscribeToAuthState((user2) => {
|
|
323
|
+
setUser(user2);
|
|
324
|
+
setLoading(false);
|
|
325
|
+
});
|
|
326
|
+
return unsubscribe;
|
|
327
|
+
}, []);
|
|
328
|
+
const signIn = useCallback(async (email, password) => {
|
|
329
|
+
setError(null);
|
|
330
|
+
try {
|
|
331
|
+
return await signInWithEmail(email, password);
|
|
332
|
+
} catch (err) {
|
|
333
|
+
const error2 = err;
|
|
334
|
+
setError(error2);
|
|
335
|
+
throw error2;
|
|
336
|
+
}
|
|
337
|
+
}, []);
|
|
338
|
+
const signUp = useCallback(
|
|
339
|
+
async (email, password, displayName) => {
|
|
340
|
+
setError(null);
|
|
341
|
+
try {
|
|
342
|
+
return await signUpWithEmail(email, password, displayName);
|
|
343
|
+
} catch (err) {
|
|
344
|
+
const error2 = err;
|
|
345
|
+
setError(error2);
|
|
346
|
+
throw error2;
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
[]
|
|
350
|
+
);
|
|
351
|
+
const signOut2 = useCallback(async () => {
|
|
352
|
+
setError(null);
|
|
353
|
+
try {
|
|
354
|
+
await signOut();
|
|
355
|
+
} catch (err) {
|
|
356
|
+
const error2 = err;
|
|
357
|
+
setError(error2);
|
|
358
|
+
throw error2;
|
|
359
|
+
}
|
|
360
|
+
}, []);
|
|
361
|
+
const signInWithGoogle2 = useCallback(async () => {
|
|
362
|
+
setError(null);
|
|
363
|
+
try {
|
|
364
|
+
return await signInWithGoogle();
|
|
365
|
+
} catch (err) {
|
|
366
|
+
const error2 = err;
|
|
367
|
+
setError(error2);
|
|
368
|
+
throw error2;
|
|
369
|
+
}
|
|
370
|
+
}, []);
|
|
371
|
+
const resetPassword2 = useCallback(async (email) => {
|
|
372
|
+
setError(null);
|
|
373
|
+
try {
|
|
374
|
+
await resetPassword(email);
|
|
375
|
+
} catch (err) {
|
|
376
|
+
const error2 = err;
|
|
377
|
+
setError(error2);
|
|
378
|
+
throw error2;
|
|
379
|
+
}
|
|
380
|
+
}, []);
|
|
381
|
+
const updateProfile2 = useCallback(
|
|
382
|
+
async (profile) => {
|
|
383
|
+
setError(null);
|
|
384
|
+
if (!user) {
|
|
385
|
+
const error2 = new Error("No authenticated user");
|
|
386
|
+
setError(error2);
|
|
387
|
+
throw error2;
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
await updateUserProfile(user, profile);
|
|
391
|
+
} catch (err) {
|
|
392
|
+
const error2 = err;
|
|
393
|
+
setError(error2);
|
|
394
|
+
throw error2;
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
[user]
|
|
398
|
+
);
|
|
399
|
+
const sendEmailVerificationFn = useCallback(async () => {
|
|
400
|
+
setError(null);
|
|
401
|
+
if (!user) {
|
|
402
|
+
const error2 = new Error("No authenticated user");
|
|
403
|
+
setError(error2);
|
|
404
|
+
throw error2;
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
await sendVerificationEmail(user);
|
|
408
|
+
} catch (err) {
|
|
409
|
+
const error2 = err;
|
|
410
|
+
setError(error2);
|
|
411
|
+
throw error2;
|
|
412
|
+
}
|
|
413
|
+
}, [user]);
|
|
414
|
+
const clearError = useCallback(() => {
|
|
415
|
+
setError(null);
|
|
416
|
+
}, []);
|
|
417
|
+
return {
|
|
418
|
+
user,
|
|
419
|
+
loading,
|
|
420
|
+
error,
|
|
421
|
+
signIn,
|
|
422
|
+
signUp,
|
|
423
|
+
signOut: signOut2,
|
|
424
|
+
signInWithGoogle: signInWithGoogle2,
|
|
425
|
+
resetPassword: resetPassword2,
|
|
426
|
+
updateProfile: updateProfile2,
|
|
427
|
+
sendEmailVerification: sendEmailVerificationFn,
|
|
428
|
+
clearError
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function useDocument(collectionPath, documentId, options = {}) {
|
|
432
|
+
const { subscribe = false } = options;
|
|
433
|
+
const [data, setData] = useState(null);
|
|
434
|
+
const [loading, setLoading] = useState(true);
|
|
435
|
+
const [error, setError] = useState(null);
|
|
436
|
+
useEffect(() => {
|
|
437
|
+
if (!documentId) {
|
|
438
|
+
setData(null);
|
|
439
|
+
setLoading(false);
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
setLoading(true);
|
|
443
|
+
setError(null);
|
|
444
|
+
if (subscribe) {
|
|
445
|
+
const unsubscribe = subscribeToDocument(
|
|
446
|
+
collectionPath,
|
|
447
|
+
documentId,
|
|
448
|
+
(doc2) => {
|
|
449
|
+
setData(doc2);
|
|
450
|
+
setLoading(false);
|
|
451
|
+
}
|
|
452
|
+
);
|
|
453
|
+
return unsubscribe;
|
|
454
|
+
} else {
|
|
455
|
+
getDocument(collectionPath, documentId).then((doc2) => {
|
|
456
|
+
setData(doc2);
|
|
457
|
+
setLoading(false);
|
|
458
|
+
}).catch((err) => {
|
|
459
|
+
setError(err);
|
|
460
|
+
setLoading(false);
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}, [collectionPath, documentId, subscribe]);
|
|
464
|
+
const refresh = useCallback(async () => {
|
|
465
|
+
if (!documentId) return;
|
|
466
|
+
setLoading(true);
|
|
467
|
+
try {
|
|
468
|
+
const doc2 = await getDocument(collectionPath, documentId);
|
|
469
|
+
setData(doc2);
|
|
470
|
+
} catch (err) {
|
|
471
|
+
setError(err);
|
|
472
|
+
} finally {
|
|
473
|
+
setLoading(false);
|
|
474
|
+
}
|
|
475
|
+
}, [collectionPath, documentId]);
|
|
476
|
+
return { data, loading, error, refresh };
|
|
477
|
+
}
|
|
478
|
+
function useCollection(collectionPath, constraints = [], options = {}) {
|
|
479
|
+
const { subscribe = false } = options;
|
|
480
|
+
const [data, setData] = useState([]);
|
|
481
|
+
const [loading, setLoading] = useState(true);
|
|
482
|
+
const [error, setError] = useState(null);
|
|
483
|
+
const constraintsKey = JSON.stringify(
|
|
484
|
+
constraints.map((c) => c.type)
|
|
485
|
+
);
|
|
486
|
+
useEffect(() => {
|
|
487
|
+
setLoading(true);
|
|
488
|
+
setError(null);
|
|
489
|
+
if (subscribe) {
|
|
490
|
+
const unsubscribe = subscribeToCollection(
|
|
491
|
+
collectionPath,
|
|
492
|
+
(docs) => {
|
|
493
|
+
setData(docs);
|
|
494
|
+
setLoading(false);
|
|
495
|
+
},
|
|
496
|
+
constraints
|
|
497
|
+
);
|
|
498
|
+
return unsubscribe;
|
|
499
|
+
} else {
|
|
500
|
+
getCollection(collectionPath, constraints).then((docs) => {
|
|
501
|
+
setData(docs);
|
|
502
|
+
setLoading(false);
|
|
503
|
+
}).catch((err) => {
|
|
504
|
+
setError(err);
|
|
505
|
+
setLoading(false);
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
}, [collectionPath, constraintsKey, subscribe]);
|
|
509
|
+
const refresh = useCallback(async () => {
|
|
510
|
+
setLoading(true);
|
|
511
|
+
try {
|
|
512
|
+
const docs = await getCollection(collectionPath, constraints);
|
|
513
|
+
setData(docs);
|
|
514
|
+
} catch (err) {
|
|
515
|
+
setError(err);
|
|
516
|
+
} finally {
|
|
517
|
+
setLoading(false);
|
|
518
|
+
}
|
|
519
|
+
}, [collectionPath, constraintsKey]);
|
|
520
|
+
return { data, loading, error, refresh };
|
|
521
|
+
}
|
|
522
|
+
function useFirestoreMutation(collectionPath) {
|
|
523
|
+
const [loading, setLoading] = useState(false);
|
|
524
|
+
const [error, setError] = useState(null);
|
|
525
|
+
const add = useCallback(
|
|
526
|
+
async (data) => {
|
|
527
|
+
setLoading(true);
|
|
528
|
+
setError(null);
|
|
529
|
+
try {
|
|
530
|
+
const id = await addDocument(collectionPath, data);
|
|
531
|
+
return id;
|
|
532
|
+
} catch (err) {
|
|
533
|
+
setError(err);
|
|
534
|
+
throw err;
|
|
535
|
+
} finally {
|
|
536
|
+
setLoading(false);
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
[collectionPath]
|
|
540
|
+
);
|
|
541
|
+
const set = useCallback(
|
|
542
|
+
async (documentId, data, merge = false) => {
|
|
543
|
+
setLoading(true);
|
|
544
|
+
setError(null);
|
|
545
|
+
try {
|
|
546
|
+
await setDocument(collectionPath, documentId, data, merge);
|
|
547
|
+
} catch (err) {
|
|
548
|
+
setError(err);
|
|
549
|
+
throw err;
|
|
550
|
+
} finally {
|
|
551
|
+
setLoading(false);
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
[collectionPath]
|
|
555
|
+
);
|
|
556
|
+
const update = useCallback(
|
|
557
|
+
async (documentId, data) => {
|
|
558
|
+
setLoading(true);
|
|
559
|
+
setError(null);
|
|
560
|
+
try {
|
|
561
|
+
await updateDocument(collectionPath, documentId, data);
|
|
562
|
+
} catch (err) {
|
|
563
|
+
setError(err);
|
|
564
|
+
throw err;
|
|
565
|
+
} finally {
|
|
566
|
+
setLoading(false);
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
[collectionPath]
|
|
570
|
+
);
|
|
571
|
+
const remove = useCallback(
|
|
572
|
+
async (documentId) => {
|
|
573
|
+
setLoading(true);
|
|
574
|
+
setError(null);
|
|
575
|
+
try {
|
|
576
|
+
await deleteDocument(collectionPath, documentId);
|
|
577
|
+
} catch (err) {
|
|
578
|
+
setError(err);
|
|
579
|
+
throw err;
|
|
580
|
+
} finally {
|
|
581
|
+
setLoading(false);
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
[collectionPath]
|
|
585
|
+
);
|
|
586
|
+
const clearError = useCallback(() => {
|
|
587
|
+
setError(null);
|
|
588
|
+
}, []);
|
|
589
|
+
return {
|
|
590
|
+
add,
|
|
591
|
+
set,
|
|
592
|
+
update,
|
|
593
|
+
remove,
|
|
594
|
+
loading,
|
|
595
|
+
error,
|
|
596
|
+
clearError
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
function useStorage() {
|
|
600
|
+
const [uploading, setUploading] = useState(false);
|
|
601
|
+
const [progress, setProgress] = useState(0);
|
|
602
|
+
const [error, setError] = useState(null);
|
|
603
|
+
const upload = useCallback(
|
|
604
|
+
async (path, file, metadata) => {
|
|
605
|
+
setError(null);
|
|
606
|
+
setUploading(true);
|
|
607
|
+
setProgress(0);
|
|
608
|
+
try {
|
|
609
|
+
const url = await uploadFile(path, file, metadata);
|
|
610
|
+
setProgress(100);
|
|
611
|
+
return url;
|
|
612
|
+
} catch (err) {
|
|
613
|
+
const error2 = err;
|
|
614
|
+
setError(error2);
|
|
615
|
+
throw error2;
|
|
616
|
+
} finally {
|
|
617
|
+
setUploading(false);
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
[]
|
|
621
|
+
);
|
|
622
|
+
const uploadWithProgress = useCallback(
|
|
623
|
+
async (path, file, metadata) => {
|
|
624
|
+
setError(null);
|
|
625
|
+
setUploading(true);
|
|
626
|
+
setProgress(0);
|
|
627
|
+
try {
|
|
628
|
+
const { promise } = uploadFileWithProgress(
|
|
629
|
+
path,
|
|
630
|
+
file,
|
|
631
|
+
(p) => setProgress(p),
|
|
632
|
+
metadata
|
|
633
|
+
);
|
|
634
|
+
const url = await promise;
|
|
635
|
+
return url;
|
|
636
|
+
} catch (err) {
|
|
637
|
+
const error2 = err;
|
|
638
|
+
setError(error2);
|
|
639
|
+
throw error2;
|
|
640
|
+
} finally {
|
|
641
|
+
setUploading(false);
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
[]
|
|
645
|
+
);
|
|
646
|
+
const remove = useCallback(async (path) => {
|
|
647
|
+
setError(null);
|
|
648
|
+
try {
|
|
649
|
+
await deleteFile(path);
|
|
650
|
+
} catch (err) {
|
|
651
|
+
const error2 = err;
|
|
652
|
+
setError(error2);
|
|
653
|
+
throw error2;
|
|
654
|
+
}
|
|
655
|
+
}, []);
|
|
656
|
+
const getURL = useCallback(async (path) => {
|
|
657
|
+
setError(null);
|
|
658
|
+
try {
|
|
659
|
+
return await getFileURL(path);
|
|
660
|
+
} catch (err) {
|
|
661
|
+
const error2 = err;
|
|
662
|
+
setError(error2);
|
|
663
|
+
throw error2;
|
|
664
|
+
}
|
|
665
|
+
}, []);
|
|
666
|
+
const clearError = useCallback(() => {
|
|
667
|
+
setError(null);
|
|
668
|
+
}, []);
|
|
669
|
+
return {
|
|
670
|
+
upload,
|
|
671
|
+
uploadWithProgress,
|
|
672
|
+
remove,
|
|
673
|
+
getURL,
|
|
674
|
+
uploading,
|
|
675
|
+
progress,
|
|
676
|
+
error,
|
|
677
|
+
clearError
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
var AuthContext = createContext(void 0);
|
|
681
|
+
function AuthProvider({
|
|
682
|
+
children,
|
|
683
|
+
onAuthStateChange,
|
|
684
|
+
loadingComponent
|
|
685
|
+
}) {
|
|
686
|
+
const [user, setUser] = useState(null);
|
|
687
|
+
const [loading, setLoading] = useState(true);
|
|
688
|
+
const [error, setError] = useState(null);
|
|
689
|
+
useEffect(() => {
|
|
690
|
+
const unsubscribe = subscribeToAuthState((user2) => {
|
|
691
|
+
setUser(user2);
|
|
692
|
+
setLoading(false);
|
|
693
|
+
onAuthStateChange?.(user2);
|
|
694
|
+
});
|
|
695
|
+
return unsubscribe;
|
|
696
|
+
}, [onAuthStateChange]);
|
|
697
|
+
const signIn = useCallback(async (email, password) => {
|
|
698
|
+
setError(null);
|
|
699
|
+
try {
|
|
700
|
+
return await signInWithEmail(email, password);
|
|
701
|
+
} catch (err) {
|
|
702
|
+
const error2 = err;
|
|
703
|
+
setError(error2);
|
|
704
|
+
throw error2;
|
|
705
|
+
}
|
|
706
|
+
}, []);
|
|
707
|
+
const signUp = useCallback(
|
|
708
|
+
async (email, password, displayName) => {
|
|
709
|
+
setError(null);
|
|
710
|
+
try {
|
|
711
|
+
return await signUpWithEmail(email, password, displayName);
|
|
712
|
+
} catch (err) {
|
|
713
|
+
const error2 = err;
|
|
714
|
+
setError(error2);
|
|
715
|
+
throw error2;
|
|
716
|
+
}
|
|
717
|
+
},
|
|
718
|
+
[]
|
|
719
|
+
);
|
|
720
|
+
const signOut2 = useCallback(async () => {
|
|
721
|
+
setError(null);
|
|
722
|
+
try {
|
|
723
|
+
await signOut();
|
|
724
|
+
} catch (err) {
|
|
725
|
+
const error2 = err;
|
|
726
|
+
setError(error2);
|
|
727
|
+
throw error2;
|
|
728
|
+
}
|
|
729
|
+
}, []);
|
|
730
|
+
const signInWithGoogle2 = useCallback(async () => {
|
|
731
|
+
setError(null);
|
|
732
|
+
try {
|
|
733
|
+
return await signInWithGoogle();
|
|
734
|
+
} catch (err) {
|
|
735
|
+
const error2 = err;
|
|
736
|
+
setError(error2);
|
|
737
|
+
throw error2;
|
|
738
|
+
}
|
|
739
|
+
}, []);
|
|
740
|
+
const resetPassword2 = useCallback(async (email) => {
|
|
741
|
+
setError(null);
|
|
742
|
+
try {
|
|
743
|
+
await resetPassword(email);
|
|
744
|
+
} catch (err) {
|
|
745
|
+
const error2 = err;
|
|
746
|
+
setError(error2);
|
|
747
|
+
throw error2;
|
|
748
|
+
}
|
|
749
|
+
}, []);
|
|
750
|
+
const updateProfile2 = useCallback(
|
|
751
|
+
async (profile) => {
|
|
752
|
+
setError(null);
|
|
753
|
+
if (!user) {
|
|
754
|
+
const error2 = new Error("No authenticated user");
|
|
755
|
+
setError(error2);
|
|
756
|
+
throw error2;
|
|
757
|
+
}
|
|
758
|
+
try {
|
|
759
|
+
await updateUserProfile(user, profile);
|
|
760
|
+
} catch (err) {
|
|
761
|
+
const error2 = err;
|
|
762
|
+
setError(error2);
|
|
763
|
+
throw error2;
|
|
764
|
+
}
|
|
765
|
+
},
|
|
766
|
+
[user]
|
|
767
|
+
);
|
|
768
|
+
const sendEmailVerificationFn = useCallback(async () => {
|
|
769
|
+
setError(null);
|
|
770
|
+
if (!user) {
|
|
771
|
+
const error2 = new Error("No authenticated user");
|
|
772
|
+
setError(error2);
|
|
773
|
+
throw error2;
|
|
774
|
+
}
|
|
775
|
+
try {
|
|
776
|
+
await sendVerificationEmail(user);
|
|
777
|
+
} catch (err) {
|
|
778
|
+
const error2 = err;
|
|
779
|
+
setError(error2);
|
|
780
|
+
throw error2;
|
|
781
|
+
}
|
|
782
|
+
}, [user]);
|
|
783
|
+
const clearError = useCallback(() => {
|
|
784
|
+
setError(null);
|
|
785
|
+
}, []);
|
|
786
|
+
const value = useMemo(
|
|
787
|
+
() => ({
|
|
788
|
+
user,
|
|
789
|
+
loading,
|
|
790
|
+
isAuthenticated: !!user,
|
|
791
|
+
error,
|
|
792
|
+
signIn,
|
|
793
|
+
signUp,
|
|
794
|
+
signOut: signOut2,
|
|
795
|
+
signInWithGoogle: signInWithGoogle2,
|
|
796
|
+
resetPassword: resetPassword2,
|
|
797
|
+
updateProfile: updateProfile2,
|
|
798
|
+
sendEmailVerification: sendEmailVerificationFn,
|
|
799
|
+
clearError
|
|
800
|
+
}),
|
|
801
|
+
[
|
|
802
|
+
user,
|
|
803
|
+
loading,
|
|
804
|
+
error,
|
|
805
|
+
signIn,
|
|
806
|
+
signUp,
|
|
807
|
+
signOut2,
|
|
808
|
+
signInWithGoogle2,
|
|
809
|
+
resetPassword2,
|
|
810
|
+
updateProfile2,
|
|
811
|
+
sendEmailVerificationFn,
|
|
812
|
+
clearError
|
|
813
|
+
]
|
|
814
|
+
);
|
|
815
|
+
if (loading && loadingComponent) {
|
|
816
|
+
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent });
|
|
817
|
+
}
|
|
818
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
|
|
819
|
+
}
|
|
820
|
+
function useAuthContext() {
|
|
821
|
+
const context = useContext(AuthContext);
|
|
822
|
+
if (context === void 0) {
|
|
823
|
+
throw new Error("useAuthContext must be used within an AuthProvider");
|
|
824
|
+
}
|
|
825
|
+
return context;
|
|
826
|
+
}
|
|
827
|
+
function withAuth(WrappedComponent, options = {}) {
|
|
828
|
+
const { LoadingComponent, UnauthenticatedComponent } = options;
|
|
829
|
+
return function WithAuthComponent(props) {
|
|
830
|
+
const { user, loading, isAuthenticated } = useAuthContext();
|
|
831
|
+
if (loading) {
|
|
832
|
+
return LoadingComponent ? /* @__PURE__ */ jsx(LoadingComponent, {}) : /* @__PURE__ */ jsx("div", { children: "Loading..." });
|
|
833
|
+
}
|
|
834
|
+
if (!isAuthenticated) {
|
|
835
|
+
return UnauthenticatedComponent ? /* @__PURE__ */ jsx(UnauthenticatedComponent, {}) : /* @__PURE__ */ jsx("div", { children: "Please sign in to continue" });
|
|
836
|
+
}
|
|
837
|
+
return /* @__PURE__ */ jsx(WrappedComponent, { ...props });
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
export { AuthProvider, addDocument, app, auth, db, deleteDocument, deleteFile, generateFilePath, getCollection, getCollectionRef, getCurrentUser, getDocRef, getDocument, getFileMetadata, getFileURL, getFirebaseAnalytics, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, getFirebaseFirestore, getFirebaseStorage, getGoogleRedirectResult, getStorageRef, initializeFirebase, listFiles, resetPassword, sendVerificationEmail, setDocument, signInWithEmail, signInWithGoogle, signInWithGoogleRedirect, signOut, signUpWithEmail, storage, subscribeToAuthState, subscribeToCollection, subscribeToDocument, trackEvent, trackLogin, trackPageView, trackSignUp, trackUserAction, updateDocument, updateFileMetadata, updateUserProfile, uploadFile, uploadFileWithProgress, useAuth, useAuthContext, useCollection, useDocument, useFirestoreMutation, useStorage, waitForAuthState, withAuth };
|
|
842
|
+
//# sourceMappingURL=index.mjs.map
|
|
843
|
+
//# sourceMappingURL=index.mjs.map
|