basalt / search/src / SearchOptions
Interface: SearchOptions
Defined in: search/src/search.ts:157
Properties
authorize?
> optional authorize?: (hits) => SearchHit[] | Promise<SearchHit[]>
Defined in: search/src/search.ts:189
Row-level authorization, applied after the driver and before the page is returned. Return the hits the caller may see, in the order given.
A driver filters by the fields declared filterable, and nothing else. In a product where visibility depends on a policy — a confidential matter is visible only to the people assigned to it — that leaves search as the one surface with no answer, and both ways around it are bad:
- Copy the ACL into the index and filter there. Fast, and it makes the index a second copy of an access rule. Removing someone from a confidential matter changes the database and not the index, and search keeps showing it to them until somebody reindexes. A stale index gives an old result; a stale ACL gives an unauthorized one.
- Over-fetch and trim afterwards. Correct, but the over-fetch factor is a guess, and a caller with little access gets short pages.
With the hook here, the package keeps asking the driver until the page is full or the index runs out — which the caller cannot do from outside.
The hook must not reorder: relevance is the driver's to decide.
Parameters
hits
Returns
SearchHit[] | Promise<SearchHit[]>
filters?
> optional filters?: Record<string, unknown>
Defined in: search/src/search.ts:164
limit?
> optional limit?: number
Defined in: search/src/search.ts:165
maxScan?
> optional maxScan?: number
Defined in: search/src/search.ts:201
How many driver rows an authorized search may scan before giving up. Default: 20 pages' worth, floor 200 — capped by the service's maxScan ceiling (default DEFAULT_MAX_SCAN); an explicit value above the ceiling throws SearchPaginationError.
A hook that authorizes almost nothing would otherwise walk the whole index on every keystroke. Reaching the budget is reported as totalExact: false rather than as an error: a short page is a worse answer than a slow one, and a wrong count is worse than both.
offset?
> optional offset?: number
Defined in: search/src/search.ts:166
tenantId?
> optional tenantId?: string
Defined in: search/src/search.ts:163
Defaults to the current tenant (ctx().tenant.id). Inside a tenant context it must name that tenant — any other value throws SearchTenantMismatchError; it only selects a tenant outside one.