@umituz/web-firebase 1.0.5 → 2.0.1

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 (69) hide show
  1. package/README.md +555 -0
  2. package/dist/application/index.d.mts +273 -0
  3. package/dist/application/index.d.ts +273 -0
  4. package/dist/application/index.js +490 -0
  5. package/dist/application/index.mjs +19 -0
  6. package/dist/chunk-34DL2QWQ.mjs +87 -0
  7. package/dist/chunk-4FP2ELQ5.mjs +96 -0
  8. package/dist/chunk-7TX3OU3O.mjs +721 -0
  9. package/dist/chunk-I6WGBPFB.mjs +439 -0
  10. package/dist/chunk-RZ4QR6TB.mjs +96 -0
  11. package/dist/chunk-U2XI4MGO.mjs +397 -0
  12. package/dist/domain/index.d.mts +325 -0
  13. package/dist/domain/index.d.ts +325 -0
  14. package/dist/domain/index.js +662 -0
  15. package/dist/domain/index.mjs +36 -0
  16. package/dist/file.repository.interface-v5vHgVsZ.d.mts +241 -0
  17. package/dist/file.repository.interface-v5vHgVsZ.d.ts +241 -0
  18. package/dist/firebase.entity-xvfEPjXZ.d.mts +15 -0
  19. package/dist/firebase.entity-xvfEPjXZ.d.ts +15 -0
  20. package/dist/index.d.mts +14 -96
  21. package/dist/index.d.ts +14 -96
  22. package/dist/index.js +1717 -78
  23. package/dist/index.mjs +88 -175
  24. package/dist/infrastructure/index.d.mts +170 -0
  25. package/dist/infrastructure/index.d.ts +170 -0
  26. package/dist/infrastructure/index.js +856 -0
  27. package/dist/infrastructure/index.mjs +46 -0
  28. package/dist/presentation/index.d.mts +25 -0
  29. package/dist/presentation/index.d.ts +25 -0
  30. package/dist/presentation/index.js +105 -0
  31. package/dist/presentation/index.mjs +6 -0
  32. package/dist/user.repository.interface-DS74TsJ5.d.mts +298 -0
  33. package/dist/user.repository.interface-DS74TsJ5.d.ts +298 -0
  34. package/package.json +37 -11
  35. package/src/application/dto/auth.dto.ts +69 -0
  36. package/src/application/dto/index.ts +7 -0
  37. package/src/application/dto/user.dto.ts +64 -0
  38. package/src/application/index.ts +7 -0
  39. package/src/application/use-cases/auth/reset-password.use-case.ts +66 -0
  40. package/src/application/use-cases/auth/sign-in-with-google.use-case.ts +86 -0
  41. package/src/application/use-cases/auth/sign-in.use-case.ts +77 -0
  42. package/src/application/use-cases/auth/sign-out.use-case.ts +22 -0
  43. package/src/application/use-cases/auth/sign-up.use-case.ts +99 -0
  44. package/src/application/use-cases/index.ts +12 -0
  45. package/src/application/use-cases/user/delete-account.use-case.ts +77 -0
  46. package/src/application/use-cases/user/update-profile.use-case.ts +98 -0
  47. package/src/domain/entities/file.entity.ts +151 -0
  48. package/src/domain/entities/timestamp.entity.ts +116 -0
  49. package/src/domain/entities/user.entity.ts +193 -0
  50. package/src/domain/errors/auth.errors.ts +115 -0
  51. package/src/domain/errors/repository.errors.ts +121 -0
  52. package/src/domain/index.ts +25 -2
  53. package/src/domain/interfaces/auth.repository.interface.ts +83 -0
  54. package/src/domain/interfaces/file.repository.interface.ts +143 -0
  55. package/src/domain/interfaces/user.repository.interface.ts +75 -0
  56. package/src/domain/value-objects/email.vo.ts +105 -0
  57. package/src/domain/value-objects/file-path.vo.ts +184 -0
  58. package/src/domain/value-objects/user-id.vo.ts +87 -0
  59. package/src/index.ts +19 -4
  60. package/src/infrastructure/firebase/auth.adapter.ts +220 -0
  61. package/src/infrastructure/firebase/client.ts +141 -0
  62. package/src/infrastructure/firebase/firestore.adapter.ts +190 -0
  63. package/src/infrastructure/firebase/storage.adapter.ts +323 -0
  64. package/src/infrastructure/index.ts +10 -5
  65. package/src/infrastructure/utils/storage.util.ts +3 -3
  66. package/src/presentation/hooks/useAuth.ts +153 -0
  67. package/src/presentation/hooks/useFirestore.ts +125 -0
  68. package/src/presentation/hooks/useStorage.ts +141 -0
  69. package/src/presentation/providers/FirebaseProvider.tsx +40 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Auth Hook
