@umituz/web-firebase 2.1.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/package.json +12 -39
  2. package/src/domains/auth/entities/index.ts +60 -0
  3. package/src/domains/auth/index.ts +13 -0
  4. package/src/domains/auth/services/auth.service.ts +245 -0
  5. package/src/domains/auth/services/index.ts +7 -0
  6. package/src/domains/auth/types/auth-service.interface.ts +72 -0
  7. package/src/domains/auth/types/index.ts +5 -0
  8. package/src/domains/firestore/entities/index.ts +82 -0
  9. package/src/domains/firestore/index.ts +13 -0
  10. package/src/domains/firestore/services/firestore.service.ts +191 -0
  11. package/src/domains/firestore/services/index.ts +7 -0
  12. package/src/domains/firestore/types/firestore-service.interface.ts +64 -0
  13. package/src/domains/firestore/types/index.ts +5 -0
  14. package/src/domains/storage/entities/index.ts +94 -0
  15. package/src/domains/storage/index.ts +13 -0
  16. package/src/domains/storage/services/index.ts +7 -0
  17. package/src/domains/storage/services/storage.service.ts +223 -0
  18. package/src/domains/storage/types/index.ts +5 -0
  19. package/src/domains/storage/types/storage-service.interface.ts +120 -0
  20. package/src/index.ts +12 -16
  21. package/src/presentation/hooks/useAuth.ts +69 -26
  22. package/src/presentation/providers/FirebaseProvider.tsx +9 -14
  23. package/dist/application/index.d.mts +0 -273
  24. package/dist/application/index.d.ts +0 -273
  25. package/dist/application/index.js +0 -490
  26. package/dist/application/index.mjs +0 -19
  27. package/dist/chunk-34DL2QWQ.mjs +0 -87
  28. package/dist/chunk-4FP2ELQ5.mjs +0 -96
  29. package/dist/chunk-7TX3OU3O.mjs +0 -721
  30. package/dist/chunk-I6WGBPFB.mjs +0 -439
  31. package/dist/chunk-RZ4QR6TB.mjs +0 -96
  32. package/dist/chunk-U2XI4MGO.mjs +0 -397
  33. package/dist/domain/index.d.mts +0 -325
  34. package/dist/domain/index.d.ts +0 -325
  35. package/dist/domain/index.js +0 -662
  36. package/dist/domain/index.mjs +0 -36
  37. package/dist/file.repository.interface-v5vHgVsZ.d.mts +0 -241
  38. package/dist/file.repository.interface-v5vHgVsZ.d.ts +0 -241
  39. package/dist/firebase.entity-xvfEPjXZ.d.mts +0 -15
  40. package/dist/firebase.entity-xvfEPjXZ.d.ts +0 -15
  41. package/dist/index.d.mts +0 -14
  42. package/dist/index.d.ts +0 -14
  43. package/dist/index.js +0 -1833
  44. package/dist/index.mjs +0 -98
  45. package/dist/infrastructure/index.d.mts +0 -170
  46. package/dist/infrastructure/index.d.ts +0 -170
  47. package/dist/infrastructure/index.js +0 -856
  48. package/dist/infrastructure/index.mjs +0 -46
  49. package/dist/presentation/index.d.mts +0 -25
  50. package/dist/presentation/index.d.ts +0 -25
  51. package/dist/presentation/index.js +0 -105
  52. package/dist/presentation/index.mjs +0 -6
  53. package/dist/user.repository.interface-DS74TsJ5.d.mts +0 -298
  54. package/dist/user.repository.interface-DS74TsJ5.d.ts +0 -298
