npm package: @mihitthakkar/react-auth-test
Description: Lightweight React wrapper for OTPless Headless SDK.
Author: Mihit Thakkar
Latest version: 0.0.6

# @mihitthakkar/react-auth-test

[![npm version](https://badge.fury.io/js/@mihitthakkar%2Freact-auth-test.svg)](https://badge.fury.io/js/@mihitthakkar%2Freact-auth-test)
[![Bundle Size](https://img.shields.io/bundlephobia/minzip/@mihitthakkar/react-auth-test)](https://bundlephobia.com/package/@mihitthakkar/react-auth-test)

**⚠️ This is a test package for verification purposes only. Use the official package when available.**

Lightweight React wrapper for the OTPless Headless SDK. No providers, no context - just simple, type-safe OTP authentication.

## Features

- 🚀 **Tiny Bundle** - Only 3.6KB minified
- 🎯 **Zero Dependencies** - Only peer dependency on React
- 📱 **Phone Authentication** - SMS OTP with country code support
- 🔄 **Loading States** - Built-in loading management
- 🎪 **Event System** - Listen to authentication events
- 🛡️ **Type Safe** - Full TypeScript support
- 🌐 **SSR Ready** - Works with Next.js and other SSR frameworks

## Installation

```bash
npm install @mihitthakkar/react-auth-test
# or
yarn add @mihitthakkar/react-auth-test
# or
pnpm add @mihitthakkar/react-auth-test
```

## Quick Start

```tsx
import { useOTPless } from '@mihitthakkar/react-auth-test';
import { useEffect } from 'react';

function MyComponent() {
  const { init, initiate, verify, on, loading, ready } = useOTPless();

  useEffect(() => {
    // Initialize with your OTPless App ID
    init('YOUR_APP_ID');

    // Listen to single event
    const unsubscribe = on('VERIFY', (event) => {
      console.log('Verification result:', event);
    });

    // Listen to multiple events at once
    const unsubscribeAll = on({
      ONETAP: (event) => {
        console.log('Auth success:', event);
      },
      OTP_AUTO_READ: (event) => {
        const autoOtp = event?.response?.otp ?? '';
        console.log('OTP auto-read:', autoOtp);
      },
      FAILED: (event) => {
        console.error('Failed:', event.response?.errorMessage);
      }
    });

    return () => {
      unsubscribe();
      unsubscribeAll();
    };
  }, [init, on]);

  const initiateAuth = async () => {
    if (!ready) {
      console.log('SDK not ready yet');
      return;
    }

    try {
      const result = await initiate({
        channel: 'PHONE',
        phone: '9876543210',
        countryCode: '+91'
      });
      
      if (result.success) {
        console.log('OTP sent successfully:', result);
      } else {
        console.error('Failed to send OTP:', result.response?.errorMessage);
      }
    } catch (error) {
      console.error('Failed to send OTP:', error);
    }
  };

  const verifyAuth = async () => {
    if (!ready) {
      console.log('SDK not ready yet');
      return;
    }

    try {
      const result = await verify({
        channel: 'PHONE',
        phone: '9876543210',
        otp: '123456',
        countryCode: '+91'
      });
      
      if (result.success) {
        console.log('OTP verified successfully:', result);
        // User is authenticated - proceed with your app logic
      } else {
        console.error('OTP verification failed:', result.response?.errorMessage);
      }
    } catch (error) {
      console.error('Verification failed:', error);
    }
  };

  if (!ready) {
    return <div>Loading OTPless SDK...</div>;
  }

  return (
    <div>
      <button onClick={initiateAuth} disabled={loading}>
        {loading ? 'Sending...' : 'Send OTP'}
      </button>
      <button onClick={verifyAuth} disabled={loading}>
        {loading ? 'Verifying...' : 'Verify OTP'}
      </button>
    </div>
  );
}
```

## API Reference

### `useOTPless()`

Returns an object with the following properties:

- `ready: boolean` - Whether the OTPless SDK is loaded and ready
- `loading: boolean` - Whether any operation (init/initiate/verify) is in progress
- `init(appId: string): Promise<void>` - Initialize the SDK with your App ID
- `initiate(request: InitiateRequest): Promise<any>` - Send OTP to phone number
- `verify(request: VerifyRequest): Promise<any>` - Verify OTP
- `on(event: EventType | EventCallbacks, callback?: Function): () => void` - Listen to events
- `off(event: EventType, callback: Function): void` - Remove event listener

### Types

```typescript
type InitiateRequest = {
  channel: 'PHONE';
  phone: string;       // digits only (e.g., '9876543210')
  countryCode: string; // with + prefix (e.g., '+91')
};

type VerifyRequest = {
  channel: 'PHONE';
  phone: string;       // digits only
  otp: string;         // digits only
  countryCode: string; // with + prefix
};

type EventType = 
  | 'ONETAP'
  | 'OTP_AUTO_READ'
  | 'SESSION_END'
  | 'FAILED'
  | 'FALLBACK_TRIGGERED';

type EventCallbacks = {
  [K in EventType]?: (event: any) => void;
};
```

## Direct Usage (without React hook)

```typescript
import { otpless } from '@mihitthakkar/react-auth-test';

// Initialize
await otpless.init('YOUR_APP_ID');

// Send OTP
await otpless.initiate({
  channel: 'PHONE',
  phone: '9876543210',
  countryCode: '+91'
});

// Verify OTP
await otpless.verify({
  channel: 'PHONE',
  phone: '9876543210',
  countryCode: '+91',
  otp: '123456'
});

// Listen to single event
const unsubscribe = otpless.on('VERIFY', (event) => {
  console.log('Verification result:', event);
});

// Listen to multiple events at once
const unsubscribeAll = otpless.on({
  ONETAP: (event) => console.log('Auth Success:', event),
  OTP_AUTO_READ: (event) => console.log('Auto OTP:', event.response?.otp),
  FAILED: (event) => console.error('Failed:', event.response?.errorMessage)
});
```

## Utility Functions

```typescript
import { normalizeCountryCode, digitsOnly, redactTokens } from '@mihitthakkar/react-auth-test';

// Normalize country code
normalizeCountryCode('91'); // '+91'
normalizeCountryCode('+1-234'); // '+1234'

// Extract digits only
digitsOnly('98-765-43210'); // '9876543210'

// Redact sensitive data for logging
const safeData = redactTokens({
  phone: '9876543210',
  otp: '123456',
  token: 'secret'
});
// { phone: '9876543210', otp: '***redacted***', token: '***redacted***' }
```

## Next.js Usage

```tsx
'use client'; // Required for client components

import { useOTPless } from '@mihitthakkar/react-auth-test';

export default function AuthPage() {
  const { ready, loading, init, initiate, verify } = useOTPless();
  
  // ... rest of your component
{{ ... }}
```

## License

MIT

## Support

For issues and questions, please visit the [GitHub repository](https://github.com/otpless-tech/react-otpless) or contact [developer@otpless.com](mailto:developer@otpless.com).