baseflow-client
v1.1.0
Published
Official TypeScript/JavaScript client for BaseFlow - a powerful BaaS with OAuth authentication, RPC functions, database indexes, real-time features, and Supabase-compatible API
Maintainers
Readme
baseflow-client
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
npm install baseflow-clientyarn add baseflow-clientpnpm add baseflow-client🏃♂️ Quick Start
1. Initialize the Client
import { createClient } from 'baseflow-client';
const baseflow = createClient({
url: 'https://your-project.baseflow.cloud',
apiKey: 'your-api-key'
});2. Query Your Database
// 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
const { data, error } = await baseflow
.from('posts')
.insert({
title: 'Hello BaseFlow!',
content: 'This is my first post.',
author_id: 1
});4. Authentication
// Sign up with email/password
const { user, session, error } = await baseflow.auth.signUp(
'[email protected]',
'password123',
{ name: 'John Doe' }
);
// Sign in with email/password
const { user, session, error } = await baseflow.auth.signInWithPassword({
email: '[email protected]',
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
// 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
// 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
// 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 recordsupdate(data)- Update existing recordsdelete()- Delete records
Filter Methods
eq(column, value)- Equal toneq(column, value)- Not equal togt(column, value)- Greater thangte(column, value)- Greater than or equallt(column, value)- Less thanlte(column, value)- Less than or equallike(column, pattern)- Pattern matchingilike(column, pattern)- Case-insensitive pattern matchingin(column, values)- Match any value in arraycontains(column, value)- Contains valuetextSearch(column, query)- Full-text search
Query Modifiers
order(column, options)- Sort resultslimit(count)- Limit number of resultsrange(from, to)- Get specific rangesingle()- Return single rowmaybeSingle()- Return single row or null
Authentication
// 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
// 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
// Call remote procedures
baseflow.rpc(functionName, params?)
// Function management
baseflow.createFunction(name, definition, options?)
baseflow.listFunctions()
baseflow.getFunction(name)
baseflow.deleteFunction(name)Database Indexes
// Index management
baseflow.createIndex(table, columns, options?)
baseflow.listIndexes(table?)
baseflow.dropIndex(name)
baseflow.analyzeQuery(query) // Performance analysisAdvanced Features
// 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:
// 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:
// 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:
// 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
// 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:
// 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
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_secretSee the OAuth Setup Guide for detailed instructions.
🛠️ TypeScript Support
BaseFlow is built with TypeScript and provides excellent type safety:
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
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
// 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
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
# .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
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 for details.
📄 License
MIT License - see the LICENSE file for details.
🔗 Links
Built with ❤️ by the BaseFlow team
