graphile-postgis 2.10.1 → 2.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +497 -13
- package/esm/index.d.ts +2 -0
- package/esm/index.js +1 -0
- package/esm/plugins/connection-filter-operators.js +22 -2
- package/esm/plugins/spatial-relations.d.ts +130 -0
- package/esm/plugins/spatial-relations.js +575 -0
- package/esm/preset.js +3 -1
- package/index.d.ts +2 -0
- package/index.js +6 -1
- package/package.json +5 -5
- package/plugins/connection-filter-operators.js +22 -2
- package/plugins/spatial-relations.d.ts +130 -0
- package/plugins/spatial-relations.js +583 -0
- package/preset.js +3 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import 'graphile-build';
|
|
2
|
+
import 'graphile-build-pg';
|
|
3
|
+
import 'graphile-connection-filter';
|
|
4
|
+
import type { GraphileConfig } from 'graphile-config';
|
|
5
|
+
/**
|
|
6
|
+
* PostgisSpatialRelationsPlugin
|
|
7
|
+
*
|
|
8
|
+
* Adds cross-table spatial filtering to `graphile-connection-filter` by
|
|
9
|
+
* reading a `@spatialRelation` smart tag on geometry/geography columns and
|
|
10
|
+
* synthesising a virtual relation + filter field that emits an EXISTS
|
|
11
|
+
* subquery joined by a PostGIS predicate (e.g. `ST_Contains`, `ST_DWithin`).
|
|
12
|
+
*
|
|
13
|
+
* The regular `ConnectionFilterBackwardRelationsPlugin` is FK-driven — it
|
|
14
|
+
* joins on column equality. Spatial relationships are not backed by FKs, so
|
|
15
|
+
* this plugin hooks the same `pgCodec`-scoped filter input types and injects
|
|
16
|
+
* its own fields whose `apply()` emits `ST_<op>(...)` instead of `a = b`.
|
|
17
|
+
*
|
|
18
|
+
* Tag grammar:
|
|
19
|
+
*
|
|
20
|
+
* ```sql
|
|
21
|
+
* COMMENT ON COLUMN <owner_table>.<owner_col> IS
|
|
22
|
+
* E'@spatialRelation <relation_name> <target_ref> <operator> [<param_name>]';
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* - `target_ref` — `schema.table.col` or `table.col` (same schema as owner).
|
|
26
|
+
* - `operator` — one of the PG-native snake_case ops in OPERATOR_REGISTRY.
|
|
27
|
+
* - `param_name` — required iff the operator is parametric (currently
|
|
28
|
+
* only `st_dwithin`, which needs a distance).
|
|
29
|
+
*
|
|
30
|
+
* Examples:
|
|
31
|
+
*
|
|
32
|
+
* ```sql
|
|
33
|
+
* -- Point in polygon
|
|
34
|
+
* COMMENT ON COLUMN telemedicine_clinics.location IS
|
|
35
|
+
* E'@spatialRelation county counties.geom st_contains';
|
|
36
|
+
*
|
|
37
|
+
* -- Self-referential radius search
|
|
38
|
+
* COMMENT ON COLUMN telemedicine_clinics.location IS
|
|
39
|
+
* E'@spatialRelation nearbyClinic telemedicine_clinics.location st_dwithin distance';
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* Generated GraphQL (for the `st_dwithin` case):
|
|
43
|
+
*
|
|
44
|
+
* ```graphql
|
|
45
|
+
* telemedicineClinics(where: {
|
|
46
|
+
* nearbyClinic: {
|
|
47
|
+
* distance: 5000,
|
|
48
|
+
* some: { specialty: { eq: "pediatrics" } }
|
|
49
|
+
* }
|
|
50
|
+
* })
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* The generated SQL uses the same EXISTS pattern as backward relations but
|
|
54
|
+
* substitutes `ST_<op>(...)` for column equality:
|
|
55
|
+
*
|
|
56
|
+
* ```sql
|
|
57
|
+
* WHERE EXISTS (
|
|
58
|
+
* SELECT 1 FROM <target_table> other
|
|
59
|
+
* WHERE ST_<op>(other.<target_col>, self.<owner_col>[, distance])
|
|
60
|
+
* AND other.<pk> <> self.<pk> -- self-relations only
|
|
61
|
+
* AND <nested filter conditions>
|
|
62
|
+
* )
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export interface SpatialOperatorRegistration {
|
|
66
|
+
/** Tag-facing op name (PG-native snake_case). */
|
|
67
|
+
name: string;
|
|
68
|
+
/** Kind of PG-level operator. */
|
|
69
|
+
kind: 'function' | 'infix';
|
|
70
|
+
/**
|
|
71
|
+
* For `kind: 'function'`, the PG function name (snake_case) resolved
|
|
72
|
+
* against the PostGIS schema at SQL-emit time. For `kind: 'infix'`,
|
|
73
|
+
* the PG binary operator token (e.g. `&&`).
|
|
74
|
+
*/
|
|
75
|
+
pgToken: string;
|
|
76
|
+
/** Whether this op takes an extra numeric parameter (e.g. `st_dwithin`). */
|
|
77
|
+
parametric: boolean;
|
|
78
|
+
description: string;
|
|
79
|
+
}
|
|
80
|
+
export declare const OPERATOR_REGISTRY: Record<string, SpatialOperatorRegistration>;
|
|
81
|
+
export interface SpatialRelationInfo {
|
|
82
|
+
/** GraphQL-facing relation name, derived from the tag. */
|
|
83
|
+
relationName: string;
|
|
84
|
+
/** The codec that owns the tag (outer side of the EXISTS). */
|
|
85
|
+
ownerCodec: any;
|
|
86
|
+
/** The owning attribute name (column). */
|
|
87
|
+
ownerAttributeName: string;
|
|
88
|
+
/** Qualified target resource (inner side of the EXISTS). */
|
|
89
|
+
targetResource: any;
|
|
90
|
+
/** Column name on the target resource. */
|
|
91
|
+
targetAttributeName: string;
|
|
92
|
+
/** Resolved operator. */
|
|
93
|
+
operator: SpatialOperatorRegistration;
|
|
94
|
+
/** Field name for the parametric argument, if any. */
|
|
95
|
+
paramFieldName: string | null;
|
|
96
|
+
/** Whether owner === target (self-relation needs row exclusion). */
|
|
97
|
+
isSelfRelation: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Cached primary-key attribute names for the owner+target codecs. Used
|
|
100
|
+
* to synthesise the self-exclusion predicate (`other.<pk> <> self.<pk>`).
|
|
101
|
+
* `null` if the codec has no discoverable PK.
|
|
102
|
+
*/
|
|
103
|
+
ownerPkAttributes: string[] | null;
|
|
104
|
+
targetPkAttributes: string[] | null;
|
|
105
|
+
}
|
|
106
|
+
interface TagParseResult {
|
|
107
|
+
ok: true;
|
|
108
|
+
relationName: string;
|
|
109
|
+
targetRef: string;
|
|
110
|
+
operator: string;
|
|
111
|
+
paramName: string | null;
|
|
112
|
+
}
|
|
113
|
+
interface TagParseError {
|
|
114
|
+
ok: false;
|
|
115
|
+
error: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Parse a single `@spatialRelation` tag value.
|
|
119
|
+
*
|
|
120
|
+
* Accepts a string of the form `<name> <target> <op> [<param>]`.
|
|
121
|
+
*/
|
|
122
|
+
export declare function parseSpatialRelationTag(raw: string): TagParseResult | TagParseError;
|
|
123
|
+
/**
|
|
124
|
+
* Build the full set of spatial relations from all resources.
|
|
125
|
+
* Validates tags and throws (at schema build) on anything malformed.
|
|
126
|
+
* Returns relations keyed by (owner codec identity, relation name).
|
|
127
|
+
*/
|
|
128
|
+
export declare function collectSpatialRelations(build: any): SpatialRelationInfo[];
|
|
129
|
+
export declare const PostgisSpatialRelationsPlugin: GraphileConfig.Plugin;
|
|
130
|
+
export {};
|