@sudobility/auth_lib 0.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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @fileoverview Configurable Firebase initialization
3
+ */
4
+ import { type FirebaseApp } from 'firebase/app';
5
+ import { type Auth } from 'firebase/auth';
6
+ import type { FirebaseConfig, FirebaseInitOptions, FirebaseInitResult } from './types';
7
+ /**
8
+ * Check if Firebase is configured with the required fields
9
+ */
10
+ export declare function isFirebaseConfigured(): boolean;
11
+ /**
12
+ * Initialize Firebase Auth with the provided configuration.
13
+ * This should be called once at app startup (e.g., in main.tsx).
14
+ *
15
+ * @param options - Firebase initialization options
16
+ * @returns Firebase app and auth instances
17
+ * @throws Error if Firebase is already initialized with different config
18
+ */
19
+ export declare function initializeFirebaseAuth(options: FirebaseInitOptions): FirebaseInitResult;
20
+ /**
21
+ * Get the Firebase app instance.
22
+ * Must call initializeFirebaseAuth() first.
23
+ *
24
+ * @returns Firebase app instance or null if not initialized
25
+ */
26
+ export declare function getFirebaseApp(): FirebaseApp | null;
27
+ /**
28
+ * Get the Firebase auth instance.
29
+ * Must call initializeFirebaseAuth() first.
30
+ *
31
+ * @returns Firebase auth instance or null if not initialized
32
+ */
33
+ export declare function getFirebaseAuth(): Auth | null;
34
+ /**
35
+ * Get the current Firebase configuration.
36
+ *
37
+ * @returns Firebase config or null if not initialized
38
+ */
39
+ export declare function getFirebaseConfig(): FirebaseConfig | null;
40
+ //# sourceMappingURL=firebase-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-init.d.ts","sourceRoot":"","sources":["../../src/config/firebase-init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAkC,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,KAAK,IAAI,EAAW,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAOjB;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAS9C;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,mBAAmB,GAC3B,kBAAkB,CAyBpB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,IAAI,GAAG,IAAI,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @fileoverview Configurable Firebase initialization
3
+ */
4
+ import { getApp, getApps, initializeApp } from 'firebase/app';
5
+ import { getAuth } from 'firebase/auth';
6
+ // Singleton state
7
+ let firebaseApp = null;
8
+ let firebaseAuth = null;
9
+ let firebaseConfig = null;
10
+ /**
11
+ * Check if Firebase is configured with the required fields
12
+ */
13
+ export function isFirebaseConfigured() {
14
+ if (!firebaseConfig)
15
+ return false;
16
+ const requiredFields = [
17
+ 'apiKey',
18
+ 'authDomain',
19
+ 'projectId',
20
+ 'appId',
21
+ ];
22
+ return requiredFields.every(field => !!firebaseConfig?.[field]);
23
+ }
24
+ /**
25
+ * Initialize Firebase Auth with the provided configuration.
26
+ * This should be called once at app startup (e.g., in main.tsx).
27
+ *
28
+ * @param options - Firebase initialization options
29
+ * @returns Firebase app and auth instances
30
+ * @throws Error if Firebase is already initialized with different config
31
+ */
32
+ export function initializeFirebaseAuth(options) {
33
+ const { config } = options;
34
+ // Store the config
35
+ firebaseConfig = config;
36
+ // Check if already initialized
37
+ if (firebaseApp && firebaseAuth) {
38
+ return { app: firebaseApp, auth: firebaseAuth };
39
+ }
40
+ // Validate configuration
41
+ if (!isFirebaseConfigured()) {
42
+ throw new Error('[auth_lib] Firebase configuration is incomplete. Required fields: apiKey, authDomain, projectId, appId');
43
+ }
44
+ // Initialize Firebase app (avoid duplicate initialization)
45
+ firebaseApp = getApps().length === 0 ? initializeApp(config) : getApp();
46
+ // Initialize Firebase Auth
47
+ firebaseAuth = getAuth(firebaseApp);
48
+ return { app: firebaseApp, auth: firebaseAuth };
49
+ }
50
+ /**
51
+ * Get the Firebase app instance.
52
+ * Must call initializeFirebaseAuth() first.
53
+ *
54
+ * @returns Firebase app instance or null if not initialized
55
+ */
56
+ export function getFirebaseApp() {
57
+ return firebaseApp;
58
+ }
59
+ /**
60
+ * Get the Firebase auth instance.
61
+ * Must call initializeFirebaseAuth() first.
62
+ *
63
+ * @returns Firebase auth instance or null if not initialized
64
+ */
65
+ export function getFirebaseAuth() {
66
+ return firebaseAuth;
67
+ }
68
+ /**
69
+ * Get the current Firebase configuration.
70
+ *
71
+ * @returns Firebase config or null if not initialized
72
+ */
73
+ export function getFirebaseConfig() {
74
+ return firebaseConfig;
75
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @fileoverview Config exports
3
+ */
4
+ export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './firebase-init';
5
+ export type { FirebaseConfig, FirebaseInitOptions, FirebaseInitResult, FirebaseAuthNetworkClientOptions, } from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview Config exports
3
+ */
4
+ export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './firebase-init';
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @fileoverview Type definitions for auth_lib
3
+ */
4
+ import type { Auth } from 'firebase/auth';
5
+ import type { FirebaseApp } from 'firebase/app';
6
+ /**
7
+ * Firebase configuration object
8
+ */
9
+ export interface FirebaseConfig {
10
+ apiKey: string;
11
+ authDomain: string;
12
+ projectId: string;
13
+ storageBucket?: string;
14
+ messagingSenderId?: string;
15
+ appId: string;
16
+ measurementId?: string;
17
+ }
18
+ /**
19
+ * Options for initializing Firebase Auth
20
+ */
21
+ export interface FirebaseInitOptions {
22
+ /** Firebase configuration */
23
+ config: FirebaseConfig;
24
+ }
25
+ /**
26
+ * Result of Firebase initialization
27
+ */
28
+ export interface FirebaseInitResult {
29
+ app: FirebaseApp;
30
+ auth: Auth;
31
+ }
32
+ /**
33
+ * Options for the Firebase Auth network client hook
34
+ */
35
+ export interface FirebaseAuthNetworkClientOptions {
36
+ /** Callback when user is logged out due to 403 */
37
+ onLogout?: () => void;
38
+ /** Callback when token refresh fails */
39
+ onTokenRefreshFailed?: (error: unknown) => void;
40
+ }
41
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6BAA6B;IAC7B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wCAAwC;IACxC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview Type definitions for auth_lib
3
+ */
4
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @fileoverview Hooks exports
3
+ */
4
+ export { useFirebaseAuthNetworkClient } from './useFirebaseAuthNetworkClient';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview Hooks exports
3
+ */
4
+ export { useFirebaseAuthNetworkClient } from './useFirebaseAuthNetworkClient';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview Hook to provide a resilient network client with automatic token refresh and logout handling.
3
+ *
4
+ * - On 401 (Unauthorized): Force refresh Firebase token and retry once
5
+ * - On 403 (Forbidden): Log the user out
6
+ */
7
+ import type { NetworkClient } from '@sudobility/types';
8
+ import type { FirebaseAuthNetworkClientOptions } from '../config/types';
9
+ /**
10
+ * Hook to get a Firebase Auth network client with automatic 401 retry and 403 logout.
11
+ *
12
+ * @param options - Optional callbacks for logout and token refresh failure
13
+ * @returns NetworkClient instance
14
+ */
15
+ export declare function useFirebaseAuthNetworkClient(options?: FirebaseAuthNetworkClientOptions): NetworkClient;
16
+ //# sourceMappingURL=useFirebaseAuthNetworkClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFirebaseAuthNetworkClient.d.ts","sourceRoot":"","sources":["../../src/hooks/useFirebaseAuthNetworkClient.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,aAAa,EAId,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,iBAAiB,CAAC;AAyLxE;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,CAAC,EAAE,gCAAgC,GACzC,aAAa,CAEf"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @fileoverview Hook to provide a resilient network client with automatic token refresh and logout handling.
3
+ *
4
+ * - On 401 (Unauthorized): Force refresh Firebase token and retry once
5
+ * - On 403 (Forbidden): Log the user out
6
+ */
7
+ import { useMemo } from 'react';
8
+ import { getNetworkService } from '@sudobility/di';
9
+ import { signOut } from 'firebase/auth';
10
+ import { getFirebaseAuth } from '../config/firebase-init';
11
+ /**
12
+ * Get a fresh Firebase ID token with force refresh.
13
+ * Returns empty string if not authenticated.
14
+ */
15
+ async function getAuthToken(forceRefresh = false) {
16
+ const auth = getFirebaseAuth();
17
+ const user = auth?.currentUser;
18
+ if (!user)
19
+ return '';
20
+ try {
21
+ return await user.getIdToken(forceRefresh);
22
+ }
23
+ catch (err) {
24
+ console.error('[useFirebaseAuthNetworkClient] Failed to get ID token:', err);
25
+ return '';
26
+ }
27
+ }
28
+ /**
29
+ * Log the user out via Firebase.
30
+ */
31
+ async function logoutUser(onLogout) {
32
+ const auth = getFirebaseAuth();
33
+ if (!auth)
34
+ return;
35
+ try {
36
+ await signOut(auth);
37
+ onLogout?.();
38
+ }
39
+ catch (err) {
40
+ console.error('[useFirebaseAuthNetworkClient] Failed to sign out:', err);
41
+ }
42
+ }
43
+ /**
44
+ * Create a network client adapter that wraps the platform network client
45
+ * with 401 retry and 403 logout handling.
46
+ */
47
+ function createFirebaseAuthNetworkClient(options) {
48
+ const platformNetwork = getNetworkService();
49
+ const parseResponse = async (response) => {
50
+ let data;
51
+ const contentType = response.headers.get('content-type');
52
+ if (contentType?.includes('application/json')) {
53
+ try {
54
+ data = (await response.json());
55
+ }
56
+ catch {
57
+ // JSON parse failed, leave data undefined
58
+ }
59
+ }
60
+ const headers = {};
61
+ response.headers.forEach((value, key) => {
62
+ headers[key] = value;
63
+ });
64
+ return {
65
+ ok: response.ok,
66
+ status: response.status,
67
+ statusText: response.statusText,
68
+ headers,
69
+ data,
70
+ success: response.ok,
71
+ timestamp: new Date().toISOString(),
72
+ };
73
+ };
74
+ /**
75
+ * Execute request with retry logic:
76
+ * - On 401: Force refresh token and retry once
77
+ * - On 403: Log user out (no retry)
78
+ */
79
+ const executeWithRetry = async (url, requestInit) => {
80
+ const response = await platformNetwork.request(url, requestInit);
81
+ // On 401, get fresh token and retry once
82
+ if (response.status === 401) {
83
+ const freshToken = await getAuthToken(true);
84
+ if (freshToken) {
85
+ const retryHeaders = {
86
+ ...requestInit.headers,
87
+ Authorization: `Bearer ${freshToken}`,
88
+ };
89
+ const retryResponse = await platformNetwork.request(url, {
90
+ ...requestInit,
91
+ headers: retryHeaders,
92
+ });
93
+ return parseResponse(retryResponse);
94
+ }
95
+ else {
96
+ // Token refresh failed
97
+ options?.onTokenRefreshFailed?.(new Error('Failed to refresh token'));
98
+ }
99
+ }
100
+ // On 403, log the user out
101
+ if (response.status === 403) {
102
+ console.warn('[useFirebaseAuthNetworkClient] 403 Forbidden - logging user out');
103
+ await logoutUser(options?.onLogout);
104
+ // Return the original response so the UI can handle it
105
+ }
106
+ return parseResponse(response);
107
+ };
108
+ return {
109
+ async request(url, reqOptions) {
110
+ const requestInit = {
111
+ method: reqOptions?.method ?? 'GET',
112
+ headers: reqOptions?.headers ?? undefined,
113
+ body: reqOptions?.body ?? undefined,
114
+ signal: reqOptions?.signal ?? undefined,
115
+ };
116
+ return executeWithRetry(url, requestInit);
117
+ },
118
+ async get(url, reqOptions) {
119
+ const requestInit = {
120
+ method: 'GET',
121
+ headers: reqOptions?.headers ?? undefined,
122
+ signal: reqOptions?.signal ?? undefined,
123
+ };
124
+ return executeWithRetry(url, requestInit);
125
+ },
126
+ async post(url, body, reqOptions) {
127
+ const requestInit = {
128
+ method: 'POST',
129
+ headers: reqOptions?.headers ?? undefined,
130
+ body: body ? JSON.stringify(body) : undefined,
131
+ signal: reqOptions?.signal ?? undefined,
132
+ };
133
+ return executeWithRetry(url, requestInit);
134
+ },
135
+ async put(url, body, reqOptions) {
136
+ const requestInit = {
137
+ method: 'PUT',
138
+ headers: reqOptions?.headers ?? undefined,
139
+ body: body ? JSON.stringify(body) : undefined,
140
+ signal: reqOptions?.signal ?? undefined,
141
+ };
142
+ return executeWithRetry(url, requestInit);
143
+ },
144
+ async delete(url, reqOptions) {
145
+ const requestInit = {
146
+ method: 'DELETE',
147
+ headers: reqOptions?.headers ?? undefined,
148
+ signal: reqOptions?.signal ?? undefined,
149
+ };
150
+ return executeWithRetry(url, requestInit);
151
+ },
152
+ };
153
+ }
154
+ /**
155
+ * Hook to get a Firebase Auth network client with automatic 401 retry and 403 logout.
156
+ *
157
+ * @param options - Optional callbacks for logout and token refresh failure
158
+ * @returns NetworkClient instance
159
+ */
160
+ export function useFirebaseAuthNetworkClient(options) {
161
+ return useMemo(() => createFirebaseAuthNetworkClient(options), [options]);
162
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview @sudobility/auth_lib - Firebase authentication utilities
3
+ *
4
+ * This library provides:
5
+ * - Configurable Firebase Auth initialization
6
+ * - Network client with automatic 401 token refresh and 403 logout handling
7
+ * - Firebase error message utilities
8
+ */
9
+ export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './config';
10
+ export type { FirebaseConfig, FirebaseInitOptions, FirebaseInitResult, FirebaseAuthNetworkClientOptions, } from './config';
11
+ export { useFirebaseAuthNetworkClient } from './hooks';
12
+ export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, isFirebaseAuthError, } from './utils';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAGvD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview @sudobility/auth_lib - Firebase authentication utilities
3
+ *
4
+ * This library provides:
5
+ * - Configurable Firebase Auth initialization
6
+ * - Network client with automatic 401 token refresh and 403 logout handling
7
+ * - Firebase error message utilities
8
+ */
9
+ // Config
10
+ export { initializeFirebaseAuth, getFirebaseApp, getFirebaseAuth, getFirebaseConfig, isFirebaseConfigured, } from './config';
11
+ // Hooks
12
+ export { useFirebaseAuthNetworkClient } from './hooks';
13
+ // Utils
14
+ export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, isFirebaseAuthError, } from './utils';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview Firebase authentication error utilities
3
+ */
4
+ /**
5
+ * Get user-friendly error message from Firebase error code
6
+ *
7
+ * @param code - Firebase error code (e.g., 'auth/user-not-found')
8
+ * @returns User-friendly error message
9
+ */
10
+ export declare function getFirebaseErrorMessage(code: string): string;
11
+ /**
12
+ * Extract error code from Firebase error
13
+ *
14
+ * @param error - Error object from Firebase
15
+ * @returns Error code string or empty string if not found
16
+ */
17
+ export declare function getFirebaseErrorCode(error: unknown): string;
18
+ /**
19
+ * Get user-friendly message from Firebase error object
20
+ *
21
+ * @param error - Error object from Firebase
22
+ * @returns User-friendly error message
23
+ */
24
+ export declare function formatFirebaseError(error: unknown): string;
25
+ /**
26
+ * Check if an error is a Firebase auth error
27
+ *
28
+ * @param error - Error object to check
29
+ * @returns True if the error is a Firebase auth error
30
+ */
31
+ export declare function isFirebaseAuthError(error: unknown): boolean;
32
+ //# sourceMappingURL=firebase-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-errors.d.ts","sourceRoot":"","sources":["../../src/utils/firebase-errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG1D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG3D"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Firebase authentication error utilities
3
+ */
4
+ /** Map of Firebase auth error codes to user-friendly messages */
5
+ const FIREBASE_ERROR_MESSAGES = {
6
+ 'auth/user-not-found': 'No account found with this email',
7
+ 'auth/wrong-password': 'Incorrect password',
8
+ 'auth/invalid-email': 'Invalid email address',
9
+ 'auth/invalid-credential': 'Invalid email or password',
10
+ 'auth/email-already-in-use': 'An account with this email already exists',
11
+ 'auth/weak-password': 'Password must be at least 6 characters',
12
+ 'auth/too-many-requests': 'Too many attempts. Please try again later.',
13
+ 'auth/network-request-failed': 'Network error. Please check your connection.',
14
+ 'auth/popup-closed-by-user': 'Sign in cancelled',
15
+ 'auth/popup-blocked': 'Popup blocked. Please allow popups for this site.',
16
+ 'auth/account-exists-with-different-credential': 'An account already exists with this email using a different sign-in method.',
17
+ 'auth/operation-not-allowed': 'This sign-in method is not enabled.',
18
+ };
19
+ /**
20
+ * Get user-friendly error message from Firebase error code
21
+ *
22
+ * @param code - Firebase error code (e.g., 'auth/user-not-found')
23
+ * @returns User-friendly error message
24
+ */
25
+ export function getFirebaseErrorMessage(code) {
26
+ return (FIREBASE_ERROR_MESSAGES[code] ?? 'Something went wrong. Please try again.');
27
+ }
28
+ /**
29
+ * Extract error code from Firebase error
30
+ *
31
+ * @param error - Error object from Firebase
32
+ * @returns Error code string or empty string if not found
33
+ */
34
+ export function getFirebaseErrorCode(error) {
35
+ if (error && typeof error === 'object' && 'code' in error) {
36
+ return error.code;
37
+ }
38
+ return '';
39
+ }
40
+ /**
41
+ * Get user-friendly message from Firebase error object
42
+ *
43
+ * @param error - Error object from Firebase
44
+ * @returns User-friendly error message
45
+ */
46
+ export function formatFirebaseError(error) {
47
+ const code = getFirebaseErrorCode(error);
48
+ return getFirebaseErrorMessage(code);
49
+ }
50
+ /**
51
+ * Check if an error is a Firebase auth error
52
+ *
53
+ * @param error - Error object to check
54
+ * @returns True if the error is a Firebase auth error
55
+ */
56
+ export function isFirebaseAuthError(error) {
57
+ const code = getFirebaseErrorCode(error);
58
+ return code.startsWith('auth/');
59
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @fileoverview Utils exports
3
+ */
4
+ export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, isFirebaseAuthError, } from './firebase-errors';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview Utils exports
3
+ */
4
+ export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, isFirebaseAuthError, } from './firebase-errors';
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@sudobility/auth_lib",
3
+ "version": "0.0.1",
4
+ "description": "Firebase authentication utilities with token refresh handling",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "clean": "rm -rf dist",
23
+ "typecheck": "bunx tsc --noEmit",
24
+ "lint": "bunx eslint src",
25
+ "lint:fix": "bunx eslint src --fix",
26
+ "format": "bunx prettier --write \"src/**/*.{ts,tsx,js,jsx,json}\"",
27
+ "test": "bun test",
28
+ "prepublishOnly": "bun run build"
29
+ },
30
+ "peerDependencies": {
31
+ "react": "^18.0.0 || ^19.0.0",
32
+ "firebase": "^12.0.0",
33
+ "@sudobility/di": "^1.5.8",
34
+ "@sudobility/types": "^1.9.40"
35
+ },
36
+ "devDependencies": {
37
+ "@eslint/js": "^9.0.0",
38
+ "@types/bun": "^1.2.8",
39
+ "@types/react": "^19.2.5",
40
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
41
+ "@typescript-eslint/parser": "^8.0.0",
42
+ "eslint": "^9.0.0",
43
+ "eslint-config-prettier": "^10.0.0",
44
+ "eslint-plugin-prettier": "^5.0.0",
45
+ "prettier": "^3.0.0",
46
+ "typescript": "~5.9.3"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "https://github.com/sudobility/auth_lib.git"
54
+ },
55
+ "license": "MIT"
56
+ }