0.3.6 • Published 6 months ago

@gw-intech/upload-it v0.3.6

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

UploadIt

A flexible and reusable file upload library with support for S3 and filesystem storage.

Features

  • 📤 Direct client-side uploads to S3
  • 💾 Local filesystem support
  • 🔒 Secure server-side credential handling
  • 📊 Upload progress tracking
  • 🔄 Automatic URL refreshing
  • ⚛️ React components and hooks
  • 📱 Next.js integration
  • 🔌 Provider-based architecture
  • 📂 File management utilities
  • 📑 Intuitive file listing with icons

Latest Updates (v0.3.6)

  • 🎨 Enhanced FileList component with file type icons - Beautiful visual indicators for different file types
  • 🖼️ Option to display file icons instead of image previews - More consistent UI and better performance
  • 🗂️ File management utilities - Easy-to-use functions for listing, fetching, and deleting files
  • 🔄 Improved filesystem integration - Better fallbacks for direct filesystem operations

Installation

npm install @gw-intech/upload-it
# or
yarn add @gw-intech/upload-it
# or
pnpm add @gw-intech/upload-it

Browser Compatibility

The library is designed to work in both browser and Node.js environments:

  • S3 Provider: Fully supported in browsers
  • Filesystem Provider: Only for server-side use (Node.js)

When using the library in client-side applications (like Vite, Create React App, etc.), you should:

  1. Use the S3 provider for direct client-side uploads
  2. Or set up server endpoints for secure uploads
// ✅ Works in browsers
import { UploadButton } from '@gw-intech/upload-it';

function App() {
  return (
    <UploadButton
      provider='s3'
      s3={{
        region: 'us-east-1',
        bucket: 'my-bucket',
        credentials: {
          // For development only! Use server mode in production
          accessKeyId: '...',
          secretAccessKey: '...',
        },
      }}
    />
  );
}

// ❌ Won't work in browsers - filesystem requires Node.js
import { UploadButton } from '@gw-intech/upload-it';

function App() {
  return (
    <UploadButton
      provider='filesystem' // ⚠️ This won't work in browsers
      filesystem={{
        uploadDir: './public/uploads',
        publicPath: '/uploads',
      }}
    />
  );
}

Usage

Basic Usage with React Component

import { UploadButton } from '@gw-intech/upload-it';

function MyApp() {
  return (
    <UploadButton
      provider='s3'
      s3={{
        region: 'us-east-1',
        bucket: 'my-bucket',
        credentials: {
          /* For development only! See secure usage below */
        },
      }}
      onUploadComplete={(files) => console.log('Uploaded files:', files)}
      multiple={true}
      accept='image/*,.pdf'
    />
  );
}

Secure Usage with Next.js

When using Next.js, you'll need to import the server-specific routes from the /server subpath:

  1. Create API routes for uploads:
// app/api/upload/presigned/route.ts
import { presignedUrlRoute } from '@gw-intech/upload-it/server';
export { presignedUrlRoute as POST };

// app/api/upload/complete/route.ts
import { completeUploadRoute } from '@gw-intech/upload-it/server';
export { completeUploadRoute as POST };

// app/api/upload/url/[fileKey]/route.ts
import { getFileUrlRoute } from '@gw-intech/upload-it/server';
export { getFileUrlRoute as GET };
  1. Configure environment variables:
UPLOAD_IT_S3_REGION=us-east-1
UPLOAD_IT_S3_BUCKET=my-bucket
UPLOAD_IT_S3_ACCESS_KEY=your-access-key
UPLOAD_IT_S3_SECRET_KEY=your-secret-key
UPLOAD_IT_S3_FOLDER=uploads
  1. Use the component with server mode:
import { UploadButton } from '@gw-intech/upload-it';

function MyApp() {
  return (
    <UploadButton
      provider='s3'
      server={{
        mode: 'server',
        endpoints: {
          getUploadUrl: '/api/upload/presigned',
          completeUpload: '/api/upload/complete',
          getAccessUrl: '/api/upload/url',
        },
      }}
      onUploadComplete={(files) => console.log('Uploaded files:', files)}
    />
  );
}

Using with Vite or non-Next.js environments

When using Vite or other build systems, you only need to import from the main package:

import {
  UploadButton,
  useUploader,
  createUploader,
} from '@gw-intech/upload-it';

The Next.js specific routes are isolated in the /server subpath to avoid dependency conflicts.

Using the React Hook

import { useUploader } from '@gw-intech/upload-it';
import { useState } from 'react';

