UNPKG

@adonis-agora/filter

Version:

Server-side query filtering/sorting/pagination for AdonisJS — Spatie-style input, a Lucid adapter, and field allow-listing. Part of the Agora ecosystem.

61 lines 3.04 kB
import type { RelationSpec } from './filter_spec.js'; import type { ComputedFields } from './types.js'; /** * The structural slice of a booted Lucid relation the aggregate-subquery * compiler reads. A real `@adonisjs/lucid` `HasMany` / `ManyToMany` relation * satisfies it — declared locally so this module never hard-imports Lucid. The * key-column fields are optional because they differ by relation kind * (one-to-many exposes `foreignKeyColumnName`; many-to-many exposes the pivot * fields), and only the relevant ones are read per kind. */ export interface LucidRelationLike { /** Relation kind — `'hasMany'` / `'manyToMany'` are the to-many kinds we correlate. */ type: string; /** Compute the relation's key columns from the naming strategy (idempotent). */ boot(): void; /** The related (child) model — its `table` is the child table name. */ relatedModel(): { table?: string; }; foreignKeyColumnName?: string; localKeyColumnName?: string; relatedKeyColumnName?: string; pivotTable?: string; pivotForeignKey?: string; pivotRelatedForeignKey?: string; } /** * The structural slice of a Lucid model the aggregate discovery reads: its table * name and a relation accessor. `$getRelation` is typed with `any` for the same * reason `QueryBuilderLike.whereHas` is — Lucid types it with a generic * literal-union `Name`, and `string` is not assignable to that union, so a * narrower signature would make every real model fail to satisfy this interface. */ export interface LucidModelLike { table?: string; $getRelation(name: any): LucidRelationLike | undefined; } /** * Discover to-many aggregate {@link ComputedSource}s from a Lucid model's * relation metadata, for the relations the spec whitelisted. For each declared * to-many relation (hasMany / manyToMany) this synthesises: * * - `<rel>.$count` — always; * - `<rel>.$sum|$avg|$min|$max.<col>` — one per column the relation's * {@link RelationSpec.aggregates} declares (Lucid does not reflect SQL column * types, so the dev asserts numeric-ness by listing the column there). * * To-one relations (belongsTo / hasOne) are excluded. The whole thing degrades * gracefully: a relation that is not on the model, is to-one, or cannot be * booted (e.g. no DB adapter yet) is simply skipped, and a model without the * introspection capability yields an empty map — so aggregates activate only * when the metadata is actually available. * * The result is merged into the spec's `computed` map, so aggregate fields ARE * computed fields with auto-generated correlated-subquery sources — they reuse * the exact same runner routing, allow-list bypass (their discovery IS their * allow-list, gated by the relation whitelist), injection-safe value binding, * and codegen surfacing. */ export declare function discoverAggregateSources(model: LucidModelLike | undefined, relations: Readonly<Record<string, RelationSpec>>): ComputedFields; //# sourceMappingURL=aggregate.d.ts.map