@@ -1,856 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/infrastructure/index.ts
21
- var infrastructure_exports = {};
22
- __export(infrastructure_exports, {
23
- AuthAdapter: () => AuthAdapter,
24
- FirestoreAdapter: () => FirestoreAdapter,
25
- StorageAdapter: () => StorageAdapter,
26
- analytics: () => analytics,
27
- app: () => app,
28
- auth: () => auth,
29
- db: () => db,
30
- deleteFile: () => deleteFile,
31
- functions: () => functions,
32
- getFirebaseAnalytics: () => getFirebaseAnalytics,
33
- getFirebaseApp: () => getFirebaseApp,
34
- getFirebaseAuth: () => getFirebaseAuth,
35
- getFirebaseDB: () => getFirebaseDB,
36
- getFirebaseFunctions: () => getFirebaseFunctions,
37
- getFirebaseInstances: () => getFirebaseInstances,
38
- getFirebaseStorage: () => getFirebaseStorage,
39
- initializeFirebase: () => initializeFirebase,
40
- storage: () => storage,
41
- uploadBase64: () => uploadBase64,
42
- uploadFile: () => uploadFile
43
- });
44
- module.exports = __toCommonJS(infrastructure_exports);
45
-
46
- // src/infrastructure/firebase/client.ts
47
- var import_app = require("firebase/app");
48
- var import_auth = require("firebase/auth");
49
- var import_firestore = require("firebase/firestore");
50
- var import_storage = require("firebase/storage");
51
- var import_analytics = require("firebase/analytics");
52
- var import_functions = require("firebase/functions");
53
- var firebaseConfig = {
54
- apiKey: process.env.VITE_FIREBASE_API_KEY,
55
- authDomain: process.env.VITE_FIREBASE_AUTH_DOMAIN,
56
- projectId: process.env.VITE_FIREBASE_PROJECT_ID,
57
- storageBucket: process.env.VITE_FIREBASE_STORAGE_BUCKET,
58
- messagingSenderId: process.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
59
- appId: process.env.VITE_FIREBASE_APP_ID,
60
- measurementId: process.env.VITE_FIREBASE_MEASUREMENT_ID
61
- };
62
- var app;
63
- var auth;
64
- var db;
65
- var storage;
66
- var functions;
67
- var analytics = null;
68
- function initializeFirebase() {
69
- if (!(0, import_app.getApps)().length) {
70
- app = (0, import_app.initializeApp)(firebaseConfig);
71
- } else {
72
- app = (0, import_app.getApps)()[0];
73
- }
74
- return app;
75
- }
76
- function getFirebaseApp() {
77
- return app || initializeFirebase();
78
- }
79
- function getFirebaseAuth() {
80
- if (!auth) {
81
- const firebaseApp = getFirebaseApp();
82
- if (typeof window !== "undefined") {
83
- try {
84
- auth = (0, import_auth.getAuth)(firebaseApp);
85
- } catch (e) {
86
- console.warn("getAuth failed, trying initializeAuth...", e);
87
- auth = (0, import_auth.initializeAuth)(firebaseApp, {
88
- persistence: import_auth.browserLocalPersistence
89
- });
90
- }
91
- } else {
92
- auth = (0, import_auth.getAuth)(firebaseApp);
93
- }
94
- }
95
- return auth;
96
- }
97
- function getFirebaseDB() {
98
- if (!db) {
99
- db = (0, import_firestore.getFirestore)(getFirebaseApp());
100
- }
101
- return db;
102
- }
103
- function getFirebaseStorage() {
104
- if (!storage) {
105
- storage = (0, import_storage.getStorage)(getFirebaseApp());
106
- }
107
- return storage;
108
- }
109
- function getFirebaseFunctions() {
110
- if (!functions) {
111
- functions = (0, import_functions.getFunctions)(getFirebaseApp());
112
- }
113
- return functions;
114
- }
115
- function getFirebaseAnalytics() {
116
- if (!analytics && typeof window !== "undefined") {
117
- analytics = (0, import_analytics.getAnalytics)(getFirebaseApp());
118
- }
119
- return analytics;
120
- }
121
- function getFirebaseInstances() {
122
- return {
123
- app: getFirebaseApp(),
124
- auth: getFirebaseAuth(),
125
- db: getFirebaseDB(),
126
- storage: getFirebaseStorage(),
127
- functions: getFirebaseFunctions(),
128
- analytics: getFirebaseAnalytics()
129
- };
130
- }
131
-
132
- // src/infrastructure/firebase/auth.adapter.ts
133
- var import_auth2 = require("firebase/auth");
134
- var import_auth3 = require("firebase/auth");
135
-
136
- // src/domain/errors/auth.errors.ts
137
- var AuthError = class extends Error {
138
- constructor(message, code, originalError) {
139
- super(message);
140
- this.code = code;
141
- this.originalError = originalError;
142
- this.name = "AuthError";
143
- }
144
- };
145
- function createAuthError(code, message, originalError) {
146
- const defaultMessage = getAuthErrorMessage(code);
147
- return new AuthError(message || defaultMessage, code, originalError);
148
- }
149
- function getAuthErrorMessage(code) {
150
- switch (code) {
151
- case "USER_NOT_FOUND" /* USER_NOT_FOUND */:
152
- return "User not found";
153
- case "USER_ALREADY_EXISTS" /* USER_ALREADY_EXISTS */:
154
- return "User already exists";
155
- case "INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */:
156
- return "Invalid credentials";
157
- case "WEAK_PASSWORD" /* WEAK_PASSWORD */:
158
- return "Password is too weak";
159
- case "EMAIL_NOT_VERIFIED" /* EMAIL_NOT_VERIFIED */:
160
- return "Email not verified";
161
- case "SESSION_EXPIRED" /* SESSION_EXPIRED */:
162
- return "Session expired";
163
- case "UNAUTHENTICATED" /* UNAUTHENTICATED */:
164
- return "User not authenticated";
165
- case "TOO_MANY_REQUESTS" /* TOO_MANY_REQUESTS */:
166
- return "Too many requests";
167
- case "OAUTH_ERROR" /* OAUTH_ERROR */:
168
- return "OAuth error occurred";
169
- case "OAUTH_CANCELLED" /* OAUTH_CANCELLED */:
170
- return "OAuth cancelled by user";
171
- case "OAUTH_ACCOUNT_EXISTS" /* OAUTH_ACCOUNT_EXISTS */:
172
- return "Account already exists with this provider";
173
- case "SIGN_IN_FAILED" /* SIGN_IN_FAILED */:
174
- return "Sign in failed";
175
- case "SIGN_UP_FAILED" /* SIGN_UP_FAILED */:
176
- return "Sign up failed";
177
- case "SIGN_OUT_FAILED" /* SIGN_OUT_FAILED */:
178
- return "Sign out failed";
179
- case "PASSWORD_RESET_FAILED" /* PASSWORD_RESET_FAILED */:
180
- return "Password reset failed";
181
- case "EMAIL_VERIFICATION_FAILED" /* EMAIL_VERIFICATION_FAILED */:
182
- return "Email verification failed";
183
- case "PROFILE_UPDATE_FAILED" /* PROFILE_UPDATE_FAILED */:
184
- return "Profile update failed";
185
- case "EMAIL_UPDATE_FAILED" /* EMAIL_UPDATE_FAILED */:
186
- return "Email update failed";
187
- case "PASSWORD_UPDATE_FAILED" /* PASSWORD_UPDATE_FAILED */:
188
- return "Password update failed";
189
- case "ACCOUNT_DELETE_FAILED" /* ACCOUNT_DELETE_FAILED */:
190
- return "Account deletion failed";
191
- case "REAUTHENTICATION_REQUIRED" /* REAUTHENTICATION_REQUIRED */:
192
- return "Reauthentication required";
193
- case "REAUTHENTICATION_FAILED" /* REAUTHENTICATION_FAILED */:
194
- return "Reauthentication failed";
195
- case "UNKNOWN" /* UNKNOWN */:
196
- default:
197
- return "An unknown error occurred";
198
- }
199
- }
200
-
201
- // src/infrastructure/firebase/auth.adapter.ts
202
- var AuthAdapter = class {
203
- get auth() {
204
- return getFirebaseAuth();
205
- }
206
- // Authentication Methods
207
- async signIn(email, password) {
208
- try {
209
- return await (0, import_auth2.signInWithEmailAndPassword)(this.auth, email, password);
210
- } catch (error) {
211
- throw this.handleAuthError(error);
212
- }
213
- }
214
- async signUp(email, password, displayName) {
215
- try {
216
- const result = await (0, import_auth2.createUserWithEmailAndPassword)(this.auth, email, password);
217
- await (0, import_auth2.updateProfile)(result.user, { displayName });
218
- await (0, import_auth2.sendEmailVerification)(result.user);
219
- return result;
220
- } catch (error) {
221
- throw this.handleAuthError(error);
222
- }
223
- }
224
- async signInWithGoogle() {
225
- try {
226
- const provider = new import_auth3.GoogleAuthProvider();
227
- provider.addScope("profile");
228
- provider.addScope("email");
229
- return await (0, import_auth2.signInWithPopup)(this.auth, provider);
230
- } catch (error) {
231
- throw this.handleAuthError(error);
232
- }
233
- }
234
- async signOut() {
235
- try {
236
- await (0, import_auth2.signOut)(this.auth);
237
- } catch (error) {
238
- throw createAuthError("SIGN_OUT_FAILED" /* SIGN_OUT_FAILED */, "Sign out failed", error);
239
- }
240
- }
241
- async sendPasswordReset(email) {
242
- try {
243
- await (0, import_auth2.sendPasswordResetEmail)(this.auth, email);
244
- } catch (error) {
245
- throw this.handleAuthError(error);
246
- }
247
- }
248
- async resendEmailVerification() {
249
- try {
250
- const user = this.auth.currentUser;
251
- if (!user) {
252
- throw createAuthError("UNAUTHENTICATED" /* UNAUTHENTICATED */, "No user logged in");
253
- }
254
- await (0, import_auth2.sendEmailVerification)(user);
255
- } catch (error) {
256
- throw createAuthError("EMAIL_VERIFICATION_FAILED" /* EMAIL_VERIFICATION_FAILED */, "Failed to resend verification", error);
257
- }
258
- }
259
- // Profile Management
260
- async updateProfile(updates) {
261
- try {
262
- const user = this.auth.currentUser;
263
- if (!user) {
264
- throw createAuthError("UNAUTHENTICATED" /* UNAUTHENTICATED */, "No user logged in");
265
- }
266
- await (0, import_auth2.updateProfile)(user, updates);
267
- } catch (error) {
268
- throw createAuthError("PROFILE_UPDATE_FAILED" /* PROFILE_UPDATE_FAILED */, "Profile update failed", error);
269
- }
270
- }
271
- async updateEmail(newEmail, password) {
272
- try {
273
- const user = this.auth.currentUser;
274
- if (!user || !user.email) {
275
- throw createAuthError("UNAUTHENTICATED" /* UNAUTHENTICATED */, "No user logged in");
276
- }
277
- const credential = import_auth2.EmailAuthProvider.credential(user.email, password);
278
- await (0, import_auth2.reauthenticateWithCredential)(user, credential);
279
- await (0, import_auth2.updateEmail)(user, newEmail);
280
- } catch (error) {
281
- throw createAuthError("EMAIL_UPDATE_FAILED" /* EMAIL_UPDATE_FAILED */, "Email update failed", error);
282
- }
283
- }
284
- async updatePassword(currentPassword, newPassword) {
285
- try {
286
- const user = this.auth.currentUser;
287
- if (!user || !user.email) {
288
- throw createAuthError("UNAUTHENTICATED" /* UNAUTHENTICATED */, "No user logged in");
289
- }
290
- const credential = import_auth2.EmailAuthProvider.credential(user.email, currentPassword);
291
- await (0, import_auth2.reauthenticateWithCredential)(user, credential);
292
- await (0, import_auth2.updatePassword)(user, newPassword);
293
- } catch (error) {
294
- throw createAuthError("PASSWORD_UPDATE_FAILED" /* PASSWORD_UPDATE_FAILED */, "Password update failed", error);
295
- }
296
- }
297
- async deleteAccount(password) {
298
- try {
299
- const user = this.auth.currentUser;
300
- if (!user || !user.email) {
301
- throw createAuthError("UNAUTHENTICATED" /* UNAUTHENTICATED */, "No user logged in");
302
- }
303
- const credential = import_auth2.EmailAuthProvider.credential(user.email, password);
304
- await (0, import_auth2.reauthenticateWithCredential)(user, credential);
305
- await user.delete();
306
- } catch (error) {
307
- throw createAuthError("ACCOUNT_DELETE_FAILED" /* ACCOUNT_DELETE_FAILED */, "Account deletion failed", error);
308
- }
309
- }
310
- // State Management
311
- getCurrentUser() {
312
- return this.auth.currentUser;
313
- }
314
- onAuthStateChanged(callback) {
315
- return this.auth.onAuthStateChanged(callback);
316
- }
317
- // Note: User document operations should be handled by UserAdapter
318
- // These methods are part of IAuthRepository interface but should be implemented separately
319
- async createUserDocument(_userId, _data) {
320
- throw new Error("createUserDocument should be handled by UserAdapter");
321
- }
322
- async updateLastLogin(_userId) {
323
- throw new Error("updateLastLogin should be handled by UserAdapter");
324
- }
325
- /**
326
- * Handle Firebase Auth errors
327
- */
328
- handleAuthError(error) {
329
- if (error instanceof Error && "code" in error) {
330
- const code = error.code;
331
- switch (code) {
332
- case "auth/user-not-found":
333
- return createAuthError("USER_NOT_FOUND" /* USER_NOT_FOUND */, "User not found", error);
334
- case "auth/wrong-password":
335
- case "auth/invalid-credential":
336
- return createAuthError("INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */, "Invalid credentials", error);
337
- case "auth/email-already-in-use":
338
- return createAuthError("USER_ALREADY_EXISTS" /* USER_ALREADY_EXISTS */, "Email already in use", error);
339
- case "auth/weak-password":
340
- return createAuthError("WEAK_PASSWORD" /* WEAK_PASSWORD */, "Password is too weak", error);
341
- case "auth/invalid-email":
342
- return createAuthError("INVALID_CREDENTIALS" /* INVALID_CREDENTIALS */, "Invalid email", error);
343
- case "auth/user-disabled":
344
- return createAuthError("USER_NOT_FOUND" /* USER_NOT_FOUND */, "Account disabled", error);
345
- case "auth/too-many-requests":
346
- return createAuthError("TOO_MANY_REQUESTS" /* TOO_MANY_REQUESTS */, "Too many requests", error);
347
- case "auth/popup-closed-by-user":
348
- return createAuthError("OAUTH_CANCELLED" /* OAUTH_CANCELLED */, "Sign in cancelled", error);
349
- case "auth/account-exists-with-different-credential":
350
- return createAuthError("OAUTH_ACCOUNT_EXISTS" /* OAUTH_ACCOUNT_EXISTS */, "Account exists with different provider", error);
351
- case "auth/requires-recent-login":
352
- return createAuthError("REAUTHENTICATION_REQUIRED" /* REAUTHENTICATION_REQUIRED */, "Please reauthenticate", error);
353
- default:
354
- return createAuthError("UNKNOWN" /* UNKNOWN */, `Auth error: ${code}`, error);
355
- }
356
- }
357
- return createAuthError("UNKNOWN" /* UNKNOWN */, "Unknown auth error", error);
358
- }
359
- };
360
-
361
- // src/infrastructure/firebase/firestore.adapter.ts
362
- var import_firestore2 = require("firebase/firestore");
363
-
364
- // src/domain/errors/repository.errors.ts
365
- var RepositoryError = class extends Error {
366
- constructor(message, code, originalError) {
367
- super(message);
368
- this.code = code;
369
- this.originalError = originalError;
370
- this.name = "RepositoryError";
371
- }
372
- };
373
- function createRepositoryError(code, message, originalError) {
374
- const defaultMessage = getRepositoryErrorMessage(code);
375
- return new RepositoryError(message || defaultMessage, code, originalError);
376
- }
377
- function getRepositoryErrorMessage(code) {
378
- switch (code) {
379
- case "DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */:
380
- return "Document not found";
381
- case "DOCUMENT_ALREADY_EXISTS" /* DOCUMENT_ALREADY_EXISTS */:
382
- return "Document already exists";
383
- case "DOCUMENT_INVALID" /* DOCUMENT_INVALID */:
384
- return "Document is invalid";
385
- case "COLLECTION_NOT_FOUND" /* COLLECTION_NOT_FOUND */:
386
- return "Collection not found";
387
- case "COLLECTION_INVALID" /* COLLECTION_INVALID */:
388
- return "Collection is invalid";
389
- case "QUERY_INVALID" /* QUERY_INVALID */:
390
- return "Query is invalid";
391
- case "QUERY_FAILED" /* QUERY_FAILED */:
392
- return "Query failed";
393
- case "TRANSACTION_FAILED" /* TRANSACTION_FAILED */:
394
- return "Transaction failed";
395
- case "TRANSACTION_ABORTED" /* TRANSACTION_ABORTED */:
396
- return "Transaction aborted";
397
- case "NETWORK_ERROR" /* NETWORK_ERROR */:
398
- return "Network error";
399
- case "TIMEOUT" /* TIMEOUT */:
400
- return "Request timeout";
401
- case "OFFLINE" /* OFFLINE */:
402
- return "Client is offline";
403
- case "PERMISSION_DENIED" /* PERMISSION_DENIED */:
404
- return "Permission denied";
405
- case "UNAUTHORIZED" /* UNAUTHORIZED */:
406
- return "Unauthorized";
407
- case "VALIDATION_FAILED" /* VALIDATION_FAILED */:
408
- return "Validation failed";
409
- case "INVALID_DATA" /* INVALID_DATA */:
410
- return "Invalid data";
411
- case "CONFLICT" /* CONFLICT */:
412
- return "Conflict occurred";
413
- case "VERSION_MISMATCH" /* VERSION_MISMATCH */:
414
- return "Version mismatch";
415
- case "STORAGE_ERROR" /* STORAGE_ERROR */:
416
- return "Storage error";
417
- case "FILE_NOT_FOUND" /* FILE_NOT_FOUND */:
418
- return "File not found";
419
- case "FILE_TOO_LARGE" /* FILE_TOO_LARGE */:
420
- return "File is too large";
421
- case "INVALID_FILE_TYPE" /* INVALID_FILE_TYPE */:
422
- return "Invalid file type";
423
- case "UNKNOWN" /* UNKNOWN */:
424
- default:
425
- return "An unknown error occurred";
426
- }
427
- }
428
-
429
- // src/infrastructure/firebase/firestore.adapter.ts
430
- var FirestoreAdapter = class {
431
- get db() {
432
- return getFirebaseDB();
433
- }
434
- USERS_COLLECTION = "users";
435
- async getUser(userId) {
436
- try {
437
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
438
- const snap = await (0, import_firestore2.getDoc)(docRef);
439
- if (!snap.exists()) {
440
- return null;
441
- }
442
- return snap.data();
443
- } catch (error) {
444
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "User not found", error);
445
- }
446
- }
447
- async getUserByEmail(email) {
448
- try {
449
- const q = (0, import_firestore2.query)((0, import_firestore2.collection)(this.db, this.USERS_COLLECTION), (0, import_firestore2.where)("profile.email", "==", email));
450
- const snap = await (0, import_firestore2.getDocs)(q);
451
- if (snap.empty) {
452
- return null;
453
- }
454
- const doc2 = snap.docs[0];
455
- return doc2.data();
456
- } catch (error) {
457
- throw createRepositoryError("QUERY_FAILED" /* QUERY_FAILED */, "Failed to query user", error);
458
- }
459
- }
460
- async createUser(userId, data) {
461
- try {
462
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
463
- await (0, import_firestore2.setDoc)(docRef, data, { merge: true });
464
- } catch (error) {
465
- throw createRepositoryError("DOCUMENT_INVALID" /* DOCUMENT_INVALID */, "Failed to create user", error);
466
- }
467
- }
468
- async updateUser(userId, data) {
469
- try {
470
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
471
- await (0, import_firestore2.updateDoc)(docRef, {
472
- ...data,
473
- "profile.updatedAt": Date.now()
474
- });
475
- } catch (error) {
476
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "Failed to update user", error);
477
- }
478
- }
479
- async deleteUser(userId) {
480
- try {
481
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
482
- await (0, import_firestore2.deleteDoc)(docRef);
483
- } catch (error) {
484
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "Failed to delete user", error);
485
- }
486
- }
487
- async updateProfile(userId, updates) {
488
- try {
489
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
490
- const updateData = {
491
- "profile.updatedAt": Date.now()
492
- };
493
- if (updates.displayName !== void 0) {
494
- updateData["profile.displayName"] = updates.displayName;
495
- }
496
- if (updates.photoURL !== void 0) {
497
- updateData["profile.photoURL"] = updates.photoURL;
498
- }
499
- if (updates.phoneNumber !== void 0) {
500
- updateData["profile.phoneNumber"] = updates.phoneNumber;
501
- }
502
- await (0, import_firestore2.updateDoc)(docRef, updateData);
503
- } catch (error) {
504
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "Failed to update profile", error);
505
- }
506
- }
507
- async updateSettings(userId, settings) {
508
- try {
509
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
510
- await (0, import_firestore2.updateDoc)(docRef, {
511
- settings: {
512
- ...settings,
513
- updatedAt: Date.now()
514
- }
515
- });
516
- } catch (error) {
517
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "Failed to update settings", error);
518
- }
519
- }
520
- async updateSubscription(userId, subscription) {
521
- try {
522
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
523
- await (0, import_firestore2.updateDoc)(docRef, {
524
- subscription: {
525
- ...subscription,
526
- updatedAt: Date.now()
527
- }
528
- });
529
- } catch (error) {
530
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "Failed to update subscription", error);
531
- }
532
- }
533
- async updateLastLogin(userId) {
534
- try {
535
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
536
- await (0, import_firestore2.updateDoc)(docRef, {
537
- "profile.lastLoginAt": Date.now()
538
- });
539
- } catch (error) {
540
- throw createRepositoryError("DOCUMENT_NOT_FOUND" /* DOCUMENT_NOT_FOUND */, "Failed to update last login", error);
541
- }
542
- }
543
- async queryUsers(constraints) {
544
- try {
545
- const q = (0, import_firestore2.query)((0, import_firestore2.collection)(this.db, this.USERS_COLLECTION), ...constraints);
546
- const snap = await (0, import_firestore2.getDocs)(q);
547
- return snap.docs.map((doc2) => doc2.data());
548
- } catch (error) {
549
- throw createRepositoryError("QUERY_FAILED" /* QUERY_FAILED */, "Failed to query users", error);
550
- }
551
- }
552
- subscribeToUser(userId, callback, onError) {
553
- const docRef = (0, import_firestore2.doc)(this.db, this.USERS_COLLECTION, userId);
554
- const unsubscribe = (0, import_firestore2.onSnapshot)(
555
- docRef,
556
- (snap) => {
557
- if (snap.exists()) {
558
- callback(snap.data());
559
- } else {
560
- callback(null);
561
- }
562
- },
563
- (error) => {
564
- onError?.(error);
565
- }
566
- );
567
- return unsubscribe;
568
- }
569
- };
570
-
571
- // src/infrastructure/firebase/storage.adapter.ts
572
- var import_storage2 = require("firebase/storage");
573
- var StorageAdapter = class {
574
- get storage() {
575
- return getFirebaseStorage();
576
- }
577
- // Upload Methods
578
- async uploadFile(userId, path, file, options) {
579
- const storageRef = (0, import_storage2.ref)(this.storage, `users/${userId}/${path}`);
580
- const uploadTask = (0, import_storage2.uploadBytesResumable)(storageRef, file);
581
- return new Promise((resolve, reject) => {
582
- uploadTask.on(
583
- "state_changed",
584
- (snapshot) => {
585
- if (options?.onProgress) {
586
- const progress = {
587
- bytesTransferred: snapshot.bytesTransferred,
588
- totalBytes: snapshot.totalBytes,
589
- progress: snapshot.bytesTransferred / snapshot.totalBytes * 100,
590
- state: "running"
591
- };
592
- options.onProgress(progress);
593
- }
594
- },
595
- (error) => reject(createRepositoryError("STORAGE_ERROR" /* STORAGE_ERROR */, "Upload failed", error)),
596
- async () => {
597
- const downloadURL = await (0, import_storage2.getDownloadURL)(uploadTask.snapshot.ref);
598
- const metadata = await (0, import_storage2.getMetadata)(uploadTask.snapshot.ref);
599
- resolve({
600
- id: uploadTask.snapshot.ref.name,
601
- name: metadata.name || uploadTask.snapshot.ref.name,
602
- fullPath: metadata.fullPath || uploadTask.snapshot.ref.fullPath,
603
- downloadURL,
604
- contentType: metadata.contentType || "",
605
- size: metadata.size || 0,
606
- createdAt: metadata.timeCreated ? new Date(metadata.timeCreated).getTime() : Date.now()
607
- });
608
- }
609
- );
610
- });
611
- }
612
- async uploadImage(userId, file, filename) {
613
- const name = filename || `${Date.now()}_${file.name}`;
614
- return this.uploadFile(userId, `images/${name}`, file);
615
- }
616
- async uploadVideo(userId, file, filename) {
617
- const name = filename || `${Date.now()}_${file.name}`;
618
- return this.uploadFile(userId, `videos/${name}`, file);
619
- }
620
- async uploadDocument(userId, file, filename) {
621
- const name = filename || `${Date.now()}_${file.name}`;
622
- return this.uploadFile(userId, `documents/${name}`, file);
623
- }
624
- async uploadProfilePicture(userId, file) {
625
- const storageRef = (0, import_storage2.ref)(this.storage, `users/${userId}/profile/${Date.now()}_${file.name}`);
626
- await (0, import_storage2.uploadBytes)(storageRef, file);
627
- const downloadURL = await (0, import_storage2.getDownloadURL)(storageRef);
628
- return {
629
- id: storageRef.name,
630
- name: file.name,
631
- fullPath: storageRef.fullPath,
632
- downloadURL,
633
- contentType: file.type,
634
- size: file.size,
635
- createdAt: Date.now()
636
- };
637
- }
638
- // Download Methods
639
- async getDownloadURL(path) {
640
- try {
641
- const storageRef = (0, import_storage2.ref)(this.storage, path);
642
- return await (0, import_storage2.getDownloadURL)(storageRef);
643
- } catch (error) {
644
- throw createRepositoryError("FILE_NOT_FOUND" /* FILE_NOT_FOUND */, "File not found", error);
645
- }
646
- }
647
- // Delete Methods
648
- async deleteFile(path) {
649
- try {
650
- const storageRef = (0, import_storage2.ref)(this.storage, path);
651
- await (0, import_storage2.deleteObject)(storageRef);
652
- } catch (error) {
653
- throw createRepositoryError("FILE_NOT_FOUND" /* FILE_NOT_FOUND */, "File not found", error);
654
- }
655
- }
656
- async deleteUserFiles(userId) {
657
- try {
658
- const userRef = (0, import_storage2.ref)(this.storage, `users/${userId}`);
659
- const result = await (0, import_storage2.listAll)(userRef);
660
- for (const prefix of result.prefixes) {
661
- const prefixResult = await (0, import_storage2.listAll)(prefix);
662
- await Promise.all(prefixResult.items.map((item) => (0, import_storage2.deleteObject)(item)));
663
- }
664
- await Promise.all(result.items.map((item) => (0, import_storage2.deleteObject)(item)));
665
- } catch (error) {
666
- throw createRepositoryError("STORAGE_ERROR" /* STORAGE_ERROR */, "Failed to delete user files", error);
667
- }
668
- }
669
- async deleteImage(userId, filename) {
670
- await this.deleteFile(`users/${userId}/images/${filename}`);
671
- }
672
- async deleteVideo(userId, filename) {
673
- await this.deleteFile(`users/${userId}/videos/${filename}`);
674
- }
675
- async deleteProfilePicture(userId, filename) {
676
- await this.deleteFile(`users/${userId}/profile/${filename}`);
677
- }
678
- // List Methods
679
- async listUserFiles(userId, path) {
680
- const userRef = (0, import_storage2.ref)(this.storage, path ? `users/${userId}/${path}` : `users/${userId}`);
681
- const result = await (0, import_storage2.listAll)(userRef);
682
- const urls = await Promise.all(result.items.map((item) => (0, import_storage2.getDownloadURL)(item)));
683
- return urls;
684
- }
685
- async listUserImages(userId) {
686
- return this.listUserFiles(userId, "images");
687
- }
688
- async listUserVideos(userId) {
689
- return this.listUserFiles(userId, "videos");
690
- }
691
- // Metadata
692
- async getFileMetadata(path) {
693
- try {
694
- const storageRef = (0, import_storage2.ref)(this.storage, path);
695
- const metadata = await (0, import_storage2.getMetadata)(storageRef);
696
- return {
697
- id: storageRef.name,
698
- name: metadata.name,
699
- fullPath: metadata.fullPath,
700
- contentType: metadata.contentType || "application/octet-stream",
701
- size: metadata.size,
702
- createdAt: metadata.timeCreated ? new Date(metadata.timeCreated).getTime() : Date.now(),
703
- updatedAt: metadata.updated ? new Date(metadata.updated).getTime() : Date.now(),
704
- userId: this.extractUserId(path) || "unknown",
705
- type: this.extractFileType(metadata.contentType || "")
706
- };
707
- } catch (error) {
708
- throw createRepositoryError("FILE_NOT_FOUND" /* FILE_NOT_FOUND */, "File not found", error);
709
- }
710
- }
711
- async queryFiles(userId, _filters) {
712
- const userRef = (0, import_storage2.ref)(this.storage, `users/${userId}`);
713
- const result = await (0, import_storage2.listAll)(userRef);
714
- const files = await Promise.all(
715
- result.items.map(async (item) => {
716
- const metadata = await (0, import_storage2.getMetadata)(item);
717
- return {
718
- id: item.name,
719
- name: metadata.name,
720
- fullPath: metadata.fullPath,
721
- contentType: metadata.contentType || "application/octet-stream",
722
- size: metadata.size,
723
- createdAt: metadata.timeCreated ? new Date(metadata.timeCreated).getTime() : Date.now(),
724
- updatedAt: metadata.updated ? new Date(metadata.updated).getTime() : Date.now(),
725
- userId,
726
- type: this.extractFileType(metadata.contentType || "")
727
- };
728
- })
729
- );
730
- return {
731
- files,
732
- totalCount: files.length,
733
- hasMore: false
734
- };
735
- }
736
- async getStorageStats(userId) {
737
- const { files, totalCount } = await this.queryFiles(userId);
738
- const stats = {
739
- totalFiles: totalCount,
740
- totalSize: files.reduce((sum, file) => sum + file.size, 0),
741
- filesByType: {
742
- image: 0,
743
- video: 0,
744
- audio: 0,
745
- document: 0,
746
- other: 0
747
- },
748
- filesByCategory: {
749
- profile: 0,
750
- content: 0,
751
- document: 0,
752
- attachment: 0,
753
- backup: 0
754
- }
755
- };
756
- files.forEach((file) => {
757
- stats.filesByType[file.type]++;
758
- stats.lastUploadAt = Math.max(stats.lastUploadAt || 0, file.createdAt);
759
- });
760
- return stats;
761
- }
762
- // Validation
763
- validateFile(file, options) {
764
- const maxSizeBytes = options?.maxSizeBytes || (options?.maxSizeMB ? options.maxSizeMB * 1024 * 1024 : 10 * 1024 * 1024);
765
- if (file.size > maxSizeBytes) {
766
- return false;
767
- }
768
- if (options?.allowedTypes && !options.allowedTypes.includes(file.type)) {
769
- return false;
770
- }
771
- return true;
772
- }
773
- isImageFile(file) {
774
- return file.type.startsWith("image/");
775
- }
776
- isVideoFile(file) {
777
- return file.type.startsWith("video/");
778
- }
779
- isDocumentFile(file) {
780
- const docTypes = [
781
- "application/pdf",
782
- "application/msword",
783
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
784
- "application/vnd.ms-excel",
785
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
786
- "text/plain"
787
- ];
788
- return docTypes.includes(file.type);
789
- }
790
- // Utility Methods
791
- generateUniqueFilename(originalName) {
792
- const timestamp = Date.now();
793
- const random = Math.random().toString(36).substring(2, 8);
794
- const extension = this.getFileExtension(originalName);
795
- return `${timestamp}_${random}.${extension}`;
796
- }
797
- getFileExtension(filename) {
798
- return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
799
- }
800
- // Helper Methods
801
- extractUserId(path) {
802
- const match = path.match(/users\/([^\/]+)/);
803
- return match ? match[1] : "";
804
- }
805
- extractFileType(contentType) {
806
- if (contentType.startsWith("image/")) return "image";
807
- if (contentType.startsWith("video/")) return "video";
808
- if (contentType.startsWith("audio/")) return "audio";
809
- if (contentType.includes("pdf") || contentType.includes("document") || contentType.includes("text")) {
810
- return "document";
811
- }
812
- return "other";
813
- }
814
- };
815
-
816
- // src/infrastructure/utils/storage.util.ts
817
- var import_storage3 = require("firebase/storage");
818
- async function uploadFile(storage2, path, file) {
819
- const storageRef = (0, import_storage3.ref)(storage2, path);
820
- await (0, import_storage3.uploadBytes)(storageRef, file);
821
- const url = await (0, import_storage3.getDownloadURL)(storageRef);
822
- return { url, path };
823
- }
824
- async function uploadBase64(storage2, path, base64, mimeType = "image/jpeg") {
825
- const storageRef = (0, import_storage3.ref)(storage2, path);
826
- const dataUrl = base64.startsWith("data:") ? base64 : `data:${mimeType};base64,${base64}`;
827
- await (0, import_storage3.uploadString)(storageRef, dataUrl, "data_url");
828
- const url = await (0, import_storage3.getDownloadURL)(storageRef);
829
- return { url, path };
830
- }
831
- async function deleteFile(storage2, path) {
832
- await (0, import_storage3.deleteObject)((0, import_storage3.ref)(storage2, path));
833
- }
834
- // Annotate the CommonJS export names for ESM import in node:
835
- 0 && (module.exports = {
836
- AuthAdapter,
837
- FirestoreAdapter,
838
- StorageAdapter,
839
- analytics,
840
- app,
841
- auth,
842
- db,
843
- deleteFile,
844
- functions,
845
- getFirebaseAnalytics,
846
- getFirebaseApp,
847
- getFirebaseAuth,
848
- getFirebaseDB,
849
- getFirebaseFunctions,
850
- getFirebaseInstances,
851
- getFirebaseStorage,
852
- initializeFirebase,
853
- storage,
854
- uploadBase64,
855
- uploadFile
856
- });