InsForge SDK provides simple, bucket-based file storage with automatic URL generation and authentication handling.
npm install @insforge/sdk
import { createClient } from '@insforge/sdk';

const insforge = createClient({
  baseUrl: 'https://your-app.us-east.insforge.app'
});

Basic File Operations

Upload a File

// Upload to specific path in bucket
const file = fileInput.files[0];
const { data, error } = await insforge.storage
  .from('avatars')
  .upload('user-123/avatar.jpg', file)

// Returns: { bucket, key, size, mimeType, uploadedAt, url }
console.log('File URL:', data.url)

Download a File

// Download file as Blob
const { data: blob, error } = await insforge.storage
  .from('avatars')
  .download('user-123/avatar.jpg')

// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'avatar.jpg';
a.click();

List Files

// List files in a bucket
const { data, error } = await insforge.storage
  .from('avatars')
  .list({
    prefix: 'user-123/',  // Optional: filter by prefix
    limit: 10             // Optional: limit results
  })

console.log(data.objects)
// [{ key, size, lastModified, etag, contentType }, ...]

Delete Files

// Delete a single file
const { error } = await insforge.storage
  .from('avatars')
  .remove(['user-123/avatar.jpg'])

// Delete multiple files
const { error } = await insforge.storage
  .from('avatars')
  .remove([
    'user-123/avatar.jpg',
    'user-123/cover.jpg'
  ])

Working with Buckets

Buckets are containers for files with access policies:
  • Public Buckets - Files accessible without authentication
  • Private Buckets - Files require authentication token
Bucket creation is admin-only. Regular users upload to existing buckets.

Public File Access

// Upload to public bucket
const { data, error } = await insforge.storage
  .from('public-assets')
  .upload('logo.png', file)

// Direct URL access (no auth needed)
const imageUrl = `https://your-app.us-east.insforge.app${data.url}`;

Private File Access

// Upload to private bucket
const { data, error } = await insforge.storage
  .from('documents')
  .upload('report.pdf', file)

// SDK handles auth automatically when downloading
const { data: blob, error } = await insforge.storage
  .from('documents')
  .download('report.pdf')

Image Upload Example

Complete example for avatar upload with preview:
async function handleAvatarUpload(fileInput) {
  const file = fileInput.files[0];
  
  // Show preview
  const reader = new FileReader();
  reader.onload = (e) => {
    document.getElementById('preview').src = e.target.result;
  };
  reader.readAsDataURL(file);
  
  // Upload file
  const { data, error } = await insforge.storage
    .from('avatars')
    .uploadAuto(file)
  
  if (error) {
    console.error('Upload failed:', error);
    return;
  }
  
  // Update user profile with new avatar URL
  const { error: updateError } = await insforge.auth.setProfile({
    avatar_url: data.url
  })
  
  if (!updateError) {
    console.log('Avatar updated successfully!');
  }
}

File Upload Progress

Track upload progress for large files:
// Note: Progress tracking requires custom implementation
const uploadWithProgress = async (file) => {
  const formData = new FormData();
  formData.append('file', file);
  
  const xhr = new XMLHttpRequest();
  
  // Track progress
  xhr.upload.addEventListener('progress', (e) => {
    if (e.lengthComputable) {
      const percentComplete = (e.loaded / e.total) * 100;
      console.log(`Upload: ${percentComplete.toFixed(2)}%`);
    }
  });
  
  // Handle completion
  return new Promise((resolve, reject) => {
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(JSON.parse(xhr.responseText));
      } else {
        reject(new Error('Upload failed'));
      }
    };
    
    xhr.open('POST', 'https://your-app.us-east.insforge.app/api/storage/buckets/uploads/objects');
    xhr.setRequestHeader('Authorization', `Bearer ${token}`);
    xhr.send(formData);
  });
};

React Component Example

import { useState } from 'react';
import { createClient } from '@insforge/sdk';

const insforge = createClient({
  baseUrl: 'https://your-app.us-east.insforge.app'
});

function FileUploader({ bucket, onUpload }) {
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState(null);
  
  const handleFileChange = async (e) => {
    const file = e.target.files[0];
    if (!file) return;
    
    setUploading(true);
    setError(null);
    
    const { data, error } = await insforge.storage
      .from(bucket)
      .uploadAuto(file);
    
    if (error) {
      setError(error.message);
    } else {
      onUpload(data);
    }
    
    setUploading(false);
  };
  
  return (
    <div>
      <input
        type="file"
        onChange={handleFileChange}
        disabled={uploading}
      />
      {uploading && <p>Uploading...</p>}
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}

Storage Patterns

User Avatars

Store in avatars bucket with user ID prefix

Product Images

Public bucket for catalog images

Documents

Private bucket with access control

Temp Files

Auto-cleanup with lifecycle rules

Error Handling

Storage operations return structured errors:
const { data, error } = await insforge.storage
  .from('avatars')
  .upload('test.jpg', file)

if (error) {
  switch (error.statusCode) {
    case 413:
      console.error('File too large');
      break;
    case 415:
      console.error('File type not supported');
      break;
    case 401:
      console.error('Not authenticated');
      break;
    default:
      console.error('Upload failed:', error.message);
  }
}

Best Practices

  1. Use uploadAuto() for automatic unique filenames
  2. Organize with prefixes like user-{id}/ for better structure
  3. Validate file types before uploading
  4. Set size limits appropriate for your use case
  5. Use public buckets for assets, private for sensitive files
  6. Clean up unused files to manage storage costs
The SDK handles authentication, URL construction, and error handling automatically.