npm package: @sravani_123/apple-signin-supabase
Description: A TypeScript package for native Sign in with Apple using Supabase for React Native/Expo apps
Latest version: 1.0.1

# Sign in with Apple for Supabase (React Native)

A lightweight TypeScript package that provides native Sign in with Apple for React Native and Expo apps using Supabase authentication.

## Features

- Native iOS Apple Sign-In dialog (not web-based OAuth)
- TypeScript-first with full type safety
- Simple, intuitive API
- Automatic nonce generation for security
- Comprehensive error handling
- Returns Supabase user and session

## Installation

```bash
npm install @supabase-community/apple-signin
```

or

```bash
yarn add @supabase-community/apple-signin
```

or

```bash
pnpm add @supabase-community/apple-signin
```

### Peer Dependencies

This package requires the following peer dependencies:

```bash
npx expo install expo-apple-authentication expo-crypto
npm install @supabase/supabase-js
```

## Prerequisites

### 1. Configure Apple Developer

1. Go to the [Apple Developer Portal](https://developer.apple.com)
2. Add "Sign in with Apple" capability to your App ID
3. Note your Bundle ID (e.g., `com.yourapp.app`)

### 2. Configure Supabase

1. Go to your [Supabase Dashboard](https://app.supabase.com)
2. Navigate to Authentication > Providers
3. Enable the Apple provider
4. Enter your Apple Service ID, Team ID, Key ID, and Private Key
5. Save the configuration

### 3. Configure Expo/React Native

Add the Apple Sign-In capability to your `app.json`:

```json
{
  "expo": {
    "ios": {
      "usesAppleSignIn": true
    }
  }
}
```

## Usage

### Basic Usage

```typescript
import { createClient } from '@supabase/supabase-js';
import { signInWithApple } from '@supabase-community/apple-signin';

const supabase = createClient(
  'YOUR_SUPABASE_URL',
  'YOUR_SUPABASE_ANON_KEY'
);

async function handleAppleSignIn() {
  const result = await signInWithApple(supabase);

  if (result.success) {
    console.log('Signed in as:', result.user.email);
    console.log('Session:', result.session);
  } else {
    if (result.cancelled) {
      // User cancelled - don't show error
      return;
    }
    console.error('Sign-in failed:', result.error);
  }
}
```

### React Native Component Example

```typescript
import React, { useState, useEffect } from 'react';
import { View, Text, Alert } from 'react-native';
import * as AppleAuthentication from 'expo-apple-authentication';
import { createClient } from '@supabase/supabase-js';
import { signInWithApple, isAppleSignInAvailable } from '@supabase-community/apple-signin';

const supabase = createClient(
  'YOUR_SUPABASE_URL',
  'YOUR_SUPABASE_ANON_KEY'
);

function AppleSignInButton() {
  const [available, setAvailable] = useState(false);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    isAppleSignInAvailable().then(setAvailable);
  }, []);

  const handleSignIn = async () => {
    setLoading(true);

    const result = await signInWithApple(supabase);

    if (result.success) {
      Alert.alert('Success', `Welcome ${result.user.email}`);
    } else if (!result.cancelled) {
      Alert.alert('Error', result.error);
    }

    setLoading(false);
  };

  if (!available) {
    return null; // Don't show button if not available
  }

  return (
    <AppleAuthentication.AppleAuthenticationButton
      buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
      buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.BLACK}
      cornerRadius={8}
      style={{ width: 280, height: 50 }}
      onPress={handleSignIn}
    />
  );
}
```

## API Reference

### `signInWithApple(supabase, options?)`

Initiates the native Sign in with Apple flow.

#### Parameters

- `supabase` (SupabaseClient): An initialized Supabase client
- `options` (AppleSignInOptions, optional): Configuration options

#### Options

```typescript
interface AppleSignInOptions {
  /**
   * OAuth scopes to request from Apple.
   * @default [AppleAuthenticationScope.FULL_NAME, AppleAuthenticationScope.EMAIL]
   */
  scopes?: AppleAuthenticationScope[];
}
```

#### Return Value

Returns a `Promise<AppleSignInResult>` which is a discriminated union:

```typescript
// Success
interface AppleSignInSuccess {
  success: true;
  provider: 'apple';
  user: User;           // Supabase user
  session: Session;     // Supabase session
  appleCredential: {
    user: string;       // Apple user ID
    email: string | null;
    fullName: AppleAuthenticationFullName | null;
  };
}

// Error
interface AppleSignInError {
  success: false;
  error: string;
  cancelled?: boolean;  // true if user cancelled
  originalError?: unknown;
}
```

### `isAppleSignInAvailable()`

Checks if Apple Sign-In is available on the current device.

```typescript
const available = await isAppleSignInAvailable();
// Returns true on iOS 13+ devices, false otherwise
```

## Error Handling

```typescript
const result = await signInWithApple(supabase);

if (!result.success) {
  if (result.cancelled) {
    // User cancelled - typically don't show an error
    return;
  }

  // Show error to user
  Alert.alert('Sign-in Failed', result.error);
}
```

## TypeScript Support

All types are exported:

```typescript
import type {
  AppleSignInOptions,
  AppleSignInResult,
  AppleSignInSuccess,
  AppleSignInError,
  AppleCredential,
} from '@supabase-community/apple-signin';
```

## Platform Support

| Platform | Supported |
|----------|-----------|
| iOS      | ✅ (iOS 13+) |
| Android  | ❌ |
| Web      | ❌ |

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.