@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.
- package/README.md +555 -0
- package/dist/application/index.d.mts +273 -0
- package/dist/application/index.d.ts +273 -0
- package/dist/application/index.js +490 -0
- package/dist/application/index.mjs +19 -0
- package/dist/chunk-34DL2QWQ.mjs +87 -0
- package/dist/chunk-4FP2ELQ5.mjs +96 -0
- package/dist/chunk-7TX3OU3O.mjs +721 -0
- package/dist/chunk-I6WGBPFB.mjs +439 -0
- package/dist/chunk-RZ4QR6TB.mjs +96 -0
- package/dist/chunk-U2XI4MGO.mjs +397 -0
- package/dist/domain/index.d.mts +325 -0
- package/dist/domain/index.d.ts +325 -0
- package/dist/domain/index.js +662 -0
- package/dist/domain/index.mjs +36 -0
- package/dist/file.repository.interface-v5vHgVsZ.d.mts +241 -0
- package/dist/file.repository.interface-v5vHgVsZ.d.ts +241 -0
- package/dist/firebase.entity-xvfEPjXZ.d.mts +15 -0
- package/dist/firebase.entity-xvfEPjXZ.d.ts +15 -0
- package/dist/index.d.mts +14 -96
- package/dist/index.d.ts +14 -96
- package/dist/index.js +1717 -78
- package/dist/index.mjs +88 -175
- package/dist/infrastructure/index.d.mts +170 -0
- package/dist/infrastructure/index.d.ts +170 -0
- package/dist/infrastructure/index.js +856 -0
- package/dist/infrastructure/index.mjs +46 -0
- package/dist/presentation/index.d.mts +25 -0
- package/dist/presentation/index.d.ts +25 -0
- package/dist/presentation/index.js +105 -0
- package/dist/presentation/index.mjs +6 -0
- package/dist/user.repository.interface-DS74TsJ5.d.mts +298 -0
- package/dist/user.repository.interface-DS74TsJ5.d.ts +298 -0
- package/package.json +37 -11
- package/src/application/dto/auth.dto.ts +69 -0
- package/src/application/dto/index.ts +7 -0
- package/src/application/dto/user.dto.ts +64 -0
- package/src/application/index.ts +7 -0
- package/src/application/use-cases/auth/reset-password.use-case.ts +66 -0
- package/src/application/use-cases/auth/sign-in-with-google.use-case.ts +86 -0
- package/src/application/use-cases/auth/sign-in.use-case.ts +77 -0
- package/src/application/use-cases/auth/sign-out.use-case.ts +22 -0
- package/src/application/use-cases/auth/sign-up.use-case.ts +99 -0
- package/src/application/use-cases/index.ts +12 -0
- package/src/application/use-cases/user/delete-account.use-case.ts +77 -0
- package/src/application/use-cases/user/update-profile.use-case.ts +98 -0
- package/src/domain/entities/file.entity.ts +151 -0
- package/src/domain/entities/timestamp.entity.ts +116 -0
- package/src/domain/entities/user.entity.ts +193 -0
- package/src/domain/errors/auth.errors.ts +115 -0
- package/src/domain/errors/repository.errors.ts +121 -0
- package/src/domain/index.ts +25 -2
- package/src/domain/interfaces/auth.repository.interface.ts +83 -0
- package/src/domain/interfaces/file.repository.interface.ts +143 -0
- package/src/domain/interfaces/user.repository.interface.ts +75 -0
- package/src/domain/value-objects/email.vo.ts +105 -0
- package/src/domain/value-objects/file-path.vo.ts +184 -0
- package/src/domain/value-objects/user-id.vo.ts +87 -0
- package/src/index.ts +19 -4
- package/src/infrastructure/firebase/auth.adapter.ts +220 -0
- package/src/infrastructure/firebase/client.ts +141 -0
- package/src/infrastructure/firebase/firestore.adapter.ts +190 -0
- package/src/infrastructure/firebase/storage.adapter.ts +323 -0
- package/src/infrastructure/index.ts +10 -5
- package/src/infrastructure/utils/storage.util.ts +3 -3
- package/src/presentation/hooks/useAuth.ts +153 -0
- package/src/presentation/hooks/useFirestore.ts +125 -0
- package/src/presentation/hooks/useStorage.ts +141 -0
- package/src/presentation/providers/FirebaseProvider.tsx +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
# @umituz/web-firebase
|
|
2
|
+
|
|
3
|
+
Comprehensive Firebase integration with Domain-Driven Design (DDD) architecture for web applications.
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- ✅ **DDD Architecture** - Clean separation of concerns with 4 distinct layers
|
|
8
|
+
- ✅ **Type-Safe** - Full TypeScript support with strict typing
|
|
9
|
+
- ✅ **Repository Pattern** - Abstract data access from business logic
|
|
10
|
+
- ✅ **Use Cases** - Orchestrated business logic operations
|
|
11
|
+
- ✅ **React Hooks** - Ready-to-use presentation layer hooks
|
|
12
|
+
- ✅ **Error Handling** - Domain-specific error types
|
|
13
|
+
- ✅ **Zero Code Duplication** - Package-driven development ready
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @umituz/web-firebase firebase@^12
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🏗️ Architecture
|
|
22
|
+
|
|
23
|
+
This package follows Domain-Driven Design principles with clear layer separation:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
┌─────────────────────────────────────────────────────────┐
|
|
27
|
+
│ Presentation Layer │
|
|
28
|
+
│ React Hooks, Providers - UI interactions │
|
|
29
|
+
└────────────────────┬────────────────────────────────────┘
|
|
30
|
+
│
|
|
31
|
+
┌────────────────────┴────────────────────────────────────┐
|
|
32
|
+
│ Application Layer │
|
|
33
|
+
│ Use Cases, DTOs - Business logic orchestration │
|
|
34
|
+
└────────────────────┬────────────────────────────────────┘
|
|
35
|
+
│
|
|
36
|
+
┌────────────────────┴────────────────────────────────────┐
|
|
37
|
+
│ Domain Layer │
|
|
38
|
+
│ Entities, Interfaces, Errors - Core business model │
|
|
39
|
+
└────────────────────┬────────────────────────────────────┘
|
|
40
|
+
│
|
|
41
|
+
┌────────────────────┴────────────────────────────────────┐
|
|
42
|
+
│ Infrastructure Layer │
|
|
43
|
+
│ Firebase Adapters - External service implementations │
|
|
44
|
+
└─────────────────────────────────────────────────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 🎯 Quick Start
|
|
48
|
+
|
|
49
|
+
### 1. Initialize Firebase
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Initialize Firebase in your app
|
|
53
|
+
import { initializeFirebaseApp } from '@umituz/web-firebase/infrastructure'
|
|
54
|
+
|
|
55
|
+
const firebaseConfig = {
|
|
56
|
+
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
|
|
57
|
+
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
|
|
58
|
+
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
|
|
59
|
+
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
|
|
60
|
+
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
|
|
61
|
+
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
initializeFirebaseApp(firebaseConfig)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 2. Use Domain Layer (Types & Interfaces)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import type { User, UserProfile } from '@umituz/web-firebase/domain'
|
|
71
|
+
import type { IAuthRepository, IUserRepository } from '@umituz/web-firebase/domain'
|
|
72
|
+
|
|
73
|
+
// Use domain entities in your app
|
|
74
|
+
const user: User = {
|
|
75
|
+
profile: {
|
|
76
|
+
email: 'user@example.com',
|
|
77
|
+
displayName: 'John Doe',
|
|
78
|
+
createdAt: Date.now(),
|
|
79
|
+
},
|
|
80
|
+
settings: {
|
|
81
|
+
theme: 'light',
|
|
82
|
+
language: 'en',
|
|
83
|
+
},
|
|
84
|
+
// ... other fields
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Use Application Layer (Use Cases)
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { SignInUseCase, SignUpUseCase } from '@umituz/web-firebase/application'
|
|
92
|
+
import { AuthAdapter } from '@umituz/web-firebase/infrastructure'
|
|
93
|
+
|
|
94
|
+
// Create adapters
|
|
95
|
+
const authRepository = new AuthAdapter()
|
|
96
|
+
const userRepository = new FirestoreAdapter()
|
|
97
|
+
|
|
98
|
+
// Create use cases
|
|
99
|
+
const signInUseCase = new SignInUseCase(authRepository)
|
|
100
|
+
const signUpUseCase = new SignUpUseCase(authRepository)
|
|
101
|
+
|
|
102
|
+
// Execute use cases
|
|
103
|
+
const result = await signInUseCase.execute({
|
|
104
|
+
email: 'user@example.com',
|
|
105
|
+
password: 'Password123',
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 4. Use Infrastructure Layer (Adapters)
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { AuthAdapter, FirestoreAdapter, StorageAdapter } from '@umituz/web-firebase/infrastructure'
|
|
113
|
+
|
|
114
|
+
// Direct adapter usage
|
|
115
|
+
const authAdapter = new AuthAdapter()
|
|
116
|
+
await authAdapter.signIn('user@example.com', 'Password123')
|
|
117
|
+
|
|
118
|
+
const firestoreAdapter = new FirestoreAdapter()
|
|
119
|
+
const user = await firestoreAdapter.getUser('user-id')
|
|
120
|
+
|
|
121
|
+
const storageAdapter = new StorageAdapter()
|
|
122
|
+
const result = await storageAdapter.uploadFile('user-id', 'path', file)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 5. Use Presentation Layer (React Hooks)
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { FirebaseProvider } from '@umituz/web-firebase/presentation'
|
|
129
|
+
import { useAuth } from '@umituz/web-firebase/presentation'
|
|
130
|
+
|
|
131
|
+
function App() {
|
|
132
|
+
return (
|
|
133
|
+
<FirebaseProvider config={firebaseConfig}>
|
|
134
|
+
<YourApp />
|
|
135
|
+
</FirebaseProvider>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function Profile() {
|
|
140
|
+
const { user, loading, signIn, signOut } = useAuth({
|
|
141
|
+
authRepository: new AuthAdapter(),
|
|
142
|
+
userRepository: new FirestoreAdapter(),
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
if (loading) return <div>Loading...</div>
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<div>
|
|
149
|
+
<p>Welcome, {user?.profile.displayName}</p>
|
|
150
|
+
<button onClick={() => signOut()}>Sign Out</button>
|
|
151
|
+
</div>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 📚 Subpath Imports
|
|
157
|
+
|
|
158
|
+
**⚠️ IMPORTANT:** Do NOT use the root barrel import. Use subpath imports for better tree-shaking and clear dependencies.
|
|
159
|
+
|
|
160
|
+
### Domain Layer
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// Entities
|
|
164
|
+
import type { User, UserProfile, UserSettings } from '@umituz/web-firebase/domain'
|
|
165
|
+
import type { FileMetadata, UploadProgress, UploadResult } from '@umituz/web-firebase/domain'
|
|
166
|
+
|
|
167
|
+
// Repository Interfaces
|
|
168
|
+
import type { IAuthRepository } from '@umituz/web-firebase/domain'
|
|
169
|
+
import type { IUserRepository } from '@umituz/web-firebase/domain'
|
|
170
|
+
import type { IFileRepository } from '@umituz/web-firebase/domain'
|
|
171
|
+
|
|
172
|
+
// Errors
|
|
173
|
+
import { AuthError, AuthErrorCode } from '@umituz/web-firebase/domain'
|
|
174
|
+
import { RepositoryError, RepositoryErrorCode } from '@umituz/web-firebase/domain'
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Application Layer
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// Use Cases
|
|
181
|
+
import { SignInUseCase, SignUpUseCase } from '@umituz/web-firebase/application'
|
|
182
|
+
import { UpdateProfileUseCase, DeleteAccountUseCase } from '@umituz/web-firebase/application'
|
|
183
|
+
|
|
184
|
+
// DTOs
|
|
185
|
+
import type { SignInDTO, SignUpDTO } from '@umituz/web-firebase/application'
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Infrastructure Layer
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Firebase Client
|
|
192
|
+
import { initializeFirebaseApp, getFirebaseAuth, getFirebaseDB } from '@umituz/web-firebase/infrastructure'
|
|
193
|
+
|
|
194
|
+
// Adapters
|
|
195
|
+
import { AuthAdapter } from '@umituz/web-firebase/infrastructure'
|
|
196
|
+
import { FirestoreAdapter } from '@umituz/web-firebase/infrastructure'
|
|
197
|
+
import { StorageAdapter } from '@umituz/web-firebase/infrastructure'
|
|
198
|
+
|
|
199
|
+
// Utils
|
|
200
|
+
import { generateUniqueFilename, getFileExtension } from '@umituz/web-firebase/infrastructure'
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Presentation Layer
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// Providers
|
|
207
|
+
import { FirebaseProvider } from '@umituz/web-firebase/presentation'
|
|
208
|
+
|
|
209
|
+
// Hooks
|
|
210
|
+
import { useAuth } from '@umituz/web-firebase/presentation'
|
|
211
|
+
import { useUser } from '@umituz/web-firebase/presentation'
|
|
212
|
+
import { useFirestore } from '@umituz/web-firebase/presentation'
|
|
213
|
+
import { useStorage } from '@umituz/web-firebase/presentation'
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## 🔥 Detailed Usage
|
|
217
|
+
|
|
218
|
+
### Authentication
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import { AuthAdapter } from '@umituz/web-firebase/infrastructure'
|
|
222
|
+
|
|
223
|
+
const auth = new AuthAdapter()
|
|
224
|
+
|
|
225
|
+
// Sign in with email/password
|
|
226
|
+
const credential = await auth.signIn('user@example.com', 'password')
|
|
227
|
+
|
|
228
|
+
// Sign up
|
|
229
|
+
const credential = await auth.signUp('user@example.com', 'password', 'John Doe')
|
|
230
|
+
|
|
231
|
+
// Sign in with Google
|
|
232
|
+
const credential = await auth.signInWithGoogle()
|
|
233
|
+
|
|
234
|
+
// Sign out
|
|
235
|
+
await auth.signOut()
|
|
236
|
+
|
|
237
|
+
// Password reset
|
|
238
|
+
await auth.sendPasswordReset('user@example.com')
|
|
239
|
+
|
|
240
|
+
// Update profile
|
|
241
|
+
await auth.updateProfile({ displayName: 'Jane Doe' })
|
|
242
|
+
|
|
243
|
+
// Update email
|
|
244
|
+
await auth.updateEmail('new@example.com', 'current-password')
|
|
245
|
+
|
|
246
|
+
// Update password
|
|
247
|
+
await auth.updatePassword('current-password', 'new-password')
|
|
248
|
+
|
|
249
|
+
// Delete account
|
|
250
|
+
await auth.deleteAccount('current-password')
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### User Management (Firestore)
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import { FirestoreAdapter } from '@umituz/web-firebase/infrastructure'
|
|
257
|
+
|
|
258
|
+
const firestore = new FirestoreAdapter()
|
|
259
|
+
|
|
260
|
+
// Get user
|
|
261
|
+
const user = await firestore.getUser('user-id')
|
|
262
|
+
|
|
263
|
+
// Get user by email
|
|
264
|
+
const user = await firestore.getUserByEmail('user@example.com')
|
|
265
|
+
|
|
266
|
+
// Create user
|
|
267
|
+
await firestore.createUser('user-id', {
|
|
268
|
+
profile: {
|
|
269
|
+
email: 'user@example.com',
|
|
270
|
+
displayName: 'John Doe',
|
|
271
|
+
createdAt: Date.now(),
|
|
272
|
+
},
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
// Update user
|
|
276
|
+
await firestore.updateUser('user-id', {
|
|
277
|
+
'settings.theme': 'dark',
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
// Update profile
|
|
281
|
+
await firestore.updateProfile('user-id', {
|
|
282
|
+
displayName: 'Jane Doe',
|
|
283
|
+
photoURL: 'https://...',
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
// Update settings
|
|
287
|
+
await firestore.updateSettings('user-id', {
|
|
288
|
+
theme: 'dark',
|
|
289
|
+
language: 'tr',
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
// Update subscription
|
|
293
|
+
await firestore.updateSubscription('user-id', {
|
|
294
|
+
plan: 'premium',
|
|
295
|
+
status: 'active',
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
// Update last login
|
|
299
|
+
await firestore.updateLastLogin('user-id')
|
|
300
|
+
|
|
301
|
+
// Delete user
|
|
302
|
+
await firestore.deleteUser('user-id')
|
|
303
|
+
|
|
304
|
+
// Query users
|
|
305
|
+
const users = await firestore.queryUsers([
|
|
306
|
+
where('profile.email', '==', 'user@example.com'),
|
|
307
|
+
])
|
|
308
|
+
|
|
309
|
+
// Subscribe to user updates
|
|
310
|
+
const unsubscribe = firestore.subscribeToUser(
|
|
311
|
+
'user-id',
|
|
312
|
+
(user) => console.log('User updated:', user),
|
|
313
|
+
(error) => console.error('Error:', error)
|
|
314
|
+
)
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### File Storage
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { StorageAdapter } from '@umituz/web-firebase/infrastructure'
|
|
321
|
+
|
|
322
|
+
const storage = new StorageAdapter()
|
|
323
|
+
|
|
324
|
+
// Upload file
|
|
325
|
+
const result = await storage.uploadFile('user-id', 'path/to/file', file, {
|
|
326
|
+
onProgress: (progress) => console.log(`${progress.progress}%`),
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
// Upload specific types
|
|
330
|
+
await storage.uploadImage('user-id', file, 'custom-name.jpg')
|
|
331
|
+
await storage.uploadVideo('user-id', file, 'custom-name.mp4')
|
|
332
|
+
await storage.uploadDocument('user-id', file, 'custom-name.pdf')
|
|
333
|
+
await storage.uploadProfilePicture('user-id', file)
|
|
334
|
+
|
|
335
|
+
// Get download URL
|
|
336
|
+
const url = await storage.getDownloadURL('users/user-id/path/to/file')
|
|
337
|
+
|
|
338
|
+
// Delete file
|
|
339
|
+
await storage.deleteFile('users/user-id/path/to/file')
|
|
340
|
+
await storage.deleteImage('user-id', 'filename.jpg')
|
|
341
|
+
await storage.deleteVideo('user-id', 'filename.mp4')
|
|
342
|
+
await storage.deleteProfilePicture('user-id', 'filename.jpg')
|
|
343
|
+
await storage.deleteUserFiles('user-id')
|
|
344
|
+
|
|
345
|
+
// List files
|
|
346
|
+
const urls = await storage.listUserFiles('user-id')
|
|
347
|
+
const images = await storage.listUserImages('user-id')
|
|
348
|
+
const videos = await storage.listUserVideos('user-id')
|
|
349
|
+
|
|
350
|
+
// Get metadata
|
|
351
|
+
const metadata = await storage.getFileMetadata('users/user-id/file.jpg')
|
|
352
|
+
|
|
353
|
+
// Query files
|
|
354
|
+
const { files, totalCount, hasMore } = await storage.queryFiles('user-id')
|
|
355
|
+
|
|
356
|
+
// Get storage stats
|
|
357
|
+
const stats = await storage.getStorageStats('user-id')
|
|
358
|
+
|
|
359
|
+
// Validate file
|
|
360
|
+
const isValid = storage.validateFile(file, {
|
|
361
|
+
maxSizeMB: 10,
|
|
362
|
+
allowedTypes: ['image/jpeg', 'image/png'],
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
// Check file types
|
|
366
|
+
storage.isImageFile(file)
|
|
367
|
+
storage.isVideoFile(file)
|
|
368
|
+
storage.isDocumentFile(file)
|
|
369
|
+
|
|
370
|
+
// Generate unique filename
|
|
371
|
+
const filename = storage.generateUniqueFilename('photo.jpg')
|
|
372
|
+
|
|
373
|
+
// Get file extension
|
|
374
|
+
const ext = storage.getFileExtension('photo.jpg')
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### React Hooks
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
import {
|
|
381
|
+
useAuth,
|
|
382
|
+
useUser,
|
|
383
|
+
useFirestore,
|
|
384
|
+
useStorage,
|
|
385
|
+
} from '@umituz/web-firebase/presentation'
|
|
386
|
+
|
|
387
|
+
function MyComponent() {
|
|
388
|
+
// Auth hook
|
|
389
|
+
const {
|
|
390
|
+
user: firebaseUser,
|
|
391
|
+
user: userData,
|
|
392
|
+
loading,
|
|
393
|
+
error,
|
|
394
|
+
signIn,
|
|
395
|
+
signUp,
|
|
396
|
+
signInWithGoogle,
|
|
397
|
+
signOut,
|
|
398
|
+
} = useAuth({
|
|
399
|
+
authRepository: new AuthAdapter(),
|
|
400
|
+
userRepository: new FirestoreAdapter(),
|
|
401
|
+
})
|
|
402
|
+
|
|
403
|
+
// User hook
|
|
404
|
+
const { user, loading: userLoading } = useUser({
|
|
405
|
+
userRepository: new FirestoreAdapter(),
|
|
406
|
+
userId: firebaseUser?.uid,
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
// Storage hook
|
|
410
|
+
const {
|
|
411
|
+
uploadFile,
|
|
412
|
+
uploadImage,
|
|
413
|
+
uploadProfilePicture,
|
|
414
|
+
deleteFile,
|
|
415
|
+
uploading,
|
|
416
|
+
progress,
|
|
417
|
+
error: storageError,
|
|
418
|
+
} = useStorage({
|
|
419
|
+
fileRepository: new StorageAdapter(),
|
|
420
|
+
userId: firebaseUser?.uid,
|
|
421
|
+
})
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## 🔄 Migration from v1.x to v2.0.0
|
|
426
|
+
|
|
427
|
+
Version 2.0.0 is a **breaking change** with complete DDD architecture. Here's how to migrate:
|
|
428
|
+
|
|
429
|
+
### Before (v1.x)
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
import { FirebaseService, AuthService } from '@umituz/web-firebase'
|
|
433
|
+
|
|
434
|
+
const service = new FirebaseService(config)
|
|
435
|
+
await service.auth.signIn(email, password)
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### After (v2.0.0)
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
import { initializeFirebaseApp } from '@umituz/web-firebase/infrastructure'
|
|
442
|
+
import { AuthAdapter } from '@umituz/web-firebase/infrastructure'
|
|
443
|
+
|
|
444
|
+
initializeFirebaseApp(config)
|
|
445
|
+
const auth = new AuthAdapter()
|
|
446
|
+
await auth.signIn(email, password)
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### Key Changes
|
|
450
|
+
|
|
451
|
+
1. **Subpath imports required** - No more root barrel imports
|
|
452
|
+
2. **Repository pattern** - Use adapters instead of services
|
|
453
|
+
3. **Error types** - Domain-specific errors instead of generic errors
|
|
454
|
+
4. **Use cases** - Business logic in application layer
|
|
455
|
+
5. **Types** - Import domain types separately
|
|
456
|
+
|
|
457
|
+
### Migration Steps
|
|
458
|
+
|
|
459
|
+
1. Update package version:
|
|
460
|
+
```bash
|
|
461
|
+
npm install @umituz/web-firebase@^2.0.0
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
2. Update imports:
|
|
465
|
+
```typescript
|
|
466
|
+
// Before
|
|
467
|
+
import { AuthService } from '@umituz/web-firebase'
|
|
468
|
+
|
|
469
|
+
// After
|
|
470
|
+
import { AuthAdapter } from '@umituz/web-firebase/infrastructure'
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
3. Update initialization:
|
|
474
|
+
```typescript
|
|
475
|
+
// Before
|
|
476
|
+
const firebase = new FirebaseService(config)
|
|
477
|
+
|
|
478
|
+
// After
|
|
479
|
+
initializeFirebaseApp(config)
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
4. Update method calls:
|
|
483
|
+
```typescript
|
|
484
|
+
// Before - service pattern
|
|
485
|
+
const user = await firebase.auth.getUser(uid)
|
|
486
|
+
|
|
487
|
+
// After - repository pattern
|
|
488
|
+
const user = await firestoreAdapter.getUser(uid)
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## 📦 Package Structure
|
|
492
|
+
|
|
493
|
+
```
|
|
494
|
+
src/
|
|
495
|
+
├── domain/ # Core business model
|
|
496
|
+
│ ├── entities/ # Domain entities
|
|
497
|
+
│ │ ├── user.entity.ts
|
|
498
|
+
│ │ └── file.entity.ts
|
|
499
|
+
│ ├── interfaces/ # Repository interfaces
|
|
500
|
+
│ │ ├── auth.repository.interface.ts
|
|
501
|
+
│ │ ├── user.repository.interface.ts
|
|
502
|
+
│ │ └── file.repository.interface.ts
|
|
503
|
+
│ └── errors/ # Domain errors
|
|
504
|
+
│ ├── auth.errors.ts
|
|
505
|
+
│ └── repository.errors.ts
|
|
506
|
+
│
|
|
507
|
+
├── application/ # Business logic
|
|
508
|
+
│ ├── use-cases/ # Use cases
|
|
509
|
+
│ │ ├── auth/
|
|
510
|
+
│ │ │ ├── sign-in.use-case.ts
|
|
511
|
+
│ │ │ ├── sign-up.use-case.ts
|
|
512
|
+
│ │ │ └── reset-password.use-case.ts
|
|
513
|
+
│ │ └── user/
|
|
514
|
+
│ │ ├── update-profile.use-case.ts
|
|
515
|
+
│ │ └── delete-account.use-case.ts
|
|
516
|
+
│ └── dto/ # Data Transfer Objects
|
|
517
|
+
│ ├── auth.dto.ts
|
|
518
|
+
│ └── user.dto.ts
|
|
519
|
+
│
|
|
520
|
+
├── infrastructure/ # External integrations
|
|
521
|
+
│ ├── firebase/ # Firebase adapters
|
|
522
|
+
│ │ ├── client.ts
|
|
523
|
+
│ │ ├── auth.adapter.ts
|
|
524
|
+
│ │ ├── firestore.adapter.ts
|
|
525
|
+
│ │ └── storage.adapter.ts
|
|
526
|
+
│ └── utils/ # Utility functions
|
|
527
|
+
│ └── storage.util.ts
|
|
528
|
+
│
|
|
529
|
+
└── presentation/ # UI layer
|
|
530
|
+
├── hooks/ # React hooks
|
|
531
|
+
│ ├── useAuth.ts
|
|
532
|
+
│ ├── useUser.ts
|
|
533
|
+
│ ├── useFirestore.ts
|
|
534
|
+
│ └── useStorage.ts
|
|
535
|
+
└── providers/ # Context providers
|
|
536
|
+
└── FirebaseProvider.tsx
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
## 🎯 Use Cases
|
|
540
|
+
|
|
541
|
+
- **Social Media Apps** - User profiles, posts, media storage
|
|
542
|
+
- **E-commerce** - Product catalogs, user accounts, order management
|
|
543
|
+
- **SaaS** - Subscription management, user settings, analytics
|
|
544
|
+
- **Chat Apps** - Real-time messaging, user presence
|
|
545
|
+
- **Blogs/CMS** - Content management, media uploads
|
|
546
|
+
|
|
547
|
+
## 📝 License
|
|
548
|
+
|
|
549
|
+
MIT
|
|
550
|
+
|
|
551
|
+
## 🤝 Contributing
|
|
552
|
+
|
|
553
|
+
Contributions are welcome! Please follow our DDD architecture principles when contributing.
|
|
554
|
+
|
|
555
|
+
Made with ❤️ by umituz
|