@akson/cortex-supabase
Version:
Comprehensive Supabase package with Auth, Storage, Database, and Realtime functionality
430 lines (335 loc) • 10.2 kB
Markdown
# @akson/cortex-supabase
Comprehensive Supabase package with Auth, Storage, Database, and Realtime functionality for React applications.
## Features
- 🔐 **Authentication** - Complete auth system with SSR support, guards, and session management
- 💾 **Storage** - File upload/download with progress tracking and validation
- 🗄️ **Database** - Type-safe database operations with React hooks
- ⚡ **Realtime** - Real-time subscriptions and live updates
- 🎯 **TypeScript First** - Fully typed with comprehensive type definitions
- ⚛️ **React Components** - Pre-built UI components for common patterns
- 🛡️ **Route Guards** - Protect routes with authentication and role-based access
- 🌐 **SSR Ready** - Server-side rendering support for Next.js
- 🔧 **Multiple Clients** - Browser, server, and middleware clients
## Installation
```bash
npm install @akson/cortex-supabase
```
## Dependencies
This package requires `@supabase/supabase-js` and `react` as peer dependencies:
```bash
npm install @supabase/supabase-js react
```
## Quick Start
### Authentication
```tsx
import { AuthProvider, useAuth, LoginPage } from '@akson/cortex-supabase';
import { createBrowserClient } from '@akson/cortex-supabase/clients';
// Setup client
const supabase = createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
// Wrap your app
function App() {
return (
<AuthProvider client={supabase}>
<MyApp />
</AuthProvider>
);
}
// Use authentication in components
function MyComponent() {
const { user, signOut, loading } = useAuth();
if (loading) return <div>Loading...</div>;
if (!user) {
return <LoginPage />;
}
return (
<div>
<p>Welcome, {user.email}!</p>
<button onClick={signOut}>Sign Out</button>
</div>
);
}
```
### File Storage
```tsx
import { useDocumentUpload, useDocumentManager } from '@akson/cortex-supabase';
function FileUploadComponent() {
const { upload, isUploading, progress, error } = useDocumentUpload({
bucketName: 'documents',
maxFileSize: 10 * 1024 * 1024, // 10MB
allowedTypes: ['image/jpeg', 'image/png', 'application/pdf'],
});
const handleFileUpload = async (file: File) => {
const result = await upload(file, {
path: 'uploads/',
metadata: { category: 'documents' },
});
if (result.success) {
console.log('File uploaded:', result.url);
}
};
return (
<div>
<input
type="file"
onChange={(e) => e.target.files?.[0] && handleFileUpload(e.target.files[0])}
disabled={isUploading}
/>
{isUploading && <p>Uploading... {progress?.percentage}%</p>}
{error && <p>Error: {error.message}</p>}
</div>
);
}
```
### Route Guards
```tsx
import { AuthGuard, RoleGuard } from '@akson/cortex-supabase';
// Protect entire routes
function ProtectedPage() {
return (
<AuthGuard fallback={<LoginPage />}>
<RoleGuard roles={['admin']} fallback={<Unauthorized />}>
<AdminDashboard />
</RoleGuard>
</AuthGuard>
);
}
```
## Package Exports
The package provides modular exports for different functionality:
```tsx
// Main package - includes everything
import { useAuth, AuthProvider, LoginPage } from '@akson/cortex-supabase';
// Specific modules
import { createBrowserClient } from '@akson/cortex-supabase/clients';
import { useDocumentUpload } from '@akson/cortex-supabase/hooks';
import { isAdmin, hasRole } from '@akson/cortex-supabase/auth';
import { SupabaseStorageService } from '@akson/cortex-supabase/storage';
```
### Available Exports
- `/clients` - Browser, server, and middleware clients
- `/auth` - Authentication utilities and helpers
- `/hooks` - React hooks for storage, auth, and data fetching
- `/storage` - Storage service and utilities
- `/components` - Pre-built UI components
- `/guards` - Route protection components
- `/pages` - Complete auth pages (login, signup, etc.)
- `/utils` - Utility functions and helpers
- `/types` - TypeScript type definitions
## Server-Side Rendering (Next.js)
### Middleware Setup
```tsx
// middleware.ts
import { createMiddleware } from '@akson/cortex-supabase/middleware';
export default createMiddleware({
redirects: {
protected: ['/dashboard', '/admin'],
public: ['/login', '/signup'],
},
});
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
```
### Server Components
```tsx
// app/dashboard/page.tsx
import { createServerClient } from '@akson/cortex-supabase/clients';
import { getCurrentUser, requireAuth } from '@akson/cortex-supabase/auth';
export default async function DashboardPage() {
// Require authentication
const user = await requireAuth();
// Or check without redirect
const currentUser = await getCurrentUser();
if (!currentUser) {
return <LoginRequired />;
}
return (
<div>
<h1>Welcome, {user.email}!</h1>
<UserProfile user={user} />
</div>
);
}
```
### Pre-built Components
```tsx
import {
LoginPage,
SignupPage,
ResetPasswordPage,
UserProfile,
AuthGuard,
RoleGuard,
} from '@akson/cortex-supabase';
// Complete auth pages with styling
function AuthRoutes() {
return (
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/signup" element={<SignupPage />} />
<Route path="/reset" element={<ResetPasswordPage />} />
</Routes>
);
}
// Protected routes with role-based access
function AdminPanel() {
return (
<RoleGuard roles={['admin', 'moderator']}>
<AdminDashboard />
</RoleGuard>
);
}
```
## Advanced Usage
### Custom Clients Configuration
```tsx
import { createBrowserClient, createServerClient } from '@akson/cortex-supabase/clients';
// Browser client with custom config
const browserClient = createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
}
);
// Server client for API routes
const serverClient = createServerClient();
```
### Storage Service Integration
```tsx
import { createStorageService, SupabaseStorageService } from '@akson/cortex-supabase/storage';
const storageService = createStorageService({
bucketName: 'documents',
maxFileSize: 100 * 1024 * 1024, // 100MB
allowedTypes: ['*'],
pathPrefix: 'uploads',
generateUniqueNames: true,
});
// Direct service usage
const result = await storageService.uploadFile(file, 'custom/path/');
const url = await storageService.getSignedUrl('path/file.pdf', 3600);
```
### Custom Authentication Logic
```tsx
import { isAdmin, hasRole, getCurrentUser } from '@akson/cortex-supabase/auth';
// Check user permissions
async function checkPermissions() {
const user = await getCurrentUser();
if (isAdmin(user)) {
return 'full_access';
}
if (hasRole(user, ['editor', 'moderator'])) {
return 'limited_access';
}
return 'read_only';
}
```
## Configuration
### Environment Variables
```bash
# Required
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
# Optional
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
SUPABASE_JWT_SECRET=your-jwt-secret
```
### Auth Configuration
```tsx
interface AuthConfig {
redirectTo?: string; // Post-auth redirect URL
autoRefresh?: boolean; // Auto-refresh tokens
persistSession?: boolean; // Persist sessions
detectSessionInUrl?: boolean; // Detect session from URL
roles?: string[]; // Available user roles
}
```
### Storage Configuration
```tsx
interface StorageConfig {
bucketName: string; // Supabase bucket name
maxFileSize?: number; // Max file size in bytes
allowedTypes?: string[]; // Allowed MIME types
pathPrefix?: string; // Path prefix for uploads
generateUniqueNames?: boolean; // Generate unique filenames
}
```
## TypeScript Support
The package is fully typed with comprehensive TypeScript definitions:
```tsx
import type {
User,
AuthSession,
AuthConfig,
StorageConfig,
UploadResult,
UploadProgress,
AuthResponse,
} from '@akson/cortex-supabase';
// Extend types for your application
interface AppUser extends User {
role: 'admin' | 'editor' | 'viewer';
department?: string;
}
```
## Error Handling
The package provides consistent error handling across all operations:
```tsx
import { AuthError, StorageError } from '@akson/cortex-supabase';
// Auth operations
try {
const user = await signIn(email, password);
} catch (error) {
if (error instanceof AuthError) {
console.error('Auth error:', error.message);
// Handle specific auth errors
}
}
// Storage operations
try {
const result = await uploadFile(file);
if (!result.success) {
console.error('Upload failed:', result.error);
}
} catch (error) {
if (error instanceof StorageError) {
console.error('Storage error:', error.message);
}
}
```
## Hooks Reference
### Authentication Hooks
- `useAuth()` - Current user and auth state
- `useSession()` - Session management
- `usePermissions()` - Role-based permissions
### Storage Hooks
- `useDocumentUpload()` - File upload with progress
- `useDocumentManager()` - Document CRUD operations
- `useBatchUpload()` - Multiple file uploads
- `useFileValidation()` - File validation utilities
### Utility Hooks
- `useSupabase()` - Access Supabase client
- `useRealtime()` - Real-time subscriptions (coming soon)
### Example Usage
```tsx
const { user, loading, signOut } = useAuth();
const { upload, isUploading, progress } = useDocumentUpload();
const { hasPermission } = usePermissions(['admin']);
```
## Version History
- **3.1.2** - Current version with full auth, storage, and component support
- **3.0.x** - Major rewrite with modular architecture
- **2.x.x** - Legacy storage-focused package
## Contributing
This is part of the Cortex packages ecosystem. Contributions are welcome!
## License
MIT
## Support
For support, please open an issue in the [Cortex Packages repository](https://github.com/antoineschaller/cortex-packages).