overskill-sdk
v0.5.5
Published
Official SDK for OverSkill generated apps - entity-first development
Readme
@overskill/sdk
Official SDK for OverSkill generated apps - build data-driven applications with zero backend code.
Features
- ✅ Entity-first development - Define entities, get instant CRUD operations
- ✅ Zero backend code - No API routes, no database setup, no auth implementation
- ✅ TypeScript support - Full type definitions included
- ✅ Edge-optimized - Queries run on Cloudflare Workers globally
- ✅ Auto-authentication - Built-in OverSkill SSO integration
- ✅ Lightweight - Just 12 KB (gzipped)
Installation
npm install @overskill/sdkQuick Start
import { createClient } from '@overskill/sdk'
// Create client instance
const overskill = createClient({
appId: 'your-app-id', // Optional
debug: true // Enable logging
})
// List entities
const todos = await overskill.entities.Todo.list()
// Create entity
const newTodo = await overskill.entities.Todo.create({
title: 'Buy groceries',
completed: false
})
// Update entity
await overskill.entities.Todo.update(newTodo.id, {
completed: true
})
// Delete entity
await overskill.entities.Todo.delete(newTodo.id)Entity Methods
list(orderBy?, limit?) / list(options)
List entities with optional sorting, limit, and pagination offset.
// List all todos
const todos = await overskill.entities.Todo.list()
// List 20 most recent
const recent = await overskill.entities.Todo.list('-created_at', 20)
// Oldest first
const oldest = await overskill.entities.Todo.list('created_at', 10)
// Object syntax (Prisma-style) with pagination
const page2 = await overskill.entities.Todo.list({
orderBy: '-created_at',
limit: 20,
skip: 20 // or `offset: 20`
})filter(filters, orderBy?, limit?) / filter(filters, options)
Filter entities by exact field values. Booleans are supported and match
records stored via create({ completed: true }).
// Filter by single field
const active = await overskill.entities.Todo.filter({ completed: false })
// Multiple filters
const urgent = await overskill.entities.Todo.filter({
completed: false,
priority: 'high'
}, '-created_at', 10)
// Options-object syntax with pagination
const page2 = await overskill.entities.Todo.filter(
{ completed: false },
{ orderBy: '-created_at', limit: 20, skip: 20 }
)get(id)
Get a single entity by ID.
const todo = await overskill.entities.Todo.get('abc123')create(data)
Create a new entity.
const todo = await overskill.entities.Todo.create({
title: 'New todo',
completed: false,
due_date: '2025-01-15'
})update(id, data)
Update an existing entity.
await overskill.entities.Todo.update('abc123', {
completed: true
})delete(id)
Delete an entity.
await overskill.entities.Todo.delete('abc123')bulkCreate(records)
Create multiple entities at once.
await overskill.entities.Todo.bulkCreate([
{ title: 'Todo 1', completed: false },
{ title: 'Todo 2', completed: false },
{ title: 'Todo 3', completed: false }
])Authentication
me()
Get current authenticated user.
try {
const user = await overskill.auth.me()
console.log('Logged in as:', user.email)
} catch (error) {
// Not authenticated
overskill.auth.login()
}login(redirectUrl?)
Redirect to OverSkill login page.
// Login and return to current page
overskill.auth.login()
// Login and redirect to specific URL
overskill.auth.login('https://myapp.com/dashboard')loginWithRedirect(callbackUrl)
Login with redirect to full URL (must be absolute).
overskill.auth.loginWithRedirect('https://myapp.com/complete-profile')logout()
Clear authentication and logout.
await overskill.auth.logout()checkSession()
Check if user is authenticated (does not throw errors).
const user = await overskill.auth.checkSession()
if (user) {
console.log('Logged in:', user.email)
} else {
console.log('Not logged in')
}isAuthenticated()
Check if user has a token (synchronous).
if (overskill.auth.isAuthenticated()) {
console.log('Has token')
}Configuration
ClientConfig Options
interface ClientConfig {
appId?: string; // App identifier (optional)
apiUrl?: string; // Custom API endpoint (defaults to current origin)
authToken?: string; // Pre-existing auth token
autoLogin?: boolean; // Auto-redirect to login on 401 (default: false)
debug?: boolean; // Enable debug logging (default: false)
}Examples
Basic usage:
const overskill = createClient()With auto-login:
const overskill = createClient({
autoLogin: true // Redirect to login if 401
})With debug logging:
const overskill = createClient({
debug: true // See all SDK operations in console
})With pre-existing token:
const overskill = createClient({
authToken: 'your-jwt-token'
})React Integration
Check Session on Mount
import { createClient } from '@overskill/sdk'
import { useEffect, useState } from 'react'
const overskill = createClient()
function App() {
const [user, setUser] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
// Check if user is logged in
overskill.auth.checkSession()
.then(user => {
if (user) {
setUser(user)
} else {
// Redirect to login
overskill.auth.login()
}
})
.finally(() => setLoading(false))
}, [])
if (loading) return <div>Loading...</div>
return <div>Welcome, {user.name}!</div>
}Entity CRUD Example
function TodoList() {
const [todos, setTodos] = useState([])
useEffect(() => {
loadTodos()
}, [])
const loadTodos = async () => {
const data = await overskill.entities.Todo.list('-created_at', 20)
setTodos(data)
}
const handleCreate = async (title: string) => {
const newTodo = await overskill.entities.Todo.create({
title,
completed: false
})
setTodos([newTodo, ...todos])
}
const handleToggle = async (id: string) => {
const todo = todos.find(t => t.id === id)
await overskill.entities.Todo.update(id, {
completed: !todo.completed
})
setTodos(todos.map(t =>
t.id === id ? { ...t, completed: !t.completed } : t
))
}
const handleDelete = async (id: string) => {
await overskill.entities.Todo.delete(id)
setTodos(todos.filter(t => t.id !== id))
}
return (
<div>
{/* UI code */}
</div>
)
}Error Handling
The SDK lets errors bubble by design, so OverSkill AI can see and fix them.
try {
const user = await overskill.auth.me()
} catch (error) {
if (error.status === 401) {
// Not authenticated
overskill.auth.login()
} else {
// Other error - let it throw for debugging
throw error
}
}Advanced Usage
Direct HTTP Client
// Make custom API calls
const response = await overskill.http.get('/api/custom/endpoint')Manual Token Management
// Set token manually
overskill.auth.setToken('your-jwt-token')
// Get current token
const token = overskill.auth.getToken()TypeScript
Full TypeScript support included:
import { createClient, type User, type EntityRecord } from '@overskill/sdk'
interface Todo extends EntityRecord {
title: string;
completed: boolean;
due_date?: string;
}
const overskill = createClient()
const todos = await overskill.entities.Todo.list() // Type: Todo[]Architecture
@overskill/sdk connects to OverSkill Workers running on Cloudflare edge:
Your App (React + @overskill/sdk)
↓
Cloudflare Worker (per-app, edge-deployed)
↓
Turso Database (per-app, isolated)- Zero backend code needed - No Express, no API routes, no DB setup
- Edge performance - ~50ms latency globally
- Automatic scaling - Handles any traffic volume
- Secure by default - User data isolated automatically
License
MIT
Support
- Documentation: https://docs.overskill.app
- Issues: https://github.com/OverskillDev/overskill/issues
- Email: [email protected]
