@umituz/web-firebase 2.1.1 → 3.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/package.json +12 -39
- package/src/domain/interfaces/auth.repository.interface.ts +4 -19
- package/src/domain/interfaces/file.repository.interface.ts +5 -102
- package/src/domain/interfaces/index.ts +7 -0
- package/src/domain/interfaces/user.repository.interface.ts +17 -44
- package/src/domains/auth/entities/index.ts +60 -0
- package/src/domains/auth/index.ts +13 -0
- package/src/domains/auth/services/auth.service.ts +245 -0
- package/src/domains/auth/services/index.ts +7 -0
- package/src/domains/auth/types/auth-service.interface.ts +72 -0
- package/src/domains/auth/types/index.ts +5 -0
- package/src/domains/firestore/entities/index.ts +82 -0
- package/src/domains/firestore/index.ts +13 -0
- package/src/domains/firestore/services/firestore.service.ts +191 -0
- package/src/domains/firestore/services/index.ts +7 -0
- package/src/domains/firestore/types/firestore-service.interface.ts +64 -0
- package/src/domains/firestore/types/index.ts +5 -0
- package/src/domains/storage/entities/index.ts +94 -0
- package/src/domains/storage/index.ts +13 -0
- package/src/domains/storage/services/index.ts +7 -0
- package/src/domains/storage/services/storage.service.ts +223 -0
- package/src/domains/storage/types/index.ts +5 -0
- package/src/domains/storage/types/storage-service.interface.ts +120 -0
- package/src/index.ts +12 -16
- package/src/presentation/hooks/useAuth.ts +69 -26
- package/src/presentation/providers/FirebaseProvider.tsx +9 -14
- package/dist/application/index.d.mts +0 -273
- package/dist/application/index.d.ts +0 -273
- package/dist/application/index.js +0 -490
- package/dist/application/index.mjs +0 -19
- package/dist/chunk-34DL2QWQ.mjs +0 -87
- package/dist/chunk-4FP2ELQ5.mjs +0 -96
- package/dist/chunk-7TX3OU3O.mjs +0 -721
- package/dist/chunk-I6WGBPFB.mjs +0 -439
- package/dist/chunk-RZ4QR6TB.mjs +0 -96
- package/dist/chunk-U2XI4MGO.mjs +0 -397
- package/dist/domain/index.d.mts +0 -325
- package/dist/domain/index.d.ts +0 -325
- package/dist/domain/index.js +0 -662
- package/dist/domain/index.mjs +0 -36
- package/dist/file.repository.interface-v5vHgVsZ.d.mts +0 -241
- package/dist/file.repository.interface-v5vHgVsZ.d.ts +0 -241
- package/dist/firebase.entity-xvfEPjXZ.d.mts +0 -15
- package/dist/firebase.entity-xvfEPjXZ.d.ts +0 -15
- package/dist/index.d.mts +0 -14
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -1833
- package/dist/index.mjs +0 -98
- package/dist/infrastructure/index.d.mts +0 -170
- package/dist/infrastructure/index.d.ts +0 -170
- package/dist/infrastructure/index.js +0 -856
- package/dist/infrastructure/index.mjs +0 -46
- package/dist/presentation/index.d.mts +0 -25
- package/dist/presentation/index.d.ts +0 -25
- package/dist/presentation/index.js +0 -105
- package/dist/presentation/index.mjs +0 -6
- package/dist/user.repository.interface-DS74TsJ5.d.mts +0 -298
- package/dist/user.repository.interface-DS74TsJ5.d.ts +0 -298
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Service Interface
|
|
3
|
+
* @description Abstract interface for authentication operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { UserCredential } from 'firebase/auth'
|
|
7
|
+
import type { AuthUser } from '../entities'
|
|
8
|
+
|
|
9
|
+
export interface IAuthService {
|
|
10
|
+
/**
|
|
11
|
+
* Sign in with email and password
|
|
12
|
+
*/
|
|
13
|
+
signIn(email: string, password: string): Promise<UserCredential>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sign up with email, password, and display name
|
|
17
|
+
*/
|
|
18
|
+
signUp(email: string, password: string, displayName: string): Promise<UserCredential>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sign in with Google OAuth
|
|
22
|
+
*/
|
|
23
|
+
signInWithGoogle(): Promise<UserCredential>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sign out current user
|
|
27
|
+
*/
|
|
28
|
+
signOut(): Promise<void>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Send password reset email
|
|
32
|
+
*/
|
|
33
|
+
sendPasswordReset(email: string): Promise<void>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resend email verification
|
|
37
|
+
*/
|
|
38
|
+
resendEmailVerification(): Promise<void>
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update user profile (displayName, photoURL)
|
|
42
|
+
*/
|
|
43
|
+
updateProfile(updates: { displayName?: string; photoURL?: string }): Promise<void>
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Update user email (requires password)
|
|
47
|
+
*/
|
|
48
|
+
updateEmail(newEmail: string, password: string): Promise<void>
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Update user password (requires current password)
|
|
52
|
+
*/
|
|
53
|
+
updatePassword(currentPassword: string, newPassword: string): Promise<void>
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Delete user account (requires password)
|
|
57
|
+
*/
|
|
58
|
+
deleteAccount(password: string): Promise<void>
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get current authenticated user
|
|
62
|
+
*/
|
|
63
|
+
getCurrentUser(): AuthUser | null
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe to auth state changes
|
|
67
|
+
*/
|
|
68
|
+
onAuthStateChanged(
|
|
69
|
+
callback: (user: AuthUser | null) => void,
|
|
70
|
+
onError?: (error: Error) => void
|
|
71
|
+
): () => void
|
|
72
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firestore Domain Entities
|
|
3
|
+
* @description Core Firestore-related entities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* User Profile Value Object
|
|
8
|
+
* Immutable user profile data
|
|
9
|
+
*/
|
|
10
|
+
export interface UserProfile {
|
|
11
|
+
readonly id: string
|
|
12
|
+
readonly email: string
|
|
13
|
+
readonly displayName: string
|
|
14
|
+
readonly photoURL?: string
|
|
15
|
+
readonly phoneNumber?: string
|
|
16
|
+
readonly createdAt: number
|
|
17
|
+
readonly updatedAt: number
|
|
18
|
+
readonly lastLoginAt: number
|
|
19
|
+
readonly emailVerified: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* User Notifications Settings
|
|
24
|
+
*/
|
|
25
|
+
export interface UserNotifications {
|
|
26
|
+
email: boolean
|
|
27
|
+
push: boolean
|
|
28
|
+
marketing: boolean
|
|
29
|
+
security: boolean
|
|
30
|
+
weeklyDigest: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* User Privacy Settings
|
|
35
|
+
*/
|
|
36
|
+
export interface UserPrivacy {
|
|
37
|
+
profileVisibility: 'public' | 'private'
|
|
38
|
+
showEmail: boolean
|
|
39
|
+
showPhone: boolean
|
|
40
|
+
dataSharing: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* User Settings Value Object
|
|
45
|
+
*/
|
|
46
|
+
export interface UserSettings {
|
|
47
|
+
theme: 'light' | 'dark' | 'system'
|
|
48
|
+
language: string
|
|
49
|
+
timezone: string
|
|
50
|
+
currency: string
|
|
51
|
+
notifications: UserNotifications
|
|
52
|
+
privacy: UserPrivacy
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* User Subscription Value Object
|
|
57
|
+
*/
|
|
58
|
+
export interface UserSubscription {
|
|
59
|
+
plan: 'free' | 'standard' | 'professional' | 'business'
|
|
60
|
+
status: 'active' | 'inactive' | 'canceled' | 'past_due'
|
|
61
|
+
polarCustomerId?: string
|
|
62
|
+
polarSubscriptionId?: string
|
|
63
|
+
currentPeriodStart?: number
|
|
64
|
+
currentPeriodEnd?: number
|
|
65
|
+
cancelAtPeriodEnd: boolean
|
|
66
|
+
readonly createdAt: number
|
|
67
|
+
readonly updatedAt: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* User Aggregate Root
|
|
72
|
+
* Main user document containing all user-related data
|
|
73
|
+
*/
|
|
74
|
+
export interface User {
|
|
75
|
+
readonly profile: UserProfile
|
|
76
|
+
settings: UserSettings
|
|
77
|
+
subscription: UserSubscription
|
|
78
|
+
connectedAccounts?: any[]
|
|
79
|
+
content?: any[]
|
|
80
|
+
analytics?: any
|
|
81
|
+
credits?: any
|
|
82
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firestore Service
|
|
3
|
+
* @description Firebase Firestore implementation of IFirestoreService
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
doc,
|
|
8
|
+
getDoc,
|
|
9
|
+
setDoc,
|
|
10
|
+
updateDoc,
|
|
11
|
+
deleteDoc,
|
|
12
|
+
query,
|
|
13
|
+
where,
|
|
14
|
+
onSnapshot,
|
|
15
|
+
collection,
|
|
16
|
+
getDocs,
|
|
17
|
+
} from 'firebase/firestore'
|
|
18
|
+
import { getFirebaseDB } from '../../../infrastructure/firebase/client'
|
|
19
|
+
import type { IFirestoreService } from '../types'
|
|
20
|
+
import type { User } from '../entities'
|
|
21
|
+
|
|
22
|
+
class FirestoreService implements IFirestoreService {
|
|
23
|
+
private get db() {
|
|
24
|
+
return getFirebaseDB()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private readonly USERS_COLLECTION = 'users'
|
|
28
|
+
|
|
29
|
+
async getUser(userId: string): Promise<User | null> {
|
|
30
|
+
try {
|
|
31
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
32
|
+
const snap = await getDoc(docRef)
|
|
33
|
+
|
|
34
|
+
if (!snap.exists()) {
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return snap.data() as User
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw new Error('User not found')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async getUserByEmail(email: string): Promise<User | null> {
|
|
45
|
+
try {
|
|
46
|
+
const q = query(collection(this.db, this.USERS_COLLECTION), where('profile.email', '==', email))
|
|
47
|
+
const snap = await getDocs(q)
|
|
48
|
+
|
|
49
|
+
if (snap.empty) {
|
|
50
|
+
return null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const doc = snap.docs[0]
|
|
54
|
+
return doc.data() as User
|
|
55
|
+
} catch (error) {
|
|
56
|
+
throw new Error('Failed to query user')
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async createUser(userId: string, data: Partial<User>): Promise<void> {
|
|
61
|
+
try {
|
|
62
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
63
|
+
await setDoc(docRef, data, { merge: true })
|
|
64
|
+
} catch (error) {
|
|
65
|
+
throw new Error('Failed to create user')
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async updateUser(userId: string, data: Partial<User>): Promise<void> {
|
|
70
|
+
try {
|
|
71
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
72
|
+
await updateDoc(docRef, {
|
|
73
|
+
...data,
|
|
74
|
+
'profile.updatedAt': Date.now(),
|
|
75
|
+
} as any)
|
|
76
|
+
} catch (error) {
|
|
77
|
+
throw new Error('Failed to update user')
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async deleteUser(userId: string): Promise<void> {
|
|
82
|
+
try {
|
|
83
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
84
|
+
await deleteDoc(docRef)
|
|
85
|
+
} catch (error) {
|
|
86
|
+
throw new Error('Failed to delete user')
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async updateProfile(
|
|
91
|
+
userId: string,
|
|
92
|
+
updates: Partial<Pick<User['profile'], 'displayName' | 'photoURL' | 'phoneNumber'>>
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
try {
|
|
95
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
96
|
+
const updateData: any = {
|
|
97
|
+
'profile.updatedAt': Date.now(),
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (updates.displayName !== undefined) {
|
|
101
|
+
updateData['profile.displayName'] = updates.displayName
|
|
102
|
+
}
|
|
103
|
+
if (updates.photoURL !== undefined) {
|
|
104
|
+
updateData['profile.photoURL'] = updates.photoURL
|
|
105
|
+
}
|
|
106
|
+
if (updates.phoneNumber !== undefined) {
|
|
107
|
+
updateData['profile.phoneNumber'] = updates.phoneNumber
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
await updateDoc(docRef, updateData)
|
|
111
|
+
} catch (error) {
|
|
112
|
+
throw new Error('Failed to update profile')
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async updateSettings(userId: string, settings: Partial<User['settings']>): Promise<void> {
|
|
117
|
+
try {
|
|
118
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
119
|
+
await updateDoc(docRef, {
|
|
120
|
+
settings: {
|
|
121
|
+
...settings,
|
|
122
|
+
updatedAt: Date.now(),
|
|
123
|
+
},
|
|
124
|
+
} as any)
|
|
125
|
+
} catch (error) {
|
|
126
|
+
throw new Error('Failed to update settings')
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async updateSubscription(userId: string, subscription: Partial<User['subscription']>): Promise<void> {
|
|
131
|
+
try {
|
|
132
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
133
|
+
await updateDoc(docRef, {
|
|
134
|
+
subscription: {
|
|
135
|
+
...subscription,
|
|
136
|
+
updatedAt: Date.now(),
|
|
137
|
+
},
|
|
138
|
+
} as any)
|
|
139
|
+
} catch (error) {
|
|
140
|
+
throw new Error('Failed to update subscription')
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async updateLastLogin(userId: string): Promise<void> {
|
|
145
|
+
try {
|
|
146
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
147
|
+
await updateDoc(docRef, {
|
|
148
|
+
'profile.lastLoginAt': Date.now(),
|
|
149
|
+
} as any)
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw new Error('Failed to update last login')
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async queryUsers(constraints: any[]): Promise<User[]> {
|
|
156
|
+
try {
|
|
157
|
+
const q = query(collection(this.db, this.USERS_COLLECTION), ...constraints)
|
|
158
|
+
const snap = await getDocs(q)
|
|
159
|
+
return snap.docs.map((doc) => doc.data() as User)
|
|
160
|
+
} catch (error) {
|
|
161
|
+
throw new Error('Failed to query users')
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
subscribeToUser(
|
|
166
|
+
userId: string,
|
|
167
|
+
callback: (user: User | null) => void,
|
|
168
|
+
onError?: (error: Error) => void
|
|
169
|
+
): () => void {
|
|
170
|
+
const docRef = doc(this.db, this.USERS_COLLECTION, userId)
|
|
171
|
+
|
|
172
|
+
const unsubscribe = onSnapshot(
|
|
173
|
+
docRef,
|
|
174
|
+
(snap) => {
|
|
175
|
+
if (snap.exists()) {
|
|
176
|
+
callback(snap.data() as User)
|
|
177
|
+
} else {
|
|
178
|
+
callback(null)
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
(error) => {
|
|
182
|
+
onError?.(error as Error)
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
return unsubscribe
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Export class and singleton instance
|
|
191
|
+
export const firestoreService = new FirestoreService()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firestore Service Interface
|
|
3
|
+
* @description Abstract interface for Firestore operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { QueryConstraint } from 'firebase/firestore'
|
|
7
|
+
import type { User } from '../entities'
|
|
8
|
+
|
|
9
|
+
export interface IFirestoreService {
|
|
10
|
+
/**
|
|
11
|
+
* Get user by ID
|
|
12
|
+
*/
|
|
13
|
+
getUser(userId: string): Promise<User | null>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get user by email
|
|
17
|
+
*/
|
|
18
|
+
getUserByEmail(email: string): Promise<User | null>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create user
|
|
22
|
+
*/
|
|
23
|
+
createUser(userId: string, data: Partial<User>): Promise<void>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Update user
|
|
27
|
+
*/
|
|
28
|
+
updateUser(userId: string, data: Partial<User>): Promise<void>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Delete user
|
|
32
|
+
*/
|
|
33
|
+
deleteUser(userId: string): Promise<void>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Update user profile
|
|
37
|
+
*/
|
|
38
|
+
updateProfile(userId: string, updates: Partial<Pick<User['profile'], 'displayName' | 'photoURL' | 'phoneNumber'>>): Promise<void>
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update user settings
|
|
42
|
+
*/
|
|
43
|
+
updateSettings(userId: string, settings: Partial<User['settings']>): Promise<void>
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Update user subscription
|
|
47
|
+
*/
|
|
48
|
+
updateSubscription(userId: string, subscription: Partial<User['subscription']>): Promise<void>
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Update last login timestamp
|
|
52
|
+
*/
|
|
53
|
+
updateLastLogin(userId: string): Promise<void>
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Query users with constraints
|
|
57
|
+
*/
|
|
58
|
+
queryUsers(constraints: QueryConstraint[]): Promise<User[]>
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Subscribe to user document changes
|
|
62
|
+
*/
|
|
63
|
+
subscribeToUser(userId: string, callback: (user: User | null) => void, onError?: (error: Error) => void): () => void
|
|
64
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Domain Entities
|
|
3
|
+
* @description File and storage-related entities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* File Metadata Entity
|
|
8
|
+
* Contains metadata about uploaded files
|
|
9
|
+
*/
|
|
10
|
+
export interface FileMetadata {
|
|
11
|
+
readonly id: string
|
|
12
|
+
readonly name: string
|
|
13
|
+
readonly fullPath: string
|
|
14
|
+
readonly contentType: string
|
|
15
|
+
readonly size: number
|
|
16
|
+
readonly createdAt: number
|
|
17
|
+
readonly updatedAt: number
|
|
18
|
+
readonly userId: string
|
|
19
|
+
readonly type: FileType
|
|
20
|
+
category?: FileCategory
|
|
21
|
+
description?: string
|
|
22
|
+
tags?: string[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* File Types
|
|
27
|
+
*/
|
|
28
|
+
export type FileType = 'image' | 'video' | 'audio' | 'document' | 'other'
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* File Categories
|
|
32
|
+
*/
|
|
33
|
+
export type FileCategory = 'profile' | 'content' | 'document' | 'attachment' | 'backup'
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Upload Progress Entity
|
|
37
|
+
* Tracks upload progress for resumable uploads
|
|
38
|
+
*/
|
|
39
|
+
export interface UploadProgress {
|
|
40
|
+
bytesTransferred: number
|
|
41
|
+
totalBytes: number
|
|
42
|
+
progress: number // 0-100
|
|
43
|
+
state: UploadState
|
|
44
|
+
speed?: number // bytes per second
|
|
45
|
+
remaining?: number // seconds remaining
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Upload States
|
|
50
|
+
*/
|
|
51
|
+
export type UploadState =
|
|
52
|
+
| 'paused'
|
|
53
|
+
| 'running'
|
|
54
|
+
| 'success'
|
|
55
|
+
| 'canceled'
|
|
56
|
+
| 'error'
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* File Upload Result Entity
|
|
60
|
+
* Result of a file upload operation
|
|
61
|
+
*/
|
|
62
|
+
export interface FileUploadResult {
|
|
63
|
+
readonly id: string
|
|
64
|
+
readonly name: string
|
|
65
|
+
readonly fullPath: string
|
|
66
|
+
readonly downloadURL: string
|
|
67
|
+
readonly contentType: string
|
|
68
|
+
readonly size: number
|
|
69
|
+
readonly createdAt: number
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Export as UploadResult for backward compatibility
|
|
73
|
+
export type UploadResult = FileUploadResult
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Upload Options
|
|
77
|
+
* Configuration for file uploads
|
|
78
|
+
*/
|
|
79
|
+
export interface UploadOptions {
|
|
80
|
+
onProgress?: (progress: UploadProgress) => void
|
|
81
|
+
metadata?: FileMetadata
|
|
82
|
+
customMetadata?: Record<string, string>
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Storage Statistics
|
|
87
|
+
*/
|
|
88
|
+
export interface StorageStats {
|
|
89
|
+
totalFiles: number
|
|
90
|
+
totalSize: number
|
|
91
|
+
filesByType: Record<FileType, number>
|
|
92
|
+
filesByCategory: Record<FileCategory, number>
|
|
93
|
+
lastUploadAt?: number
|
|
94
|
+
}
|