@wattsoft/auth-app 1.0.1 → 1.0.2

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 CHANGED
@@ -1,33 +1,257 @@
1
- # Welcome to your Expo app 👋
1
+ # @wattsoft/auth-app
2
2
 
3
- This is an [Expo](https://expo.dev) project created with [`create-expo-app`](https://www.npmjs.com/package/create-expo-app).
3
+ A complete, production-ready authentication library for React Native and Expo apps.
4
4
 
5
- ## Get started
5
+ **Zero authentication code needed. Just import and use.** 🎉
6
6
 
7
- 1. Install dependencies
7
+ [![npm version](https://img.shields.io/npm/v/@wattsoft/auth-app.svg)](https://www.npmjs.com/package/@wattsoft/auth-app)
8
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
9
 
9
- ```bash
10
- npm install
11
- ```
10
+ ## Features
12
11
 
13
- 2. Start the app
12
+ - **Pre-built Auth Screens** - Sign-in & sign-up screens, ready to use
13
+ - ✅ **Email & Password Authentication** - Standard authentication flow
14
+ - ✅ **Google Sign-In** - OAuth 2.0 integration
15
+ - ✅ **Biometric Authentication** - Fingerprint & Face ID
16
+ - ✅ **Passkey Support** - Passwordless authentication
17
+ - ✅ **TypeScript** - Full type safety
18
+ - ✅ **Secure Storage** - Encrypted token storage
19
+ - ✅ **Clerk Integration** - Powered by Clerk
20
+ - ✅ **Custom Hooks** - For advanced use cases
21
+ - ✅ **Zero Config** - Works out of the box
14
22
 
15
- ```bash
16
- npx expo start
17
- ```
23
+ ## Quick Start
18
24
 
19
- In the output, you'll find options to open the app in a
25
+ ### 1. Install
20
26
 
21
- - [development build](https://docs.expo.dev/develop/development-builds/introduction/)
22
- - [Android emulator](https://docs.expo.dev/workflow/android-studio-emulator/)
23
- - [iOS simulator](https://docs.expo.dev/workflow/ios-simulator/)
24
- - [Expo Go](https://expo.dev/go), a limited sandbox for trying out app development with Expo
27
+ ```bash
28
+ npm install @wattsoft/auth-app
29
+ ```
30
+
31
+ ### 2. Setup
32
+
33
+ ```tsx
34
+ import { AuthProvider } from "@wattsoft/auth-app";
35
+
36
+ export default function App() {
37
+ return (
38
+ <AuthProvider publishableKey="pk_test_....">{/* Your app */}</AuthProvider>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ### 3. Use Screens
44
+
45
+ ```tsx
46
+ import { SignInScreen, SignUpScreen } from '@wattsoft/auth-app';
47
+
48
+ // In your navigation
49
+ <Stack.Screen name="sign-in" component={SignInScreen} />
50
+ <Stack.Screen name="sign-up" component={SignUpScreen} />
51
+ ```
52
+
53
+ **That's it!** Your app now has complete authentication. ✅
54
+
55
+ ## Documentation
56
+
57
+ - **[SETUP_GUIDE.md](./SETUP_GUIDE.md)** - Complete setup instructions
58
+ - **[INTEGRATION_EXAMPLE.md](./INTEGRATION_EXAMPLE.md)** - Step-by-step integration guide
59
+ - **[PUBLISHING_GUIDE.md](./PUBLISHING_GUIDE.md)** - How to publish to npm
60
+
61
+ ## Available Exports
62
+
63
+ ### Screens (Ready to Use)
64
+
65
+ - `SignInScreen` - Complete sign-in UI
66
+ - `SignUpScreen` - Complete sign-up UI
67
+
68
+ ### Components
69
+
70
+ - `BiometricSignIn` - Biometric authentication UI
71
+ - `GoogleSignIn` - Google OAuth UI
72
+ - `Passkey` - Passkey authentication UI
73
+ - `SignOut` - Sign-out button
74
+
75
+ ### Hooks (Custom Implementation)
76
+
77
+ - `useAuth()` - Get auth state
78
+ - `useSignInForm()` - Email/password sign-in
79
+ - `useSignUpForm()` - Email/password sign-up
80
+ - `useBiometric()` - Biometric auth
81
+ - `useSignOutUser()` - Sign-out logic
82
+
83
+ ### Provider
84
+
85
+ - `AuthProvider` - Setup component
86
+ - `initializeAuth()` - Initialize auth
87
+
88
+ ## Example App Structure
89
+
90
+ ```tsx
91
+ import {
92
+ AuthProvider,
93
+ useAuth,
94
+ SignInScreen,
95
+ SignUpScreen,
96
+ } from "@wattsoft/auth-app";
97
+
98
+ function AuthStack() {
99
+ return (
100
+ <Stack.Navigator screenOptions={{ headerShown: false }}>
101
+ <Stack.Screen name="sign-in" component={SignInScreen} />
102
+ <Stack.Screen name="sign-up" component={SignUpScreen} />
103
+ </Stack.Navigator>
104
+ );
105
+ }
106
+
107
+ function AppStack() {
108
+ return (
109
+ <Stack.Navigator>
110
+ <Stack.Screen name="home" component={HomeScreen} />
111
+ </Stack.Navigator>
112
+ );
113
+ }
114
+
115
+ function RootNavigator() {
116
+ const { isLoaded, isSignedIn } = useAuth();
117
+
118
+ if (!isLoaded) return null;
119
+
120
+ return (
121
+ <NavigationContainer>
122
+ {isSignedIn ? <AppStack /> : <AuthStack />}
123
+ </NavigationContainer>
124
+ );
125
+ }
126
+
127
+ export default function App() {
128
+ return (
129
+ <AuthProvider publishableKey={CLERK_PUBLISHABLE_KEY}>
130
+ <RootNavigator />
131
+ </AuthProvider>
132
+ );
133
+ }
134
+ ```
135
+
136
+ ## Requirements
137
+
138
+ - React 18.0+
139
+ - React Native 0.70+
140
+ - Expo 50+
141
+ - Clerk account (free tier available)
142
+
143
+ ## Installation with Dependencies
144
+
145
+ ```bash
146
+ npm install @wattsoft/auth-app expo-router @clerk/clerk-expo \
147
+ expo-local-authentication expo-secure-store @react-navigation/native \
148
+ react-native-gesture-handler react-native-reanimated \
149
+ react-native-safe-area-context react-native-screens
150
+ ```
151
+
152
+ ## Setup Clerk
153
+
154
+ 1. Create free account at [clerk.com](https://clerk.com)
155
+ 2. Create new application
156
+ 3. Get your Publishable Key
157
+ 4. Add to your app
158
+
159
+ ```tsx
160
+ <AuthProvider publishableKey="pk_test_your_key_here">
161
+ ```
162
+
163
+ ## What's NOT Needed
164
+
165
+ ❌ No authentication logic to write
166
+ ❌ No form validation to build
167
+ ❌ No secure storage setup
168
+ ❌ No OAuth configuration code
169
+ ❌ No biometric handling code
170
+ ❌ No error handling to implement
171
+
172
+ ✅ All included and ready to use!
173
+
174
+ ## API Reference
175
+
176
+ ### `<AuthProvider />`
177
+
178
+ Wraps your app to enable authentication.
179
+
180
+ ```tsx
181
+ <AuthProvider publishableKey={string}>{children}</AuthProvider>
182
+ ```
183
+
184
+ ### `useAuth()`
185
+
186
+ Returns current authentication state.
187
+
188
+ ```tsx
189
+ const { isLoaded, isSignedIn, user, session } = useAuth();
190
+ ```
191
+
192
+ ### `useSignInForm()`
193
+
194
+ Returns sign-in methods.
195
+
196
+ ```tsx
197
+ const { signInWithEmail, loading, error } = useSignInForm();
198
+ await signInWithEmail("user@example.com", "password");
199
+ ```
200
+
201
+ ### `useSignOutUser()`
202
+
203
+ Returns sign-out method.
204
+
205
+ ```tsx
206
+ const { signOutUser, loading } = useSignOutUser();
207
+ await signOutUser();
208
+ ```
209
+
210
+ ## Browser Support
211
+
212
+ - ✅ iOS 11+
213
+ - ✅ Android 6+
214
+ - ✅ Web (experimental)
215
+
216
+ ## TypeScript
217
+
218
+ Fully typed with TypeScript. All types exported from `@wattsoft/auth-app`.
219
+
220
+ ```tsx
221
+ import type {
222
+ AuthState,
223
+ SignInResult,
224
+ UseSignInFormResult,
225
+ } from "@wattsoft/auth-app";
226
+ ```
227
+
228
+ ## Troubleshooting
229
+
230
+ See [SETUP_GUIDE.md#Troubleshooting](./SETUP_GUIDE.md#troubleshooting)
231
+
232
+ ## Contributing
233
+
234
+ Found a bug? Have a feature request? Open an issue!
235
+
236
+ ## License
237
+
238
+ MIT
239
+
240
+ ## Support
241
+
242
+ - 📧 Email: support@wattsoft.com
243
+ - 🐛 GitHub Issues: [Report a bug](https://github.com/wattsoft/auth-app/issues)
244
+ - 📖 Docs: [SETUP_GUIDE.md](./SETUP_GUIDE.md)
245
+
246
+ ---
25
247
 
26
- You can start developing by editing the files inside the **app** directory. This project uses [file-based routing](https://docs.expo.dev/router/introduction).
248
+ Made with ❤️ by Wattsoft
27
249
 
28
- ## Get a fresh project
250
+ **Quick Links:**
29
251
 
30
- When you're ready, run:
252
+ - [npm Package](https://www.npmjs.com/package/@wattsoft/auth-app)
253
+ - [GitHub Repository](https://github.com/wattsoft/auth-app)
254
+ - [Clerk Documentation](https://clerk.com/docs)
31
255
 
32
256
  ```bash
33
257
  npm run reset-project
package/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ // Export all components from the auth-app package
2
+
3
+ // ===== AUTHENTICATION PROVIDER & SETUP =====
4
+ export { AuthProvider, initializeAuth } from "./lib/AuthProvider";
5
+
6
+ // ===== CUSTOM HOOKS =====
7
+ export {
8
+ useAuth, useBiometric, useSignInForm, useSignOutUser, useSignUpForm
9
+ } from "./lib/hooks";
10
+
11
+ // ===== TYPE DEFINITIONS =====
12
+ export type {
13
+ AuthProviderProps,
14
+ AuthState, BiometricSignInProps, GoogleSignInProps,
15
+ PasskeyProps, SignInResult, SignOutButtonProps, SignOutResult, SignUpResult, UseBiometricResult, UseSignInFormResult, UseSignOutUserResult, UseSignUpFormResult
16
+ } from "./lib/types";
17
+
18
+ // ===== UI COMPONENTS =====
19
+ export {
20
+ default as BiometricSignIn,
21
+ saveCredentialsForBiometric
22
+ } from "./components/BiometricSignIn";
23
+ export {
24
+ default as GoogleSignIn,
25
+ useWarmUpBrowser
26
+ } from "./components/GoogleSignIn";
27
+ export { SignInWithPasskeyButton as Passkey } from "./components/Passkey";
28
+ export { SignOutButton as SignOut } from "./components/SignOut";
29
+
30
+ // ===== READY-TO-USE SCREENS =====
31
+ export { default as SignInScreen } from "./app/(app)/sign-in";
32
+ export { default as SignUpScreen } from "./app/(app)/sign-up";
33
+
@@ -0,0 +1,70 @@
1
+ import { ClerkProvider } from "@clerk/clerk-expo";
2
+ import * as SecureStore from "expo-secure-store";
3
+ import React, { ReactNode } from "react";
4
+
5
+ interface AuthProviderProps {
6
+ children: ReactNode;
7
+ publishableKey: string;
8
+ }
9
+
10
+ /**
11
+ * AuthProvider - Setup component for the auth library
12
+ * Wrap your app with this provider
13
+ *
14
+ * Usage example:
15
+ * import { AuthProvider } from '@wattsoft/auth-app';
16
+ *
17
+ * export default function App() {
18
+ * return (
19
+ * <AuthProvider publishableKey={CLERK_PUBLISHABLE_KEY}>
20
+ * {children}
21
+ * </AuthProvider>
22
+ * );
23
+ * }
24
+ */
25
+ export function AuthProvider({ children, publishableKey }: AuthProviderProps) {
26
+ const tokenCache = {
27
+ async getToken(key: string) {
28
+ try {
29
+ const item = await SecureStore.getItemAsync(key);
30
+ if (item) {
31
+ console.log(`${key} was used securely`);
32
+ } else {
33
+ console.log("No values stored under key: " + key);
34
+ }
35
+ return item;
36
+ } catch (error) {
37
+ console.error("SecureStore read error: ", error);
38
+ await SecureStore.deleteItemAsync(key);
39
+ return null;
40
+ }
41
+ },
42
+ async saveToken(key: string, value: string) {
43
+ try {
44
+ await SecureStore.setItemAsync(key, value);
45
+ } catch (err) {
46
+ console.error("SecureStore error: ", err);
47
+ }
48
+ },
49
+ };
50
+
51
+ return (
52
+ <ClerkProvider publishableKey={publishableKey} tokenCache={tokenCache}>
53
+ {children}
54
+ </ClerkProvider>
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Initialize auth library - Call this once in your app
60
+ * @param publishableKey - Your Clerk publishable key from https://dashboard.clerk.com
61
+ * @returns AuthProvider component
62
+ */
63
+ export function initializeAuth(publishableKey: string) {
64
+ if (!publishableKey) {
65
+ throw new Error(
66
+ "Clerk publishable key is required. Get it from https://dashboard.clerk.com",
67
+ );
68
+ }
69
+ return publishableKey;
70
+ }
package/lib/hooks.ts ADDED
@@ -0,0 +1,245 @@
1
+ import {
2
+ useClerk,
3
+ useAuth as useClerkAuth,
4
+ useSession,
5
+ useSignIn,
6
+ useSignUp,
7
+ useUser,
8
+ } from "@clerk/clerk-expo";
9
+ import * as LocalAuthentication from "expo-local-authentication";
10
+ import { useRouter } from "expo-router";
11
+ import React from "react";
12
+
13
+ /**
14
+ * useAuth - Get current authentication state
15
+ * @returns Object with user, isLoaded, isSignedIn
16
+ */
17
+ export function useAuth() {
18
+ const { isLoaded, isSignedIn } = useClerkAuth();
19
+ const { user } = useUser();
20
+ const { session } = useSession();
21
+
22
+ return {
23
+ isLoaded,
24
+ isSignedIn,
25
+ user,
26
+ session,
27
+ };
28
+ }
29
+
30
+ /**
31
+ * useSignInForm - Handle email/password sign in
32
+ * @returns Object with methods and state for sign in
33
+ */
34
+ export function useSignInForm() {
35
+ const { signIn, setActive, isLoaded } = useSignIn();
36
+ const router = useRouter();
37
+ const [loading, setLoading] = React.useState(false);
38
+ const [error, setError] = React.useState<string | null>(null);
39
+
40
+ const signInWithEmail = React.useCallback(
41
+ async (email: string, password: string) => {
42
+ if (!isLoaded) return;
43
+ setLoading(true);
44
+ setError(null);
45
+
46
+ try {
47
+ const signInAttempt = await signIn.create({
48
+ identifier: email,
49
+ password,
50
+ });
51
+
52
+ if (signInAttempt.status === "complete") {
53
+ await setActive({
54
+ session: signInAttempt.createdSessionId,
55
+ });
56
+ router.replace("/");
57
+ return { success: true };
58
+ } else {
59
+ setError("Sign in incomplete. Please try again.");
60
+ return { success: false, status: signInAttempt.status };
61
+ }
62
+ } catch (err: any) {
63
+ const errorMessage =
64
+ err?.errors?.[0]?.message || err.message || "Sign in failed";
65
+ setError(errorMessage);
66
+ return { success: false, error: errorMessage };
67
+ } finally {
68
+ setLoading(false);
69
+ }
70
+ },
71
+ [isLoaded, signIn, setActive, router],
72
+ );
73
+
74
+ return {
75
+ signInWithEmail,
76
+ loading,
77
+ error,
78
+ setError,
79
+ };
80
+ }
81
+
82
+ /**
83
+ * useSignUpForm - Handle email/password sign up
84
+ * @returns Object with methods and state for sign up
85
+ */
86
+ export function useSignUpForm() {
87
+ const { signUp, setActive, isLoaded } = useSignUp();
88
+ const router = useRouter();
89
+ const [loading, setLoading] = React.useState(false);
90
+ const [error, setError] = React.useState<string | null>(null);
91
+
92
+ const signUpWithEmail = React.useCallback(
93
+ async (
94
+ email: string,
95
+ password: string,
96
+ firstName?: string,
97
+ lastName?: string,
98
+ ) => {
99
+ if (!isLoaded) return;
100
+ setLoading(true);
101
+ setError(null);
102
+
103
+ try {
104
+ const signUpAttempt = await signUp.create({
105
+ emailAddress: email,
106
+ password,
107
+ firstName,
108
+ lastName,
109
+ });
110
+
111
+ if (signUpAttempt.status === "complete") {
112
+ await setActive?.({
113
+ session: signUpAttempt.createdSessionId,
114
+ });
115
+ router.replace("/");
116
+ return { success: true };
117
+ }
118
+
119
+ router.push({
120
+ pathname: "/sign-up",
121
+ params: { email },
122
+ });
123
+
124
+ return { success: true };
125
+ } catch (err: any) {
126
+ const errorMessage =
127
+ err?.errors?.[0]?.message || err.message || "Sign up failed";
128
+ setError(errorMessage);
129
+ return { success: false, error: errorMessage };
130
+ } finally {
131
+ setLoading(false);
132
+ }
133
+ },
134
+ [isLoaded, signUp, router, setActive],
135
+ );
136
+
137
+ return {
138
+ signUpWithEmail,
139
+ loading,
140
+ error,
141
+ setError,
142
+ };
143
+ }
144
+
145
+ /**
146
+ * useBiometric - Handle biometric authentication
147
+ * @returns Object with methods for biometric sign in
148
+ */
149
+ export function useBiometric() {
150
+ const { signIn, setActive, isLoaded } = useSignIn();
151
+ const router = useRouter();
152
+ const [loading, setLoading] = React.useState(false);
153
+ const [error, setError] = React.useState<string | null>(null);
154
+ const [isBiometricAvailable, setIsBiometricAvailable] = React.useState(false);
155
+
156
+ React.useEffect(() => {
157
+ checkBiometricAvailability();
158
+ }, []);
159
+
160
+ const checkBiometricAvailability = async () => {
161
+ try {
162
+ const compatible = await LocalAuthentication.hasHardwareAsync();
163
+ const enrolled = await LocalAuthentication.isEnrolledAsync();
164
+ setIsBiometricAvailable(compatible && enrolled);
165
+ } catch (err) {
166
+ setIsBiometricAvailable(false);
167
+ }
168
+ };
169
+
170
+ const signInWithBiometric = React.useCallback(
171
+ async (email: string, password: string) => {
172
+ if (!isLoaded) return;
173
+ setLoading(true);
174
+ setError(null);
175
+
176
+ try {
177
+ const authenticated = await LocalAuthentication.authenticateAsync({
178
+ disableDeviceFallback: false,
179
+ fallbackLabel: "Use passcode",
180
+ });
181
+
182
+ if (authenticated.success) {
183
+ const signInAttempt = await signIn.create({
184
+ identifier: email,
185
+ password,
186
+ });
187
+
188
+ if (signInAttempt.status === "complete") {
189
+ await setActive({
190
+ session: signInAttempt.createdSessionId,
191
+ });
192
+ router.replace("/");
193
+ return { success: true };
194
+ }
195
+ } else {
196
+ setError("Biometric authentication cancelled");
197
+ return { success: false, error: "Cancelled" };
198
+ }
199
+ } catch (err: any) {
200
+ const errorMessage = err?.message || "Biometric sign in failed";
201
+ setError(errorMessage);
202
+ return { success: false, error: errorMessage };
203
+ } finally {
204
+ setLoading(false);
205
+ }
206
+ },
207
+ [isLoaded, signIn, setActive, router],
208
+ );
209
+
210
+ return {
211
+ signInWithBiometric,
212
+ isBiometricAvailable,
213
+ loading,
214
+ error,
215
+ setError,
216
+ };
217
+ }
218
+
219
+ /**
220
+ * useSignOutUser - Handle user sign out
221
+ * @returns Object with sign out method
222
+ */
223
+ export function useSignOutUser() {
224
+ const { signOut } = useClerk();
225
+ const router = useRouter();
226
+ const [loading, setLoading] = React.useState(false);
227
+
228
+ const signOutUser = React.useCallback(async () => {
229
+ setLoading(true);
230
+ try {
231
+ await signOut();
232
+ router.replace("/sign-in");
233
+ return { success: true };
234
+ } catch (err: any) {
235
+ return { success: false, error: err.message };
236
+ } finally {
237
+ setLoading(false);
238
+ }
239
+ }, [signOut, router]);
240
+
241
+ return {
242
+ signOutUser,
243
+ loading,
244
+ };
245
+ }
package/lib/types.ts ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Type definitions for @wattsoft/auth-app
3
+ */
4
+
5
+ import { ReactNode } from "react";
6
+
7
+ /**
8
+ * Props for AuthProvider component
9
+ */
10
+ export interface AuthProviderProps {
11
+ children: ReactNode;
12
+ publishableKey: string;
13
+ }
14
+
15
+ /**
16
+ * Return type for sign-in operations
17
+ */
18
+ export interface SignInResult {
19
+ success: boolean;
20
+ status?: string;
21
+ error?: string;
22
+ createdSessionId?: string;
23
+ }
24
+
25
+ /**
26
+ * Return type for sign-up operations
27
+ */
28
+ export interface SignUpResult {
29
+ success: boolean;
30
+ error?: string;
31
+ emailAddress?: string;
32
+ }
33
+
34
+ /**
35
+ * Return type for sign-out operations
36
+ */
37
+ export interface SignOutResult {
38
+ success: boolean;
39
+ error?: string;
40
+ }
41
+
42
+ /**
43
+ * Authentication state from useAuth hook
44
+ */
45
+ export interface AuthState {
46
+ isLoaded: boolean;
47
+ isSignedIn: boolean | undefined;
48
+ user: any;
49
+ session: any;
50
+ }
51
+
52
+ /**
53
+ * Sign-in form hook return type
54
+ */
55
+ export interface UseSignInFormResult {
56
+ signInWithEmail: (email: string, password: string) => Promise<SignInResult>;
57
+ loading: boolean;
58
+ error: string | null;
59
+ setError: (error: string | null) => void;
60
+ }
61
+
62
+ /**
63
+ * Sign-up form hook return type
64
+ */
65
+ export interface UseSignUpFormResult {
66
+ signUpWithEmail: (
67
+ email: string,
68
+ password: string,
69
+ firstName?: string,
70
+ lastName?: string,
71
+ ) => Promise<SignUpResult>;
72
+ loading: boolean;
73
+ error: string | null;
74
+ setError: (error: string | null) => void;
75
+ }
76
+
77
+ /**
78
+ * Biometric authentication hook return type
79
+ */
80
+ export interface UseBiometricResult {
81
+ signInWithBiometric: (
82
+ email: string,
83
+ password: string,
84
+ ) => Promise<SignInResult>;
85
+ isBiometricAvailable: boolean;
86
+ loading: boolean;
87
+ error: string | null;
88
+ setError: (error: string | null) => void;
89
+ }
90
+
91
+ /**
92
+ * Sign-out hook return type
93
+ */
94
+ export interface UseSignOutUserResult {
95
+ signOutUser: () => Promise<SignOutResult>;
96
+ loading: boolean;
97
+ }
98
+
99
+ /**
100
+ * Google Sign-In props
101
+ */
102
+ export interface GoogleSignInProps {
103
+ onSuccess?: (result: any) => void;
104
+ onError?: (error: any) => void;
105
+ }
106
+
107
+ /**
108
+ * Passkey authentication props
109
+ */
110
+ export interface PasskeyProps {
111
+ onSuccess?: (result: any) => void;
112
+ onError?: (error: any) => void;
113
+ }
114
+
115
+ /**
116
+ * Sign-out button props
117
+ */
118
+ export interface SignOutButtonProps {
119
+ onSuccess?: () => void;
120
+ onError?: (error: Error) => void;
121
+ }
122
+
123
+ /**
124
+ * Biometric sign-in component props
125
+ */
126
+ export interface BiometricSignInProps {
127
+ onSuccess?: (result: any) => void;
128
+ onError?: (error: Error) => void;
129
+ email?: string;
130
+ password?: string;
131
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wattsoft/auth-app",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Reusable authentication components for Expo/React Native apps with Clerk, biometric, Google sign-in, and passkey support",
5
5
  "license": "MIT",
6
6
  "author": "Wattsoft",
@@ -47,8 +47,10 @@
47
47
  "files": [
48
48
  "dist",
49
49
  "components",
50
+ "lib",
50
51
  "app",
51
- "assets"
52
+ "assets",
53
+ "index.ts"
52
54
  ],
53
55
  "keywords": [
54
56
  "react",