npm package: @skbhati199/upload
Description: Image upload library for React, React Native and JavaScript applications
Author: Sonu Kumar
Latest version: 1.0.2

# @skbhati199/upload

A universal image upload library that works with React, React Native, and vanilla JavaScript applications. It provides an easy way to upload images to AWS S3, with support for both client-direct and server-side upload methods.

## Installation

```bash
npm install @skbhati199/upload
```

or

```bash
yarn add @skbhati199/upload
```

## Features

- 🔄 Works in React, React Native, and vanilla JavaScript
- 🔐 Authentication with JWT tokens
- 📤 Direct-to-S3 uploads in development environment
- 🔄 Server-side uploads in production environment
- 📊 Upload progress tracking
- 🎣 React hook for easy integration with React applications
- 📱 TypeScript support

## Basic Usage

### React Application

```tsx
import React, { useState } from 'react';
import { useUpload } from '@skbhati199/upload';

function ImageUploader() {
  const [file, setFile] = useState<File | null>(null);
  
  const { 
    uploadFile, 
    isUploading, 
    progress, 
    response, 
    error 
  } = useUpload({
    config: {
      baseUrl: 'https://your-api-url.com',
      environment: 'production'
    },
    userId: 'user-123',
    autoAuth: true
  });

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files[0]) {
      setFile(e.target.files[0]);
    }
  };

  const handleUpload = async () => {
    if (!file) return;
    try {
      const result = await uploadFile(file);
      console.log('Upload successful:', result);
    } catch (err) {
      console.error('Upload failed:', err);
    }
  };

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      <button onClick={handleUpload} disabled={!file || isUploading}>
        {isUploading ? `Uploading... ${progress}%` : 'Upload'}
      </button>
      
      {response && (
        <div>
          <p>Upload successful!</p>
          <img src={response.url} alt="Uploaded" width="200" />
        </div>
      )}
      
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}
```

### React Native Application

```tsx
import React, { useState } from 'react';
import { View, Button, Image, Text } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import { useUpload, FileInfo } from '@skbhati199/upload';

function ImageUploader() {
  const [image, setImage] = useState<FileInfo | null>(null);
  
  const { 
    uploadFile, 
    isUploading, 
    progress, 
    response, 
    error 
  } = useUpload({
    config: {
      baseUrl: 'https://your-api-url.com',
      environment: 'production'
    },
    userId: 'user-123',
    autoAuth: true
  });

  const pickImage = async () => {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled && result.assets && result.assets.length > 0) {
      const selectedAsset = result.assets[0];
      setImage({
        uri: selectedAsset.uri,
        name: selectedAsset.uri.split('/').pop() || 'photo.jpg',
        type: 'image/jpeg', // Adjust based on your needs
      });
    }
  };

  const handleUpload = async () => {
    if (!image) return;
    try {
      const result = await uploadFile(image);
      console.log('Upload successful:', result);
    } catch (err) {
      console.error('Upload failed:', err);
    }
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="Pick an image" onPress={pickImage} />
      
      {image && (
        <Image source={{ uri: image.uri }} style={{ width: 200, height: 200, marginVertical: 20 }} />
      )}
      
      <Button 
        title={isUploading ? `Uploading... ${progress}%` : 'Upload Image'} 
        onPress={handleUpload} 
        disabled={!image || isUploading} 
      />
      
      {response && (
        <View>
          <Text>Upload successful!</Text>
          <Image source={{ uri: response.url }} style={{ width: 200, height: 200, marginVertical: 20 }} />
        </View>
      )}
      
      {error && <Text>Error: {error.message}</Text>}
    </View>
  );
}
```

### Vanilla JavaScript

```javascript
import { createUploadClient } from '@skbhati199/upload';

// Create upload client
const uploadClient = createUploadClient({
  baseUrl: 'https://your-api-url.com',
  environment: 'production',
  onProgress: (progress) => {
    console.log(`Upload progress: ${progress}%`);
    // Update UI with progress
    document.getElementById('progress').textContent = `${progress}%`;
  }
});

// Authentication
async function authenticate() {
  try {
    const token = await uploadClient.getAuthToken({ userId: 'user-123' });
    console.log('Authentication successful:', token);
    return token;
  } catch (error) {
    console.error('Authentication failed:', error);
  }
}

// File upload handler
async function handleFileUpload(file) {
  try {
    // Make sure we're authenticated
    const token = await authenticate();
    
    // Upload the file
    const result = await uploadClient.uploadFile(file, token);
    console.log('Upload successful:', result);
    
    // Display the uploaded image
    const imgElement = document.createElement('img');
    imgElement.src = result.url;
    imgElement.width = 200;
    document.body.appendChild(imgElement);
    
    return result;
  } catch (error) {
    console.error('Upload failed:', error);
  }
}

// Set up file input listener
document.getElementById('fileInput').addEventListener('change', (event) => {
  const file = event.target.files[0];
  if (file) {
    handleFileUpload(file);
  }
});
```

## API Reference

### ImageUploadClient

The core client for interacting with the upload service.

```typescript
const client = new ImageUploadClient({
  baseUrl: 'https://your-api-url.com',
  environment: 'production',
  maxRetries: 3,
  timeout: 30000,
  onProgress: (progress) => console.log(`Progress: ${progress}%`)
});
```

#### Methods

- `getAuthToken(request: { userId: string }): Promise<string>`
- `setAuthToken(token: string): void`
- `getUploadToken(request: { filename: string, contentType: string }): Promise<UploadTokenResponse>`
- `uploadFile(file: File | Blob | FileInfo, authToken?: string): Promise<UploadResponse>`
- `getImageUrl(fileKey: string): Promise<string>`

### useUpload React Hook

A hook for using the upload client in React components.

```typescript
const { 
  uploadFile, 
  getAuthToken, 
  setAuthToken, 
  getImageUrl,
  isUploading, 
  progress, 
  error, 
  response 
} = useUpload({
  config: {
    baseUrl: 'https://your-api-url.com',
    environment: 'production'
  },
  userId: 'user-123',
  autoAuth: true
});
```

## License

MIT