3
+ * @description React hook for authentication operations
4
+ * Migrated from: /Users/umituz/Desktop/github/umituz/apps/web/app-growth-factory/src/domains/firebase/hooks/useAuth.ts
5
+ * Refactored to use use cases
6
+ */
7
+
8
+ import { useEffect, useState, useCallback } from 'react'
9
+ import { User as FirebaseUser } from 'firebase/auth'
10
+ import type { User } from '../../domain/entities/user.entity'
11
+ import type { IAuthRepository } from '../../domain/interfaces/auth.repository.interface'
12
+ import type { IUserRepository } from '../../domain/interfaces/user.repository.interface'
13
+ import type { SignInDTO, SignUpDTO } from '../../application/dto/auth.dto'
14
+
15
+ export interface UseAuthOptions {
16
+ authRepository: IAuthRepository
17
+ userRepository: IUserRepository
18
+ }
19
+
20
+ export function useAuth({ authRepository, userRepository }: UseAuthOptions) {
21
+ const [firebaseUser, setFirebaseUser] = useState<FirebaseUser | null>(null)
22
+ const [user, setUser] = useState<User | null>(null)
23
+ const [loading, setLoading] = useState(true)
24
+ const [error, setError] = useState<Error | null>(null)
25
+
26
+ useEffect(() => {
27
+ const unsubscribe = authRepository.onAuthStateChanged(async (fbUser) => {
28
+ setFirebaseUser(fbUser)
29
+
30
+ if (fbUser) {
31
+ try {
32
+ const userData = await userRepository.getUser(fbUser.uid)
33
+ setUser(userData)
34
+ } catch (err) {
35
+ console.error('Error fetching user data:', err)
36
+ setError(err as Error)
37
+ }
38
+ } else {
39
+ setUser(null)
40
+ }
41
+
42
+ setLoading(false)
43
+ })
44
+
45
+ return () => unsubscribe()
46
+ }, [authRepository, userRepository])
47
+
48
+ const signIn = useCallback(async (dto: SignInDTO) => {
49
+ setError(null)
50
+ try {
51
+ return await authRepository.signIn(dto.email, dto.password)
52
+ } catch (err) {
53
+ setError(err as Error)
54
+ throw err
55
+ }
56
+ }, [authRepository])
57
+
58
+ const signUp = useCallback(async (dto: SignUpDTO) => {
59
+ setError(null)
60
+ try {
61
+ return await authRepository.signUp(dto.email, dto.password, dto.displayName)
62
+ } catch (err) {
63
+ setError(err as Error)
64
+ throw err
65
+ }
66
+ }, [authRepository])
67
+
68
+ const signInWithGoogle = useCallback(async () => {
69
+ setError(null)
70
+ try {
71
+ return await authRepository.signInWithGoogle()
72
+ } catch (err) {
73
+ setError(err as Error)
74
+ throw err
75
+ }
76
+ }, [authRepository])
77
+
78
+ const signOut = useCallback(async () => {
79
+ setError(null)
80
+ try {
81
+ await authRepository.signOut()
82
+ setUser(null)
83
+ setFirebaseUser(null)
84
+ } catch (err) {
85
+ setError(err as Error)
86
+ throw err
87
+ }
88
+ }, [authRepository])
89
+
90
+ const sendPasswordReset = useCallback(async (email: string) => {
91
+ setError(null)
92
+ try {
93
+ await authRepository.sendPasswordReset(email)
94
+ } catch (err) {
95
+ setError(err as Error)
96
+ throw err
97
+ }
98
+ }, [authRepository])
99
+
100
+ const resendEmailVerification = useCallback(async () => {
101
+ setError(null)
102
+ try {
103
+ await authRepository.resendEmailVerification()
104
+ } catch (err) {
105
+ setError(err as Error)
106
+ throw err
107
+ }
108
+ }, [authRepository])
109
+
110
+ const updateProfile = useCallback(async (updates: { displayName?: string; photoURL?: string }) => {
111
+ setError(null)
112
+ try {
113
+ await authRepository.updateProfile(updates)
114
+ if (firebaseUser) {
115
+ const userData = await userRepository.getUser(firebaseUser.uid)
116
+ setUser(userData)
117
+ }
118
+ } catch (err) {
119
+ setError(err as Error)
120
+ throw err
121
+ }
122
+ }, [authRepository, userRepository, firebaseUser])
123
+
124
+ const refreshUser = useCallback(async () => {
125
+ setError(null)
126
+ try {
127
+ if (firebaseUser) {
128
+ const userData = await userRepository.getUser(firebaseUser.uid)
129
+ setUser(userData)
130
+ }
131
+ } catch (err) {
132
+ setError(err as Error)
133
+ throw err
134
+ }
135
+ }, [userRepository, firebaseUser])
136
+
137
+ return {
138
+ firebaseUser,
139
+ user,
140
+ loading,
141
+ error,
142
+ isAuthenticated: !!firebaseUser,
143
+ isEmailVerified: firebaseUser?.emailVerified || false,
144
+ signIn,
145
+ signUp,
146
+ signInWithGoogle,
147
+ signOut,
148
+ sendPasswordReset,
149
+ resendEmailVerification,
150
+ updateProfile,
151
+ refreshUser,
152
+ }
153
+ }
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Firestore Hook
3
+ * @description React hook for Firestore real-time data
4
+ * Migrated from: /Users/umituz/Desktop/github/umituz/apps/web/app-growth-factory/src/domains/firebase/hooks/useFirestore.ts
5
+ */
6
+
7
+ import { useEffect, useState } from 'react'
8
+ import { doc, onSnapshot, query, collection, type QuerySnapshot, type DocumentData } from 'firebase/firestore'
9
+ import type { Firestore } from 'firebase/firestore'
10
+
11
+ export function useUser(db: Firestore, userId: string) {
12
+ const [user, setUser] = useState<any>(null)
13
+ const [loading, setLoading] = useState(true)
14
+ const [error, setError] = useState<Error | null>(null)
15
+
16
+ useEffect(() => {
17
+ if (!userId) {
18
+ setUser(null)
19
+ setLoading(false)
20
+ return
21
+ }
22
+
23
+ const unsubscribe = onSnapshot(doc(db, 'users', userId), (docSnap) => {
24
+ if (docSnap.exists()) {
25
+ setUser(docSnap.data())
26
+ } else {
27
+ setUser(null)
28
+ }
29
+ setLoading(false)
30
+ }, (err) => {
31
+ setError(err as Error)
32
+ setLoading(false)
33
+ })
34
+
35
+ return () => unsubscribe()
36
+ }, [db, userId])
37
+
38
+ return { user, loading, error }
39
+ }
40
+
41
+ export function useUserRealtime<T>(db: Firestore, collectionName: string, docId: string) {
42
+ const [data, setData] = useState<T | null>(null)
43
+ const [loading, setLoading] = useState(true)
44
+ const [error, setError] = useState<Error | null>(null)
45
+
46
+ useEffect(() => {
47
+ if (!docId) {
48
+ setData(null)
49
+ setLoading(false)
50
+ return
51
+ }
52
+
53
+ const unsubscribe = onSnapshot(doc(db, collectionName, docId), (docSnap) => {
54
+ if (docSnap.exists()) {
55
+ setData(docSnap.data() as T)
56
+ } else {
57
+ setData(null)
58
+ }
59
+ setLoading(false)
60
+ }, (err) => {
61
+ setError(err as Error)
62
+ setLoading(false)
63
+ })
64
+
65
+ return () => unsubscribe()
66
+ }, [db, collectionName, docId])
67
+
68
+ return { data, loading, error }
69
+ }
70
+
71
+ export function useCollectionRealtime<T>(
72
+ db: Firestore,
73
+ collectionName: string,
74
+ constraints?: any[]
75
+ ) {
76
+ const [data, setData] = useState<T[]>([])
77
+ const [loading, setLoading] = useState(true)
78
+ const [error, setError] = useState<Error | null>(null)
79
+
80
+ useEffect(() => {
81
+ const q = constraints
82
+ ? query(collection(db, collectionName), ...constraints)
83
+ : collection(db, collectionName)
84
+
85
+ const unsubscribe = onSnapshot(q, (querySnap: QuerySnapshot<DocumentData>) => {
86
+ const items = querySnap.docs.map((doc) => ({ id: doc.id, ...doc.data() } as T))
87
+ setData(items)
88
+ setLoading(false)
89
+ }, (err) => {
90
+ setError(err as Error)
91
+ setLoading(false)
92
+ })
93
+
94
+ return () => unsubscribe()
95
+ }, [db, collectionName, JSON.stringify(constraints)])
96
+
97
+ return { data, loading, error }
98
+ }
99
+
100
+ export function useDocumentValue<T>(
101
+ db: Firestore,
102
+ collectionName: string,
103
+ docId: string
104
+ ) {
105
+ const [data, setData] = useState<T | null>(null)
106
+
107
+ useEffect(() => {
108
+ if (!docId) {
109
+ setData(null)
110
+ return
111
+ }
112
+
113
+ const unsubscribe = onSnapshot(doc(db, collectionName, docId), (docSnap) => {
114
+ if (docSnap.exists()) {
115
+ setData(docSnap.data() as T)
116
+ } else {
117
+ setData(null)
118
+ }
119
+ })
120
+
121
+ return () => unsubscribe()
122
+ }, [db, collectionName, docId])
123
+
124
+ return data
125
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Storage Hook
3
+ * @description React hook for file storage operations
4
+ * Migrated from: /Users/umituz/Desktop/github/umituz/apps/web/app-growth-factory/src/domains/firebase/hooks/useStorage.ts
5
+ */
6
+
7
+ import { useState, useCallback } from 'react'
8
+ import type { IFileRepository } from '../../domain/interfaces/file.repository.interface'
9
+ import type { UploadProgress, UploadResult } from '../../domain/entities/file.entity'
10
+
11
+ export interface UseStorageOptions {
12
+ fileRepository: IFileRepository
13
+ userId: string
14
+ }
15
+
16
+ export function useStorage({ fileRepository, userId }: UseStorageOptions) {
17
+ const [uploading, setUploading] = useState(false)
18
+ const [progress, setProgress] = useState(0)
19
+ const [error, setError] = useState<Error | null>(null)
20
+
21
+ const uploadFile = useCallback(
22
+ async (path: string, file: File): Promise<UploadResult> => {
23
+ setUploading(true)
24
+ setProgress(0)
25
+ setError(null)
26
+
27
+ try {
28
+ const result = await fileRepository.uploadFile(userId, path, file, {
29
+ onProgress: (progress: UploadProgress) => {
30
+ setProgress(progress.progress)
31
+ },
32
+ })
33
+
34
+ setProgress(100)
35
+ return result
36
+ } catch (err) {
37
+ setError(err as Error)
38
+ throw err
39
+ } finally {
40
+ setUploading(false)
41
+ }
42
+ },
43
+ [fileRepository, userId]
44
+ )
45
+
46
+ const uploadImage = useCallback(
47
+ async (file: File): Promise<UploadResult> => {
48
+ return uploadFile('images', file)
49
+ },
50
+ [uploadFile]
51
+ )
52
+
53
+ const uploadVideo = useCallback(
54
+ async (file: File): Promise<UploadResult> => {
55
+ return uploadFile('videos', file)
56
+ },
57
+ [uploadFile]
58
+ )
59
+
60
+ const uploadDocument = useCallback(
61
+ async (file: File): Promise<UploadResult> => {
62
+ return uploadFile('documents', file)
63
+ },
64
+ [uploadFile]
65
+ )
66
+
67
+ const uploadProfilePicture = useCallback(
68
+ async (file: File): Promise<UploadResult> => {
69
+ setUploading(true)
70
+ setError(null)
71
+
72
+ try {
73
+ const result = await fileRepository.uploadProfilePicture(userId, file)
74
+ return result
75
+ } catch (err) {
76
+ setError(err as Error)
77
+ throw err
78
+ } finally {
79
+ setUploading(false)
80
+ }
81
+ },
82
+ [fileRepository, userId]
83
+ )
84
+
85
+ const deleteFile = useCallback(
86
+ async (path: string): Promise<void> => {
87
+ setUploading(true)
88
+ setError(null)
89
+
90
+ try {
91
+ await fileRepository.deleteFile(path)
92
+ } catch (err) {
93
+ setError(err as Error)
94
+ throw err
95
+ } finally {
96
+ setUploading(false)
97
+ }
98
+ },
99
+ [fileRepository]
100
+ )
101
+
102
+ const listUserImages = useCallback(
103
+ async (): Promise<string[]> => {
104
+ setError(null)
105
+ try {
106
+ return await fileRepository.listUserImages(userId)
107
+ } catch (err) {
108
+ setError(err as Error)
109
+ throw err
110
+ }
111
+ },
112
+ [fileRepository, userId]
113
+ )
114
+
115
+ const listUserVideos = useCallback(
116
+ async (): Promise<string[]> => {
117
+ setError(null)
118
+ try {
119
+ return await fileRepository.listUserVideos(userId)
120
+ } catch (err) {
121
+ setError(err as Error)
122
+ throw err
123
+ }
124
+ },
125
+ [fileRepository, userId]
126
+ )
127
+
128
+ return {
129
+ uploadFile,
130
+ uploadImage,
131
+ uploadVideo,
132
+ uploadDocument,
133
+ uploadProfilePicture,
134
+ deleteFile,
135
+ listUserImages,
136
+ listUserVideos,
137
+ uploading,
138
+ progress,
139
+ error,
140
+ }
141
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * FirebaseProvider
3
+ * @description React Context Provider for Firebase initialization
4
+ */
5
+
6
+ import { createContext, useContext, type ReactNode } from 'react'
7
+ import type { FirebaseInstances } from '../../infrastructure/firebase/client'
8
+ import { getFirebaseInstances } from '../../infrastructure/firebase/client'
9
+
10
+ interface FirebaseContextValue {
11
+ instances: FirebaseInstances
12
+ isInitialized: boolean
13
+ }
14
+
15
+ const FirebaseContext = createContext<FirebaseContextValue | null>(null)
16
+
17
+ export interface FirebaseProviderProps {
18
+ children: ReactNode
19
+ }
20
+
21
+ export function FirebaseProvider({ children }: FirebaseProviderProps) {
22
+ // Note: Firebase is already initialized via environment variables
23
+ // This provider just makes instances available via context
24
+ const instances = getFirebaseInstances()
25
+
26
+ const value: FirebaseContextValue = {
27
+ instances,
28
+ isInitialized: true,
29
+ }
30
+
31
+ return <FirebaseContext.Provider value={value}>{children}</FirebaseContext.Provider>
32
+ }
33
+
34
+ export function useFirebaseContext() {
35
+ const context = useContext(FirebaseContext)
36
+ if (!context) {
37
+ throw new Error('useFirebaseContext must be used within FirebaseProvider')
38
+ }
39
+ return context
40
+ }