Package Exports
- pb-params
Readme
pb-params
Type-safe PocketBase query parameters builder with pocketbase-typegen integration and auto-expand functionality.
Overview
pb-params
is a comprehensive TypeScript library that provides type-safe building of all PocketBase query parameters including filtering, field selection, relation expansion, sorting, and pagination. It's designed to work seamlessly with types generated by pocketbase-typegen.
Features
- 🔥 Complete Parameter Coverage: Filter, fields, expand, sort, and pagination
- 🎯 Type-Safe: Full TypeScript support with collection-specific typing
- 🔗 Typegen Integration: Works seamlessly with pocketbase-typegen output
- 🏗️ Fluent API: Chain methods for intuitive query building
- ⚡ Auto-Expand: Automatically generates expand from field paths - no redundancy!
- 📦 Zero Dependencies: Lightweight with no runtime dependencies
- 🎨 Conditional Building: Apply parameters based on runtime conditions
Installation
Install pb-params with your preferred package manager:
# npm
npm install pb-params
# pnpm
pnpm add pb-params
# yarn
yarn add pb-params
# bun
bun add pb-params
Requirements
- TypeScript: 5.0+
- Node.js: 18+
Getting Started
1. Generate Types (Optional but Recommended)
First, generate TypeScript types for your PocketBase collections:
npx pocketbase-typegen --db ./pb_data/data.db --out pocketbase-types.ts
2. Basic Usage
import { pbParams } from 'pb-params'
import PocketBase from 'pocketbase'
import type { UsersRecord } from './pocketbase-types' // Generated types
const pb = new PocketBase('http://127.0.0.1:8090')
// Build comprehensive query parameters with auto-expand
const params = pbParams<UsersRecord>()
.filter(q => q
.equal('verified', true)
.and()
.like('name', 'John%')
)
.fields(['id', 'name', 'email', 'created', 'expand.profile.avatar', 'expand.organization.name'])
.sort(['-created', 'name'])
.page(1, 20)
.build()
// Auto-generates: { expand: "profile,organization" }
// Use with PocketBase SDK
const records = await pb.collection('users').getList(1, 20, params)
3. Without Generated Types
You can also use pb-params without generated types:
interface User {
id: string
name: string
email: string
verified: boolean
expand?: {
profile?: { avatar: string }
}
}
const params = pbParams<User>()
.filter(q => q.equal('verified', true))
.fields(['id', 'name', 'email', 'expand.profile.avatar'])
.build()
// Auto-generates: { expand: "profile" }
API Reference
pbParams<T>()
Creates a new parameter builder for collection type T
.
const builder = pbParams<UsersRecord>()
Filtering
Build type-safe filters with full operator support:
pbParams<UsersRecord>()
.filter(q => q
.equal('status', 'active')
.and()
.greaterThan('age', 18)
.and()
.like('email', '%@company.com')
)
Supported operators:
equal
,notEqual
greaterThan
,greaterThanOrEqual
,lessThan
,lessThanOrEqual
like
,notLike
anyEqual
,anyNotEqual
,anyGreaterThan
, etc. (for arrays/relations)
Helper methods:
search(keys, value)
- Search across multiple fieldsin(key, values)
- Value in arraybetween(key, from, to)
- Range queriesisNull(key)
,isNotNull(key)
- Null checks
Field Selection & Auto-Expand
Select specific fields and automatically expand relations:
pbParams<UsersRecord>()
.fields([
'id',
'name',
'email',
'expand.profile.avatar', // Auto-expands: profile
'expand.profile.bio',
'expand.organization.name' // Auto-expands: organization
])
// Results in: {
// fields: "id,name,email,expand.profile.avatar,expand.profile.bio,expand.organization.name",
// expand: "profile,organization"
// }
Nested Relations
Handle deeply nested relations with ease:
pbParams<UsersRecord>()
.fields([
'id',
'expand.profile.expand.preferences.theme', // Auto-expands: profile,profile.preferences
'expand.profile.expand.preferences.notifications'
])
Sorting
Sort results by one or more fields:
pbParams<UsersRecord>()
.sort(['-created', 'name']) // Descending by created, then ascending by name
Pagination
Set page and page size:
pbParams<UsersRecord>()
.page(2, 50) // Page 2, 50 records per page
Conditional Building
Apply parameters based on runtime conditions:
const includeProfile = user.isAdmin
const sortByDate = filters.sortBy === 'date'
pbParams<UsersRecord>()
.filterIf(filters.verified !== undefined, q => q.equal('verified', filters.verified))
.fieldsIf(includeProfile, ['id', 'name', 'expand.profile.avatar']) // Auto-expands profile when included
.sortIf(sortByDate, ['-created'])
Integration with pocketbase-typegen
- Generate types for your PocketBase collections:
npx pocketbase-typegen --db ./pb_data/data.db --out pocketbase-types.ts
- Use the generated types with pb-params:
import type { CollectionRecords } from './pocketbase-types'
// Type-safe parameter building
const params = pbParams<CollectionRecords['users']>()
.filter(q => q.equal('status', 'active')) // 'status' is validated against user fields
.fields(['id', 'name', 'email']) // Field names are type-checked
.build()
Advanced Usage
Custom Filter Expressions
pbParams<UsersRecord>()
.filter(q => q
.group(sub => sub
.equal('role', 'admin')
.or()
.equal('role', 'moderator')
)
.and()
.isNotNull('lastLogin')
)
Date Filtering with Macros
pbParams<UsersRecord>()
.filter(q => q
.greaterThan('created', '@monthStart')
.and()
.lessThan('updated', '@now')
)
Type Inference
const result = pbParams<UsersRecord>()
.fields(['id', 'name'])
.expand(['profile'])
.buildTyped()
// result.resultType contains the inferred type shape
// result.params contains the query parameters
// result.raw contains the raw filter query and values
Migration from v0.1.0
Version 0.1.1 introduces auto-expand functionality that eliminates API redundancy:
Before (v0.1.0):
pbParams<User>()
.fields(['id', 'expand.profile.bio', 'expand.organization.name'])
.expand(['profile', 'organization']) // Redundant!
.build()
After (v0.1.1):
pbParams<User>()
.fields(['id', 'expand.profile.bio', 'expand.organization.name'])
.build() // Auto-generates expand: "profile,organization"
The expand()
and expandIf()
methods have been removed as expansion is now automatically inferred from field paths.
Credits & Inspiration
This project was inspired by:
- @emresandikci/pocketbase-query - Initial inspiration for type-safe PocketBase queries
- sergio9929/pb-query - Excellent filtering API design
- @patmood/pocketbase-typegen - All the Typescript types.
Comparison with pb-query
pb-params
builds upon the success of pb-query but provides:
- Broader Scope: Complete parameter coverage vs. filtering only
- Collection-Specific Types: Built for pocketbase-typegen integration from day one
- Unified API: Single library for all PocketBase query needs
- Auto-Expand: Eliminates redundancy with automatic expand generation
- Enhanced Features: Conditional building, nested expansion, type inference
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.