function MyUploader() {
  const [files, setFiles] = useState([]);

  const uploader = useUploader({
    provider: 's3',
    s3: {
      region: 'us-east-1',
      bucket: 'my-bucket',
      credentials: {
        /* ... */
      },
    },
    onSuccess: (uploadedFiles) => {
      setFiles(uploadedFiles);
    },
  });

  const handleFileChange = async (e) => {
    const selectedFiles = e.target.files;
    if (selectedFiles.length > 0) {
      await uploader.uploadFiles(Array.from(selectedFiles));
    }
  };

  return (
    <div>
      <input type='file' multiple onChange={handleFileChange} />
      {uploader.isUploading && (
        <div>
          Uploading... {Object.values(uploader.progress)[0]?.percentage}%
        </div>
      )}
      {files.map((file) => (
        <div key={file.key}>
          {file.name} -{' '}
          <a href={file.url} target='_blank' rel='noopener noreferrer'>
            View
          </a>
        </div>
      ))}
    </div>
  );
}

Filesystem Storage

import { UploadButton } from '@gw-intech/upload-it';

function MyApp() {
  return (
    <UploadButton
      provider='filesystem'
      filesystem={{
        uploadDir: './public/uploads',
        publicPath: '/uploads',
      }}
      onUploadComplete={(files) => console.log('Uploaded files:', files)}
    />
  );
}

Core API (Non-React)

import { createUploader } from '@gw-intech/upload-it';

const uploader = createUploader({
  provider: 's3',
  s3: {
    region: 'us-east-1',
    bucket: 'my-bucket',
    credentials: {
      /* ... */
    },
  },
  onUploadProgress: (file, progress) => {
    console.log(`${file.name}: ${progress.percentage}%`);
  },
});

async function uploadFile(file) {
  try {
    const result = await uploader.uploadFile(file);
    console.log('File uploaded:', result);
    return result;
  } catch (error) {
    console.error('Upload failed:', error);
  }
}

Component Props

UploadButton Props

The UploadButton component accepts the following props:

Core Configuration

PropTypeRequiredDescription
provider's3' \| 'filesystem'YesStorage provider to use
s3S3ConfigOnly with s3 providerS3 configuration
filesystemFilesystemConfigOnly with filesystem providerFilesystem configuration
serverServerConfigNoServer configuration for secure mode
maxFileSizenumberNoMaximum file size in bytes
allowedFileTypesstring[]NoAllowed file types (e.g., 'image/*', '.pdf')

UI Customization

PropTypeRequiredDefaultDescription
classNamestringNo''CSS class applied to the button
buttonTextstringNo'Upload'Text displayed on the button
childrenReact.ReactNodeNonullContent to render inside the button
showProgressDialogbooleanNotrueWhether to show the progress dialog
dialogTitlestringNo'Upload File'Title for the progress dialog

Upload Options

PropTypeRequiredDefaultDescription
multiplebooleanNofalseAllow multiple file selection
acceptstringNoundefinedFile type filter (e.g., "image/*,.pdf")
folderstringNoundefinedOptional folder path for uploaded files

Callbacks

PropTypeRequiredDescription
onSuccess(files: FileMetadata[]) => voidNoCalled when uploads complete successfully
onError(error: Error) => voidNoCalled when an error occurs

Advanced Customization

PropTypeRequiredDescription
renderButton(props: { onClick: () => void; isUploading: boolean }) => React.ReactNodeNoCustom button rendering
renderDialog(props: { isOpen: boolean; onClose: () => void; progress: number; isComplete: boolean; hasErrors: boolean; }) => React.ReactNodeNoCustom dialog rendering

Configuration Options

Common Options

OptionTypeDescription
provider's3' \| 'filesystem'Storage provider to use
maxFileSizenumberMaximum file size in bytes
allowedFileTypesstring[]Allowed file types (e.g., ['image/*', '.pdf'])

S3 Provider Options

OptionTypeDescription
regionstringAWS region
bucketstringS3 bucket name
credentials{ accessKeyId: string, secretAccessKey: string }AWS credentials
endpointstringCustom endpoint (for S3-compatible storage)
uploadFolderstringFolder prefix for uploaded files

Filesystem Provider Options

OptionTypeDescription
uploadDirstringDirectory to store uploaded files
publicPathstringPublic URL path to access files
createDirIfNotExistbooleanCreate directory if it doesn't exist

Server Options

OptionTypeDescription
mode'client' \| 'server'Whether to use client or server mode
endpoints{ getUploadUrl?: string, completeUpload?: string, getAccessUrl?: string }API endpoints for server operations

License

MIT

0.3.6

6 months ago

0.3.5

6 months ago

0.3.4

6 months ago

0.3.3

6 months ago

0.3.1

6 months ago

0.3.0

6 months ago

0.2.5

6 months ago

0.2.4

6 months ago

0.2.3

6 months ago

0.2.2

6 months ago

0.2.1

6 months ago

0.2.0

6 months ago

0.1.3

6 months ago

0.1.2

6 months ago

0.1.1

6 months ago