UNPKG

baseflow-client

Version:

Official TypeScript/JavaScript client for BaseFlow - a powerful BaaS with OAuth authentication, RPC functions, database indexes, real-time features, and Supabase-compatible API

611 lines (479 loc) 15.6 kB
# baseflow-client [![npm version](https://badge.fury.io/js/@baseflow%2Fclient.svg)](https://badge.fury.io/js/@baseflow%2Fclient) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) The official TypeScript/JavaScript client for **BaseFlow** - a powerful Backend-as-a-Service (BaaS) platform with advanced query capabilities, real-time features, and Supabase-compatible API. ## 🚀 Features - **Advanced Query Builder**: Supabase-like API with 20+ filter methods - **Smart JOINs**: Automatic foreign key detection and relationship queries - **Real-time Subscriptions**: Listen to database changes in real-time - **Authentication**: Email/password + OAuth (GitHub, Google) - **OAuth Providers**: Third-party sign-in with GitHub and Google - **RPC Functions**: Call server-side functions remotely - **Database Indexes**: Create and manage indexes for performance optimization - **File Storage**: Upload, manage, and serve files - **TypeScript First**: Fully typed with excellent IntelliSense support - **Universal**: Works in browsers, Node.js, React Native, and edge environments ## 📦 Installation ```bash npm install baseflow-client ``` ```bash yarn add baseflow-client ``` ```bash pnpm add baseflow-client ``` ## 🏃‍♂️ Quick Start ### 1. Initialize the Client ```typescript import { createClient } from 'baseflow-client'; const baseflow = createClient({ url: 'https://your-project.baseflow.cloud', apiKey: 'your-api-key' }); ``` ### 2. Query Your Database ```typescript // Simple query const { data, error } = await baseflow .from('users') .select('*') .eq('status', 'active'); // Advanced query with JOINs const { data, error } = await baseflow .from('posts') .select('title, content, author:users(name, email)') .eq('published', true) .order('created_at', { ascending: false }) .limit(10); ``` ### 3. Insert Data ```typescript const { data, error } = await baseflow .from('posts') .insert({ title: 'Hello BaseFlow!', content: 'This is my first post.', author_id: 1 }); ``` ### 4. Authentication ```typescript // Sign up with email/password const { user, session, error } = await baseflow.auth.signUp( 'user@example.com', 'password123', { name: 'John Doe' } ); // Sign in with email/password const { user, session, error } = await baseflow.auth.signInWithPassword({ email: 'user@example.com', password: 'password123' }); // Sign in with OAuth (GitHub or Google) const { data } = await baseflow.auth.signInWithOAuth('github'); window.location.href = data.url; // Redirect to GitHub // Handle OAuth callback const result = await baseflow.auth.handleOAuthCallback(code, 'github'); console.log('User:', result.data.user); // Listen to auth changes baseflow.auth.onAuthStateChange((event) => { console.log('Auth event:', event.type, event.user); }); ``` ### 5. File Storage ```typescript // Upload file const { data, error } = await baseflow.storage.upload( 'avatars/user-123.jpg', fileBuffer, { mimetype: 'image/jpeg' } ); // Get public URL const { data: urlData } = await baseflow.storage.getUrl('avatars/user-123.jpg'); ``` ### 6. RPC Functions ```typescript // Call a remote procedure const { data, error } = await baseflow.rpc('calculate_total', { user_id: 123, start_date: '2024-01-01' }); // Create a function await baseflow.createFunction('hello_world', ` return { message: 'Hello, ' + params.name }; `, { language: 'javascript', parameters: [{ name: 'name', type: 'string' }] }); ``` ### 7. Database Indexes ```typescript // Create an index for better query performance const { data, error } = await baseflow.createIndex('users', ['email'], { unique: true, name: 'idx_users_email' }); // List all indexes const { data: indexes } = await baseflow.listIndexes('users'); // Drop an index await baseflow.dropIndex('idx_users_email'); ``` ## 📚 API Reference ### Database Operations #### Query Methods - `select(columns)` - Select specific columns (supports JOINs) - `insert(data)` - Insert new records - `update(data)` - Update existing records - `delete()` - Delete records #### Filter Methods - `eq(column, value)` - Equal to - `neq(column, value)` - Not equal to - `gt(column, value)` - Greater than - `gte(column, value)` - Greater than or equal - `lt(column, value)` - Less than - `lte(column, value)` - Less than or equal - `like(column, pattern)` - Pattern matching - `ilike(column, pattern)` - Case-insensitive pattern matching - `in(column, values)` - Match any value in array - `contains(column, value)` - Contains value - `textSearch(column, query)` - Full-text search #### Query Modifiers - `order(column, options)` - Sort results - `limit(count)` - Limit number of results - `range(from, to)` - Get specific range - `single()` - Return single row - `maybeSingle()` - Return single row or null ### Authentication ```typescript // Email/Password Authentication baseflow.auth.signUp(email, password, options?) baseflow.auth.signInWithPassword(credentials) baseflow.auth.signOut() baseflow.auth.getUser() baseflow.auth.getSession() baseflow.auth.onAuthStateChange(callback) // OAuth Authentication baseflow.auth.signInWithOAuth(provider, options?) // provider: 'github' | 'google' baseflow.auth.handleOAuthCallback(code, provider) ``` ### Storage ```typescript // Available methods baseflow.storage.upload(path, file, options?) baseflow.storage.download(path) baseflow.storage.getUrl(path) baseflow.storage.list(path?) baseflow.storage.delete(path) baseflow.storage.createFolder(path) ``` ### RPC & Functions ```typescript // Call remote procedures baseflow.rpc(functionName, params?) // Function management baseflow.createFunction(name, definition, options?) baseflow.listFunctions() baseflow.getFunction(name) baseflow.deleteFunction(name) ``` ### Database Indexes ```typescript // Index management baseflow.createIndex(table, columns, options?) baseflow.listIndexes(table?) baseflow.dropIndex(name) baseflow.analyzeQuery(query) // Performance analysis ``` ### Advanced Features ```typescript // Raw SQL queries const { data, error } = await baseflow.sql( 'SELECT * FROM users WHERE created_at > ?', ['2024-01-01'] ); // Schema management const { data, error } = await baseflow.defineSchema({ users: { id: { type: 'INTEGER', primaryKey: true, autoIncrement: true }, name: { type: 'TEXT', required: true }, email: { type: 'TEXT', unique: true, required: true } } }); ``` ## ⚡ RPC Functions Call server-side functions for complex operations: ```typescript // Call a function const { data, error } = await baseflow.rpc('calculate_user_stats', { user_id: 123, start_date: '2024-01-01', end_date: '2024-12-31' }); console.log('Stats:', data); // Create a JavaScript function await baseflow.createFunction('greet_user', ` return { message: 'Hello, ' + params.name + '!', timestamp: new Date().toISOString() }; `, { language: 'javascript', parameters: [ { name: 'name', type: 'string', default: 'Guest' } ], description: 'Greets a user by name' }); // Create a SQL function await baseflow.createFunction('get_active_users', ` SELECT * FROM users WHERE last_login > datetime('now', '-7 days') `, { language: 'sql', returnType: 'table' }); // List all functions const { data: functions } = await baseflow.listFunctions(); console.log('Available functions:', functions); ``` ## 📊 Database Indexes Optimize query performance with indexes: ```typescript // Create a single-column index await baseflow.createIndex('users', ['email'], { unique: true, name: 'idx_users_email' }); // Create a composite index await baseflow.createIndex('posts', ['user_id', 'created_at'], { name: 'idx_posts_user_date' }); // List all indexes for a table const { data: indexes } = await baseflow.listIndexes('users'); console.log('Indexes:', indexes); // Analyze query performance const { data: analysis } = await baseflow.analyzeQuery(` SELECT * FROM posts WHERE user_id = 123 ORDER BY created_at DESC `); console.log('Query plan:', analysis.queryPlan); console.log('Estimated rows:', analysis.estimatedRows); console.log('Uses index:', analysis.usesIndex); // Drop an index await baseflow.dropIndex('idx_users_email'); ``` ## 🔗 Advanced Queries BaseFlow supports sophisticated queries with automatic relationship detection: ```typescript // Automatic JOINs based on foreign keys const { data } = await baseflow .from('posts') .select(` title, content, author:users(name, email, avatar_url), comments(count), tags:post_tags(tag:tags(name)) `) .eq('published', true); // Aggregations const { data } = await baseflow .from('users') .select('name, posts(count)') .gte('created_at', '2024-01-01'); ``` ## 🔄 Real-time Subscriptions ```typescript // Connect to real-time server await baseflow.realtime.connect(); // Listen to all changes const unsubscribe = baseflow.realtime.subscribe('posts', (payload) => { console.log('Change received!', payload); console.log('Event:', payload.event); // INSERT, UPDATE, DELETE console.log('New data:', payload.new); console.log('Old data:', payload.old); }); // Unsubscribe when done unsubscribe(); ``` ## 🔐 OAuth Authentication BaseFlow supports OAuth authentication with GitHub and Google: ```typescript // Sign in with GitHub async function signInWithGitHub() { const { data, error } = await baseflow.auth.signInWithOAuth('github', { redirectTo: 'http://localhost:3000/callback' }); if (error) { console.error('OAuth error:', error); return; } // Redirect user to GitHub window.location.href = data.url; } // Handle OAuth callback (in your callback page) async function handleCallback() { const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get('code'); if (code) { const { data, error } = await baseflow.auth.handleOAuthCallback(code, 'github'); if (error) { console.error('Authentication failed:', error); return; } console.log('User:', data.user); console.log('Session:', data.session); // User is now authenticated! } } // Sign in with Google async function signInWithGoogle() { const { data } = await baseflow.auth.signInWithOAuth('google'); window.location.href = data.url; } ``` ### OAuth Setup To use OAuth, configure your providers in the BaseFlow server: ```env # .env GITHUB_CLIENT_ID=your_github_client_id GITHUB_CLIENT_SECRET=your_github_client_secret GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret ``` See the [OAuth Setup Guide](https://github.com/baseflow/baseflow/blob/main/OAUTH_SETUP_GUIDE.md) for detailed instructions. ## 🛠️ TypeScript Support BaseFlow is built with TypeScript and provides excellent type safety: ```typescript interface User { id: number; name: string; email: string; created_at: string; } const { data, error } = await baseflow .from<User>('users') .select('*') .eq('id', 1) .single(); // data is typed as User | null // error is typed as BaseFlowError | null ``` ## 🌐 Environment Support BaseFlow client works in all JavaScript environments: - ✅ **Browsers** (Chrome, Firefox, Safari, Edge) - ✅ **Node.js** (16+) - ✅ **React Native** - ✅ **Next.js** (App Router & Pages Router) - ✅ **Vite** - ✅ **Webpack** - ✅ **Edge Runtime** (Vercel, Cloudflare Workers) ## 📖 Examples ### React Integration ```tsx import { createClient } from 'baseflow-client'; import { useEffect, useState } from 'react'; const baseflow = createClient({ url: process.env.NEXT_PUBLIC_BASEFLOW_URL!, apiKey: process.env.NEXT_PUBLIC_BASEFLOW_ANON_KEY! }); function UsersList() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchUsers() { const { data, error } = await baseflow .from('users') .select('*') .order('created_at', { ascending: false }); if (data) setUsers(data); setLoading(false); } fetchUsers(); }, []); if (loading) return <div>Loading...</div>; return ( <ul> {users.map(user => ( <li key={user.id}>{user.name} - {user.email}</li> ))} </ul> ); } ``` ### Next.js API Route ```typescript // pages/api/users.ts import { createClient } from 'baseflow-client'; const baseflow = createClient({ url: process.env.BASEFLOW_URL!, apiKey: process.env.BASEFLOW_SERVICE_ROLE_KEY! }); export default async function handler(req, res) { if (req.method === 'GET') { const { data, error } = await baseflow .from('users') .select('*'); if (error) { return res.status(400).json({ error: error.message }); } return res.json({ users: data }); } } ``` ## 🔧 Configuration ### Client Options ```typescript interface BaseFlowClientOptions { url: string; // Your BaseFlow project URL apiKey: string; // Your project API key headers?: Record<string, string>; // Additional headers fetch?: typeof fetch; // Custom fetch implementation } ``` ### Environment Variables ```bash # .env.local NEXT_PUBLIC_BASEFLOW_URL=https://your-project.baseflow.cloud NEXT_PUBLIC_BASEFLOW_ANON_KEY=your-anon-key BASEFLOW_SERVICE_ROLE_KEY=your-service-role-key ``` ## 🚨 Error Handling ```typescript const { data, error } = await baseflow .from('users') .select('*'); if (error) { console.error('Error:', error.message); console.error('Code:', error.code); console.error('Details:', error.details); } else { console.log('Users:', data); } ``` ## 🆚 Comparison with Other BaaS | Feature | BaseFlow | Supabase | Firebase | PlanetScale | |---------|----------|----------|----------|-------------| | Advanced JOINs | ✅ | ✅ | ❌ | ✅ | | Auto FK Detection | ✅ | ❌ | ❌ | ❌ | | OAuth (GitHub/Google) | ✅ | ✅ | ✅ | ❌ | | RPC Functions | ✅ | ✅ | ✅ | ❌ | | Database Indexes | ✅ | ✅ | ✅ | ✅ | | TypeScript First | ✅ | ✅ | ⚠️ | ✅ | | Local Development | ✅ | ✅ | ❌ | ❌ | | Real-time | ✅ | ✅ | ✅ | ❌ | | File Storage | ✅ | ✅ | ✅ | ❌ | | Edge Functions | 🔄 | ✅ | ✅ | ❌ | | SQLite Backend | ✅ | ❌ | ❌ | ❌ | ## 🤝 Contributing We welcome contributions! Please see our [Contributing Guide](https://github.com/baseflow/baseflow/blob/main/CONTRIBUTING.md) for details. ## 📄 License MIT License - see the [LICENSE](https://github.com/baseflow/baseflow/blob/main/LICENSE) file for details. ## 🔗 Links - [Documentation](https://docs.baseflow.cloud) - [GitHub](https://github.com/baseflow/baseflow) - [Website](https://baseflow.cloud) - [Discord Community](https://discord.gg/baseflow) --- **Built with ❤️ by the BaseFlow team**