@vaiftech/client
v1.5.7
Published
TypeScript SDK for VAIF Studio BaaS
Maintainers
Readme
@vaiftech/client
The official TypeScript SDK for VAIF Studio - a Backend-as-a-Service platform.
Installation
npm install @vaiftech/client
# or
pnpm add @vaiftech/client
# or
yarn add @vaiftech/clientQuick Start
import { createVaifClient } from '@vaiftech/client';
const vaif = createVaifClient({
baseUrl: 'https://api.vaif.studio',
projectId: 'your-project-id',
apiKey: 'vaif_pk_xxx',
});Modules
The client provides access to the following modules:
| Module | Description |
|--------|-------------|
| vaif.auth | Authentication (email, OAuth, MFA, magic link) |
| vaif.from() | Database operations with query builder |
| vaif.mongodb | MongoDB document database |
| vaif.realtime() | Real-time subscriptions and presence |
| vaif.storage | File storage and CDN |
| vaif.functions | Edge functions |
| vaif.projects | Project management |
| vaif.orgs | Organization management |
| vaif.schema | Database schema migrations |
| vaif.secrets | Secret management |
| vaif.deployments | Deployment management |
| vaif.integrations | Webhooks and events |
| vaif.billing | Billing and subscriptions |
| vaif.flags | Feature flags |
| vaif.security | Security and environment variables |
| vaif.ai | AI-powered code generation |
| vaif.templates | Project templates |
| vaif.oauth | OAuth provider configuration |
| vaif.docs | Documentation management |
Authentication
// Sign up (positional args)
const { user, session } = await vaif.auth.signUp(
'[email protected]',
'securepassword',
{ name: 'John Doe' } // optional
);
// Login
const result = await vaif.auth.login(
'[email protected]',
'securepassword'
);
// OAuth - get the sign-in URL
const { url } = await vaif.auth.getOAuthSignInUrl({
provider: 'google',
redirectUrl: 'https://myapp.com/callback',
});
// Handle OAuth callback
const { user, session } = await vaif.auth.handleOAuthCallback({
provider: 'google',
code: 'auth_code_from_callback',
});
// Magic Link
await vaif.auth.requestMagicLink({ email: '[email protected]' });
const { user, session } = await vaif.auth.verifyMagicLink({ token: 'xxx' });
// MFA
const { qrCode, secret } = await vaif.auth.setupMFA('totp');
await vaif.auth.enableMFA('123456');
const result = await vaif.auth.verifyMFA('mfa_token', '123456');
// Get current user
const user = await vaif.auth.getUser();
// Logout
await vaif.auth.logout();
// Session management
const { sessions } = await vaif.auth.listSessions();
await vaif.auth.revokeSession('session_id');
await vaif.auth.revokeOtherSessions();Database Operations
// Define your types
interface User {
id: string;
email: string;
name: string;
createdAt: string;
}
// List with filters
const users = await vaif.from<User>('users')
.select('id', 'name', 'email')
.eq('active', true)
.orderBy('createdAt', 'desc')
.limit(10)
.list();
// Get single record
const user = await vaif.from<User>('users')
.eq('id', 'user-123')
.single();
// Create
const newUser = await vaif.from<User>('users').create({
email: '[email protected]',
name: 'New User',
});
// Update
const updated = await vaif.from<User>('users')
.eq('id', 'user-123')
.update({ name: 'Updated Name' });
// Delete
await vaif.from<User>('users')
.eq('id', 'user-123')
.delete();
// Batch operations
await vaif.from<User>('users').batchCreate([
{ email: '[email protected]', name: 'User 1' },
{ email: '[email protected]', name: 'User 2' },
]);
// Pagination
const { data, total, page, pageSize } = await vaif.from<User>('users')
.paginate({ page: 1, pageSize: 20 });
// Aggregations
const stats = await vaif.from<User>('users')
.aggregate({ count: '*', avg: 'age' });MongoDB Operations
Full MongoDB support for document-based data:
// Get a collection reference
const users = vaif.mongodb.collection<User>('users');
// Find documents
const activeUsers = await users.find({
filter: { status: 'active' },
sort: { createdAt: -1 },
limit: 10,
});
// Find one document
const user = await users.findOne({ email: '[email protected]' });
// Find by ID
const userById = await users.findById('507f1f77bcf86cd799439011');
// Insert documents
const newUser = await users.insertOne({
email: '[email protected]',
name: 'New User',
createdAt: new Date(),
});
const manyUsers = await users.insertMany([
{ email: '[email protected]', name: 'User 1' },
{ email: '[email protected]', name: 'User 2' },
]);
// Update documents
await users.updateOne(
{ email: '[email protected]' },
{ $set: { name: 'Updated Name' } }
);
await users.updateMany(
{ status: 'pending' },
{ $set: { status: 'active' } }
);
// Atomic operations
const updated = await users.findOneAndUpdate(
{ email: '[email protected]' },
{ $inc: { loginCount: 1 } },
{ returnDocument: 'after' }
);
// Delete documents
await users.deleteOne({ email: '[email protected]' });
await users.deleteMany({ status: 'inactive' });
// Aggregation pipeline
const stats = await users.aggregate([
{ $match: { status: 'active' } },
{ $group: { _id: '$country', count: { $sum: 1 } } },
{ $sort: { count: -1 } },
]);
// Count and distinct
const totalUsers = await users.count({ status: 'active' });
const countries = await users.distinct('country', { status: 'active' });
// Index management
const indexes = await users.listIndexes();
await users.createIndex({ email: 1 }, { unique: true });
await users.dropIndex('old_index');
// Bulk operations
await users.bulkWrite([
{ insertOne: { document: { email: '[email protected]' } } },
{ updateOne: { filter: { email: '[email protected]' }, update: { $set: { migrated: true } } } },
{ deleteOne: { filter: { email: '[email protected]' } } },
]);
// Collection management
const collections = await vaif.mongodb.listCollections();
await vaif.mongodb.createCollection('logs');Cursor Support
For large datasets, use cursors to paginate through results:
const cursor = await users.findWithCursor({
filter: { status: 'active' },
batchSize: 100,
});
let batch = await cursor.next();
while (batch.length > 0) {
for (const user of batch) {
console.log(user.email);
}
batch = await cursor.next();
}
await cursor.close();Realtime Subscriptions
const realtime = vaif.realtime();
await realtime.connect();
// Subscribe to table changes
realtime.subscribe(
{ table: 'messages', event: 'INSERT' },
(event) => {
console.log('New message:', event.new);
}
);
// Channel messaging
const channel = realtime.channel('room-1');
// Presence
channel.presence.track({ userId: 'user-123', status: 'online' });
channel.presence.onSync((state) => {
console.log('Online users:', Object.keys(state));
});
// Broadcast
channel.broadcast.send('typing', { userId: 'user-123' });
channel.broadcast.on('typing', (payload) => {
console.log('User typing:', payload.userId);
});
// Cleanup
realtime.unsubscribe({ table: 'messages' });
await realtime.disconnect();Storage
// Upload file
const result = await vaif.storage.upload('avatars/user-123.jpg', file, {
contentType: 'image/jpeg',
isPublic: true,
});
// Download file
const blob = await vaif.storage.download('avatars/user-123.jpg');
// Get public URL
const url = vaif.storage.getPublicUrl('avatars/user-123.jpg');
// Get signed URL (temporary access)
const signedUrl = await vaif.storage.getSignedUrl('private/doc.pdf', {
expiresIn: 3600,
});
// List files
const { files } = await vaif.storage.list({ prefix: 'avatars/' });
// Delete file
await vaif.storage.delete('avatars/old-avatar.jpg');
// Multipart uploads for large files
const upload = await vaif.storage.createMultipartUpload('large-file.zip');
await vaif.storage.uploadPart(upload.uploadId, 1, chunk1);
await vaif.storage.uploadPart(upload.uploadId, 2, chunk2);
await vaif.storage.completeMultipartUpload(upload.uploadId, parts);Edge Functions
// Invoke a function
const result = await vaif.functions.invoke('send-email', {
to: '[email protected]',
subject: 'Hello',
body: 'Welcome to VAIF!',
});
// Invoke with options
const result = await vaif.functions.invoke('process-data', payload, {
timeout: 30000,
retry: { attempts: 3, backoff: 'exponential' },
});
// Batch invoke
const results = await vaif.functions.batchInvoke([
{ name: 'func1', payload: { data: 1 } },
{ name: 'func2', payload: { data: 2 } },
]);
// List functions
const functions = await vaif.functions.list({ projectId: 'proj-123' });
// Deploy a function
await vaif.functions.deploy('my-function', {
code: functionCode,
runtime: 'node20',
});Integrations (Webhooks & Events)
// Create a webhook subscription
const subscription = await vaif.integrations.createSubscription({
type: 'webhook',
url: 'https://myapp.com/webhooks',
events: ['user.created', 'user.updated'],
secret: 'whsec_xxx',
});
// Publish custom events
await vaif.integrations.publish({
name: 'order.completed',
data: { orderId: '123', amount: 99.99 },
});
// List webhook deliveries
const deliveries = await vaif.integrations.listDeliveries({
subscriptionId: 'sub-123',
});
// Retry failed delivery
await vaif.integrations.retryDelivery('delivery-123');TypeScript Support
The SDK is fully typed. Use generics for type-safe operations:
interface Post {
id: string;
title: string;
content: string;
authorId: string;
createdAt: string;
}
// Full type inference
const posts = await vaif.from<Post>('posts').list();
// posts is Post[]
// MongoDB with types
const users = vaif.mongodb.collection<User>('users');
const user = await users.findOne({ email: '[email protected]' });
// user is User | nullError Handling
import {
VaifError,
VaifAuthError,
VaifNotFoundError,
isVaifError
} from '@vaiftech/client';
try {
await vaif.from('users').eq('id', 'invalid').single();
} catch (error) {
if (error instanceof VaifNotFoundError) {
console.log('User not found');
} else if (error instanceof VaifAuthError) {
console.log('Authentication failed');
} else if (isVaifError(error)) {
console.log('VAIF error:', error.message);
}
}Related Packages
- @vaiftech/auth - Standalone authentication client
- @vaiftech/react - React hooks
- @vaiftech/sdk-expo - React Native/Expo SDK
- @vaiftech/cli - CLI tools
License
MIT
