Skip to main content
Version: 3.7.0

PocketBase Driver

Targets PocketBase — the open-source single-binary backend (SQLite + realtime + auth), with its expression-language filter parameter and page-based pagination.

Configure

import { DriverEnum, provideNgQubee } from 'ng-qubee';

bootstrapApplication(AppComponent, {
providers: [provideNgQubee({ driver: DriverEnum.POCKETBASE })]
});

Point setBaseUrl at the records endpoint root (e.g. https://pb.example.com/api/collections) and use the collection name + /records as the resource, or bake the full path into your HTTP layer.

Wire format

ConcernOutput
Filters (single value)filter=(field='value') (strings quoted, numbers/booleans bare)
Filters (multi-value)filter=((field='v1' || field='v2')) (OR group)
Operator filtersexpression terms inside filter=(...) — see below
Sortsort=-created,title (CSV, - prefix = DESC)
Selectfields=id,title (CSV)
Includesexpand=author,comments (CSV)
Paginationpage=N&perPage=M

The page / perPage / sort / filter / expand / fields keys are fixed by the PocketBase records API and ignore request key overrides. Simple filters and operator filters merge into a single filter=(...) expression, AND-joined.

String literals are single-quoted with embedded quotes backslash-escaped (name='O\'Brien').

Operator filters

FilterOperatorEnum translates to PocketBase's expression operators:

import { FilterOperatorEnum } from 'ng-qubee';

qb.addFilterOperator('views', FilterOperatorEnum.GT, 100); // filter=(views>100)
qb.addFilterOperator('title', FilterOperatorEnum.CONTAINS, 'hello'); // filter=(title~'hello')
qb.addFilterOperator('title', FilterOperatorEnum.SW, 'Intro'); // filter=(title~'Intro%')
qb.addFilterOperator('id', FilterOperatorEnum.IN, 1, 2, 3); // filter=((id=1 || id=2 || id=3))
qb.addFilterOperator('status', FilterOperatorEnum.NOT, 'draft'); // filter=(status!='draft')
qb.addFilterOperator('price', FilterOperatorEnum.BTW, 10, 50); // filter=((price>=10 && price<=50))
qb.addFilterOperator('deleted', FilterOperatorEnum.NULL, true); // filter=(deleted=null)

Translation table

FilterOperatorEnumPocketBase expression
EQfield='value'
GT / GTE / LT / LTE> / >= / < / <=
CONTAINS / ILIKEfield~'value' (PocketBase's ~ is case-insensitive and auto-wraps in %...%)
SWfield~'value%' (explicit trailing wildcard disables the auto-wrap)
INOR group (field='v1' || field='v2')
BTWAND group (field>=min && field<=max) (arity-checked)
NOT (single)field!='value'
NOT (multi)AND group of != terms
NULLfield=null (value true) / field!=null (value false); arity/type-checked
FTS / PHFTS / PLFTS / WFTSunsupported — throws UnsupportedFilterOperatorError

PocketBase's ?= / ?~ any-of relation operators and !~ (not-like) have no FilterOperatorEnum counterpart and are not exposed.

Value shape rules

BTW requires exactly 2 values (min, max); NULL requires exactly 1 boolean — both enforced at call time with InvalidFilterOperatorValueError. Other operators leave shape validation to the server.

Feature matrix

MethodSupported?Notes
addFilter / deleteFiltersExpression terms inside the single filter=(...) param
addFilterOperator / deleteOperatorFiltersSee translation table above
addSort / deleteSortsCSV sort= with - prefix for DESC
setLimit / setPagepage + perPage
addSelect / deleteSelectfields= CSV
addFields / deleteFields / deleteFieldsByModelNo per-model field selection
addIncludes / deleteIncludesexpand= CSV (dotted names pass through for nested expansion)
addEmbedded / deleteEmbeddedThrows UnsupportedEmbeddedError
setSearch / deleteSearchNo global search param — use a CONTAINS operator filter instead

Response shape

PocketBase records-list responses are flat:

{
"page": 1,
"perPage": 30,
"totalItems": 48,
"totalPages": 2,
"items": [{ "id": "abc123", "title": "Hello" }]
}

PocketbaseResponseStrategy maps items → data, totalItems → total, totalPages → lastPage, page → page, perPage → perPage; from/to are computed from page × perPage (clamped to the total on the last page). The envelope carries no navigation links, so the URL slots on PaginatedCollection stay undefined.

Note: with skipTotal=1 (a server-side optimisation this driver does not emit), PocketBase reports totalItems/totalPages as -1.

All key paths are configurable (dot notation supported):

provideNgQubee({
driver: DriverEnum.POCKETBASE,
response: {
data: 'records',
total: 'meta.count'
}
});

Defaults are encoded in PocketbaseResponseOptions.