baseflow-local-client
v1.0.2
Published
Official TypeScript/JavaScript client for BaseFlow Local - a local-first BaaS with SQLite database, authentication, file storage, and real-time features
Maintainers
Readme
BaseFlow Local Client
Official TypeScript/JavaScript client for BaseFlow Local - a local-first Backend-as-a-Service with SQLite database, authentication, file storage, and real-time features.
Installation
npm install @baseflow/local-clientQuick Start
import { createClient } from '@baseflow/local-client';
// Create client (connects to local server)
const baseflow = createClient({
url: 'http://localhost:5555', // Optional, defaults to localhost:5555
apiKey: 'your-api-key-here' // Optional: API key for authentication
});
// Query data
const { data, error } = await baseflow
.from('users')
.select('*')
.eq('status', 'active');
// Insert data
await baseflow.from('posts').insert({
title: 'Hello World',
content: 'My first post'
});
// Update data
await baseflow
.from('users')
.update({ name: 'Jane Doe' })
.eq('id', 1);
// Delete data
await baseflow
.from('posts')
.delete()
.eq('id', 123);API Key Authentication
BaseFlow Local generates an API key for each project. You can find your API key in the .baseflow/api-keys.json file or by visiting http://localhost:5555/api/keys.
const baseflow = createClient({
url: 'http://localhost:5555',
apiKey: 'bf_local_your_api_key_here'
});Alternatively, you can pass the API key in headers:
const baseflow = createClient({
url: 'http://localhost:5555',
headers: {
'x-api-key': 'bf_local_your_api_key_here'
}
});Features
- 🗄️ Database Operations - Full CRUD with query builder
- 🔐 Authentication - JWT-based auth with signup/login
- 📁 File Storage - Upload, download, and manage files
- 🔄 Real-time - Subscribe to database changes
- 🚀 TypeScript - Full type safety and IntelliSense
- 🌐 Universal - Works in Node.js and browsers
Authentication
// Register a new user
const { data, error } = await baseflow.auth.signUp({
email: '[email protected]',
password: 'SecurePassword123',
name: 'John Doe'
});
// Login
const { data, error } = await baseflow.auth.signInWithPassword({
email: '[email protected]',
password: 'SecurePassword123'
});
// Get current user
const { data, error } = await baseflow.auth.getUser();
// Logout
await baseflow.auth.signOut();
// Listen to auth state changes
const unsubscribe = baseflow.auth.onAuthStateChange((event) => {
if (event.type === 'SIGNED_IN') {
console.log('User signed in:', event.user);
}
});File Storage
// Upload file (Node.js)
const fs = require('fs');
const fileBuffer = fs.readFileSync('image.jpg');
const { data, error } = await baseflow.storage.upload(fileBuffer, {
filename: 'image.jpg',
folder: 'images',
isPublic: true
});
// Upload file (Browser)
const file = document.getElementById('input').files[0];
const { data, error } = await baseflow.storage.upload(file, {
folder: 'uploads',
isPublic: true
});
// List files
const { data, error } = await baseflow.storage.list('images');
// Get file URL
const url = baseflow.storage.getUrl('images/photo.jpg');
// Delete file
await baseflow.storage.delete(fileId);- 🔍 Advanced Queries - Filtering, sorting, pagination
- 📦 TypeScript Support - Full type safety
- 🎯 Supabase-like API - Familiar developer experience
Database Operations
Select
// Select all
const { data } = await baseflow.from('users').select('*');
// Select specific columns
const { data } = await baseflow.from('users').select('id, name, email');
// With filters
const { data } = await baseflow
.from('users')
.select('*')
.eq('status', 'active')
.gt('age', 18);
// With sorting
const { data } = await baseflow
.from('posts')
.select('*')
.order('created_at', { ascending: false });
// With pagination
const { data } = await baseflow
.from('users')
.select('*')
.range(0, 9); // First 10 records
// Single record
const { data } = await baseflow
.from('users')
.select('*')
.eq('id', 1)
.single();Insert
// Insert single record
const { data, error } = await baseflow.from('users').insert({
name: 'John Doe',
email: '[email protected]'
});
// Insert multiple records
const { data, error } = await baseflow.from('users').insert([
{ name: 'Alice', email: '[email protected]' },
{ name: 'Bob', email: '[email protected]' }
]);Update
// Update with filter
const { data, error } = await baseflow
.from('users')
.update({ status: 'inactive' })
.eq('last_login', null);
// Update single record
const { data, error } = await baseflow
.from('users')
.update({ name: 'Jane Smith' })
.eq('id', 1);Delete
// Delete with filter
const { data, error } = await baseflow
.from('posts')
.delete()
.eq('status', 'draft');
// Delete single record
const { data, error } = await baseflow
.from('users')
.delete()
.eq('id', 123);Filters
// Equals
.eq('column', 'value')
// Not equals
.neq('column', 'value')
// Greater than
.gt('column', 10)
// Greater than or equal
.gte('column', 10)
// Less than
.lt('column', 10)
// Less than or equal
.lte('column', 10)
// Like (pattern matching)
.like('column', '%pattern%')
// Case-insensitive like
.ilike('column', '%pattern%')
// Is null
.is('column', null)
// In array
.in('column', [1, 2, 3])
// Match multiple conditions
.match({ status: 'active', role: 'admin' })Authentication
Sign Up
const { data, error } = await baseflow.auth.signUp({
email: '[email protected]',
password: 'securepassword',
name: 'John Doe' // Optional
});
if (data) {
console.log('User:', data.user);
console.log('Token:', data.token);
}Sign In
const { data, error } = await baseflow.auth.signInWithPassword({
email: '[email protected]',
password: 'securepassword'
});
if (data) {
console.log('Logged in:', data.user);
}Get Current User
const { data, error } = await baseflow.auth.getUser();
if (data) {
console.log('Current user:', data.user);
}Sign Out
await baseflow.auth.signOut();Auth State Changes
const unsubscribe = baseflow.auth.onAuthStateChange((event) => {
if (event.type === 'SIGNED_IN') {
console.log('User signed in:', event.user);
} else if (event.type === 'SIGNED_OUT') {
console.log('User signed out');
}
});
// Unsubscribe when done
unsubscribe();Manual Session Management
// Set session manually (e.g., from localStorage)
baseflow.auth.setSession({
token: 'your-jwt-token',
user: { id: 1, email: '[email protected]' }
});
// Get current session
const session = baseflow.auth.getSession();
console.log(session.token, session.user);File Storage
Upload File
// From file input
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const { data, error } = await baseflow.storage.upload(file, {
folder: 'images',
isPublic: true
});
if (data) {
console.log('File uploaded:', data.filename);
console.log('Public URL:', data.publicUrl);
}Upload with Node.js
import fs from 'fs';
const fileBuffer = fs.readFileSync('./image.jpg');
const { data, error } = await baseflow.storage.upload(fileBuffer, {
folder: 'uploads',
isPublic: false
});List Files
// List all files
const { data, error } = await baseflow.storage.list();
// List files in folder
const { data, error } = await baseflow.storage.list('images');
if (data) {
console.log('Files:', data.files);
console.log('Count:', data.count);
}Get File URL
const url = baseflow.storage.getUrl('path/to/file.jpg');
console.log('File URL:', url);Download File
const { data, error } = await baseflow.storage.download('path/to/file.jpg');Delete File
const { data, error } = await baseflow.storage.delete(fileId);RPC Functions
Call custom server-side functions:
const { data, error } = await baseflow.rpc('myFunction', {
param1: 'value1',
param2: 'value2'
});Utility Methods
List Tables
const { data, error } = await baseflow.listTables();
console.log('Tables:', data.tables);Get Schema
const { data, error } = await baseflow.getSchema();
console.log('Schema:', data);TypeScript Support
The client is fully typed for TypeScript:
interface User {
id: number;
name: string;
email: string;
created_at: string;
}
// Type-safe queries
const { data, error } = await baseflow
.from<User>('users')
.select('*')
.eq('email', '[email protected]');
// data is typed as User[] | null
if (data) {
data.forEach(user => {
console.log(user.name); // TypeScript knows this exists
});
}Error Handling
All methods return a response object with data and error:
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('Data:', data);
}Configuration
Custom URL
const baseflow = createClient({
url: 'http://192.168.1.100:5555' // Custom server URL
});With Authentication Token
const baseflow = createClient({
url: 'http://localhost:5555',
token: 'your-jwt-token' // Pre-authenticated
});Custom Headers
const baseflow = createClient({
url: 'http://localhost:5555',
headers: {
'X-Custom-Header': 'value'
}
});Custom Fetch Implementation
import fetch from 'node-fetch';
const baseflow = createClient({
url: 'http://localhost:5555',
fetch: fetch as any
});Differences from Cloud Client
| Feature | Cloud Client | Local Client |
|---------|--------------|--------------|
| URL | https://api.baseflow.dev | http://localhost:5555 |
| Auth | API Key + Project ID | JWT tokens |
| Endpoints | /rest/v1/... | /api/... |
| Real-time | Cloud WebSocket | Local WebSocket (coming soon) |
| OAuth | Supported | Not supported |
Examples
Complete CRUD Example
import { createClient } from '@baseflow/local-client';
const baseflow = createClient();
// Create
const { data: newUser } = await baseflow.from('users').insert({
name: 'Alice',
email: '[email protected]'
});
// Read
const { data: users } = await baseflow
.from('users')
.select('*')
.eq('email', '[email protected]');
// Update
await baseflow
.from('users')
.update({ name: 'Alice Smith' })
.eq('id', newUser.id);
// Delete
await baseflow
.from('users')
.delete()
.eq('id', newUser.id);Authentication Flow
// Register
const { data: signUpData } = await baseflow.auth.signUp({
email: '[email protected]',
password: 'password123',
name: 'John Doe'
});
// Login
const { data: signInData } = await baseflow.auth.signInWithPassword({
email: '[email protected]',
password: 'password123'
});
// Get user
const { data: userData } = await baseflow.auth.getUser();
// Logout
await baseflow.auth.signOut();File Upload Example
// Browser
const handleUpload = async (event) => {
const file = event.target.files[0];
const { data, error } = await baseflow.storage.upload(file, {
folder: 'avatars',
isPublic: true
});
if (data) {
console.log('Uploaded:', data.publicUrl);
}
};
// Node.js
import fs from 'fs';
const buffer = fs.readFileSync('./document.pdf');
const { data } = await baseflow.storage.upload(buffer, {
folder: 'documents',
isPublic: false
});License
MIT
Links
Support
For questions and support, please visit our GitHub Discussions.
