graphile-postgis 1.1.1 → 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/README.md +22 -45
- package/constants.d.ts +1 -0
- package/constants.js +10 -1
- package/esm/constants.d.ts +13 -0
- package/esm/constants.js +9 -0
- package/esm/index.d.ts +24 -0
- package/esm/index.js +25 -33
- package/esm/plugins/codec.d.ts +19 -0
- package/esm/plugins/codec.js +174 -0
- package/esm/plugins/detect-extension.d.ts +14 -0
- package/esm/plugins/detect-extension.js +57 -0
- package/esm/plugins/geometry-fields.d.ts +21 -0
- package/esm/plugins/geometry-fields.js +245 -0
- package/esm/plugins/inflection.d.ts +8 -0
- package/esm/plugins/inflection.js +52 -0
- package/esm/plugins/register-types.d.ts +22 -0
- package/esm/plugins/register-types.js +319 -0
- package/esm/preset.d.ts +18 -0
- package/esm/preset.js +30 -0
- package/esm/types.d.ts +84 -0
- package/esm/utils.d.ts +21 -0
- package/esm/utils.js +18 -7
- package/index.d.ts +24 -15
- package/index.js +39 -47
- package/package.json +23 -18
- package/plugins/codec.d.ts +19 -0
- package/plugins/codec.js +180 -0
- package/plugins/detect-extension.d.ts +14 -0
- package/plugins/detect-extension.js +60 -0
- package/plugins/geometry-fields.d.ts +21 -0
- package/plugins/geometry-fields.js +248 -0
- package/plugins/inflection.d.ts +8 -0
- package/plugins/inflection.js +55 -0
- package/plugins/register-types.d.ts +22 -0
- package/plugins/register-types.js +325 -0
- package/preset.d.ts +18 -0
- package/preset.js +33 -0
- package/types.d.ts +69 -44
- package/utils.d.ts +16 -0
- package/utils.js +17 -6
- package/PostgisExtensionDetectionPlugin.d.ts +0 -3
- package/PostgisExtensionDetectionPlugin.js +0 -28
- package/PostgisInflectionPlugin.d.ts +0 -3
- package/PostgisInflectionPlugin.js +0 -36
- package/PostgisRegisterTypesPlugin.d.ts +0 -3
- package/PostgisRegisterTypesPlugin.js +0 -234
- package/PostgisVersionPlugin.d.ts +0 -3
- package/PostgisVersionPlugin.js +0 -24
- package/Postgis_GeometryCollection_GeometriesPlugin.d.ts +0 -3
- package/Postgis_GeometryCollection_GeometriesPlugin.js +0 -43
- package/Postgis_LineString_PointsPlugin.d.ts +0 -3
- package/Postgis_LineString_PointsPlugin.js +0 -40
- package/Postgis_MultiLineString_LineStringsPlugin.d.ts +0 -3
- package/Postgis_MultiLineString_LineStringsPlugin.js +0 -38
- package/Postgis_MultiPoint_PointsPlugin.d.ts +0 -3
- package/Postgis_MultiPoint_PointsPlugin.js +0 -38
- package/Postgis_MultiPolygon_PolygonsPlugin.d.ts +0 -3
- package/Postgis_MultiPolygon_PolygonsPlugin.js +0 -38
- package/Postgis_Point_LatitudeLongitudePlugin.d.ts +0 -3
- package/Postgis_Point_LatitudeLongitudePlugin.js +0 -43
- package/Postgis_Polygon_RingsPlugin.d.ts +0 -3
- package/Postgis_Polygon_RingsPlugin.js +0 -49
- package/esm/PostgisExtensionDetectionPlugin.js +0 -26
- package/esm/PostgisInflectionPlugin.js +0 -34
- package/esm/PostgisRegisterTypesPlugin.js +0 -229
- package/esm/PostgisVersionPlugin.js +0 -22
- package/esm/Postgis_GeometryCollection_GeometriesPlugin.js +0 -41
- package/esm/Postgis_LineString_PointsPlugin.js +0 -38
- package/esm/Postgis_MultiLineString_LineStringsPlugin.js +0 -36
- package/esm/Postgis_MultiPoint_PointsPlugin.js +0 -36
- package/esm/Postgis_MultiPolygon_PolygonsPlugin.js +0 -36
- package/esm/Postgis_Point_LatitudeLongitudePlugin.js +0 -41
- package/esm/Postgis_Polygon_RingsPlugin.js +0 -47
- package/esm/makeGeoJSONType.js +0 -39
- package/makeGeoJSONType.d.ts +0 -1
- package/makeGeoJSONType.js +0 -42
package/esm/preset.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PostgisCodecPlugin } from './plugins/codec';
|
|
2
|
+
import { PostgisInflectionPlugin } from './plugins/inflection';
|
|
3
|
+
import { PostgisExtensionDetectionPlugin } from './plugins/detect-extension';
|
|
4
|
+
import { PostgisRegisterTypesPlugin } from './plugins/register-types';
|
|
5
|
+
import { PostgisGeometryFieldsPlugin } from './plugins/geometry-fields';
|
|
6
|
+
/**
|
|
7
|
+
* GraphilePostgisPreset
|
|
8
|
+
*
|
|
9
|
+
* A preset that includes all PostGIS plugins for PostGraphile v5.
|
|
10
|
+
* Use this as the recommended way to add PostGIS support.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { GraphilePostgisPreset } from 'graphile-postgis';
|
|
15
|
+
*
|
|
16
|
+
* const preset = {
|
|
17
|
+
* extends: [GraphilePostgisPreset]
|
|
18
|
+
* };
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const GraphilePostgisPreset = {
|
|
22
|
+
plugins: [
|
|
23
|
+
PostgisCodecPlugin,
|
|
24
|
+
PostgisInflectionPlugin,
|
|
25
|
+
PostgisExtensionDetectionPlugin,
|
|
26
|
+
PostgisRegisterTypesPlugin,
|
|
27
|
+
PostgisGeometryFieldsPlugin
|
|
28
|
+
]
|
|
29
|
+
};
|
|
30
|
+
export default GraphilePostgisPreset;
|
package/esm/types.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { PgCodec } from '@dataplan/pg';
|
|
2
|
+
import type { Geometry } from 'geojson';
|
|
3
|
+
import type { GraphQLInterfaceType, GraphQLObjectType } from 'graphql';
|
|
4
|
+
import type { SQL } from 'pg-sql2';
|
|
5
|
+
import type { GisSubtype } from './constants';
|
|
6
|
+
export interface GisTypeDetails {
|
|
7
|
+
subtype: GisSubtype;
|
|
8
|
+
hasZ: boolean;
|
|
9
|
+
hasM: boolean;
|
|
10
|
+
srid: number;
|
|
11
|
+
}
|
|
12
|
+
export interface GisFieldValue {
|
|
13
|
+
__gisType: string;
|
|
14
|
+
__srid: number;
|
|
15
|
+
__geojson: Geometry;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* PostGIS extension detection result stored on the build object.
|
|
19
|
+
*/
|
|
20
|
+
export interface PostgisExtensionInfo {
|
|
21
|
+
/** The schema name where PostGIS is installed (e.g. 'public') */
|
|
22
|
+
schemaName: string;
|
|
23
|
+
/** The geometry codec from the registry */
|
|
24
|
+
geometryCodec: PgCodec;
|
|
25
|
+
/** The geography codec from the registry (optional — not all databases use geography columns) */
|
|
26
|
+
geographyCodec: PgCodec | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Module augmentations for PostGraphile v5 types.
|
|
30
|
+
*
|
|
31
|
+
* These declare the custom properties that our PostGIS plugins add to the
|
|
32
|
+
* build object, inflection, and scope interfaces. This allows downstream
|
|
33
|
+
* code (including our own plugins) to use these properties without `any` casts.
|
|
34
|
+
*/
|
|
35
|
+
declare global {
|
|
36
|
+
namespace GraphileBuild {
|
|
37
|
+
interface Build {
|
|
38
|
+
/** PostGIS extension info (set by PostgisExtensionDetectionPlugin) */
|
|
39
|
+
pgGISExtensionInfo?: PostgisExtensionInfo;
|
|
40
|
+
/** Map of codec name -> gisTypeKey -> GraphQL type name (for resolveType) */
|
|
41
|
+
pgGISGraphQLTypesByCodecAndSubtype?: Record<string, Record<string | number, string>>;
|
|
42
|
+
/** Gets a registered PostGIS GraphQL type by geometry type, subtype, and dimension */
|
|
43
|
+
getPostgisTypeByGeometryType?(gisCodecName: string, subtype: GisSubtype, hasZ?: boolean, hasM?: boolean, srid?: number): GraphQLObjectType | GraphQLInterfaceType | undefined;
|
|
44
|
+
/** Wraps a geometry/geography SQL expression in json_build_object() with metadata */
|
|
45
|
+
pgGISWrapExpression?(fragment: SQL): SQL;
|
|
46
|
+
/** Creates an SQL fragment to convert GeoJSON input to a geometry value */
|
|
47
|
+
pgGISFromGeoJSON?(value: Record<string, unknown>, codecName: string): SQL;
|
|
48
|
+
}
|
|
49
|
+
interface Inflection {
|
|
50
|
+
/** Generate GraphQL type name for a PostGIS concrete type */
|
|
51
|
+
gisType(typeName: string, subtype: GisSubtype, hasZ: boolean, hasM: boolean, srid?: number): string;
|
|
52
|
+
/** Generate interface name for a PostGIS base type (e.g. GeometryInterface) */
|
|
53
|
+
gisInterfaceName(typeName: string): string;
|
|
54
|
+
/** Generate dimension interface name (e.g. GeometryGeometryZ) */
|
|
55
|
+
gisDimensionInterfaceName(typeName: string, hasZ: boolean, hasM: boolean): string;
|
|
56
|
+
/** Generate GeoJSON field name */
|
|
57
|
+
geojsonFieldName(): string;
|
|
58
|
+
/** Generate X coordinate field name */
|
|
59
|
+
gisXFieldName(typeName: string): string;
|
|
60
|
+
/** Generate Y coordinate field name */
|
|
61
|
+
gisYFieldName(typeName: string): string;
|
|
62
|
+
/** Generate Z coordinate field name */
|
|
63
|
+
gisZFieldName(typeName: string): string;
|
|
64
|
+
}
|
|
65
|
+
interface ScopeObject {
|
|
66
|
+
/** Whether this is a PostGIS concrete type */
|
|
67
|
+
isPgGISType?: boolean;
|
|
68
|
+
/** The codec name (geometry/geography) this type belongs to */
|
|
69
|
+
pgGISCodecName?: string;
|
|
70
|
+
/** The type details (subtype, hasZ, hasM, srid) */
|
|
71
|
+
pgGISTypeDetails?: GisTypeDetails;
|
|
72
|
+
}
|
|
73
|
+
interface ScopeInterface {
|
|
74
|
+
/** Whether this is a PostGIS base interface */
|
|
75
|
+
isPgGISInterface?: boolean;
|
|
76
|
+
/** Whether this is a PostGIS dimension interface */
|
|
77
|
+
isPgGISDimensionInterface?: boolean;
|
|
78
|
+
/** The codec name (geometry/geography) this interface belongs to */
|
|
79
|
+
pgGISCodecName?: string;
|
|
80
|
+
/** The ZM flag (-1 for base, 0-3 for dimension) */
|
|
81
|
+
pgGISZMFlag?: number;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
package/esm/utils.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GisSubtype } from './constants';
|
|
2
|
+
import type { GisTypeDetails } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Decodes a PostGIS type modifier into its component parts.
|
|
5
|
+
*
|
|
6
|
+
* Implements the C macro bit layout from liblwgeom.h:
|
|
7
|
+
* - SRID: bits 8-28
|
|
8
|
+
* - Subtype: bits 2-7
|
|
9
|
+
* - hasZ: bit 1
|
|
10
|
+
* - hasM: bit 0
|
|
11
|
+
*/
|
|
12
|
+
export declare const getGISTypeDetails: (modifier: number) => GisTypeDetails;
|
|
13
|
+
/**
|
|
14
|
+
* Encodes PostGIS type details into a type modifier integer.
|
|
15
|
+
*/
|
|
16
|
+
export declare const getGISTypeModifier: (subtype: GisSubtype, hasZ: boolean, hasM: boolean, srid: number) => number;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the GIS type name string for a given subtype and Z/M flags.
|
|
19
|
+
* E.g. "PointZ", "MultiPolygonZM", "LineString"
|
|
20
|
+
*/
|
|
21
|
+
export declare const getGISTypeName: (subtype: GisSubtype, hasZ: boolean, hasM: boolean) => string;
|
package/esm/utils.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GisSubtype, GIS_SUBTYPE_NAME } from './constants';
|
|
2
|
+
/**
|
|
3
|
+
* Decodes a PostGIS type modifier into its component parts.
|
|
4
|
+
*
|
|
5
|
+
* Implements the C macro bit layout from liblwgeom.h:
|
|
6
|
+
* - SRID: bits 8-28
|
|
7
|
+
* - Subtype: bits 2-7
|
|
8
|
+
* - hasZ: bit 1
|
|
9
|
+
* - hasM: bit 0
|
|
10
|
+
*/
|
|
2
11
|
export const getGISTypeDetails = (modifier) => {
|
|
3
12
|
const allZeroesHopefully = modifier >> 24;
|
|
4
13
|
if (allZeroesHopefully !== 0) {
|
|
@@ -24,13 +33,11 @@ export const getGISTypeDetails = (modifier) => {
|
|
|
24
33
|
throw new Error(`Unsupported PostGIS modifier, expected 0-7, received ${subtypeNumeric} (${modifier})`);
|
|
25
34
|
}
|
|
26
35
|
const subtype = subtypeNumeric;
|
|
27
|
-
return {
|
|
28
|
-
subtype,
|
|
29
|
-
hasZ,
|
|
30
|
-
hasM,
|
|
31
|
-
srid
|
|
32
|
-
};
|
|
36
|
+
return { subtype, hasZ, hasM, srid };
|
|
33
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* Encodes PostGIS type details into a type modifier integer.
|
|
40
|
+
*/
|
|
34
41
|
export const getGISTypeModifier = (subtype, hasZ, hasM, srid) => {
|
|
35
42
|
// Ref: https://github.com/postgis/postgis/blob/2.5.2/liblwgeom/liblwgeom.h.in#L156-L173
|
|
36
43
|
// #define TYPMOD_SET_SRID(typmod, srid) ((typmod) = (((typmod) & 0xE00000FF) | ((srid & 0x001FFFFF)<<8)))
|
|
@@ -42,6 +49,10 @@ export const getGISTypeModifier = (subtype, hasZ, hasM, srid) => {
|
|
|
42
49
|
(hasZ ? 0x00000002 : 0) +
|
|
43
50
|
(hasM ? 0x00000001 : 0));
|
|
44
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Returns the GIS type name string for a given subtype and Z/M flags.
|
|
54
|
+
* E.g. "PointZ", "MultiPolygonZM", "LineString"
|
|
55
|
+
*/
|
|
45
56
|
export const getGISTypeName = (subtype, hasZ, hasM) => {
|
|
46
57
|
return `${GIS_SUBTYPE_NAME[subtype]}${hasZ ? 'Z' : ''}${hasM ? 'M' : ''}`;
|
|
47
58
|
};
|
package/index.d.ts
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export
|
|
1
|
+
/**
|
|
2
|
+
* PostGraphile v5 PostGIS Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides PostGIS geometry/geography type support for PostGraphile v5.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { GraphilePostgisPreset } from 'graphile-postgis';
|
|
9
|
+
*
|
|
10
|
+
* const preset = {
|
|
11
|
+
* extends: [GraphilePostgisPreset]
|
|
12
|
+
* };
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export { GraphilePostgisPreset } from './preset';
|
|
16
|
+
export { PostgisCodecPlugin } from './plugins/codec';
|
|
17
|
+
export { PostgisInflectionPlugin } from './plugins/inflection';
|
|
18
|
+
export { PostgisExtensionDetectionPlugin } from './plugins/detect-extension';
|
|
19
|
+
export { PostgisRegisterTypesPlugin } from './plugins/register-types';
|
|
20
|
+
export { PostgisGeometryFieldsPlugin } from './plugins/geometry-fields';
|
|
21
|
+
export { GisSubtype, SUBTYPE_STRING_BY_SUBTYPE, GIS_SUBTYPE_NAME, CONCRETE_SUBTYPES } from './constants';
|
|
22
|
+
export { getGISTypeDetails, getGISTypeModifier, getGISTypeName } from './utils';
|
|
23
|
+
export type { GisTypeDetails, GisFieldValue } from './types';
|
|
24
|
+
export type { PostgisExtensionInfo } from './plugins/detect-extension';
|
package/index.js
CHANGED
|
@@ -1,49 +1,41 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
/**
|
|
3
|
+
* PostGraphile v5 PostGIS Plugin
|
|
4
|
+
*
|
|
5
|
+
* Provides PostGIS geometry/geography type support for PostGraphile v5.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { GraphilePostgisPreset } from 'graphile-postgis';
|
|
10
|
+
*
|
|
11
|
+
* const preset = {
|
|
12
|
+
* extends: [GraphilePostgisPreset]
|
|
13
|
+
* };
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
exports
|
|
13
|
-
|
|
14
|
-
exports
|
|
15
|
-
|
|
16
|
-
exports
|
|
17
|
-
|
|
18
|
-
exports
|
|
19
|
-
|
|
20
|
-
exports
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
exports
|
|
25
|
-
|
|
26
|
-
exports
|
|
27
|
-
|
|
28
|
-
exports
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
await (0, PostgisInflectionPlugin_1.default)(builder, options);
|
|
32
|
-
await (0, PostgisExtensionDetectionPlugin_1.default)(builder, options);
|
|
33
|
-
await (0, PostgisRegisterTypesPlugin_1.default)(builder, options);
|
|
34
|
-
// Enhancing the `Point` type:
|
|
35
|
-
await (0, Postgis_Point_LatitudeLongitudePlugin_1.default)(builder, options);
|
|
36
|
-
// Enhancing the `LineString` type:
|
|
37
|
-
await (0, Postgis_LineString_PointsPlugin_1.default)(builder, options);
|
|
38
|
-
// Enhancing the `Polygon` type:
|
|
39
|
-
await (0, Postgis_Polygon_RingsPlugin_1.default)(builder, options);
|
|
40
|
-
// Enhancing the `MultiPoint` type:
|
|
41
|
-
await (0, Postgis_MultiPoint_PointsPlugin_1.default)(builder, options);
|
|
42
|
-
// Enhancing the `MultiLineString` type:
|
|
43
|
-
await (0, Postgis_MultiLineString_LineStringsPlugin_1.default)(builder, options);
|
|
44
|
-
// Enhancing the `MultiPolygon` type:
|
|
45
|
-
await (0, Postgis_MultiPolygon_PolygonsPlugin_1.default)(builder, options);
|
|
46
|
-
// Enhancing the `GeometryCollection` type:
|
|
47
|
-
await (0, Postgis_GeometryCollection_GeometriesPlugin_1.default)(builder, options);
|
|
48
|
-
};
|
|
49
|
-
exports.default = PostgisPlugin;
|
|
17
|
+
exports.getGISTypeName = exports.getGISTypeModifier = exports.getGISTypeDetails = exports.CONCRETE_SUBTYPES = exports.GIS_SUBTYPE_NAME = exports.SUBTYPE_STRING_BY_SUBTYPE = exports.GisSubtype = exports.PostgisGeometryFieldsPlugin = exports.PostgisRegisterTypesPlugin = exports.PostgisExtensionDetectionPlugin = exports.PostgisInflectionPlugin = exports.PostgisCodecPlugin = exports.GraphilePostgisPreset = void 0;
|
|
18
|
+
// Preset (recommended entry point)
|
|
19
|
+
var preset_1 = require("./preset");
|
|
20
|
+
Object.defineProperty(exports, "GraphilePostgisPreset", { enumerable: true, get: function () { return preset_1.GraphilePostgisPreset; } });
|
|
21
|
+
// Individual plugins
|
|
22
|
+
var codec_1 = require("./plugins/codec");
|
|
23
|
+
Object.defineProperty(exports, "PostgisCodecPlugin", { enumerable: true, get: function () { return codec_1.PostgisCodecPlugin; } });
|
|
24
|
+
var inflection_1 = require("./plugins/inflection");
|
|
25
|
+
Object.defineProperty(exports, "PostgisInflectionPlugin", { enumerable: true, get: function () { return inflection_1.PostgisInflectionPlugin; } });
|
|
26
|
+
var detect_extension_1 = require("./plugins/detect-extension");
|
|
27
|
+
Object.defineProperty(exports, "PostgisExtensionDetectionPlugin", { enumerable: true, get: function () { return detect_extension_1.PostgisExtensionDetectionPlugin; } });
|
|
28
|
+
var register_types_1 = require("./plugins/register-types");
|
|
29
|
+
Object.defineProperty(exports, "PostgisRegisterTypesPlugin", { enumerable: true, get: function () { return register_types_1.PostgisRegisterTypesPlugin; } });
|
|
30
|
+
var geometry_fields_1 = require("./plugins/geometry-fields");
|
|
31
|
+
Object.defineProperty(exports, "PostgisGeometryFieldsPlugin", { enumerable: true, get: function () { return geometry_fields_1.PostgisGeometryFieldsPlugin; } });
|
|
32
|
+
// Constants and utilities
|
|
33
|
+
var constants_1 = require("./constants");
|
|
34
|
+
Object.defineProperty(exports, "GisSubtype", { enumerable: true, get: function () { return constants_1.GisSubtype; } });
|
|
35
|
+
Object.defineProperty(exports, "SUBTYPE_STRING_BY_SUBTYPE", { enumerable: true, get: function () { return constants_1.SUBTYPE_STRING_BY_SUBTYPE; } });
|
|
36
|
+
Object.defineProperty(exports, "GIS_SUBTYPE_NAME", { enumerable: true, get: function () { return constants_1.GIS_SUBTYPE_NAME; } });
|
|
37
|
+
Object.defineProperty(exports, "CONCRETE_SUBTYPES", { enumerable: true, get: function () { return constants_1.CONCRETE_SUBTYPES; } });
|
|
38
|
+
var utils_1 = require("./utils");
|
|
39
|
+
Object.defineProperty(exports, "getGISTypeDetails", { enumerable: true, get: function () { return utils_1.getGISTypeDetails; } });
|
|
40
|
+
Object.defineProperty(exports, "getGISTypeModifier", { enumerable: true, get: function () { return utils_1.getGISTypeModifier; } });
|
|
41
|
+
Object.defineProperty(exports, "getGISTypeName", { enumerable: true, get: function () { return utils_1.getGISTypeName; } });
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphile-postgis",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.2.0",
|
|
4
|
+
"description": "PostGIS support for PostGraphile v5",
|
|
5
5
|
"author": "Constructive <developers@constructive.io>",
|
|
6
6
|
"homepage": "https://github.com/constructive-io/constructive",
|
|
7
7
|
"license": "MIT",
|
|
@@ -10,12 +10,11 @@
|
|
|
10
10
|
"types": "index.d.ts",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"clean": "makage clean",
|
|
13
|
-
"
|
|
14
|
-
"prepack": "pnpm run build",
|
|
13
|
+
"prepack": "npm run build",
|
|
15
14
|
"build": "makage build",
|
|
16
15
|
"build:dev": "makage build --dev",
|
|
17
16
|
"lint": "eslint . --fix",
|
|
18
|
-
"test": "jest
|
|
17
|
+
"test": "jest",
|
|
19
18
|
"test:watch": "jest --watch"
|
|
20
19
|
},
|
|
21
20
|
"publishConfig": {
|
|
@@ -33,24 +32,30 @@
|
|
|
33
32
|
"postgres",
|
|
34
33
|
"graphql",
|
|
35
34
|
"constructive",
|
|
36
|
-
"pgpm"
|
|
35
|
+
"pgpm",
|
|
36
|
+
"geojson",
|
|
37
|
+
"geometry",
|
|
38
|
+
"geography"
|
|
37
39
|
],
|
|
38
40
|
"bugs": {
|
|
39
41
|
"url": "https://github.com/constructive-io/constructive/issues"
|
|
40
42
|
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@dataplan/pg": "^1.0.0-rc.5",
|
|
45
|
+
"grafast": "^1.0.0-rc.7",
|
|
46
|
+
"graphile-build": "^5.0.0-rc.4",
|
|
47
|
+
"graphile-build-pg": "^5.0.0-rc.5",
|
|
48
|
+
"graphile-config": "^1.0.0-rc.5",
|
|
49
|
+
"graphql": "^16.9.0",
|
|
50
|
+
"pg-sql2": "^5.0.0-rc.4",
|
|
51
|
+
"postgraphile": "^5.0.0-rc.4"
|
|
52
|
+
},
|
|
41
53
|
"devDependencies": {
|
|
42
54
|
"@types/geojson": "^7946.0.14",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"find-and-require-package-json": "^0.9.0",
|
|
49
|
-
"graphile-build": "^4.14.1",
|
|
50
|
-
"graphile-build-pg": "^4.14.1",
|
|
51
|
-
"graphile-utils": "^4.14.1",
|
|
52
|
-
"graphql": "15.10.1",
|
|
53
|
-
"pg": "^8.17.1"
|
|
55
|
+
"@types/node": "^22.19.1",
|
|
56
|
+
"graphile-test": "^4.2.0",
|
|
57
|
+
"makage": "^0.1.10",
|
|
58
|
+
"pgsql-test": "^4.2.0"
|
|
54
59
|
},
|
|
55
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "b758178b808ce0bf451e86c0bd7e92079155db7c"
|
|
56
61
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import 'graphile-build-pg';
|
|
2
|
+
import type { GraphileConfig } from 'graphile-config';
|
|
3
|
+
/**
|
|
4
|
+
* PostgisCodecPlugin
|
|
5
|
+
*
|
|
6
|
+
* Teaches PostGraphile v5 how to handle PostgreSQL's geometry and geography types.
|
|
7
|
+
*
|
|
8
|
+
* This plugin:
|
|
9
|
+
* 1. Creates codecs for geometry/geography via gather.hooks.pgCodecs_findPgCodec
|
|
10
|
+
* 2. The registered codecs use castFromPg to wrap geometry values in
|
|
11
|
+
* json_build_object() with __gisType, __srid, __geojson metadata
|
|
12
|
+
* 3. fromPg normalizes the geometry type names for resolveType lookups
|
|
13
|
+
*
|
|
14
|
+
* Without castFromPg, PostGraphile defaults to `column::text` which returns
|
|
15
|
+
* WKB hex — unusable for GraphQL. The json_build_object wrapper provides
|
|
16
|
+
* structured metadata that downstream plugins use for type resolution and
|
|
17
|
+
* field values (x/y coordinates, GeoJSON, SRID, etc.).
|
|
18
|
+
*/
|
|
19
|
+
export declare const PostgisCodecPlugin: GraphileConfig.Plugin;
|
package/plugins/codec.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
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.PostgisCodecPlugin = void 0;
|
|
7
|
+
require("graphile-build-pg");
|
|
8
|
+
const pg_sql2_1 = __importDefault(require("pg-sql2"));
|
|
9
|
+
/**
|
|
10
|
+
* Map from PostGIS uppercase geometry type names (from geometrytype()) to
|
|
11
|
+
* our mixed-case format used by resolveType lookups.
|
|
12
|
+
*
|
|
13
|
+
* PostGIS `geometrytype()` returns uppercase: 'POINT', 'POINTZ', 'MULTIPOLYGON', etc.
|
|
14
|
+
* Our GIS_SUBTYPE_NAME uses mixed case: 'Point', 'LineString', 'MultiPolygon', etc.
|
|
15
|
+
* The getGISTypeName() utility produces: 'Point', 'PointZ', 'MultiPolygonZM', etc.
|
|
16
|
+
*/
|
|
17
|
+
const GIS_TYPE_NORMALIZE = {
|
|
18
|
+
POINT: 'Point',
|
|
19
|
+
POINTZ: 'PointZ',
|
|
20
|
+
POINTM: 'PointM',
|
|
21
|
+
POINTZM: 'PointZM',
|
|
22
|
+
LINESTRING: 'LineString',
|
|
23
|
+
LINESTRINGZ: 'LineStringZ',
|
|
24
|
+
LINESTRINGM: 'LineStringM',
|
|
25
|
+
LINESTRINGZM: 'LineStringZM',
|
|
26
|
+
POLYGON: 'Polygon',
|
|
27
|
+
POLYGONZ: 'PolygonZ',
|
|
28
|
+
POLYGONM: 'PolygonM',
|
|
29
|
+
POLYGONZM: 'PolygonZM',
|
|
30
|
+
MULTIPOINT: 'MultiPoint',
|
|
31
|
+
MULTIPOINTZ: 'MultiPointZ',
|
|
32
|
+
MULTIPOINTM: 'MultiPointM',
|
|
33
|
+
MULTIPOINTZM: 'MultiPointZM',
|
|
34
|
+
MULTILINESTRING: 'MultiLineString',
|
|
35
|
+
MULTILINESTRINGZ: 'MultiLineStringZ',
|
|
36
|
+
MULTILINESTRINGM: 'MultiLineStringM',
|
|
37
|
+
MULTILINESTRINGZM: 'MultiLineStringZM',
|
|
38
|
+
MULTIPOLYGON: 'MultiPolygon',
|
|
39
|
+
MULTIPOLYGONZ: 'MultiPolygonZ',
|
|
40
|
+
MULTIPOLYGONM: 'MultiPolygonM',
|
|
41
|
+
MULTIPOLYGONZM: 'MultiPolygonZM',
|
|
42
|
+
GEOMETRYCOLLECTION: 'GeometryCollection',
|
|
43
|
+
GEOMETRYCOLLECTIONZ: 'GeometryCollectionZ',
|
|
44
|
+
GEOMETRYCOLLECTIONM: 'GeometryCollectionM',
|
|
45
|
+
GEOMETRYCOLLECTIONZM: 'GeometryCollectionZM'
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Normalize the __gisType from PostGIS uppercase to our mixed-case format.
|
|
49
|
+
* Falls back to the raw value if not in the map.
|
|
50
|
+
*/
|
|
51
|
+
function normalizeGisType(raw) {
|
|
52
|
+
return GIS_TYPE_NORMALIZE[raw] ?? raw;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a codec for a PostGIS geometry or geography type.
|
|
56
|
+
*
|
|
57
|
+
* The codec:
|
|
58
|
+
* - castFromPg: wraps the SQL column in json_build_object() with __gisType,
|
|
59
|
+
* __srid, and __geojson fields (using PostGIS functions ST_SRID, ST_AsGeoJSON,
|
|
60
|
+
* geometrytype). This replaces the default ::text cast.
|
|
61
|
+
* - fromPg: parses the JSON text result and normalizes __gisType case.
|
|
62
|
+
* - toPg: converts GeoJSON input back to a PostGIS-compatible value using
|
|
63
|
+
* ST_GeomFromGeoJSON.
|
|
64
|
+
*/
|
|
65
|
+
function buildGisCodec(typeName, schemaName, typeOid, serviceName) {
|
|
66
|
+
return {
|
|
67
|
+
name: typeName,
|
|
68
|
+
sqlType: pg_sql2_1.default.identifier(schemaName, typeName),
|
|
69
|
+
/**
|
|
70
|
+
* castFromPg replaces the default `::text` cast. PostGraphile calls this
|
|
71
|
+
* to determine the SQL expression for selecting the column value.
|
|
72
|
+
*
|
|
73
|
+
* We wrap in json_build_object() so the result contains:
|
|
74
|
+
* - __gisType: geometry subtype name (e.g. "POINT", "POLYGON")
|
|
75
|
+
* - __srid: spatial reference ID
|
|
76
|
+
* - __geojson: the GeoJSON representation
|
|
77
|
+
*
|
|
78
|
+
* The result is cast to ::text so PostgreSQL sends it as a string,
|
|
79
|
+
* which fromPg then JSON.parses.
|
|
80
|
+
*/
|
|
81
|
+
// NOTE: `fragment` is evaluated 4 times in the SQL. This is acceptable because
|
|
82
|
+
// PostGraphile v5 always passes simple column references here.
|
|
83
|
+
// If this changes, consider wrapping in a LATERAL subexpression.
|
|
84
|
+
castFromPg(fragment) {
|
|
85
|
+
return pg_sql2_1.default.fragment `(case when (${fragment}) is null then null else json_build_object(
|
|
86
|
+
'__gisType', ${pg_sql2_1.default.identifier(schemaName, 'geometrytype')}(${fragment}),
|
|
87
|
+
'__srid', ${pg_sql2_1.default.identifier(schemaName, 'st_srid')}(${fragment}),
|
|
88
|
+
'__geojson', ${pg_sql2_1.default.identifier(schemaName, 'st_asgeojson')}(${fragment})::json
|
|
89
|
+
)::text end)`;
|
|
90
|
+
},
|
|
91
|
+
/**
|
|
92
|
+
* fromPg receives the text value from PostgreSQL (output of castFromPg)
|
|
93
|
+
* and converts it to a JavaScript object.
|
|
94
|
+
*
|
|
95
|
+
* If castFromPg is working correctly, the value is always valid JSON.
|
|
96
|
+
* We normalize __gisType from PostGIS uppercase to our mixed-case format.
|
|
97
|
+
*/
|
|
98
|
+
fromPg(value) {
|
|
99
|
+
let parsed;
|
|
100
|
+
try {
|
|
101
|
+
parsed = JSON.parse(value);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
throw new Error(`Failed to parse PostGIS geometry value: ${e instanceof Error ? e.message : String(e)}. ` +
|
|
105
|
+
`Raw value (first 200 chars): ${String(value).slice(0, 200)}`);
|
|
106
|
+
}
|
|
107
|
+
if (parsed && typeof parsed === 'object' && parsed.__gisType) {
|
|
108
|
+
parsed.__gisType = normalizeGisType(parsed.__gisType);
|
|
109
|
+
}
|
|
110
|
+
return parsed;
|
|
111
|
+
},
|
|
112
|
+
/**
|
|
113
|
+
* toPg serializes a JavaScript value for insertion into PostgreSQL.
|
|
114
|
+
* Accepts GeoJSON objects and converts them to a JSON string that
|
|
115
|
+
* PostgreSQL can process via ST_GeomFromGeoJSON.
|
|
116
|
+
*/
|
|
117
|
+
toPg(value) {
|
|
118
|
+
if (value && typeof value === 'object' && '__geojson' in value) {
|
|
119
|
+
return JSON.stringify(value.__geojson);
|
|
120
|
+
}
|
|
121
|
+
return JSON.stringify(value);
|
|
122
|
+
},
|
|
123
|
+
attributes: undefined,
|
|
124
|
+
executor: undefined,
|
|
125
|
+
extensions: {
|
|
126
|
+
oid: typeOid,
|
|
127
|
+
pg: {
|
|
128
|
+
serviceName,
|
|
129
|
+
schemaName,
|
|
130
|
+
name: typeName
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* PostgisCodecPlugin
|
|
137
|
+
*
|
|
138
|
+
* Teaches PostGraphile v5 how to handle PostgreSQL's geometry and geography types.
|
|
139
|
+
*
|
|
140
|
+
* This plugin:
|
|
141
|
+
* 1. Creates codecs for geometry/geography via gather.hooks.pgCodecs_findPgCodec
|
|
142
|
+
* 2. The registered codecs use castFromPg to wrap geometry values in
|
|
143
|
+
* json_build_object() with __gisType, __srid, __geojson metadata
|
|
144
|
+
* 3. fromPg normalizes the geometry type names for resolveType lookups
|
|
145
|
+
*
|
|
146
|
+
* Without castFromPg, PostGraphile defaults to `column::text` which returns
|
|
147
|
+
* WKB hex — unusable for GraphQL. The json_build_object wrapper provides
|
|
148
|
+
* structured metadata that downstream plugins use for type resolution and
|
|
149
|
+
* field values (x/y coordinates, GeoJSON, SRID, etc.).
|
|
150
|
+
*/
|
|
151
|
+
exports.PostgisCodecPlugin = {
|
|
152
|
+
name: 'PostgisCodecPlugin',
|
|
153
|
+
version: '2.0.0',
|
|
154
|
+
description: 'Registers codecs for PostGIS geometry and geography types',
|
|
155
|
+
gather: {
|
|
156
|
+
hooks: {
|
|
157
|
+
async pgCodecs_findPgCodec(info, event) {
|
|
158
|
+
if (event.pgCodec) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const { pgType: type, serviceName } = event;
|
|
162
|
+
// Find the namespace for this type by its OID
|
|
163
|
+
const typeNamespace = await info.helpers.pgIntrospection.getNamespace(serviceName, type.typnamespace);
|
|
164
|
+
if (!typeNamespace) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
// We look for geometry/geography types in any schema (PostGIS can be
|
|
168
|
+
// installed in different schemas, commonly 'public' or 'postgis')
|
|
169
|
+
if (type.typname === 'geometry') {
|
|
170
|
+
event.pgCodec = buildGisCodec('geometry', typeNamespace.nspname, type._id, serviceName);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (type.typname === 'geography') {
|
|
174
|
+
event.pgCodec = buildGisCodec('geography', typeNamespace.nspname, type._id, serviceName);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import 'graphile-build';
|
|
2
|
+
import 'graphile-build-pg';
|
|
3
|
+
import type { GraphileConfig } from 'graphile-config';
|
|
4
|
+
export type { PostgisExtensionInfo } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* PostgisExtensionDetectionPlugin
|
|
7
|
+
*
|
|
8
|
+
* Detects PostGIS presence in the database by searching for geometry/geography
|
|
9
|
+
* codecs in the pgRegistry. Stores detected info on the build object for
|
|
10
|
+
* downstream plugins.
|
|
11
|
+
*
|
|
12
|
+
* Gracefully degrades if PostGIS is not installed.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PostgisExtensionDetectionPlugin: GraphileConfig.Plugin;
|