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
Markdown
# baseflow-client
[](https://badge.fury.io/js/@baseflow%2Fclient)
[](https://www.typescriptlang.org/)
[](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**