import 'graphile-build'; import 'graphile-build-pg'; import 'graphile-connection-filter'; import type { GraphileConfig } from 'graphile-config'; /** * PostgisSpatialRelationsPlugin * * Adds cross-table spatial filtering to `graphile-connection-filter` by * reading a `@spatialRelation` smart tag on geometry/geography columns and * synthesising a virtual relation + filter field that emits an EXISTS * subquery joined by a PostGIS predicate (e.g. `ST_Contains`, `ST_DWithin`). * * The regular `ConnectionFilterBackwardRelationsPlugin` is FK-driven — it * joins on column equality. Spatial relationships are not backed by FKs, so * this plugin hooks the same `pgCodec`-scoped filter input types and injects * its own fields whose `apply()` emits `ST_(...)` instead of `a = b`. * * Tag grammar: * * ```sql * COMMENT ON COLUMN . IS * E'@spatialRelation []'; * ``` * * - `target_ref` — `schema.table.col` or `table.col` (same schema as owner). * - `operator` — one of the PG-native snake_case ops in OPERATOR_REGISTRY. * - `param_name` — required iff the operator is parametric (currently * only `st_dwithin`, which needs a distance). * * Examples: * * ```sql * -- Point in polygon * COMMENT ON COLUMN telemedicine_clinics.location IS * E'@spatialRelation county counties.geom st_contains'; * * -- Self-referential radius search * COMMENT ON COLUMN telemedicine_clinics.location IS * E'@spatialRelation nearbyClinic telemedicine_clinics.location st_dwithin distance'; * ``` * * Generated GraphQL (for the `st_dwithin` case): * * ```graphql * telemedicineClinics(where: { * nearbyClinic: { * distance: 5000, * some: { specialty: { eq: "pediatrics" } } * } * }) * ``` * * The generated SQL uses the same EXISTS pattern as backward relations but * substitutes `ST_(...)` for column equality: * * ```sql * WHERE EXISTS ( * SELECT 1 FROM other * WHERE ST_(other., self.[, distance]) * AND other. <> self. -- self-relations only * AND * ) * ``` */ export interface SpatialOperatorRegistration { /** Tag-facing op name (PG-native snake_case). */ name: string; /** Kind of PG-level operator. */ kind: 'function' | 'infix'; /** * For `kind: 'function'`, the PG function name (snake_case) resolved * against the PostGIS schema at SQL-emit time. For `kind: 'infix'`, * the PG binary operator token (e.g. `&&`). */ pgToken: string; /** Whether this op takes an extra numeric parameter (e.g. `st_dwithin`). */ parametric: boolean; description: string; } export declare const OPERATOR_REGISTRY: Record; export interface SpatialRelationInfo { /** GraphQL-facing relation name, derived from the tag. */ relationName: string; /** The codec that owns the tag (outer side of the EXISTS). */ ownerCodec: any; /** The owning attribute name (column). */ ownerAttributeName: string; /** Qualified target resource (inner side of the EXISTS). */ targetResource: any; /** Column name on the target resource. */ targetAttributeName: string; /** Resolved operator. */ operator: SpatialOperatorRegistration; /** Field name for the parametric argument, if any. */ paramFieldName: string | null; /** Whether owner === target (self-relation needs row exclusion). */ isSelfRelation: boolean; /** * Cached primary-key attribute names for the owner+target codecs. Used * to synthesise the self-exclusion predicate (`other. <> self.`). * `null` if the codec has no discoverable PK. */ ownerPkAttributes: string[] | null; targetPkAttributes: string[] | null; } interface TagParseResult { ok: true; relationName: string; targetRef: string; operator: string; paramName: string | null; } interface TagParseError { ok: false; error: string; } /** * Parse a single `@spatialRelation` tag value. * * Accepts a string of the form ` []`. */ export declare function parseSpatialRelationTag(raw: string): TagParseResult | TagParseError; /** * Build the full set of spatial relations from all resources. * Validates tags and throws (at schema build) on anything malformed. * Returns relations keyed by (owner codec identity, relation name). */ export declare function collectSpatialRelations(build: any): SpatialRelationInfo[]; export declare const PostgisSpatialRelationsPlugin: GraphileConfig.Plugin; export {};