svelte-firekit 0.0.25 → 0.1.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 +445 -213
- package/dist/components/Collection.svelte +150 -0
- package/dist/components/Collection.svelte.d.ts +27 -0
- package/dist/components/Ddoc.svelte +131 -0
- package/dist/components/Ddoc.svelte.d.ts +28 -0
- package/dist/components/Node.svelte +97 -0
- package/dist/components/Node.svelte.d.ts +23 -0
- package/dist/components/auth-guard.svelte +89 -0
- package/dist/components/auth-guard.svelte.d.ts +26 -0
- package/dist/components/custom-guard.svelte +122 -0
- package/dist/components/custom-guard.svelte.d.ts +31 -0
- package/dist/components/download-url.svelte +92 -0
- package/dist/components/download-url.svelte.d.ts +19 -0
- package/dist/components/firebase-app.svelte +30 -0
- package/dist/components/firebase-app.svelte.d.ts +7 -0
- package/dist/components/node-list.svelte +102 -0
- package/dist/components/node-list.svelte.d.ts +27 -0
- package/dist/components/signed-in.svelte +42 -0
- package/dist/components/signed-in.svelte.d.ts +11 -0
- package/dist/components/signed-out.svelte +42 -0
- package/dist/components/signed-out.svelte.d.ts +11 -0
- package/dist/components/storage-list.svelte +97 -0
- package/dist/components/storage-list.svelte.d.ts +26 -0
- package/dist/components/upload-task.svelte +108 -0
- package/dist/components/upload-task.svelte.d.ts +24 -0
- package/dist/config.js +17 -39
- package/dist/firebase.d.ts +43 -21
- package/dist/firebase.js +121 -35
- package/dist/index.d.ts +21 -13
- package/dist/index.js +27 -15
- package/dist/services/auth.d.ts +397 -0
- package/dist/services/auth.js +882 -0
- package/dist/services/collection.svelte.d.ts +286 -0
- package/dist/services/collection.svelte.js +871 -0
- package/dist/services/document.svelte.d.ts +288 -0
- package/dist/services/document.svelte.js +555 -0
- package/dist/services/mutations.d.ts +336 -0
- package/dist/services/mutations.js +1079 -0
- package/dist/services/presence.svelte.d.ts +141 -0
- package/dist/services/presence.svelte.js +727 -0
- package/dist/{realtime → services}/realtime.svelte.d.ts +3 -1
- package/dist/{realtime → services}/realtime.svelte.js +13 -7
- package/dist/services/storage.svelte.d.ts +257 -0
- package/dist/services/storage.svelte.js +374 -0
- package/dist/services/user.svelte.d.ts +296 -0
- package/dist/services/user.svelte.js +609 -0
- package/dist/types/auth.d.ts +158 -0
- package/dist/types/auth.js +106 -0
- package/dist/types/collection.d.ts +360 -0
- package/dist/types/collection.js +167 -0
- package/dist/types/document.d.ts +342 -0
- package/dist/types/document.js +148 -0
- package/dist/types/firebase.d.ts +44 -0
- package/dist/types/firebase.js +33 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +4 -0
- package/dist/types/mutations.d.ts +387 -0
- package/dist/types/mutations.js +205 -0
- package/dist/types/presence.d.ts +282 -0
- package/dist/types/presence.js +80 -0
- package/dist/utils/errors.d.ts +21 -0
- package/dist/utils/errors.js +35 -0
- package/dist/utils/firestore.d.ts +9 -0
- package/dist/utils/firestore.js +33 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/providers.d.ts +16 -0
- package/dist/utils/providers.js +30 -0
- package/dist/utils/user.d.ts +8 -0
- package/dist/utils/user.js +29 -0
- package/package.json +64 -64
- package/dist/auth/auth.d.ts +0 -117
- package/dist/auth/auth.js +0 -194
- package/dist/auth/presence.svelte.d.ts +0 -139
- package/dist/auth/presence.svelte.js +0 -373
- package/dist/auth/user.svelte.d.ts +0 -112
- package/dist/auth/user.svelte.js +0 -155
- package/dist/firestore/awaitable-doc.svelte.d.ts +0 -141
- package/dist/firestore/awaitable-doc.svelte.js +0 -183
- package/dist/firestore/batch-mutations.svelte.d.ts +0 -140
- package/dist/firestore/batch-mutations.svelte.js +0 -218
- package/dist/firestore/collection-group.svelte.d.ts +0 -78
- package/dist/firestore/collection-group.svelte.js +0 -120
- package/dist/firestore/collection.svelte.d.ts +0 -96
- package/dist/firestore/collection.svelte.js +0 -137
- package/dist/firestore/doc.svelte.d.ts +0 -90
- package/dist/firestore/doc.svelte.js +0 -131
- package/dist/firestore/document-mutations.svelte.d.ts +0 -164
- package/dist/firestore/document-mutations.svelte.js +0 -273
- package/dist/storage/download-url.svelte.d.ts +0 -83
- package/dist/storage/download-url.svelte.js +0 -114
- package/dist/storage/storage-list.svelte.d.ts +0 -89
- package/dist/storage/storage-list.svelte.js +0 -123
- package/dist/storage/upload-task.svelte.d.ts +0 -94
- package/dist/storage/upload-task.svelte.js +0 -138
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Presence types and interfaces for FirekitPresence
|
|
3
|
+
* @module PresenceTypes
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Geolocation configuration options
|
|
8
|
+
*/
|
|
9
|
+
export interface GeolocationConfig {
|
|
10
|
+
/** Whether geolocation tracking is enabled */
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
/** Type of geolocation service to use */
|
|
13
|
+
type: 'browser' | 'ip' | 'custom';
|
|
14
|
+
/** Custom function for retrieving geolocation */
|
|
15
|
+
customGeolocationFn?: () => Promise<{
|
|
16
|
+
latitude: number;
|
|
17
|
+
longitude: number;
|
|
18
|
+
}>;
|
|
19
|
+
/** URL for IP-based geolocation service */
|
|
20
|
+
ipServiceUrl?: string;
|
|
21
|
+
/** Whether user consent is required for location tracking */
|
|
22
|
+
requireConsent?: boolean;
|
|
23
|
+
/** High accuracy GPS tracking */
|
|
24
|
+
enableHighAccuracy?: boolean;
|
|
25
|
+
/** Location timeout in milliseconds */
|
|
26
|
+
timeout?: number;
|
|
27
|
+
/** Maximum age of cached location in milliseconds */
|
|
28
|
+
maximumAge?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Presence service configuration options
|
|
32
|
+
*/
|
|
33
|
+
export interface PresenceConfig {
|
|
34
|
+
/** Geolocation settings */
|
|
35
|
+
geolocation?: GeolocationConfig;
|
|
36
|
+
/** Session timeout in milliseconds (default: 30 minutes) */
|
|
37
|
+
sessionTTL?: number;
|
|
38
|
+
/** Presence update interval in milliseconds (default: 1 minute) */
|
|
39
|
+
updateInterval?: number;
|
|
40
|
+
/** Custom user metadata to track */
|
|
41
|
+
customMetadata?: Record<string, any>;
|
|
42
|
+
/** Whether to track device information */
|
|
43
|
+
trackDeviceInfo?: boolean;
|
|
44
|
+
/** Custom session collection path in Firebase */
|
|
45
|
+
sessionPath?: string;
|
|
46
|
+
/** Whether to enable automatic status detection based on page visibility */
|
|
47
|
+
enableAutoStatusDetection?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Location data structure
|
|
51
|
+
*/
|
|
52
|
+
export interface Location {
|
|
53
|
+
latitude: number;
|
|
54
|
+
longitude: number;
|
|
55
|
+
accuracy?: number;
|
|
56
|
+
altitude?: number;
|
|
57
|
+
altitudeAccuracy?: number;
|
|
58
|
+
heading?: number;
|
|
59
|
+
speed?: number;
|
|
60
|
+
lastUpdated: string;
|
|
61
|
+
source: 'browser' | 'ip' | 'custom';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Device information structure
|
|
65
|
+
*/
|
|
66
|
+
export interface DeviceInfo {
|
|
67
|
+
id: string;
|
|
68
|
+
type: 'desktop' | 'mobile' | 'tablet' | 'unknown';
|
|
69
|
+
browser: string;
|
|
70
|
+
browserVersion: string;
|
|
71
|
+
os: string;
|
|
72
|
+
osVersion: string;
|
|
73
|
+
userAgent: string;
|
|
74
|
+
screenResolution?: string;
|
|
75
|
+
timezone?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Session data structure
|
|
79
|
+
*/
|
|
80
|
+
export interface SessionData {
|
|
81
|
+
id: string;
|
|
82
|
+
userId: string;
|
|
83
|
+
status: 'online' | 'offline' | 'away' | 'busy' | 'invisible';
|
|
84
|
+
createdAt: string;
|
|
85
|
+
lastSeen: string;
|
|
86
|
+
location?: Location;
|
|
87
|
+
device?: DeviceInfo;
|
|
88
|
+
metadata?: Record<string, any>;
|
|
89
|
+
connectionType?: 'wifi' | 'cellular' | 'ethernet' | 'unknown';
|
|
90
|
+
lastActivity?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* User presence summary
|
|
94
|
+
*/
|
|
95
|
+
export interface UserPresence {
|
|
96
|
+
userId: string;
|
|
97
|
+
status: SessionData['status'];
|
|
98
|
+
lastSeen: string;
|
|
99
|
+
sessionCount: number;
|
|
100
|
+
activeDevices: string[];
|
|
101
|
+
primarySession?: SessionData;
|
|
102
|
+
location?: Location;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Presence statistics
|
|
106
|
+
*/
|
|
107
|
+
export interface PresenceStats {
|
|
108
|
+
totalSessions: number;
|
|
109
|
+
onlineSessions: number;
|
|
110
|
+
awaySessions: number;
|
|
111
|
+
offlineSessions: number;
|
|
112
|
+
uniqueDevices: number;
|
|
113
|
+
averageSessionDuration: number;
|
|
114
|
+
lastActivity: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Presence event types
|
|
118
|
+
*/
|
|
119
|
+
export type PresenceEventType = 'status_change' | 'session_created' | 'session_updated' | 'session_expired' | 'location_update' | 'location_error' | 'error' | 'init' | 'disconnect' | 'reconnect' | 'consent_requested' | 'consent_granted' | 'consent_denied' | 'device_detected' | 'visibility_change';
|
|
120
|
+
/**
|
|
121
|
+
* Presence event structure
|
|
122
|
+
*/
|
|
123
|
+
export interface PresenceEvent {
|
|
124
|
+
type: PresenceEventType;
|
|
125
|
+
data?: any;
|
|
126
|
+
error?: Error;
|
|
127
|
+
timestamp: number;
|
|
128
|
+
sessionId?: string;
|
|
129
|
+
userId?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Presence event callback function type
|
|
133
|
+
*/
|
|
134
|
+
export type PresenceEventCallback = (event: PresenceEvent) => void;
|
|
135
|
+
/**
|
|
136
|
+
* Geolocation provider interface
|
|
137
|
+
*/
|
|
138
|
+
export interface GeolocationProvider {
|
|
139
|
+
getCurrentLocation(): Promise<Location | null>;
|
|
140
|
+
watchPosition?(callback: (location: Location | null) => void): number;
|
|
141
|
+
clearWatch?(watchId: number): void;
|
|
142
|
+
requestPermission?(): Promise<boolean>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Session storage interface
|
|
146
|
+
*/
|
|
147
|
+
export interface SessionStorage {
|
|
148
|
+
saveSession(userId: string, session: SessionData): Promise<void>;
|
|
149
|
+
loadSessions(userId: string): Promise<SessionData[]>;
|
|
150
|
+
deleteSession(userId: string, sessionId: string): Promise<void>;
|
|
151
|
+
cleanupExpiredSessions(userId: string, ttl: number): Promise<void>;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Presence service interface
|
|
155
|
+
*/
|
|
156
|
+
export interface PresenceService {
|
|
157
|
+
initialize(user: any, config?: PresenceConfig): Promise<void>;
|
|
158
|
+
setPresence(status: SessionData['status']): Promise<void>;
|
|
159
|
+
getCurrentSession(): SessionData | null;
|
|
160
|
+
getAllSessions(): SessionData[];
|
|
161
|
+
getPresenceStats(): PresenceStats;
|
|
162
|
+
addEventListener(callback: PresenceEventCallback): () => void;
|
|
163
|
+
dispose(): Promise<void>;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Connection info structure
|
|
167
|
+
*/
|
|
168
|
+
export interface ConnectionInfo {
|
|
169
|
+
effectiveType?: 'slow-2g' | '2g' | '3g' | '4g';
|
|
170
|
+
type?: 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown';
|
|
171
|
+
downlink?: number;
|
|
172
|
+
rtt?: number;
|
|
173
|
+
saveData?: boolean;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Browser capability detection
|
|
177
|
+
*/
|
|
178
|
+
export interface BrowserCapabilities {
|
|
179
|
+
geolocation: boolean;
|
|
180
|
+
notifications: boolean;
|
|
181
|
+
serviceWorker: boolean;
|
|
182
|
+
indexedDB: boolean;
|
|
183
|
+
webRTC: boolean;
|
|
184
|
+
websockets: boolean;
|
|
185
|
+
localStorage: boolean;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Presence filter options
|
|
189
|
+
*/
|
|
190
|
+
export interface PresenceFilter {
|
|
191
|
+
status?: SessionData['status'][];
|
|
192
|
+
deviceTypes?: DeviceInfo['type'][];
|
|
193
|
+
timeRange?: {
|
|
194
|
+
start: string;
|
|
195
|
+
end: string;
|
|
196
|
+
};
|
|
197
|
+
hasLocation?: boolean;
|
|
198
|
+
activeOnly?: boolean;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Bulk presence update
|
|
202
|
+
*/
|
|
203
|
+
export interface BulkPresenceUpdate {
|
|
204
|
+
userId: string;
|
|
205
|
+
updates: Partial<SessionData>[];
|
|
206
|
+
timestamp: string;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Presence query options
|
|
210
|
+
*/
|
|
211
|
+
export interface PresenceQueryOptions {
|
|
212
|
+
limit?: number;
|
|
213
|
+
orderBy?: 'lastSeen' | 'createdAt' | 'status';
|
|
214
|
+
direction?: 'asc' | 'desc';
|
|
215
|
+
filter?: PresenceFilter;
|
|
216
|
+
includeExpired?: boolean;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Custom presence status
|
|
220
|
+
*/
|
|
221
|
+
export interface CustomPresenceStatus {
|
|
222
|
+
key: string;
|
|
223
|
+
label: string;
|
|
224
|
+
color?: string;
|
|
225
|
+
icon?: string;
|
|
226
|
+
priority?: number;
|
|
227
|
+
autoDetect?: boolean;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Presence analytics data
|
|
231
|
+
*/
|
|
232
|
+
export interface PresenceAnalytics {
|
|
233
|
+
userId: string;
|
|
234
|
+
dailyActiveTime: number;
|
|
235
|
+
weeklyActiveTime: number;
|
|
236
|
+
monthlyActiveTime: number;
|
|
237
|
+
mostActiveDevice: string;
|
|
238
|
+
mostActiveHour: number;
|
|
239
|
+
averageSessionLength: number;
|
|
240
|
+
locationHistory: Location[];
|
|
241
|
+
statusHistory: Array<{
|
|
242
|
+
status: SessionData['status'];
|
|
243
|
+
timestamp: string;
|
|
244
|
+
duration: number;
|
|
245
|
+
}>;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Error types for presence service
|
|
249
|
+
*/
|
|
250
|
+
export declare enum PresenceErrorCode {
|
|
251
|
+
INITIALIZATION_FAILED = "presence/initialization-failed",
|
|
252
|
+
USER_NOT_AUTHENTICATED = "presence/user-not-authenticated",
|
|
253
|
+
GEOLOCATION_DENIED = "presence/geolocation-denied",
|
|
254
|
+
GEOLOCATION_UNAVAILABLE = "presence/geolocation-unavailable",
|
|
255
|
+
GEOLOCATION_TIMEOUT = "presence/geolocation-timeout",
|
|
256
|
+
DATABASE_ERROR = "presence/database-error",
|
|
257
|
+
SESSION_EXPIRED = "presence/session-expired",
|
|
258
|
+
INVALID_CONFIG = "presence/invalid-config",
|
|
259
|
+
BROWSER_NOT_SUPPORTED = "presence/browser-not-supported",
|
|
260
|
+
NETWORK_ERROR = "presence/network-error",
|
|
261
|
+
PERMISSION_DENIED = "presence/permission-denied"
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Custom presence error class
|
|
265
|
+
*/
|
|
266
|
+
export declare class PresenceError extends Error {
|
|
267
|
+
code: PresenceErrorCode;
|
|
268
|
+
originalError?: any | undefined;
|
|
269
|
+
constructor(code: PresenceErrorCode, message: string, originalError?: any | undefined);
|
|
270
|
+
/**
|
|
271
|
+
* Get user-friendly error message
|
|
272
|
+
*/
|
|
273
|
+
getFriendlyMessage(): string;
|
|
274
|
+
/**
|
|
275
|
+
* Check if error is retryable
|
|
276
|
+
*/
|
|
277
|
+
isRetryable(): boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Check if error requires user action
|
|
280
|
+
*/
|
|
281
|
+
requiresUserAction(): boolean;
|
|
282
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Presence types and interfaces for FirekitPresence
|
|
3
|
+
* @module PresenceTypes
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Error types for presence service
|
|
8
|
+
*/
|
|
9
|
+
export var PresenceErrorCode;
|
|
10
|
+
(function (PresenceErrorCode) {
|
|
11
|
+
PresenceErrorCode["INITIALIZATION_FAILED"] = "presence/initialization-failed";
|
|
12
|
+
PresenceErrorCode["USER_NOT_AUTHENTICATED"] = "presence/user-not-authenticated";
|
|
13
|
+
PresenceErrorCode["GEOLOCATION_DENIED"] = "presence/geolocation-denied";
|
|
14
|
+
PresenceErrorCode["GEOLOCATION_UNAVAILABLE"] = "presence/geolocation-unavailable";
|
|
15
|
+
PresenceErrorCode["GEOLOCATION_TIMEOUT"] = "presence/geolocation-timeout";
|
|
16
|
+
PresenceErrorCode["DATABASE_ERROR"] = "presence/database-error";
|
|
17
|
+
PresenceErrorCode["SESSION_EXPIRED"] = "presence/session-expired";
|
|
18
|
+
PresenceErrorCode["INVALID_CONFIG"] = "presence/invalid-config";
|
|
19
|
+
PresenceErrorCode["BROWSER_NOT_SUPPORTED"] = "presence/browser-not-supported";
|
|
20
|
+
PresenceErrorCode["NETWORK_ERROR"] = "presence/network-error";
|
|
21
|
+
PresenceErrorCode["PERMISSION_DENIED"] = "presence/permission-denied";
|
|
22
|
+
})(PresenceErrorCode || (PresenceErrorCode = {}));
|
|
23
|
+
/**
|
|
24
|
+
* Custom presence error class
|
|
25
|
+
*/
|
|
26
|
+
export class PresenceError extends Error {
|
|
27
|
+
code;
|
|
28
|
+
originalError;
|
|
29
|
+
constructor(code, message, originalError) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.originalError = originalError;
|
|
33
|
+
this.name = 'PresenceError';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get user-friendly error message
|
|
37
|
+
*/
|
|
38
|
+
getFriendlyMessage() {
|
|
39
|
+
switch (this.code) {
|
|
40
|
+
case PresenceErrorCode.GEOLOCATION_DENIED:
|
|
41
|
+
return 'Location access was denied. Please enable location services to use this feature.';
|
|
42
|
+
case PresenceErrorCode.GEOLOCATION_UNAVAILABLE:
|
|
43
|
+
return 'Location services are not available on this device.';
|
|
44
|
+
case PresenceErrorCode.GEOLOCATION_TIMEOUT:
|
|
45
|
+
return 'Location request timed out. Please try again.';
|
|
46
|
+
case PresenceErrorCode.USER_NOT_AUTHENTICATED:
|
|
47
|
+
return 'Please sign in to use presence features.';
|
|
48
|
+
case PresenceErrorCode.NETWORK_ERROR:
|
|
49
|
+
return 'Network connection error. Please check your internet connection.';
|
|
50
|
+
case PresenceErrorCode.BROWSER_NOT_SUPPORTED:
|
|
51
|
+
return 'Your browser does not support all required features.';
|
|
52
|
+
case PresenceErrorCode.SESSION_EXPIRED:
|
|
53
|
+
return 'Your session has expired. Please refresh the page.';
|
|
54
|
+
default:
|
|
55
|
+
return this.message || 'An unknown error occurred.';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if error is retryable
|
|
60
|
+
*/
|
|
61
|
+
isRetryable() {
|
|
62
|
+
const retryableCodes = [
|
|
63
|
+
PresenceErrorCode.NETWORK_ERROR,
|
|
64
|
+
PresenceErrorCode.GEOLOCATION_TIMEOUT,
|
|
65
|
+
PresenceErrorCode.DATABASE_ERROR
|
|
66
|
+
];
|
|
67
|
+
return retryableCodes.includes(this.code);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if error requires user action
|
|
71
|
+
*/
|
|
72
|
+
requiresUserAction() {
|
|
73
|
+
const userActionCodes = [
|
|
74
|
+
PresenceErrorCode.GEOLOCATION_DENIED,
|
|
75
|
+
PresenceErrorCode.USER_NOT_AUTHENTICATED,
|
|
76
|
+
PresenceErrorCode.PERMISSION_DENIED
|
|
77
|
+
];
|
|
78
|
+
return userActionCodes.includes(this.code);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { FirekitAuthError } from '../types/auth.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a standardized FirekitAuthError with context
|
|
4
|
+
* @param {any} error Original error object
|
|
5
|
+
* @param {string} context Context of the operation that failed
|
|
6
|
+
* @returns {FirekitAuthError} Standardized error object
|
|
7
|
+
*/
|
|
8
|
+
export declare function createAuthError(error: any, context: string): FirekitAuthError;
|
|
9
|
+
/**
|
|
10
|
+
* Validates that a current user exists and returns the user
|
|
11
|
+
* @param {any} auth Firebase auth instance
|
|
12
|
+
* @returns {any} Current Firebase user
|
|
13
|
+
* @throws {FirekitAuthError} If no authenticated user found
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateCurrentUser(auth: any): any;
|
|
16
|
+
/**
|
|
17
|
+
* Handles Firebase authentication errors and throws FirekitAuthError with friendly message
|
|
18
|
+
* @param {any} error Original Firebase error
|
|
19
|
+
* @returns {never} Never returns, always throws
|
|
20
|
+
*/
|
|
21
|
+
export declare function handleAuthError(error: any): never;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { FirekitAuthError, AuthErrorCode } from '../types/auth.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a standardized FirekitAuthError with context
|
|
4
|
+
* @param {any} error Original error object
|
|
5
|
+
* @param {string} context Context of the operation that failed
|
|
6
|
+
* @returns {FirekitAuthError} Standardized error object
|
|
7
|
+
*/
|
|
8
|
+
export function createAuthError(error, context) {
|
|
9
|
+
const code = error.code;
|
|
10
|
+
return new FirekitAuthError(code || `${context}-failed`, `Failed to ${context}: ${error.message}`);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Validates that a current user exists and returns the user
|
|
14
|
+
* @param {any} auth Firebase auth instance
|
|
15
|
+
* @returns {any} Current Firebase user
|
|
16
|
+
* @throws {FirekitAuthError} If no authenticated user found
|
|
17
|
+
*/
|
|
18
|
+
export function validateCurrentUser(auth) {
|
|
19
|
+
const user = auth.currentUser;
|
|
20
|
+
if (!user) {
|
|
21
|
+
throw new FirekitAuthError(AuthErrorCode.USER_NOT_FOUND, 'No authenticated user found.');
|
|
22
|
+
}
|
|
23
|
+
return user;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Handles Firebase authentication errors and throws FirekitAuthError with friendly message
|
|
27
|
+
* @param {any} error Original Firebase error
|
|
28
|
+
* @returns {never} Never returns, always throws
|
|
29
|
+
*/
|
|
30
|
+
export function handleAuthError(error) {
|
|
31
|
+
const code = error.code;
|
|
32
|
+
const firekitError = new FirekitAuthError(code, error.message, error);
|
|
33
|
+
// Use the existing getFriendlyMessage method from FirekitAuthError
|
|
34
|
+
throw new FirekitAuthError(code, firekitError.getFriendlyMessage(), error);
|
|
35
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Firestore } from 'firebase/firestore';
|
|
2
|
+
import type { User } from 'firebase/auth';
|
|
3
|
+
/**
|
|
4
|
+
* Updates user data in Firestore with comprehensive profile information
|
|
5
|
+
* @param {Firestore} firestore Firestore instance
|
|
6
|
+
* @param {User} user Firebase user object
|
|
7
|
+
* @returns {Promise<void>} Promise that resolves when update completes
|
|
8
|
+
*/
|
|
9
|
+
export declare function updateUserInFirestore(firestore: Firestore, user: User): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { doc, setDoc, serverTimestamp } from 'firebase/firestore';
|
|
2
|
+
/**
|
|
3
|
+
* Updates user data in Firestore with comprehensive profile information
|
|
4
|
+
* @param {Firestore} firestore Firestore instance
|
|
5
|
+
* @param {User} user Firebase user object
|
|
6
|
+
* @returns {Promise<void>} Promise that resolves when update completes
|
|
7
|
+
*/
|
|
8
|
+
export async function updateUserInFirestore(firestore, user) {
|
|
9
|
+
try {
|
|
10
|
+
const userRef = doc(firestore, 'users', user.uid);
|
|
11
|
+
const userData = {
|
|
12
|
+
uid: user.uid,
|
|
13
|
+
email: user.email,
|
|
14
|
+
emailVerified: user.emailVerified,
|
|
15
|
+
displayName: user.displayName,
|
|
16
|
+
photoURL: user.photoURL,
|
|
17
|
+
phoneNumber: user.phoneNumber,
|
|
18
|
+
isAnonymous: user.isAnonymous,
|
|
19
|
+
providerId: user.providerId,
|
|
20
|
+
providerData: user.providerData,
|
|
21
|
+
metadata: {
|
|
22
|
+
creationTime: user.metadata.creationTime,
|
|
23
|
+
lastSignInTime: user.metadata.lastSignInTime
|
|
24
|
+
},
|
|
25
|
+
lastUpdated: serverTimestamp()
|
|
26
|
+
};
|
|
27
|
+
await setDoc(userRef, userData, { merge: true });
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error('Failed to update user in Firestore:', error);
|
|
31
|
+
// Don't throw here to avoid blocking auth operations
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { mapFirebaseUserToProfile } from './user.js';
|
|
2
|
+
export { updateUserInFirestore } from './firestore.js';
|
|
3
|
+
export { createAuthError, validateCurrentUser, handleAuthError } from './errors.js';
|
|
4
|
+
export { createGoogleProvider, createFacebookProvider, createAppleProvider } from './providers.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// User utilities
|
|
2
|
+
export { mapFirebaseUserToProfile } from './user.js';
|
|
3
|
+
// Firestore utilities
|
|
4
|
+
export { updateUserInFirestore } from './firestore.js';
|
|
5
|
+
// Error handling utilities
|
|
6
|
+
export { createAuthError, validateCurrentUser, handleAuthError } from './errors.js';
|
|
7
|
+
// Provider utilities
|
|
8
|
+
export { createGoogleProvider, createFacebookProvider, createAppleProvider } from './providers.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { GoogleAuthProvider, FacebookAuthProvider, OAuthProvider } from 'firebase/auth';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a configured Google Auth provider
|
|
4
|
+
* @returns {GoogleAuthProvider} Configured Google provider
|
|
5
|
+
*/
|
|
6
|
+
export declare function createGoogleProvider(): GoogleAuthProvider;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a configured Facebook Auth provider
|
|
9
|
+
* @returns {FacebookAuthProvider} Configured Facebook provider
|
|
10
|
+
*/
|
|
11
|
+
export declare function createFacebookProvider(): FacebookAuthProvider;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a configured Apple Auth provider
|
|
14
|
+
* @returns {OAuthProvider} Configured Apple provider
|
|
15
|
+
*/
|
|
16
|
+
export declare function createAppleProvider(): OAuthProvider;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { GoogleAuthProvider, FacebookAuthProvider, OAuthProvider } from 'firebase/auth';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a configured Google Auth provider
|
|
4
|
+
* @returns {GoogleAuthProvider} Configured Google provider
|
|
5
|
+
*/
|
|
6
|
+
export function createGoogleProvider() {
|
|
7
|
+
const provider = new GoogleAuthProvider();
|
|
8
|
+
provider.addScope('email');
|
|
9
|
+
provider.addScope('profile');
|
|
10
|
+
return provider;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a configured Facebook Auth provider
|
|
14
|
+
* @returns {FacebookAuthProvider} Configured Facebook provider
|
|
15
|
+
*/
|
|
16
|
+
export function createFacebookProvider() {
|
|
17
|
+
const provider = new FacebookAuthProvider();
|
|
18
|
+
provider.addScope('email');
|
|
19
|
+
return provider;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a configured Apple Auth provider
|
|
23
|
+
* @returns {OAuthProvider} Configured Apple provider
|
|
24
|
+
*/
|
|
25
|
+
export function createAppleProvider() {
|
|
26
|
+
const provider = new OAuthProvider('apple.com');
|
|
27
|
+
provider.addScope('email');
|
|
28
|
+
provider.addScope('name');
|
|
29
|
+
return provider;
|
|
30
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { User } from 'firebase/auth';
|
|
2
|
+
import type { UserProfile } from '../types/auth.js';
|
|
3
|
+
/**
|
|
4
|
+
* Maps Firebase User to UserProfile interface
|
|
5
|
+
* @param {User} user Firebase user object
|
|
6
|
+
* @returns {UserProfile} Mapped user profile
|
|
7
|
+
*/
|
|
8
|
+
export declare function mapFirebaseUserToProfile(user: User): UserProfile;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps Firebase User to UserProfile interface
|
|
3
|
+
* @param {User} user Firebase user object
|
|
4
|
+
* @returns {UserProfile} Mapped user profile
|
|
5
|
+
*/
|
|
6
|
+
export function mapFirebaseUserToProfile(user) {
|
|
7
|
+
return {
|
|
8
|
+
uid: user.uid,
|
|
9
|
+
email: user.email,
|
|
10
|
+
displayName: user.displayName,
|
|
11
|
+
photoURL: user.photoURL,
|
|
12
|
+
phoneNumber: user.phoneNumber,
|
|
13
|
+
emailVerified: user.emailVerified,
|
|
14
|
+
isAnonymous: user.isAnonymous,
|
|
15
|
+
providerId: user.providerId,
|
|
16
|
+
metadata: {
|
|
17
|
+
creationTime: user.metadata.creationTime,
|
|
18
|
+
lastSignInTime: user.metadata.lastSignInTime
|
|
19
|
+
},
|
|
20
|
+
providerData: user.providerData.map((provider) => ({
|
|
21
|
+
providerId: provider.providerId,
|
|
22
|
+
uid: provider.uid,
|
|
23
|
+
displayName: provider.displayName,
|
|
24
|
+
email: provider.email,
|
|
25
|
+
phoneNumber: provider.phoneNumber,
|
|
26
|
+
photoURL: provider.photoURL
|
|
27
|
+
}))
|
|
28
|
+
};
|
|
29
|
+
}
|