@gzl10/baserow
v1.2.2
Published
Modern TypeScript client for Baserow API with 3-client architecture, 21 field types, and optimized bulk operations
Maintainers
Readme
@gzl10/baserow
Modern TypeScript client for Baserow API v1.35+ with 3-client architecture, PrismaBaserowMapper, 21/22 field types, and automatic JWT refresh.
Features
- 🎯 3-Client Architecture: Token, Admin Global, and Admin Workspace
- 🔐 Auto-Refresh JWT: Automatic access/refresh token management
- 🗺️ PrismaBaserowMapper: Familiar Prisma-style query syntax (35+ tests)
- 📋 21/22 Field Types: Complete coverage including file, autonumber, count, rollup, lookup
- 🚀 Optimized HTTP: axios-retry + axios-rate-limit (36% less code)
- 🔄 Hierarchical API: Intuitive workspace → database → table → fields/rows navigation
- ⚡ Bulk Operations: Optimized batch processing with retry logic
Installation
pnpm add @gzl10/baserowQuick Start
import { BaserowClient } from '@gzl10/baserow'
// 1. Database Token (read-only)
const client = await BaserowClient.create({
url: 'https://baserow.example.com',
token: 'db_token_123'
})
// 2. Admin Global (multi-workspace)
const admin = await BaserowClient.create({
url: 'https://baserow.example.com',
credentials: { email: '[email protected]', password: 'password' }
})
// 3. Admin Workspace (scoped)
const adminWS = await BaserowClient.create({
url: 'https://baserow.example.com',
credentials: { email: '[email protected]', password: 'password' },
workspace: 'My Workspace'
})Client Types
| Client | Auth | Capabilities | Use Cases | | ------------------ | -------------- | ------------------------------------ | ---------------------------- | | BaserowClient | Database Token | Data CRUD, bulk operations | Apps, data integration, APIs | | AdminGlobal | JWT Multi-WS | Full workspace/database/table mgmt | Admin scripts, DevOps tools | | AdminWorkspace | JWT Scoped | Operations within specific workspace | Enterprise apps, dashboards |
PrismaBaserowMapper
Familiar Prisma-style syntax for Baserow queries:
const employees = await client
.database(123)
.table(456)
.rows.findMany({
where: {
AND: [{ status: 'active' }, { age: { gte: 18, lt: 65 } }, { email: { contains: '@company.com' } }]
},
orderBy: [{ created_at: 'desc' }, { name: 'asc' }],
take: 20,
skip: 40
})Supported operators: equals, not, contains, startsWith, endsWith, gt, gte, lt, lte, AND, OR, NOT, isEmpty, isNotEmpty
Basic Usage
Data Operations (Token Client)
const rows = await client.database(123).table(456).rows.list()
const newRow = await client.database(123).table(456).rows.create({
name: 'John Doe',
email: '[email protected]'
})
// Bulk operations
const bulkRows = await client.database(123).table(456).rows.createBulk(items, { batchSize: 100 })Admin Operations
// Workspaces
const workspaces = await admin.workspaces.list()
const newWS = await admin.workspaces.create({ name: 'New Company' })
// Databases
const database = await admin.workspace('Company').databases.create('CRM')
// Tables
const table = await admin
.workspace('Company')
.database('CRM')
.tables.create({
name: 'Customers',
data: [
['Name', 'Email'],
['Alice', '[email protected]']
],
first_row_header: true
})Field Types (21/22)
Text & Communication
await table.field.createText('full_name')
await table.field.createLongText('description')
await table.field.createUrl('website')
await table.field.createEmail('contact_email')
await table.field.createPhoneNumber('phone')Numeric & Boolean
await table.field.createNumber('price', 2) // 2 decimals
await table.field.createBoolean('is_active')
await table.field.createRating('rating', 5)Date & Audit
await table.field.createDate('birthdate')
await table.field.createLastModified('updated_at')
await table.field.createCreatedOn('created_at')Selection
await table.field.createSingleSelect('status', [
{ value: 'active', color: 'green' },
{ value: 'inactive', color: 'red' }
])
await table.field.createMultipleSelect('tags', options)Relational
await table.field.createLinkRow('related_items', targetTableId)
await table.field.createFormula('total', 'field("qty") * field("price")')Advanced
await table.field.createFile('documents')
await table.field.createAutonumber('ticket_id')
await table.field.createCount('items_count', targetTableId)
await table.field.createRollup('total_amount', tableId, fieldId, 'sum')
await table.field.createLookup('item_names', tableId, fieldId)Configuration
Performance Presets
import { BaserowClient, PERFORMANCE_PRESETS } from '@gzl10/baserow'
const client = await BaserowClient.create({
url: 'https://baserow.example.com',
token: 'your_token',
performance: PERFORMANCE_PRESETS.production
})| Preset | Timeout | Retries | Rate (req/s) |
| -------------- | ------- | ------- | ------------ |
| production | 30s | 3 | 10 |
| development | 60s | 2 | 5 |
| testing | 45s | 2 | 5 |
| aggressive | 15s | 5 | 20 |
| conservative | 60s | 1 | 2 |
Keep-Alive (24/7 Backends)
const client = await BaserowClient.create({
url: 'https://baserow.example.com',
credentials: { email: '[email protected]', password: 'password' },
keepAlive: {
enabled: true,
intervalMinutes: 7200 // Re-login every 5 days
}
})⚠️ Baserow limitation: Refresh token expires 7 days after login (fixed). Keep-alive performs automatic re-login to prevent expiration.
Express Utilities (Optional)
import { BaserowClient, express as baserowExpress } from '@gzl10/baserow'
app.use('/api', baserowExpress.baserowContext(client))
app.use('/api', baserowExpress.requireAuth())
app.get('/api/rows', async (req, res) => {
const rows = await req.baserow!.database(123).table(456).rows.list()
res.json(baserowExpress.serializePaginated(rows))
})
app.use(baserowExpress.errorHandler())Error Handling
import {
BaserowError,
BaserowNotFoundError,
BaserowValidationError,
BaserowAuthTokenExpiredError
} from '@gzl10/baserow'
try {
await client.database(999).table(456).rows.list()
} catch (error) {
if (error instanceof BaserowNotFoundError) {
console.error('Resource not found:', error.message)
}
}Testing
pnpm test # All tests
pnpm test:watch # Watch mode
pnpm test:smoke # CI/CD smoke tests60+ tests including 35+ integration tests and 34 error handling tests.
Documentation
Compatibility
✅ Baserow v1.35.3 - Fully compatible, safe upgrade from v1.35.0+
Support
License
MIT License - See LICENSE
