@butterbase/sdk
v2.0.2
Published
Universal TypeScript SDK for Butterbase
Maintainers
Readme
@butterbase/sdk
Universal TypeScript SDK for Butterbase - works in browser, Node.js, and Deno environments.
Installation
npm install @butterbase/sdkQuick Start
import { createClient } from '@butterbase/sdk';
// Initialize client
const butterbase = createClient({
appId: 'app_abc123',
apiUrl: 'https://api.butterbase.ai',
anonKey: 'your-anon-key' // Optional, for public access
});
// Query data
const { data, error } = await butterbase
.from('posts')
.select('*')
.eq('status', 'published')
.order('created_at', { ascending: false })
.limit(10);
// Insert data
const { data, error } = await butterbase
.from('posts')
.insert({ title: 'Hello World', content: 'My first post' });
// Update data
const { data, error } = await butterbase
.from('posts')
.update({ status: 'archived' })
.eq('id', '123');
// Delete data
const { data, error } = await butterbase
.from('posts')
.delete()
.eq('id', '123');Migration from 0.x to 1.0
Breaking Change: The authUrl parameter has been removed. All auth endpoints now run on the same URL as the API.
Before (0.x):
const butterbase = createClient({
appId: 'app_abc123',
apiUrl: 'https://api.butterbase.ai',
authUrl: 'https://auth.butterbase.com', // ❌ No longer needed
});After (1.0):
const butterbase = createClient({
appId: 'app_abc123',
apiUrl: 'https://api.butterbase.ai', // ✅ All endpoints use this URL
});Authentication
Sessions are automatically persisted to localStorage and restored on page refresh. Access tokens are automatically refreshed before they expire.
// Sign up
const { data, error } = await butterbase.auth.signUp({
email: '[email protected]',
password: 'secure123'
});
// Sign in (session is automatically persisted)
const { data, error } = await butterbase.auth.signIn({
email: '[email protected]',
password: 'secure123'
});
// Get current user (works after page refresh)
const { data: user } = await butterbase.auth.getUser();
// Sign out (clears persisted session)
await butterbase.auth.signOut();
// Refresh session manually (uses stored refresh token if none provided)
const { data } = await butterbase.auth.refreshSession();
// OAuth
const { url } = butterbase.auth.signInWithOAuth({
provider: 'google',
redirectTo: 'http://localhost:3000/callback'
});
window.location.href = url;Auth State Changes
Subscribe to authentication events to react to sign-ins, sign-outs, and token refreshes:
const { unsubscribe } = butterbase.onAuthStateChange((event, session) => {
// event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'SESSION_RESTORED'
console.log(event, session?.user);
});
// Stop listening
unsubscribe();React Usage
import { useEffect, useState } from 'react';
import { butterbase } from './lib';
function App() {
const [user, setUser] = useState(null);
useEffect(() => {
// Session is auto-restored — check current state
const session = butterbase.sessionManager.getSession();
if (session) setUser(session.user);
// React to future auth changes
const { unsubscribe } = butterbase.onAuthStateChange((event, session) => {
setUser(session?.user ?? null);
});
return unsubscribe;
}, []);
}Custom Storage
By default, the SDK uses localStorage with an in-memory fallback for SSR/Node.js environments. You can provide a custom storage adapter:
import { createClient, MemorySessionStorage } from '@butterbase/sdk';
// Memory-only (no persistence)
const butterbase = createClient({
appId: 'app_abc123',
apiUrl: 'https://api.butterbase.ai',
persistSession: false,
});
// Custom storage adapter (e.g., for React Native)
const butterbase = createClient({
appId: 'app_abc123',
apiUrl: 'https://api.butterbase.ai',
sessionStorage: myCustomStorage, // implements { getItem, setItem, removeItem }
});Storage
// Upload file
const { data, error } = await butterbase.storage.upload(file);
// Get download URL
const { data } = await butterbase.storage.getDownloadUrl(objectId);
// List files
const { data: objects } = await butterbase.storage.list();
// Delete file
await butterbase.storage.delete(objectId);Functions
// Invoke serverless function
const { data, error } = await butterbase.functions.invoke('my-function', {
body: { key: 'value' },
method: 'POST'
});Query Builder
Operators
eq(column, value)- Equal toneq(column, value)- Not equal togt(column, value)- Greater thangte(column, value)- Greater than or equal tolt(column, value)- Less thanlte(column, value)- Less than or equal tolike(column, pattern)- Pattern matching (case-sensitive)ilike(column, pattern)- Pattern matching (case-insensitive)in(column, values)- Value in arrayis(column, value)- Is null/true/false
Modifiers
select(columns)- Select specific columnsorder(column, options)- Order resultslimit(count)- Limit resultsoffset(count)- Skip results
Usage in Deno
import { createClient } from 'npm:@butterbase/sdk';
const butterbase = createClient({
appId: Deno.env.get('BUTTERBASE_APP_ID')!,
apiUrl: Deno.env.get('BUTTERBASE_API_URL')!,
});
// Use in serverless functions
export async function handler(req: Request, ctx: any) {
const { data } = await butterbase.from('posts').select('*');
return Response.json({ data });
}TypeScript Support
The SDK is fully typed with TypeScript. All methods return ButterbaseResponse<T> with proper type inference:
interface Post {
id: string;
title: string;
content: string;
status: 'draft' | 'published';
}
const { data, error } = await butterbase
.from<Post>('posts')
.select('*')
.eq('status', 'published');
// data is typed as Post[] | null
// error is typed as Error | nullIntegrations
Connect third-party services to your app and execute actions on behalf of your users.
Admin configuration (API key)
// Enable a toolkit
await bb.integrations.configure('gmail', { displayName: 'Gmail' });
// List enabled integrations
const { data } = await bb.integrations.getConfig();
// Disable a toolkit
await bb.integrations.disable('gmail');
// Search available toolkits
const { data } = await bb.integrations.listAvailable({ search: 'salesforce' });End-user OAuth flow (user JWT)
// Generate connect URL — redirect the user to authUrl
const { data } = await bb.integrations.connect('gmail', {
redirectUrl: 'https://yourapp.com/settings',
});
window.location.href = data.authUrl;
// List user's connected accounts
const { data } = await bb.integrations.listConnections();
// Disconnect an account
await bb.integrations.disconnect(connectionId);Executing tools
// List tools for a toolkit
const { data } = await bb.integrations.getTools('gmail');
// data[0] = { name: 'GMAIL_SEND_EMAIL', description: '...', parameters: { ... } }
// Execute a tool (user JWT auth)
const { data } = await bb.integrations.execute('GMAIL_SEND_EMAIL', {
to: '[email protected]',
subject: 'Hello',
body: 'Sent via Butterbase integrations.',
});
// Execute on behalf of a user (API key + userId, e.g. in a cron)
const { data } = await bb.integrations
.asUser('user-uuid')
.execute('GOOGLECALENDAR_EVENTS_LIST', { timeMin: new Date().toISOString() });License
MIT
