graphile-plugin-connection-filter-postgis 2.1.0 → 2.2.0

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/index.js CHANGED
@@ -1,30 +1,24 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ /**
3
+ * PostGIS Connection Filter Plugin for PostGraphile v5
4
+ *
5
+ * Adds PostGIS spatial filter operators (ST_Contains, ST_Intersects, etc.)
6
+ * to postgraphile-plugin-connection-filter.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { PostgisConnectionFilterPreset } from 'graphile-plugin-connection-filter-postgis';
11
+ *
12
+ * const preset = {
13
+ * extends: [PostgisConnectionFilterPreset]
14
+ * };
15
+ * ```
16
+ */
5
17
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PostGraphileConnectionFilterPostgisPlugin = void 0;
7
- const find_and_require_package_json_1 = require("find-and-require-package-json");
8
- const PgConnectionArgFilterPostgisOperatorsPlugin_1 = __importDefault(require("./PgConnectionArgFilterPostgisOperatorsPlugin"));
9
- const pkg = (0, find_and_require_package_json_1.findAndRequirePackageJson)(__dirname);
10
- const PostGraphileConnectionFilterPostgisPlugin = (builder, options) => {
11
- builder.hook("build", (build) => {
12
- if (!build.versions) {
13
- throw new Error(`Plugin ${pkg.name}@${pkg.version} requires graphile-build@^4.1.0 in order to check dependencies (current version: ${build.graphileBuildVersion})`);
14
- }
15
- const depends = (name, range) => {
16
- if (!build.hasVersion(name, range)) {
17
- throw new Error(`Plugin ${pkg.name}@${pkg.version} requires ${name}@${range} (${build.versions[name]
18
- ? `current version: ${build.versions[name]}`
19
- : "not found"})`);
20
- }
21
- };
22
- depends("graphile-build-pg", "^4.5.0");
23
- depends("graphile-plugin-connection-filter", "^3.0.0");
24
- build.versions = build.extend(build.versions, { [pkg.name]: pkg.version });
25
- return build;
26
- });
27
- (0, PgConnectionArgFilterPostgisOperatorsPlugin_1.default)(builder, options);
28
- };
29
- exports.PostGraphileConnectionFilterPostgisPlugin = PostGraphileConnectionFilterPostgisPlugin;
30
- exports.default = PostGraphileConnectionFilterPostgisPlugin;
18
+ exports.PgConnectionArgFilterPostgisOperatorsPlugin = exports.PostgisConnectionFilterPreset = void 0;
19
+ // Preset (recommended entry point)
20
+ var preset_1 = require("./preset");
21
+ Object.defineProperty(exports, "PostgisConnectionFilterPreset", { enumerable: true, get: function () { return preset_1.PostgisConnectionFilterPreset; } });
22
+ // Plugin
23
+ var plugin_1 = require("./plugin");
24
+ Object.defineProperty(exports, "PgConnectionArgFilterPostgisOperatorsPlugin", { enumerable: true, get: function () { return plugin_1.PgConnectionArgFilterPostgisOperatorsPlugin; } });
package/package.json CHANGED
@@ -1,23 +1,13 @@
1
1
  {
2
2
  "name": "graphile-plugin-connection-filter-postgis",
3
- "version": "2.1.0",
4
- "description": "PostGIS filtering options in PostGraphile",
5
- "author": "Matt Bretl",
6
- "homepage": "https://github.com/constructive-io/constructive",
7
- "license": "MIT",
3
+ "version": "2.2.0",
4
+ "author": "Constructive <developers@constructive.io>",
5
+ "description": "PostGIS operators for postgraphile-plugin-connection-filter (PostGraphile v5)",
8
6
  "main": "index.js",
9
7
  "module": "esm/index.js",
10
8
  "types": "index.d.ts",
11
- "scripts": {
12
- "clean": "makage clean",
13
- "copy": "makage assets",
14
- "prepack": "pnpm run build",
15
- "build": "makage build",
16
- "build:dev": "makage build --dev",
17
- "lint": "eslint . --fix",
18
- "test": "jest --passWithNoTests",
19
- "test:watch": "jest --watch"
20
- },
9
+ "homepage": "https://github.com/constructive-io/constructive",
10
+ "license": "MIT",
21
11
  "publishConfig": {
22
12
  "access": "public",
23
13
  "directory": "dist"
@@ -29,35 +19,49 @@
29
19
  "bugs": {
30
20
  "url": "https://github.com/constructive-io/constructive/issues"
31
21
  },
32
- "keywords": [
33
- "postgraphile",
34
- "graphile",
35
- "plugin",
36
- "postgres",
37
- "postgresql",
38
- "postgis",
39
- "filters",
40
- "constructive",
41
- "pgpm"
42
- ],
43
- "dependencies": {
44
- "find-and-require-package-json": "^0.9.0",
45
- "graphile-build": "^4.14.1",
46
- "graphile-build-pg": "^4.14.1",
47
- "graphile-plugin-connection-filter": "^3.1.0",
48
- "graphile-postgis": "^1.1.0"
22
+ "scripts": {
23
+ "clean": "makage clean",
24
+ "prepack": "npm run build",
25
+ "build": "makage build",
26
+ "build:dev": "makage build --dev",
27
+ "lint": "eslint . --fix",
28
+ "test": "jest",
29
+ "test:watch": "jest --watch"
49
30
  },
50
31
  "peerDependencies": {
51
- "postgraphile": "^4.14.1"
32
+ "graphile-build": "^5.0.0-rc.4",
33
+ "graphile-config": "^1.0.0-rc.5",
34
+ "graphile-postgis": "^2.0.0",
35
+ "graphql": "^16.9.0",
36
+ "pg-sql2": "^5.0.0-rc.4",
37
+ "postgraphile": "^5.0.0-rc.4",
38
+ "postgraphile-plugin-connection-filter": "^3.0.0-rc.1"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "postgraphile-plugin-connection-filter": {
42
+ "optional": false
43
+ },
44
+ "graphile-postgis": {
45
+ "optional": false
46
+ }
52
47
  },
53
48
  "devDependencies": {
54
- "@types/pg": "^8.16.0",
55
- "graphile-test": "^3.1.0",
56
- "graphql": "15.10.1",
57
- "makage": "^0.1.12",
58
- "pg": "^8.17.1",
59
- "pgsql-test": "^3.1.0",
60
- "postgraphile": "^4.14.1"
49
+ "@types/node": "^22.19.1",
50
+ "graphile-postgis": "^2.2.0",
51
+ "graphile-test": "^4.2.0",
52
+ "makage": "^0.1.10",
53
+ "postgraphile-plugin-connection-filter": "^3.0.0-rc.1"
61
54
  },
62
- "gitHead": "048188f6b43ffaa6146e7694b2b0d35d34cb2945"
55
+ "keywords": [
56
+ "postgraphile",
57
+ "graphql",
58
+ "postgresql",
59
+ "postgis",
60
+ "connection-filter",
61
+ "spatial",
62
+ "geometry",
63
+ "geography",
64
+ "constructive"
65
+ ],
66
+ "gitHead": "b758178b808ce0bf451e86c0bd7e92079155db7c"
63
67
  }
package/plugin.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import 'graphile-build';
2
+ import type { GraphileConfig } from 'graphile-config';
3
+ /**
4
+ * PgConnectionArgFilterPostgisOperatorsPlugin
5
+ *
6
+ * Adds PostGIS spatial filter operators to postgraphile-plugin-connection-filter.
7
+ *
8
+ * Includes:
9
+ * - ST_ function-based operators (contains, intersects, within, etc.)
10
+ * - SQL operator-based operators (&&, =, ~, etc. for bounding box ops)
11
+ *
12
+ * Requires graphile-postgis and postgraphile-plugin-connection-filter to be loaded.
13
+ */
14
+ export declare const PgConnectionArgFilterPostgisOperatorsPlugin: GraphileConfig.Plugin;
package/plugin.js ADDED
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PgConnectionArgFilterPostgisOperatorsPlugin = void 0;
7
+ require("graphile-build");
8
+ const pg_sql2_1 = __importDefault(require("pg-sql2"));
9
+ const graphile_postgis_1 = require("graphile-postgis");
10
+ const ALLOWED_SQL_OPERATORS = new Set([
11
+ '=',
12
+ '&&',
13
+ '&&&',
14
+ '&<',
15
+ '&<|',
16
+ '&>',
17
+ '|&>',
18
+ '<<',
19
+ '<<|',
20
+ '>>',
21
+ '|>>',
22
+ '~',
23
+ '~=',
24
+ ]);
25
+ /**
26
+ * PgConnectionArgFilterPostgisOperatorsPlugin
27
+ *
28
+ * Adds PostGIS spatial filter operators to postgraphile-plugin-connection-filter.
29
+ *
30
+ * Includes:
31
+ * - ST_ function-based operators (contains, intersects, within, etc.)
32
+ * - SQL operator-based operators (&&, =, ~, etc. for bounding box ops)
33
+ *
34
+ * Requires graphile-postgis and postgraphile-plugin-connection-filter to be loaded.
35
+ */
36
+ exports.PgConnectionArgFilterPostgisOperatorsPlugin = {
37
+ name: 'PgConnectionArgFilterPostgisOperatorsPlugin',
38
+ version: '2.0.0',
39
+ description: 'Adds PostGIS spatial filter operators to connection filter',
40
+ after: [
41
+ 'PostgisRegisterTypesPlugin',
42
+ 'PostgisExtensionDetectionPlugin',
43
+ 'PostgisInflectionPlugin',
44
+ 'PgConnectionArgFilterPlugin'
45
+ ],
46
+ schema: {
47
+ hooks: {
48
+ init(_, build) {
49
+ const postgisInfo = build.pgGISExtensionInfo;
50
+ if (!postgisInfo) {
51
+ return _;
52
+ }
53
+ const addConnectionFilterOperator = build.addConnectionFilterOperator;
54
+ if (typeof addConnectionFilterOperator !== 'function') {
55
+ return _;
56
+ }
57
+ const { inflection } = build;
58
+ const { schemaName, geometryCodec, geographyCodec } = postgisInfo;
59
+ // Collect all GQL type names for geometry and geography
60
+ const gqlTypeNamesByBase = {
61
+ geometry: [],
62
+ geography: []
63
+ };
64
+ const codecPairs = [['geometry', geometryCodec]];
65
+ if (geographyCodec) {
66
+ codecPairs.push(['geography', geographyCodec]);
67
+ }
68
+ for (const [baseKey, codec] of codecPairs) {
69
+ const typeName = codec.name;
70
+ gqlTypeNamesByBase[baseKey].push(inflection.gisInterfaceName(typeName));
71
+ for (const subtype of graphile_postgis_1.CONCRETE_SUBTYPES) {
72
+ for (const hasZ of [false, true]) {
73
+ for (const hasM of [false, true]) {
74
+ gqlTypeNamesByBase[baseKey].push(inflection.gisType(typeName, subtype, hasZ, hasM, 0));
75
+ }
76
+ }
77
+ }
78
+ }
79
+ // PostGIS function-based operators
80
+ const functionSpecs = [
81
+ [
82
+ 'ST_3DIntersects',
83
+ ['geometry'],
84
+ 'intersects3D',
85
+ 'They share any portion of space in 3D.'
86
+ ],
87
+ [
88
+ 'ST_Contains',
89
+ ['geometry'],
90
+ 'contains',
91
+ 'No points of the specified geometry lie in the exterior, and at least one point of the interior of the specified geometry lies in the interior.'
92
+ ],
93
+ [
94
+ 'ST_ContainsProperly',
95
+ ['geometry'],
96
+ 'containsProperly',
97
+ 'The specified geometry intersects the interior but not the boundary (or exterior).'
98
+ ],
99
+ [
100
+ 'ST_CoveredBy',
101
+ ['geometry', 'geography'],
102
+ 'coveredBy',
103
+ 'No point is outside the specified geometry.'
104
+ ],
105
+ [
106
+ 'ST_Covers',
107
+ ['geometry', 'geography'],
108
+ 'covers',
109
+ 'No point in the specified geometry is outside.'
110
+ ],
111
+ [
112
+ 'ST_Crosses',
113
+ ['geometry'],
114
+ 'crosses',
115
+ 'They have some, but not all, interior points in common.'
116
+ ],
117
+ [
118
+ 'ST_Disjoint',
119
+ ['geometry'],
120
+ 'disjoint',
121
+ 'They do not share any space together.'
122
+ ],
123
+ [
124
+ 'ST_Equals',
125
+ ['geometry'],
126
+ 'equals',
127
+ 'They represent the same geometry. Directionality is ignored.'
128
+ ],
129
+ [
130
+ 'ST_Intersects',
131
+ ['geometry', 'geography'],
132
+ 'intersects',
133
+ 'They share any portion of space in 2D.'
134
+ ],
135
+ [
136
+ 'ST_OrderingEquals',
137
+ ['geometry'],
138
+ 'orderingEquals',
139
+ 'They represent the same geometry and points are in the same directional order.'
140
+ ],
141
+ [
142
+ 'ST_Overlaps',
143
+ ['geometry'],
144
+ 'overlaps',
145
+ 'They share space, are of the same dimension, but are not completely contained by each other.'
146
+ ],
147
+ [
148
+ 'ST_Touches',
149
+ ['geometry'],
150
+ 'touches',
151
+ 'They have at least one point in common, but their interiors do not intersect.'
152
+ ],
153
+ [
154
+ 'ST_Within',
155
+ ['geometry'],
156
+ 'within',
157
+ 'Completely inside the specified geometry.'
158
+ ]
159
+ ];
160
+ // SQL operator-based operators
161
+ const operatorSpecs = [
162
+ [
163
+ '=',
164
+ ['geometry', 'geography'],
165
+ 'exactlyEquals',
166
+ 'Coordinates and coordinate order are the same as specified geometry.'
167
+ ],
168
+ [
169
+ '&&',
170
+ ['geometry', 'geography'],
171
+ 'bboxIntersects2D',
172
+ "2D bounding box intersects the specified geometry's 2D bounding box."
173
+ ],
174
+ [
175
+ '&&&',
176
+ ['geometry'],
177
+ 'bboxIntersectsND',
178
+ "n-D bounding box intersects the specified geometry's n-D bounding box."
179
+ ],
180
+ [
181
+ '&<',
182
+ ['geometry'],
183
+ 'bboxOverlapsOrLeftOf',
184
+ "Bounding box overlaps or is to the left of the specified geometry's bounding box."
185
+ ],
186
+ [
187
+ '&<|',
188
+ ['geometry'],
189
+ 'bboxOverlapsOrBelow',
190
+ "Bounding box overlaps or is below the specified geometry's bounding box."
191
+ ],
192
+ [
193
+ '&>',
194
+ ['geometry'],
195
+ 'bboxOverlapsOrRightOf',
196
+ "Bounding box overlaps or is to the right of the specified geometry's bounding box."
197
+ ],
198
+ [
199
+ '|&>',
200
+ ['geometry'],
201
+ 'bboxOverlapsOrAbove',
202
+ "Bounding box overlaps or is above the specified geometry's bounding box."
203
+ ],
204
+ [
205
+ '<<',
206
+ ['geometry'],
207
+ 'bboxLeftOf',
208
+ "Bounding box is strictly to the left of the specified geometry's bounding box."
209
+ ],
210
+ [
211
+ '<<|',
212
+ ['geometry'],
213
+ 'bboxBelow',
214
+ "Bounding box is strictly below the specified geometry's bounding box."
215
+ ],
216
+ [
217
+ '>>',
218
+ ['geometry'],
219
+ 'bboxRightOf',
220
+ "Bounding box is strictly to the right of the specified geometry's bounding box."
221
+ ],
222
+ [
223
+ '|>>',
224
+ ['geometry'],
225
+ 'bboxAbove',
226
+ "Bounding box is strictly above the specified geometry's bounding box."
227
+ ],
228
+ [
229
+ '~',
230
+ ['geometry'],
231
+ 'bboxContains',
232
+ "Bounding box contains the specified geometry's bounding box."
233
+ ],
234
+ [
235
+ '~=',
236
+ ['geometry'],
237
+ 'bboxEquals',
238
+ "Bounding box is the same as the specified geometry's bounding box."
239
+ ]
240
+ ];
241
+ const allSpecs = [];
242
+ // Process function-based operators
243
+ for (const [fn, baseTypes, operatorName, description] of functionSpecs) {
244
+ for (const baseType of baseTypes) {
245
+ const sqlGisFunction = pg_sql2_1.default.identifier(schemaName, fn.toLowerCase());
246
+ allSpecs.push({
247
+ typeNames: gqlTypeNamesByBase[baseType],
248
+ operatorName,
249
+ description,
250
+ resolve: (i, v) => pg_sql2_1.default.fragment `${sqlGisFunction}(${i}, ${v})`
251
+ });
252
+ }
253
+ }
254
+ // Process SQL operator-based operators
255
+ for (const [op, baseTypes, operatorName, description] of operatorSpecs) {
256
+ if (!ALLOWED_SQL_OPERATORS.has(op)) {
257
+ throw new Error(`Unexpected SQL operator: ${op}`);
258
+ }
259
+ for (const baseType of baseTypes) {
260
+ allSpecs.push({
261
+ typeNames: gqlTypeNamesByBase[baseType],
262
+ operatorName,
263
+ description,
264
+ resolve: (i, v) => pg_sql2_1.default.fragment `${i} ${pg_sql2_1.default.raw(op)} ${v}`
265
+ });
266
+ }
267
+ }
268
+ // Sort by operator name for deterministic schema output
269
+ allSpecs.sort((a, b) => a.operatorName.localeCompare(b.operatorName));
270
+ // Register each operator with the connection filter plugin
271
+ for (const spec of allSpecs) {
272
+ for (const typeName of spec.typeNames) {
273
+ addConnectionFilterOperator(typeName, spec.operatorName, {
274
+ description: spec.description,
275
+ resolveType: (fieldType) => fieldType,
276
+ resolve(sqlIdentifier, sqlValue, _input, _$where, _details) {
277
+ return spec.resolve(sqlIdentifier, sqlValue);
278
+ }
279
+ });
280
+ }
281
+ }
282
+ return _;
283
+ }
284
+ }
285
+ }
286
+ };
package/preset.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { GraphileConfig } from 'graphile-config';
2
+ /**
3
+ * PostGIS Connection Filter Preset
4
+ *
5
+ * Adds PostGIS spatial filter operators to postgraphile-plugin-connection-filter.
6
+ * Requires graphile-postgis and postgraphile-plugin-connection-filter to be loaded.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { GraphilePostgisPreset } from 'graphile-postgis';
11
+ * import { PostGraphileConnectionFilterPreset } from 'postgraphile-plugin-connection-filter';
12
+ * import { PostgisConnectionFilterPreset } from 'graphile-plugin-connection-filter-postgis';
13
+ *
14
+ * const preset = {
15
+ * extends: [
16
+ * GraphilePostgisPreset,
17
+ * PostGraphileConnectionFilterPreset,
18
+ * PostgisConnectionFilterPreset
19
+ * ]
20
+ * };
21
+ * ```
22
+ */
23
+ export declare const PostgisConnectionFilterPreset: GraphileConfig.Preset;
package/preset.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostgisConnectionFilterPreset = void 0;
4
+ const plugin_1 = require("./plugin");
5
+ /**
6
+ * PostGIS Connection Filter Preset
7
+ *
8
+ * Adds PostGIS spatial filter operators to postgraphile-plugin-connection-filter.
9
+ * Requires graphile-postgis and postgraphile-plugin-connection-filter to be loaded.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { GraphilePostgisPreset } from 'graphile-postgis';
14
+ * import { PostGraphileConnectionFilterPreset } from 'postgraphile-plugin-connection-filter';
15
+ * import { PostgisConnectionFilterPreset } from 'graphile-plugin-connection-filter-postgis';
16
+ *
17
+ * const preset = {
18
+ * extends: [
19
+ * GraphilePostgisPreset,
20
+ * PostGraphileConnectionFilterPreset,
21
+ * PostgisConnectionFilterPreset
22
+ * ]
23
+ * };
24
+ * ```
25
+ */
26
+ exports.PostgisConnectionFilterPreset = {
27
+ plugins: [plugin_1.PgConnectionArgFilterPostgisOperatorsPlugin]
28
+ };
package/types.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { SQL } from 'pg-sql2';
2
+ export interface PostgisFilterOperatorSpec {
3
+ /** PostGIS SQL function name (e.g. 'ST_Contains') */
4
+ sqlFunction?: string;
5
+ /** SQL operator (e.g. '&&', '=') — used instead of sqlFunction for operator-based specs */
6
+ sqlOperator?: string;
7
+ /** GraphQL filter operator name (e.g. 'contains', 'bboxIntersects2D') */
8
+ operatorName: string;
9
+ /** Human-readable description of the operator */
10
+ description: string;
11
+ /** Which base types this operator applies to: 'geometry', 'geography', or both */
12
+ baseTypes: ('geometry' | 'geography')[];
13
+ }
14
+ export interface ResolvedFilterSpec {
15
+ /** GraphQL type names this operator applies to (interface + all concrete types) */
16
+ typeNames: string[];
17
+ /** GraphQL filter operator name */
18
+ operatorName: string;
19
+ /** Description */
20
+ description: string;
21
+ /** SQL resolve function: (identifier, value) => SQL expression */
22
+ resolve: (i: SQL, v: SQL) => SQL;
23
+ }
package/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +0,0 @@
1
- import type { Plugin } from "graphile-build";
2
- declare const PgConnectionArgFilterPostgisOperatorsPlugin: Plugin;
3
- export default PgConnectionArgFilterPostgisOperatorsPlugin;