├── .circleci └── config.yml ├── .gitignore ├── .prettierrc.js ├── .travis.yml ├── README.md ├── __tests__ ├── __snapshots__ │ ├── schema.minimal_dimensional.test.ts.snap │ ├── schema.minimal_type.test.ts.snap │ ├── schema.minimal_type_and_srid.test.ts.snap │ ├── schema.minimal_unconstrained.test.ts.snap │ └── schema.test.ts.snap ├── fixtures │ └── queries │ │ ├── geog.graphql │ │ ├── geog_geometry.graphql │ │ ├── geog_geometrym.graphql │ │ ├── geog_geometryz.graphql │ │ ├── geog_geometryzm.graphql │ │ ├── geog_linestring.graphql │ │ ├── geog_linestringm.graphql │ │ ├── geog_linestringz.graphql │ │ ├── geog_linestringzm.graphql │ │ ├── geog_multilinestring.graphql │ │ ├── geog_multilinestringm.graphql │ │ ├── geog_multilinestringz.graphql │ │ ├── geog_multilinestringzm.graphql │ │ ├── geog_multipoint.graphql │ │ ├── geog_multipointm.graphql │ │ ├── geog_multipointz.graphql │ │ ├── geog_multipointzm.graphql │ │ ├── geog_multipolygon.graphql │ │ ├── geog_multipolygonm.graphql │ │ ├── geog_multipolygonz.graphql │ │ ├── geog_multipolygonzm.graphql │ │ ├── geog_point.graphql │ │ ├── geog_pointm.graphql │ │ ├── geog_pointz.graphql │ │ ├── geog_pointzm.graphql │ │ ├── geog_polygon.graphql │ │ ├── geog_polygonm.graphql │ │ ├── geog_polygonz.graphql │ │ ├── geog_polygonzm.graphql │ │ ├── geom.graphql │ │ ├── geom_geometry.graphql │ │ ├── geom_geometrym.graphql │ │ ├── geom_geometryz.graphql │ │ ├── geom_geometryzm.graphql │ │ ├── geom_linestring.graphql │ │ ├── geom_linestringm.graphql │ │ ├── geom_linestringz.graphql │ │ ├── geom_linestringzm.graphql │ │ ├── geom_multilinestring.graphql │ │ ├── geom_multilinestringm.graphql │ │ ├── geom_multilinestringz.graphql │ │ ├── geom_multilinestringzm.graphql │ │ ├── geom_multipoint.graphql │ │ ├── geom_multipointm.graphql │ │ ├── geom_multipointz.graphql │ │ ├── geom_multipointzm.graphql │ │ ├── geom_multipolygon.graphql │ │ ├── geom_multipolygonm.graphql │ │ ├── geom_multipolygonz.graphql │ │ ├── geom_multipolygonzm.graphql │ │ ├── geom_point.graphql │ │ ├── geom_pointm.graphql │ │ ├── geom_pointz.graphql │ │ ├── geom_pointzm.graphql │ │ ├── geom_polygon.graphql │ │ ├── geom_polygonm.graphql │ │ ├── geom_polygonz.graphql │ │ ├── geom_polygonzm.graphql │ │ ├── srid.geography.graphql │ │ └── srid.geometry.graphql ├── helpers.ts ├── integration │ ├── __snapshots__ │ │ └── queries.test.ts.snap │ └── queries.test.ts ├── schema.minimal_dimensional.test.ts ├── schema.minimal_type.test.ts ├── schema.minimal_type_and_srid.test.ts ├── schema.minimal_unconstrained.test.ts ├── schema.sql └── schema.test.ts ├── jest.config.js ├── package.json ├── scripts └── test ├── src ├── NOTES.md ├── PostgisExtensionDetectionPlugin.ts ├── PostgisInflectionPlugin.ts ├── PostgisRegisterTypesPlugin.ts ├── PostgisVersionPlugin.ts ├── Postgis_GeometryCollection_GeometriesPlugin.ts ├── Postgis_LineString_PointsPlugin.ts ├── Postgis_MultiLineString_LineStringsPlugin.ts ├── Postgis_MultiPoint_PointsPlugin.ts ├── Postgis_MultiPolygon_PolygonsPlugin.ts ├── Postgis_Point_LatitudeLongitudePlugin.ts ├── Postgis_Polygon_RingsPlugin.ts ├── constants.ts ├── debug.ts ├── index.ts ├── interfaces.ts ├── makeGeoJSONType.ts └── utils.ts ├── tsconfig.json ├── tslint.json └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | node10_pg9.6postgis: 4 | docker: 5 | - image: circleci/node:10 6 | - image: circleci/postgres:9.6-alpine-postgis 7 | environment: 8 | POSTGRES_HOST_AUTH_METHOD: trust 9 | POSTGRES_USER: circleci 10 | POSTGRES_DB: circle_test 11 | steps: 12 | - checkout 13 | - run: sudo apt update 14 | - run: sudo apt install -y postgresql-client 15 | - restore_cache: 16 | keys: 17 | - yarn-packages-{{ checksum "yarn.lock" }} 18 | - run: 19 | command: yarn install --frozen-lockfile 20 | - save_cache: 21 | key: yarn-packages-{{ checksum "yarn.lock" }} 22 | paths: 23 | - ~/.cache/yarn 24 | - run: yarn lint 25 | - run: 26 | command: yarn test 27 | environment: 28 | TEST_DATABASE_URL: postgres://circleci@localhost:5432/circle_test 29 | node10_pg10postgis: 30 | docker: 31 | - image: circleci/node:10 32 | - image: circleci/postgres:10-alpine-postgis 33 | environment: 34 | POSTGRES_HOST_AUTH_METHOD: trust 35 | POSTGRES_USER: circleci 36 | POSTGRES_DB: circle_test 37 | steps: 38 | - checkout 39 | - run: sudo apt update 40 | - run: sudo apt install -y postgresql-client 41 | - restore_cache: 42 | keys: 43 | - yarn-packages-{{ checksum "yarn.lock" }} 44 | - run: 45 | command: yarn install --frozen-lockfile 46 | - save_cache: 47 | key: yarn-packages-{{ checksum "yarn.lock" }} 48 | paths: 49 | - ~/.cache/yarn 50 | - run: yarn lint 51 | - run: 52 | command: yarn test 53 | environment: 54 | TEST_DATABASE_URL: postgres://circleci@localhost:5432/circle_test 55 | node12_pg11postgis: 56 | docker: 57 | - image: circleci/node:12 58 | - image: circleci/postgres:11-alpine-postgis 59 | environment: 60 | POSTGRES_HOST_AUTH_METHOD: trust 61 | POSTGRES_USER: circleci 62 | POSTGRES_DB: circle_test 63 | steps: 64 | - checkout 65 | - run: sudo apt update 66 | - run: sudo apt install -y postgresql-client 67 | - restore_cache: 68 | keys: 69 | - yarn-packages-{{ checksum "yarn.lock" }} 70 | - run: 71 | command: yarn install --frozen-lockfile 72 | - save_cache: 73 | key: yarn-packages-{{ checksum "yarn.lock" }} 74 | paths: 75 | - ~/.cache/yarn 76 | - run: yarn lint 77 | - run: 78 | command: yarn test 79 | environment: 80 | TEST_DATABASE_URL: postgres://circleci@localhost:5432/circle_test 81 | workflows: 82 | version: 2 83 | test: 84 | jobs: 85 | - node10_pg9.6postgis 86 | - node10_pg10postgis 87 | - node12_pg11postgis 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: "es5" 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "10" 5 | 6 | addons: 7 | postgresql: "9.4" 8 | apt: 9 | packages: 10 | - postgresql-server-dev-9.4 11 | - postgresql-9.4-postgis-2.4 12 | 13 | env: 14 | TEST_DATABASE_URL: postgres://localhost:5432/travis 15 | PGVERSION: 9.4 16 | 17 | cache: yarn 18 | 19 | install: 20 | - yarn install 21 | 22 | before_script: 23 | - psql -c "ALTER USER travis WITH PASSWORD 'travis';" 24 | 25 | script: 26 | - yarn test 27 | 28 | matrix: 29 | include: 30 | - addons: 31 | apt: 32 | packages: 33 | - postgresql-10 34 | - postgresql-client-10 35 | - postgresql-server-dev-10 36 | - postgresql-10-postgis-2.4 37 | - postgresql-10-postgis-2.4-scripts 38 | - postgis 39 | postgresql: 10 40 | env: 41 | - PGPORT=5433 42 | - TEST_DATABASE_URL=postgres://travis:travis@localhost:5433/travis 43 | - PGVERSION=10 44 | sudo: false 45 | dist: trusty 46 | - name: "Lint" 47 | addons: skip 48 | before_script: skip 49 | script: yarn lint 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @graphile/postgis 2 | 3 | This is a [PostGraphile schema 4 | plugin](https://www.graphile.org/postgraphile/extending/) that provides 5 | support for the popular [PostGIS](http://postgis.net/) spatial database 6 | system. 7 | 8 | Create a [PostgreSQL](https://www.postgresql.org/) database with PostGIS 9 | columns, run [PostGraphile](https://www.graphile.org/postgraphile/) with this 10 | plugin, and have a fully functional geospatial-aware 11 | [GraphQL](http://graphql.org/) API for your database. 12 | 13 | ## Roadmap 14 | 15 | Work is ongoing, here's the plan: 16 | 17 | - [x] Read-only support for `geojson` field from all geography types (via a shared GraphQL interface) 18 | - [x] Add GraphQL types for all the expected geography types (implementing this interface) 19 | - [x] Read-only support for determining the geometry sub-types of columns and exposing these directly (rather than the interface) 20 | - [x] Read-only support for `longitude` and `latitude` on `geography(POINT)` columns 21 | - [x] Read-only support for viewing the list of `geometries` in a `geography(GEOMETRYCOLLECTION)` 22 | - [x] Read-only support for a list of points (`longitude` and `latitude`) on 23 | `geography(LINESTRING)` and `geography(POLYGON)` columns 24 | - [x] Create/update/null support for `geography(POINT)` columns 25 | - [x] Create/update/null support for `geography(LINESTRING)` and `geography(POLYGON)` columns 26 | - [x] Integration with `postgraphile-plugin-connection-filter` to enable PostGIS specific filtering (via [postgraphile-plugin-connection-filter-postgis](https://github.com/mattbretl/postgraphile-plugin-connection-filter-postgis/)) 27 | - [ ] Read-only support for computed attributes on 28 | `geography(LINESTRING)` and `geography(POLYGON)`, such as `area`, 29 | `length`, `perimeter`, and `centroid` - currently possible by adding a plugin and consuming the GeoJSON directly. 30 | 31 | There are many, many other features that this plugin could support - if you 32 | have specific needs please get in touch! 33 | 34 | ## Usage 35 | 36 | This plugin requires PostGraphile **v4.4.0** or higher to function correctly. 37 | 38 | Add PostGIS to your database: 39 | 40 | ```sql 41 | CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA public; 42 | ``` 43 | 44 | Load the plugin: 45 | 46 | ``` 47 | postgraphile --append-plugins @graphile/postgis 48 | ``` 49 | 50 | #### Querying and mutating 51 | 52 | Using this table as example: 53 | 54 | ```sql 55 | CREATE TABLE data ( 56 | id UUID PRIMARY KEY DEFAULT uuid_generate_v1mc(), 57 | geom_point geometry(Point, 4326) default null 58 | ); 59 | ``` 60 | 61 | In **queries** `geom_point` is represented as type `GeometryPoint`. Example: 62 | 63 | ```graphql 64 | query { 65 | allDatas { 66 | nodes { 67 | geomPoint { 68 | geojson 69 | srid 70 | x 71 | y 72 | } 73 | } 74 | } 75 | } 76 | ``` 77 | 78 | In **mutations** `geom_point` is represented as type `GeoJSON`. Example: 79 | 80 | ```graphql 81 | mutation ($id: UUID!, $geomPoint: GeoJSON!) { 82 | updateDataById( 83 | input: { 84 | id: $id, 85 | dataPatch: { 86 | geomPoint: $geomPoint 87 | } 88 | } 89 | ) { ... } 90 | } 91 | ``` 92 | 93 | with these variables: 94 | 95 | ```json 96 | { 97 | "id": "0116254a-0146-11ea-8418-4f89d6596247", 98 | "geomPoint": { 99 | "type": "Point", 100 | "coordinates": [8.5, 47.5] 101 | } 102 | } 103 | ``` 104 | 105 | Beware of the fact that since 2016 the `GeoJSON` spec expects the coordinates to be of SRID 4326/WGS84 (see https://tools.ietf.org/html/rfc7946#section-4). So adding a `crs` field to the GeoJSON is deprecated. Thus since v3 PostGIS will be happy to receive above GeoJSON. 106 | 107 | **In earlier versions PostGIS expects a SRID to be passed**. So the variables would be: 108 | 109 | ```json 110 | { 111 | "id": "0116254a-0146-11ea-8418-4f89d6596247", 112 | "geomPoint": { 113 | "type": "Point", 114 | "coordinates": [8.5, 47.5], 115 | "crs": { 116 | "type": "name", 117 | "properties": { 118 | "name": "urn:ogc:def:crs:EPSG::4326" 119 | } 120 | } 121 | } 122 | } 123 | ``` 124 | 125 | ## Development 126 | 127 | Contributions are extremely welcome! To get started, clone down this repo and then: 128 | 129 | ``` 130 | createdb graphile_test 131 | export TEST_DATABASE_URL=postgres://localhost:5432/graphile_test 132 | yarn 133 | yarn dev 134 | ``` 135 | 136 | Note the development server runs at http://localhost:5123/graphiql 137 | 138 | To run the tests: 139 | 140 | ``` 141 | yarn test 142 | ``` 143 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/schema.minimal_dimensional.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`prints a schema with this plugin 1`] = ` 4 | """All input for the create \`Foo\` mutation.""" 5 | input CreateFooInput { 6 | """ 7 | An arbitrary string value with no semantic meaning. Will be included in the 8 | payload verbatim. May be used to track mutations by the client. 9 | """ 10 | clientMutationId: String 11 | 12 | """The \`Foo\` to be created by this mutation.""" 13 | foo: FooInput! 14 | } 15 | 16 | """The output of our create \`Foo\` mutation.""" 17 | type CreateFooPayload { 18 | """ 19 | The exact same \`clientMutationId\` that was provided in the mutation input, 20 | unchanged and unused. May be used by a client to track mutations. 21 | """ 22 | clientMutationId: String 23 | 24 | """The \`Foo\` that was created by this mutation.""" 25 | foo: Foo 26 | 27 | """An edge for our \`Foo\`. May be used by Relay 1.""" 28 | fooEdge( 29 | """The method to use when ordering \`Foo\`.""" 30 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 31 | ): FoosEdge 32 | 33 | """ 34 | Our root query field type. Allows us to run any query from our mutation payload. 35 | """ 36 | query: Query 37 | } 38 | 39 | """A location in a connection that can be used for resuming pagination.""" 40 | scalar Cursor 41 | 42 | """All input for the \`deleteFooById\` mutation.""" 43 | input DeleteFooByIdInput { 44 | """ 45 | An arbitrary string value with no semantic meaning. Will be included in the 46 | payload verbatim. May be used to track mutations by the client. 47 | """ 48 | clientMutationId: String 49 | id: Int! 50 | } 51 | 52 | """All input for the \`deleteFoo\` mutation.""" 53 | input DeleteFooInput { 54 | """ 55 | An arbitrary string value with no semantic meaning. Will be included in the 56 | payload verbatim. May be used to track mutations by the client. 57 | """ 58 | clientMutationId: String 59 | 60 | """ 61 | The globally unique \`ID\` which will identify a single \`Foo\` to be deleted. 62 | """ 63 | nodeId: ID! 64 | } 65 | 66 | """The output of our delete \`Foo\` mutation.""" 67 | type DeleteFooPayload { 68 | """ 69 | The exact same \`clientMutationId\` that was provided in the mutation input, 70 | unchanged and unused. May be used by a client to track mutations. 71 | """ 72 | clientMutationId: String 73 | deletedFooId: ID 74 | 75 | """The \`Foo\` that was deleted by this mutation.""" 76 | foo: Foo 77 | 78 | """An edge for our \`Foo\`. May be used by Relay 1.""" 79 | fooEdge( 80 | """The method to use when ordering \`Foo\`.""" 81 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 82 | ): FoosEdge 83 | 84 | """ 85 | Our root query field type. Allows us to run any query from our mutation payload. 86 | """ 87 | query: Query 88 | } 89 | 90 | type Foo implements Node { 91 | geomGeometry: GeometryGeometry 92 | id: Int! 93 | 94 | """ 95 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 96 | """ 97 | nodeId: ID! 98 | } 99 | 100 | """ 101 | A condition to be used against \`Foo\` object types. All fields are tested for equality and combined with a logical ‘and.’ 102 | """ 103 | input FooCondition { 104 | """Checks for equality with the object’s \`geomGeometry\` field.""" 105 | geomGeometry: GeoJSON 106 | 107 | """Checks for equality with the object’s \`id\` field.""" 108 | id: Int 109 | } 110 | 111 | """An input for mutations affecting \`Foo\`""" 112 | input FooInput { 113 | geomGeometry: GeoJSON 114 | id: Int 115 | } 116 | 117 | """Represents an update to a \`Foo\`. Fields that are set will be updated.""" 118 | input FooPatch { 119 | geomGeometry: GeoJSON 120 | id: Int 121 | } 122 | 123 | """A connection to a list of \`Foo\` values.""" 124 | type FoosConnection { 125 | """ 126 | A list of edges which contains the \`Foo\` and cursor to aid in pagination. 127 | """ 128 | edges: [FoosEdge!]! 129 | 130 | """A list of \`Foo\` objects.""" 131 | nodes: [Foo]! 132 | 133 | """Information to aid in pagination.""" 134 | pageInfo: PageInfo! 135 | 136 | """The count of *all* \`Foo\` you could get from the connection.""" 137 | totalCount: Int! 138 | } 139 | 140 | """A \`Foo\` edge in the connection.""" 141 | type FoosEdge { 142 | """A cursor for use in pagination.""" 143 | cursor: Cursor 144 | 145 | """The \`Foo\` at the end of the edge.""" 146 | node: Foo 147 | } 148 | 149 | """Methods to use when ordering \`Foo\`.""" 150 | enum FoosOrderBy { 151 | GEOM_GEOMETRY_ASC 152 | GEOM_GEOMETRY_DESC 153 | ID_ASC 154 | ID_DESC 155 | NATURAL 156 | PRIMARY_KEY_ASC 157 | PRIMARY_KEY_DESC 158 | } 159 | 160 | """ 161 | The \`GeoJSON\` scalar type represents GeoJSON values as specified by[RFC 7946](https://tools.ietf.org/html/rfc7946). 162 | """ 163 | scalar GeoJSON 164 | 165 | """All geometry XY types implement this interface""" 166 | interface GeometryGeometry { 167 | """Converts the object to GeoJSON""" 168 | geojson: GeoJSON 169 | 170 | """Spatial reference identifier (SRID)""" 171 | srid: Int! 172 | } 173 | 174 | type GeometryGeometryCollection implements GeometryGeometry & GeometryInterface { 175 | geojson: GeoJSON 176 | geometries: [GeometryGeometry] 177 | srid: Int! 178 | } 179 | 180 | """All geometry types implement this interface""" 181 | interface GeometryInterface { 182 | """Converts the object to GeoJSON""" 183 | geojson: GeoJSON 184 | 185 | """Spatial reference identifier (SRID)""" 186 | srid: Int! 187 | } 188 | 189 | type GeometryLineString implements GeometryGeometry & GeometryInterface { 190 | geojson: GeoJSON 191 | points: [GeometryPoint] 192 | srid: Int! 193 | } 194 | 195 | type GeometryMultiLineString implements GeometryGeometry & GeometryInterface { 196 | geojson: GeoJSON 197 | lines: [GeometryLineString] 198 | srid: Int! 199 | } 200 | 201 | type GeometryMultiPoint implements GeometryGeometry & GeometryInterface { 202 | geojson: GeoJSON 203 | points: [GeometryPoint] 204 | srid: Int! 205 | } 206 | 207 | type GeometryMultiPolygon implements GeometryGeometry & GeometryInterface { 208 | geojson: GeoJSON 209 | polygons: [GeometryPolygon] 210 | srid: Int! 211 | } 212 | 213 | type GeometryPoint implements GeometryGeometry & GeometryInterface { 214 | geojson: GeoJSON 215 | srid: Int! 216 | x: Float! 217 | y: Float! 218 | } 219 | 220 | type GeometryPolygon implements GeometryGeometry & GeometryInterface { 221 | exterior: GeometryLineString 222 | geojson: GeoJSON 223 | interiors: [GeometryLineString] 224 | srid: Int! 225 | } 226 | 227 | """ 228 | The root mutation type which contains root level fields which mutate data. 229 | """ 230 | type Mutation { 231 | """Creates a single \`Foo\`.""" 232 | createFoo( 233 | """ 234 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 235 | """ 236 | input: CreateFooInput! 237 | ): CreateFooPayload 238 | 239 | """Deletes a single \`Foo\` using its globally unique id.""" 240 | deleteFoo( 241 | """ 242 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 243 | """ 244 | input: DeleteFooInput! 245 | ): DeleteFooPayload 246 | 247 | """Deletes a single \`Foo\` using a unique key.""" 248 | deleteFooById( 249 | """ 250 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 251 | """ 252 | input: DeleteFooByIdInput! 253 | ): DeleteFooPayload 254 | 255 | """Updates a single \`Foo\` using its globally unique id and a patch.""" 256 | updateFoo( 257 | """ 258 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 259 | """ 260 | input: UpdateFooInput! 261 | ): UpdateFooPayload 262 | 263 | """Updates a single \`Foo\` using a unique key and a patch.""" 264 | updateFooById( 265 | """ 266 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 267 | """ 268 | input: UpdateFooByIdInput! 269 | ): UpdateFooPayload 270 | } 271 | 272 | """An object with a globally unique \`ID\`.""" 273 | interface Node { 274 | """ 275 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 276 | """ 277 | nodeId: ID! 278 | } 279 | 280 | """Information about pagination in a connection.""" 281 | type PageInfo { 282 | """When paginating forwards, the cursor to continue.""" 283 | endCursor: Cursor 284 | 285 | """When paginating forwards, are there more items?""" 286 | hasNextPage: Boolean! 287 | 288 | """When paginating backwards, are there more items?""" 289 | hasPreviousPage: Boolean! 290 | 291 | """When paginating backwards, the cursor to continue.""" 292 | startCursor: Cursor 293 | } 294 | 295 | """The root query type which gives access points into the data universe.""" 296 | type Query implements Node { 297 | """Reads and enables pagination through a set of \`Foo\`.""" 298 | allFoos( 299 | """Read all values in the set after (below) this cursor.""" 300 | after: Cursor 301 | 302 | """Read all values in the set before (above) this cursor.""" 303 | before: Cursor 304 | 305 | """ 306 | A condition to be used in determining which values should be returned by the collection. 307 | """ 308 | condition: FooCondition 309 | 310 | """Only read the first \`n\` values of the set.""" 311 | first: Int 312 | 313 | """Only read the last \`n\` values of the set.""" 314 | last: Int 315 | 316 | """ 317 | Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor 318 | based pagination. May not be used with \`last\`. 319 | """ 320 | offset: Int 321 | 322 | """The method to use when ordering \`Foo\`.""" 323 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 324 | ): FoosConnection 325 | 326 | """Reads a single \`Foo\` using its globally unique \`ID\`.""" 327 | foo( 328 | """The globally unique \`ID\` to be used in selecting a single \`Foo\`.""" 329 | nodeId: ID! 330 | ): Foo 331 | fooById(id: Int!): Foo 332 | 333 | """Fetches an object given its globally unique \`ID\`.""" 334 | node( 335 | """The globally unique \`ID\`.""" 336 | nodeId: ID! 337 | ): Node 338 | 339 | """ 340 | The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`. 341 | """ 342 | nodeId: ID! 343 | 344 | """ 345 | Exposes the root query type nested one level down. This is helpful for Relay 1 346 | which can only query top level fields if they are in a particular form. 347 | """ 348 | query: Query! 349 | } 350 | 351 | """All input for the \`updateFooById\` mutation.""" 352 | input UpdateFooByIdInput { 353 | """ 354 | An arbitrary string value with no semantic meaning. Will be included in the 355 | payload verbatim. May be used to track mutations by the client. 356 | """ 357 | clientMutationId: String 358 | 359 | """ 360 | An object where the defined keys will be set on the \`Foo\` being updated. 361 | """ 362 | fooPatch: FooPatch! 363 | id: Int! 364 | } 365 | 366 | """All input for the \`updateFoo\` mutation.""" 367 | input UpdateFooInput { 368 | """ 369 | An arbitrary string value with no semantic meaning. Will be included in the 370 | payload verbatim. May be used to track mutations by the client. 371 | """ 372 | clientMutationId: String 373 | 374 | """ 375 | An object where the defined keys will be set on the \`Foo\` being updated. 376 | """ 377 | fooPatch: FooPatch! 378 | 379 | """ 380 | The globally unique \`ID\` which will identify a single \`Foo\` to be updated. 381 | """ 382 | nodeId: ID! 383 | } 384 | 385 | """The output of our update \`Foo\` mutation.""" 386 | type UpdateFooPayload { 387 | """ 388 | The exact same \`clientMutationId\` that was provided in the mutation input, 389 | unchanged and unused. May be used by a client to track mutations. 390 | """ 391 | clientMutationId: String 392 | 393 | """The \`Foo\` that was updated by this mutation.""" 394 | foo: Foo 395 | 396 | """An edge for our \`Foo\`. May be used by Relay 1.""" 397 | fooEdge( 398 | """The method to use when ordering \`Foo\`.""" 399 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 400 | ): FoosEdge 401 | 402 | """ 403 | Our root query field type. Allows us to run any query from our mutation payload. 404 | """ 405 | query: Query 406 | } 407 | 408 | `; 409 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/schema.minimal_type.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`prints a schema with this plugin 1`] = ` 4 | """All input for the create \`Foo\` mutation.""" 5 | input CreateFooInput { 6 | """ 7 | An arbitrary string value with no semantic meaning. Will be included in the 8 | payload verbatim. May be used to track mutations by the client. 9 | """ 10 | clientMutationId: String 11 | 12 | """The \`Foo\` to be created by this mutation.""" 13 | foo: FooInput! 14 | } 15 | 16 | """The output of our create \`Foo\` mutation.""" 17 | type CreateFooPayload { 18 | """ 19 | The exact same \`clientMutationId\` that was provided in the mutation input, 20 | unchanged and unused. May be used by a client to track mutations. 21 | """ 22 | clientMutationId: String 23 | 24 | """The \`Foo\` that was created by this mutation.""" 25 | foo: Foo 26 | 27 | """An edge for our \`Foo\`. May be used by Relay 1.""" 28 | fooEdge( 29 | """The method to use when ordering \`Foo\`.""" 30 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 31 | ): FoosEdge 32 | 33 | """ 34 | Our root query field type. Allows us to run any query from our mutation payload. 35 | """ 36 | query: Query 37 | } 38 | 39 | """A location in a connection that can be used for resuming pagination.""" 40 | scalar Cursor 41 | 42 | """All input for the \`deleteFooById\` mutation.""" 43 | input DeleteFooByIdInput { 44 | """ 45 | An arbitrary string value with no semantic meaning. Will be included in the 46 | payload verbatim. May be used to track mutations by the client. 47 | """ 48 | clientMutationId: String 49 | id: Int! 50 | } 51 | 52 | """All input for the \`deleteFoo\` mutation.""" 53 | input DeleteFooInput { 54 | """ 55 | An arbitrary string value with no semantic meaning. Will be included in the 56 | payload verbatim. May be used to track mutations by the client. 57 | """ 58 | clientMutationId: String 59 | 60 | """ 61 | The globally unique \`ID\` which will identify a single \`Foo\` to be deleted. 62 | """ 63 | nodeId: ID! 64 | } 65 | 66 | """The output of our delete \`Foo\` mutation.""" 67 | type DeleteFooPayload { 68 | """ 69 | The exact same \`clientMutationId\` that was provided in the mutation input, 70 | unchanged and unused. May be used by a client to track mutations. 71 | """ 72 | clientMutationId: String 73 | deletedFooId: ID 74 | 75 | """The \`Foo\` that was deleted by this mutation.""" 76 | foo: Foo 77 | 78 | """An edge for our \`Foo\`. May be used by Relay 1.""" 79 | fooEdge( 80 | """The method to use when ordering \`Foo\`.""" 81 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 82 | ): FoosEdge 83 | 84 | """ 85 | Our root query field type. Allows us to run any query from our mutation payload. 86 | """ 87 | query: Query 88 | } 89 | 90 | type Foo implements Node { 91 | geomPoint: GeometryPoint 92 | id: Int! 93 | 94 | """ 95 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 96 | """ 97 | nodeId: ID! 98 | } 99 | 100 | """ 101 | A condition to be used against \`Foo\` object types. All fields are tested for equality and combined with a logical ‘and.’ 102 | """ 103 | input FooCondition { 104 | """Checks for equality with the object’s \`geomPoint\` field.""" 105 | geomPoint: GeoJSON 106 | 107 | """Checks for equality with the object’s \`id\` field.""" 108 | id: Int 109 | } 110 | 111 | """An input for mutations affecting \`Foo\`""" 112 | input FooInput { 113 | geomPoint: GeoJSON 114 | id: Int 115 | } 116 | 117 | """Represents an update to a \`Foo\`. Fields that are set will be updated.""" 118 | input FooPatch { 119 | geomPoint: GeoJSON 120 | id: Int 121 | } 122 | 123 | """A connection to a list of \`Foo\` values.""" 124 | type FoosConnection { 125 | """ 126 | A list of edges which contains the \`Foo\` and cursor to aid in pagination. 127 | """ 128 | edges: [FoosEdge!]! 129 | 130 | """A list of \`Foo\` objects.""" 131 | nodes: [Foo]! 132 | 133 | """Information to aid in pagination.""" 134 | pageInfo: PageInfo! 135 | 136 | """The count of *all* \`Foo\` you could get from the connection.""" 137 | totalCount: Int! 138 | } 139 | 140 | """A \`Foo\` edge in the connection.""" 141 | type FoosEdge { 142 | """A cursor for use in pagination.""" 143 | cursor: Cursor 144 | 145 | """The \`Foo\` at the end of the edge.""" 146 | node: Foo 147 | } 148 | 149 | """Methods to use when ordering \`Foo\`.""" 150 | enum FoosOrderBy { 151 | GEOM_POINT_ASC 152 | GEOM_POINT_DESC 153 | ID_ASC 154 | ID_DESC 155 | NATURAL 156 | PRIMARY_KEY_ASC 157 | PRIMARY_KEY_DESC 158 | } 159 | 160 | """ 161 | The \`GeoJSON\` scalar type represents GeoJSON values as specified by[RFC 7946](https://tools.ietf.org/html/rfc7946). 162 | """ 163 | scalar GeoJSON 164 | 165 | """All geometry XY types implement this interface""" 166 | interface GeometryGeometry { 167 | """Converts the object to GeoJSON""" 168 | geojson: GeoJSON 169 | 170 | """Spatial reference identifier (SRID)""" 171 | srid: Int! 172 | } 173 | 174 | """All geometry types implement this interface""" 175 | interface GeometryInterface { 176 | """Converts the object to GeoJSON""" 177 | geojson: GeoJSON 178 | 179 | """Spatial reference identifier (SRID)""" 180 | srid: Int! 181 | } 182 | 183 | type GeometryPoint implements GeometryGeometry & GeometryInterface { 184 | geojson: GeoJSON 185 | srid: Int! 186 | x: Float! 187 | y: Float! 188 | } 189 | 190 | """ 191 | The root mutation type which contains root level fields which mutate data. 192 | """ 193 | type Mutation { 194 | """Creates a single \`Foo\`.""" 195 | createFoo( 196 | """ 197 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 198 | """ 199 | input: CreateFooInput! 200 | ): CreateFooPayload 201 | 202 | """Deletes a single \`Foo\` using its globally unique id.""" 203 | deleteFoo( 204 | """ 205 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 206 | """ 207 | input: DeleteFooInput! 208 | ): DeleteFooPayload 209 | 210 | """Deletes a single \`Foo\` using a unique key.""" 211 | deleteFooById( 212 | """ 213 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 214 | """ 215 | input: DeleteFooByIdInput! 216 | ): DeleteFooPayload 217 | 218 | """Updates a single \`Foo\` using its globally unique id and a patch.""" 219 | updateFoo( 220 | """ 221 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 222 | """ 223 | input: UpdateFooInput! 224 | ): UpdateFooPayload 225 | 226 | """Updates a single \`Foo\` using a unique key and a patch.""" 227 | updateFooById( 228 | """ 229 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 230 | """ 231 | input: UpdateFooByIdInput! 232 | ): UpdateFooPayload 233 | } 234 | 235 | """An object with a globally unique \`ID\`.""" 236 | interface Node { 237 | """ 238 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 239 | """ 240 | nodeId: ID! 241 | } 242 | 243 | """Information about pagination in a connection.""" 244 | type PageInfo { 245 | """When paginating forwards, the cursor to continue.""" 246 | endCursor: Cursor 247 | 248 | """When paginating forwards, are there more items?""" 249 | hasNextPage: Boolean! 250 | 251 | """When paginating backwards, are there more items?""" 252 | hasPreviousPage: Boolean! 253 | 254 | """When paginating backwards, the cursor to continue.""" 255 | startCursor: Cursor 256 | } 257 | 258 | """The root query type which gives access points into the data universe.""" 259 | type Query implements Node { 260 | """Reads and enables pagination through a set of \`Foo\`.""" 261 | allFoos( 262 | """Read all values in the set after (below) this cursor.""" 263 | after: Cursor 264 | 265 | """Read all values in the set before (above) this cursor.""" 266 | before: Cursor 267 | 268 | """ 269 | A condition to be used in determining which values should be returned by the collection. 270 | """ 271 | condition: FooCondition 272 | 273 | """Only read the first \`n\` values of the set.""" 274 | first: Int 275 | 276 | """Only read the last \`n\` values of the set.""" 277 | last: Int 278 | 279 | """ 280 | Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor 281 | based pagination. May not be used with \`last\`. 282 | """ 283 | offset: Int 284 | 285 | """The method to use when ordering \`Foo\`.""" 286 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 287 | ): FoosConnection 288 | 289 | """Reads a single \`Foo\` using its globally unique \`ID\`.""" 290 | foo( 291 | """The globally unique \`ID\` to be used in selecting a single \`Foo\`.""" 292 | nodeId: ID! 293 | ): Foo 294 | fooById(id: Int!): Foo 295 | 296 | """Fetches an object given its globally unique \`ID\`.""" 297 | node( 298 | """The globally unique \`ID\`.""" 299 | nodeId: ID! 300 | ): Node 301 | 302 | """ 303 | The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`. 304 | """ 305 | nodeId: ID! 306 | 307 | """ 308 | Exposes the root query type nested one level down. This is helpful for Relay 1 309 | which can only query top level fields if they are in a particular form. 310 | """ 311 | query: Query! 312 | } 313 | 314 | """All input for the \`updateFooById\` mutation.""" 315 | input UpdateFooByIdInput { 316 | """ 317 | An arbitrary string value with no semantic meaning. Will be included in the 318 | payload verbatim. May be used to track mutations by the client. 319 | """ 320 | clientMutationId: String 321 | 322 | """ 323 | An object where the defined keys will be set on the \`Foo\` being updated. 324 | """ 325 | fooPatch: FooPatch! 326 | id: Int! 327 | } 328 | 329 | """All input for the \`updateFoo\` mutation.""" 330 | input UpdateFooInput { 331 | """ 332 | An arbitrary string value with no semantic meaning. Will be included in the 333 | payload verbatim. May be used to track mutations by the client. 334 | """ 335 | clientMutationId: String 336 | 337 | """ 338 | An object where the defined keys will be set on the \`Foo\` being updated. 339 | """ 340 | fooPatch: FooPatch! 341 | 342 | """ 343 | The globally unique \`ID\` which will identify a single \`Foo\` to be updated. 344 | """ 345 | nodeId: ID! 346 | } 347 | 348 | """The output of our update \`Foo\` mutation.""" 349 | type UpdateFooPayload { 350 | """ 351 | The exact same \`clientMutationId\` that was provided in the mutation input, 352 | unchanged and unused. May be used by a client to track mutations. 353 | """ 354 | clientMutationId: String 355 | 356 | """The \`Foo\` that was updated by this mutation.""" 357 | foo: Foo 358 | 359 | """An edge for our \`Foo\`. May be used by Relay 1.""" 360 | fooEdge( 361 | """The method to use when ordering \`Foo\`.""" 362 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 363 | ): FoosEdge 364 | 365 | """ 366 | Our root query field type. Allows us to run any query from our mutation payload. 367 | """ 368 | query: Query 369 | } 370 | 371 | `; 372 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/schema.minimal_type_and_srid.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`prints a schema with this plugin 1`] = ` 4 | """All input for the create \`Foo\` mutation.""" 5 | input CreateFooInput { 6 | """ 7 | An arbitrary string value with no semantic meaning. Will be included in the 8 | payload verbatim. May be used to track mutations by the client. 9 | """ 10 | clientMutationId: String 11 | 12 | """The \`Foo\` to be created by this mutation.""" 13 | foo: FooInput! 14 | } 15 | 16 | """The output of our create \`Foo\` mutation.""" 17 | type CreateFooPayload { 18 | """ 19 | The exact same \`clientMutationId\` that was provided in the mutation input, 20 | unchanged and unused. May be used by a client to track mutations. 21 | """ 22 | clientMutationId: String 23 | 24 | """The \`Foo\` that was created by this mutation.""" 25 | foo: Foo 26 | 27 | """An edge for our \`Foo\`. May be used by Relay 1.""" 28 | fooEdge( 29 | """The method to use when ordering \`Foo\`.""" 30 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 31 | ): FoosEdge 32 | 33 | """ 34 | Our root query field type. Allows us to run any query from our mutation payload. 35 | """ 36 | query: Query 37 | } 38 | 39 | """A location in a connection that can be used for resuming pagination.""" 40 | scalar Cursor 41 | 42 | """All input for the \`deleteFooById\` mutation.""" 43 | input DeleteFooByIdInput { 44 | """ 45 | An arbitrary string value with no semantic meaning. Will be included in the 46 | payload verbatim. May be used to track mutations by the client. 47 | """ 48 | clientMutationId: String 49 | id: Int! 50 | } 51 | 52 | """All input for the \`deleteFoo\` mutation.""" 53 | input DeleteFooInput { 54 | """ 55 | An arbitrary string value with no semantic meaning. Will be included in the 56 | payload verbatim. May be used to track mutations by the client. 57 | """ 58 | clientMutationId: String 59 | 60 | """ 61 | The globally unique \`ID\` which will identify a single \`Foo\` to be deleted. 62 | """ 63 | nodeId: ID! 64 | } 65 | 66 | """The output of our delete \`Foo\` mutation.""" 67 | type DeleteFooPayload { 68 | """ 69 | The exact same \`clientMutationId\` that was provided in the mutation input, 70 | unchanged and unused. May be used by a client to track mutations. 71 | """ 72 | clientMutationId: String 73 | deletedFooId: ID 74 | 75 | """The \`Foo\` that was deleted by this mutation.""" 76 | foo: Foo 77 | 78 | """An edge for our \`Foo\`. May be used by Relay 1.""" 79 | fooEdge( 80 | """The method to use when ordering \`Foo\`.""" 81 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 82 | ): FoosEdge 83 | 84 | """ 85 | Our root query field type. Allows us to run any query from our mutation payload. 86 | """ 87 | query: Query 88 | } 89 | 90 | type Foo implements Node { 91 | geomPoint27700: GeometryPoint 92 | id: Int! 93 | 94 | """ 95 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 96 | """ 97 | nodeId: ID! 98 | } 99 | 100 | """ 101 | A condition to be used against \`Foo\` object types. All fields are tested for equality and combined with a logical ‘and.’ 102 | """ 103 | input FooCondition { 104 | """Checks for equality with the object’s \`geomPoint27700\` field.""" 105 | geomPoint27700: GeoJSON 106 | 107 | """Checks for equality with the object’s \`id\` field.""" 108 | id: Int 109 | } 110 | 111 | """An input for mutations affecting \`Foo\`""" 112 | input FooInput { 113 | geomPoint27700: GeoJSON 114 | id: Int 115 | } 116 | 117 | """Represents an update to a \`Foo\`. Fields that are set will be updated.""" 118 | input FooPatch { 119 | geomPoint27700: GeoJSON 120 | id: Int 121 | } 122 | 123 | """A connection to a list of \`Foo\` values.""" 124 | type FoosConnection { 125 | """ 126 | A list of edges which contains the \`Foo\` and cursor to aid in pagination. 127 | """ 128 | edges: [FoosEdge!]! 129 | 130 | """A list of \`Foo\` objects.""" 131 | nodes: [Foo]! 132 | 133 | """Information to aid in pagination.""" 134 | pageInfo: PageInfo! 135 | 136 | """The count of *all* \`Foo\` you could get from the connection.""" 137 | totalCount: Int! 138 | } 139 | 140 | """A \`Foo\` edge in the connection.""" 141 | type FoosEdge { 142 | """A cursor for use in pagination.""" 143 | cursor: Cursor 144 | 145 | """The \`Foo\` at the end of the edge.""" 146 | node: Foo 147 | } 148 | 149 | """Methods to use when ordering \`Foo\`.""" 150 | enum FoosOrderBy { 151 | GEOM_POINT_27700_ASC 152 | GEOM_POINT_27700_DESC 153 | ID_ASC 154 | ID_DESC 155 | NATURAL 156 | PRIMARY_KEY_ASC 157 | PRIMARY_KEY_DESC 158 | } 159 | 160 | """ 161 | The \`GeoJSON\` scalar type represents GeoJSON values as specified by[RFC 7946](https://tools.ietf.org/html/rfc7946). 162 | """ 163 | scalar GeoJSON 164 | 165 | """All geometry XY types implement this interface""" 166 | interface GeometryGeometry { 167 | """Converts the object to GeoJSON""" 168 | geojson: GeoJSON 169 | 170 | """Spatial reference identifier (SRID)""" 171 | srid: Int! 172 | } 173 | 174 | """All geometry types implement this interface""" 175 | interface GeometryInterface { 176 | """Converts the object to GeoJSON""" 177 | geojson: GeoJSON 178 | 179 | """Spatial reference identifier (SRID)""" 180 | srid: Int! 181 | } 182 | 183 | type GeometryPoint implements GeometryGeometry & GeometryInterface { 184 | geojson: GeoJSON 185 | srid: Int! 186 | x: Float! 187 | y: Float! 188 | } 189 | 190 | """ 191 | The root mutation type which contains root level fields which mutate data. 192 | """ 193 | type Mutation { 194 | """Creates a single \`Foo\`.""" 195 | createFoo( 196 | """ 197 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 198 | """ 199 | input: CreateFooInput! 200 | ): CreateFooPayload 201 | 202 | """Deletes a single \`Foo\` using its globally unique id.""" 203 | deleteFoo( 204 | """ 205 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 206 | """ 207 | input: DeleteFooInput! 208 | ): DeleteFooPayload 209 | 210 | """Deletes a single \`Foo\` using a unique key.""" 211 | deleteFooById( 212 | """ 213 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 214 | """ 215 | input: DeleteFooByIdInput! 216 | ): DeleteFooPayload 217 | 218 | """Updates a single \`Foo\` using its globally unique id and a patch.""" 219 | updateFoo( 220 | """ 221 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 222 | """ 223 | input: UpdateFooInput! 224 | ): UpdateFooPayload 225 | 226 | """Updates a single \`Foo\` using a unique key and a patch.""" 227 | updateFooById( 228 | """ 229 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 230 | """ 231 | input: UpdateFooByIdInput! 232 | ): UpdateFooPayload 233 | } 234 | 235 | """An object with a globally unique \`ID\`.""" 236 | interface Node { 237 | """ 238 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 239 | """ 240 | nodeId: ID! 241 | } 242 | 243 | """Information about pagination in a connection.""" 244 | type PageInfo { 245 | """When paginating forwards, the cursor to continue.""" 246 | endCursor: Cursor 247 | 248 | """When paginating forwards, are there more items?""" 249 | hasNextPage: Boolean! 250 | 251 | """When paginating backwards, are there more items?""" 252 | hasPreviousPage: Boolean! 253 | 254 | """When paginating backwards, the cursor to continue.""" 255 | startCursor: Cursor 256 | } 257 | 258 | """The root query type which gives access points into the data universe.""" 259 | type Query implements Node { 260 | """Reads and enables pagination through a set of \`Foo\`.""" 261 | allFoos( 262 | """Read all values in the set after (below) this cursor.""" 263 | after: Cursor 264 | 265 | """Read all values in the set before (above) this cursor.""" 266 | before: Cursor 267 | 268 | """ 269 | A condition to be used in determining which values should be returned by the collection. 270 | """ 271 | condition: FooCondition 272 | 273 | """Only read the first \`n\` values of the set.""" 274 | first: Int 275 | 276 | """Only read the last \`n\` values of the set.""" 277 | last: Int 278 | 279 | """ 280 | Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor 281 | based pagination. May not be used with \`last\`. 282 | """ 283 | offset: Int 284 | 285 | """The method to use when ordering \`Foo\`.""" 286 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 287 | ): FoosConnection 288 | 289 | """Reads a single \`Foo\` using its globally unique \`ID\`.""" 290 | foo( 291 | """The globally unique \`ID\` to be used in selecting a single \`Foo\`.""" 292 | nodeId: ID! 293 | ): Foo 294 | fooById(id: Int!): Foo 295 | 296 | """Fetches an object given its globally unique \`ID\`.""" 297 | node( 298 | """The globally unique \`ID\`.""" 299 | nodeId: ID! 300 | ): Node 301 | 302 | """ 303 | The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`. 304 | """ 305 | nodeId: ID! 306 | 307 | """ 308 | Exposes the root query type nested one level down. This is helpful for Relay 1 309 | which can only query top level fields if they are in a particular form. 310 | """ 311 | query: Query! 312 | } 313 | 314 | """All input for the \`updateFooById\` mutation.""" 315 | input UpdateFooByIdInput { 316 | """ 317 | An arbitrary string value with no semantic meaning. Will be included in the 318 | payload verbatim. May be used to track mutations by the client. 319 | """ 320 | clientMutationId: String 321 | 322 | """ 323 | An object where the defined keys will be set on the \`Foo\` being updated. 324 | """ 325 | fooPatch: FooPatch! 326 | id: Int! 327 | } 328 | 329 | """All input for the \`updateFoo\` mutation.""" 330 | input UpdateFooInput { 331 | """ 332 | An arbitrary string value with no semantic meaning. Will be included in the 333 | payload verbatim. May be used to track mutations by the client. 334 | """ 335 | clientMutationId: String 336 | 337 | """ 338 | An object where the defined keys will be set on the \`Foo\` being updated. 339 | """ 340 | fooPatch: FooPatch! 341 | 342 | """ 343 | The globally unique \`ID\` which will identify a single \`Foo\` to be updated. 344 | """ 345 | nodeId: ID! 346 | } 347 | 348 | """The output of our update \`Foo\` mutation.""" 349 | type UpdateFooPayload { 350 | """ 351 | The exact same \`clientMutationId\` that was provided in the mutation input, 352 | unchanged and unused. May be used by a client to track mutations. 353 | """ 354 | clientMutationId: String 355 | 356 | """The \`Foo\` that was updated by this mutation.""" 357 | foo: Foo 358 | 359 | """An edge for our \`Foo\`. May be used by Relay 1.""" 360 | fooEdge( 361 | """The method to use when ordering \`Foo\`.""" 362 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 363 | ): FoosEdge 364 | 365 | """ 366 | Our root query field type. Allows us to run any query from our mutation payload. 367 | """ 368 | query: Query 369 | } 370 | 371 | `; 372 | -------------------------------------------------------------------------------- /__tests__/__snapshots__/schema.minimal_unconstrained.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`prints a schema with this plugin 1`] = ` 4 | """All input for the create \`Foo\` mutation.""" 5 | input CreateFooInput { 6 | """ 7 | An arbitrary string value with no semantic meaning. Will be included in the 8 | payload verbatim. May be used to track mutations by the client. 9 | """ 10 | clientMutationId: String 11 | 12 | """The \`Foo\` to be created by this mutation.""" 13 | foo: FooInput! 14 | } 15 | 16 | """The output of our create \`Foo\` mutation.""" 17 | type CreateFooPayload { 18 | """ 19 | The exact same \`clientMutationId\` that was provided in the mutation input, 20 | unchanged and unused. May be used by a client to track mutations. 21 | """ 22 | clientMutationId: String 23 | 24 | """The \`Foo\` that was created by this mutation.""" 25 | foo: Foo 26 | 27 | """An edge for our \`Foo\`. May be used by Relay 1.""" 28 | fooEdge( 29 | """The method to use when ordering \`Foo\`.""" 30 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 31 | ): FoosEdge 32 | 33 | """ 34 | Our root query field type. Allows us to run any query from our mutation payload. 35 | """ 36 | query: Query 37 | } 38 | 39 | """A location in a connection that can be used for resuming pagination.""" 40 | scalar Cursor 41 | 42 | """All input for the \`deleteFooById\` mutation.""" 43 | input DeleteFooByIdInput { 44 | """ 45 | An arbitrary string value with no semantic meaning. Will be included in the 46 | payload verbatim. May be used to track mutations by the client. 47 | """ 48 | clientMutationId: String 49 | id: Int! 50 | } 51 | 52 | """All input for the \`deleteFoo\` mutation.""" 53 | input DeleteFooInput { 54 | """ 55 | An arbitrary string value with no semantic meaning. Will be included in the 56 | payload verbatim. May be used to track mutations by the client. 57 | """ 58 | clientMutationId: String 59 | 60 | """ 61 | The globally unique \`ID\` which will identify a single \`Foo\` to be deleted. 62 | """ 63 | nodeId: ID! 64 | } 65 | 66 | """The output of our delete \`Foo\` mutation.""" 67 | type DeleteFooPayload { 68 | """ 69 | The exact same \`clientMutationId\` that was provided in the mutation input, 70 | unchanged and unused. May be used by a client to track mutations. 71 | """ 72 | clientMutationId: String 73 | deletedFooId: ID 74 | 75 | """The \`Foo\` that was deleted by this mutation.""" 76 | foo: Foo 77 | 78 | """An edge for our \`Foo\`. May be used by Relay 1.""" 79 | fooEdge( 80 | """The method to use when ordering \`Foo\`.""" 81 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 82 | ): FoosEdge 83 | 84 | """ 85 | Our root query field type. Allows us to run any query from our mutation payload. 86 | """ 87 | query: Query 88 | } 89 | 90 | type Foo implements Node { 91 | geom: GeometryInterface 92 | id: Int! 93 | 94 | """ 95 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 96 | """ 97 | nodeId: ID! 98 | } 99 | 100 | """ 101 | A condition to be used against \`Foo\` object types. All fields are tested for equality and combined with a logical ‘and.’ 102 | """ 103 | input FooCondition { 104 | """Checks for equality with the object’s \`geom\` field.""" 105 | geom: GeoJSON 106 | 107 | """Checks for equality with the object’s \`id\` field.""" 108 | id: Int 109 | } 110 | 111 | """An input for mutations affecting \`Foo\`""" 112 | input FooInput { 113 | geom: GeoJSON 114 | id: Int 115 | } 116 | 117 | """Represents an update to a \`Foo\`. Fields that are set will be updated.""" 118 | input FooPatch { 119 | geom: GeoJSON 120 | id: Int 121 | } 122 | 123 | """A connection to a list of \`Foo\` values.""" 124 | type FoosConnection { 125 | """ 126 | A list of edges which contains the \`Foo\` and cursor to aid in pagination. 127 | """ 128 | edges: [FoosEdge!]! 129 | 130 | """A list of \`Foo\` objects.""" 131 | nodes: [Foo]! 132 | 133 | """Information to aid in pagination.""" 134 | pageInfo: PageInfo! 135 | 136 | """The count of *all* \`Foo\` you could get from the connection.""" 137 | totalCount: Int! 138 | } 139 | 140 | """A \`Foo\` edge in the connection.""" 141 | type FoosEdge { 142 | """A cursor for use in pagination.""" 143 | cursor: Cursor 144 | 145 | """The \`Foo\` at the end of the edge.""" 146 | node: Foo 147 | } 148 | 149 | """Methods to use when ordering \`Foo\`.""" 150 | enum FoosOrderBy { 151 | GEOM_ASC 152 | GEOM_DESC 153 | ID_ASC 154 | ID_DESC 155 | NATURAL 156 | PRIMARY_KEY_ASC 157 | PRIMARY_KEY_DESC 158 | } 159 | 160 | """ 161 | The \`GeoJSON\` scalar type represents GeoJSON values as specified by[RFC 7946](https://tools.ietf.org/html/rfc7946). 162 | """ 163 | scalar GeoJSON 164 | 165 | """All geometry XY types implement this interface""" 166 | interface GeometryGeometry { 167 | """Converts the object to GeoJSON""" 168 | geojson: GeoJSON 169 | 170 | """Spatial reference identifier (SRID)""" 171 | srid: Int! 172 | } 173 | 174 | type GeometryGeometryCollection implements GeometryGeometry & GeometryInterface { 175 | geojson: GeoJSON 176 | geometries: [GeometryGeometry] 177 | srid: Int! 178 | } 179 | 180 | type GeometryGeometryCollectionM implements GeometryGeometryM & GeometryInterface { 181 | geojson: GeoJSON 182 | geometries: [GeometryGeometryM] 183 | srid: Int! 184 | } 185 | 186 | type GeometryGeometryCollectionZ implements GeometryGeometryZ & GeometryInterface { 187 | geojson: GeoJSON 188 | geometries: [GeometryGeometryZ] 189 | srid: Int! 190 | } 191 | 192 | type GeometryGeometryCollectionZM implements GeometryGeometryZM & GeometryInterface { 193 | geojson: GeoJSON 194 | geometries: [GeometryGeometryZM] 195 | srid: Int! 196 | } 197 | 198 | """All geometry XYM types implement this interface""" 199 | interface GeometryGeometryM { 200 | """Converts the object to GeoJSON""" 201 | geojson: GeoJSON 202 | 203 | """Spatial reference identifier (SRID)""" 204 | srid: Int! 205 | } 206 | 207 | """All geometry XYZ types implement this interface""" 208 | interface GeometryGeometryZ { 209 | """Converts the object to GeoJSON""" 210 | geojson: GeoJSON 211 | 212 | """Spatial reference identifier (SRID)""" 213 | srid: Int! 214 | } 215 | 216 | """All geometry XYZM types implement this interface""" 217 | interface GeometryGeometryZM { 218 | """Converts the object to GeoJSON""" 219 | geojson: GeoJSON 220 | 221 | """Spatial reference identifier (SRID)""" 222 | srid: Int! 223 | } 224 | 225 | """All geometry types implement this interface""" 226 | interface GeometryInterface { 227 | """Converts the object to GeoJSON""" 228 | geojson: GeoJSON 229 | 230 | """Spatial reference identifier (SRID)""" 231 | srid: Int! 232 | } 233 | 234 | type GeometryLineString implements GeometryGeometry & GeometryInterface { 235 | geojson: GeoJSON 236 | points: [GeometryPoint] 237 | srid: Int! 238 | } 239 | 240 | type GeometryLineStringM implements GeometryGeometryM & GeometryInterface { 241 | geojson: GeoJSON 242 | points: [GeometryPointM] 243 | srid: Int! 244 | } 245 | 246 | type GeometryLineStringZ implements GeometryGeometryZ & GeometryInterface { 247 | geojson: GeoJSON 248 | points: [GeometryPointZ] 249 | srid: Int! 250 | } 251 | 252 | type GeometryLineStringZM implements GeometryGeometryZM & GeometryInterface { 253 | geojson: GeoJSON 254 | points: [GeometryPointZM] 255 | srid: Int! 256 | } 257 | 258 | type GeometryMultiLineString implements GeometryGeometry & GeometryInterface { 259 | geojson: GeoJSON 260 | lines: [GeometryLineString] 261 | srid: Int! 262 | } 263 | 264 | type GeometryMultiLineStringM implements GeometryGeometryM & GeometryInterface { 265 | geojson: GeoJSON 266 | lines: [GeometryLineStringM] 267 | srid: Int! 268 | } 269 | 270 | type GeometryMultiLineStringZ implements GeometryGeometryZ & GeometryInterface { 271 | geojson: GeoJSON 272 | lines: [GeometryLineStringZ] 273 | srid: Int! 274 | } 275 | 276 | type GeometryMultiLineStringZM implements GeometryGeometryZM & GeometryInterface { 277 | geojson: GeoJSON 278 | lines: [GeometryLineStringZM] 279 | srid: Int! 280 | } 281 | 282 | type GeometryMultiPoint implements GeometryGeometry & GeometryInterface { 283 | geojson: GeoJSON 284 | points: [GeometryPoint] 285 | srid: Int! 286 | } 287 | 288 | type GeometryMultiPointM implements GeometryGeometryM & GeometryInterface { 289 | geojson: GeoJSON 290 | points: [GeometryPointM] 291 | srid: Int! 292 | } 293 | 294 | type GeometryMultiPointZ implements GeometryGeometryZ & GeometryInterface { 295 | geojson: GeoJSON 296 | points: [GeometryPointZ] 297 | srid: Int! 298 | } 299 | 300 | type GeometryMultiPointZM implements GeometryGeometryZM & GeometryInterface { 301 | geojson: GeoJSON 302 | points: [GeometryPointZM] 303 | srid: Int! 304 | } 305 | 306 | type GeometryMultiPolygon implements GeometryGeometry & GeometryInterface { 307 | geojson: GeoJSON 308 | polygons: [GeometryPolygon] 309 | srid: Int! 310 | } 311 | 312 | type GeometryMultiPolygonM implements GeometryGeometryM & GeometryInterface { 313 | geojson: GeoJSON 314 | polygons: [GeometryPolygonM] 315 | srid: Int! 316 | } 317 | 318 | type GeometryMultiPolygonZ implements GeometryGeometryZ & GeometryInterface { 319 | geojson: GeoJSON 320 | polygons: [GeometryPolygonZ] 321 | srid: Int! 322 | } 323 | 324 | type GeometryMultiPolygonZM implements GeometryGeometryZM & GeometryInterface { 325 | geojson: GeoJSON 326 | polygons: [GeometryPolygonZM] 327 | srid: Int! 328 | } 329 | 330 | type GeometryPoint implements GeometryGeometry & GeometryInterface { 331 | geojson: GeoJSON 332 | srid: Int! 333 | x: Float! 334 | y: Float! 335 | } 336 | 337 | type GeometryPointM implements GeometryGeometryM & GeometryInterface { 338 | geojson: GeoJSON 339 | srid: Int! 340 | x: Float! 341 | y: Float! 342 | } 343 | 344 | type GeometryPointZ implements GeometryGeometryZ & GeometryInterface { 345 | geojson: GeoJSON 346 | srid: Int! 347 | x: Float! 348 | y: Float! 349 | z: Float! 350 | } 351 | 352 | type GeometryPointZM implements GeometryGeometryZM & GeometryInterface { 353 | geojson: GeoJSON 354 | srid: Int! 355 | x: Float! 356 | y: Float! 357 | z: Float! 358 | } 359 | 360 | type GeometryPolygon implements GeometryGeometry & GeometryInterface { 361 | exterior: GeometryLineString 362 | geojson: GeoJSON 363 | interiors: [GeometryLineString] 364 | srid: Int! 365 | } 366 | 367 | type GeometryPolygonM implements GeometryGeometryM & GeometryInterface { 368 | exterior: GeometryLineStringM 369 | geojson: GeoJSON 370 | interiors: [GeometryLineStringM] 371 | srid: Int! 372 | } 373 | 374 | type GeometryPolygonZ implements GeometryGeometryZ & GeometryInterface { 375 | exterior: GeometryLineStringZ 376 | geojson: GeoJSON 377 | interiors: [GeometryLineStringZ] 378 | srid: Int! 379 | } 380 | 381 | type GeometryPolygonZM implements GeometryGeometryZM & GeometryInterface { 382 | exterior: GeometryLineStringZM 383 | geojson: GeoJSON 384 | interiors: [GeometryLineStringZM] 385 | srid: Int! 386 | } 387 | 388 | """ 389 | The root mutation type which contains root level fields which mutate data. 390 | """ 391 | type Mutation { 392 | """Creates a single \`Foo\`.""" 393 | createFoo( 394 | """ 395 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 396 | """ 397 | input: CreateFooInput! 398 | ): CreateFooPayload 399 | 400 | """Deletes a single \`Foo\` using its globally unique id.""" 401 | deleteFoo( 402 | """ 403 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 404 | """ 405 | input: DeleteFooInput! 406 | ): DeleteFooPayload 407 | 408 | """Deletes a single \`Foo\` using a unique key.""" 409 | deleteFooById( 410 | """ 411 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 412 | """ 413 | input: DeleteFooByIdInput! 414 | ): DeleteFooPayload 415 | 416 | """Updates a single \`Foo\` using its globally unique id and a patch.""" 417 | updateFoo( 418 | """ 419 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 420 | """ 421 | input: UpdateFooInput! 422 | ): UpdateFooPayload 423 | 424 | """Updates a single \`Foo\` using a unique key and a patch.""" 425 | updateFooById( 426 | """ 427 | The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields. 428 | """ 429 | input: UpdateFooByIdInput! 430 | ): UpdateFooPayload 431 | } 432 | 433 | """An object with a globally unique \`ID\`.""" 434 | interface Node { 435 | """ 436 | A globally unique identifier. Can be used in various places throughout the system to identify this single value. 437 | """ 438 | nodeId: ID! 439 | } 440 | 441 | """Information about pagination in a connection.""" 442 | type PageInfo { 443 | """When paginating forwards, the cursor to continue.""" 444 | endCursor: Cursor 445 | 446 | """When paginating forwards, are there more items?""" 447 | hasNextPage: Boolean! 448 | 449 | """When paginating backwards, are there more items?""" 450 | hasPreviousPage: Boolean! 451 | 452 | """When paginating backwards, the cursor to continue.""" 453 | startCursor: Cursor 454 | } 455 | 456 | """The root query type which gives access points into the data universe.""" 457 | type Query implements Node { 458 | """Reads and enables pagination through a set of \`Foo\`.""" 459 | allFoos( 460 | """Read all values in the set after (below) this cursor.""" 461 | after: Cursor 462 | 463 | """Read all values in the set before (above) this cursor.""" 464 | before: Cursor 465 | 466 | """ 467 | A condition to be used in determining which values should be returned by the collection. 468 | """ 469 | condition: FooCondition 470 | 471 | """Only read the first \`n\` values of the set.""" 472 | first: Int 473 | 474 | """Only read the last \`n\` values of the set.""" 475 | last: Int 476 | 477 | """ 478 | Skip the first \`n\` values from our \`after\` cursor, an alternative to cursor 479 | based pagination. May not be used with \`last\`. 480 | """ 481 | offset: Int 482 | 483 | """The method to use when ordering \`Foo\`.""" 484 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 485 | ): FoosConnection 486 | 487 | """Reads a single \`Foo\` using its globally unique \`ID\`.""" 488 | foo( 489 | """The globally unique \`ID\` to be used in selecting a single \`Foo\`.""" 490 | nodeId: ID! 491 | ): Foo 492 | fooById(id: Int!): Foo 493 | 494 | """Fetches an object given its globally unique \`ID\`.""" 495 | node( 496 | """The globally unique \`ID\`.""" 497 | nodeId: ID! 498 | ): Node 499 | 500 | """ 501 | The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`. 502 | """ 503 | nodeId: ID! 504 | 505 | """ 506 | Exposes the root query type nested one level down. This is helpful for Relay 1 507 | which can only query top level fields if they are in a particular form. 508 | """ 509 | query: Query! 510 | } 511 | 512 | """All input for the \`updateFooById\` mutation.""" 513 | input UpdateFooByIdInput { 514 | """ 515 | An arbitrary string value with no semantic meaning. Will be included in the 516 | payload verbatim. May be used to track mutations by the client. 517 | """ 518 | clientMutationId: String 519 | 520 | """ 521 | An object where the defined keys will be set on the \`Foo\` being updated. 522 | """ 523 | fooPatch: FooPatch! 524 | id: Int! 525 | } 526 | 527 | """All input for the \`updateFoo\` mutation.""" 528 | input UpdateFooInput { 529 | """ 530 | An arbitrary string value with no semantic meaning. Will be included in the 531 | payload verbatim. May be used to track mutations by the client. 532 | """ 533 | clientMutationId: String 534 | 535 | """ 536 | An object where the defined keys will be set on the \`Foo\` being updated. 537 | """ 538 | fooPatch: FooPatch! 539 | 540 | """ 541 | The globally unique \`ID\` which will identify a single \`Foo\` to be updated. 542 | """ 543 | nodeId: ID! 544 | } 545 | 546 | """The output of our update \`Foo\` mutation.""" 547 | type UpdateFooPayload { 548 | """ 549 | The exact same \`clientMutationId\` that was provided in the mutation input, 550 | unchanged and unused. May be used by a client to track mutations. 551 | """ 552 | clientMutationId: String 553 | 554 | """The \`Foo\` that was updated by this mutation.""" 555 | foo: Foo 556 | 557 | """An edge for our \`Foo\`. May be used by Relay 1.""" 558 | fooEdge( 559 | """The method to use when ordering \`Foo\`.""" 560 | orderBy: [FoosOrderBy!] = [PRIMARY_KEY_ASC] 561 | ): FoosEdge 562 | 563 | """ 564 | Our root query field type. Allows us to run any query from our mutation payload. 565 | """ 566 | query: Query 567 | } 568 | 569 | `; 570 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geog { 5 | __typename 6 | geojson 7 | ... on GeographyPoint { 8 | ...geogPoint 9 | } 10 | ... on GeographyLineString { 11 | ...geogLinestring 12 | } 13 | ... on GeographyPolygon { 14 | ...geogPolygon 15 | } 16 | ... on GeographyMultiPoint { 17 | ...geogMultipoint 18 | } 19 | ... on GeographyMultiLineString { 20 | ...geogMultilinestring 21 | } 22 | ... on GeographyMultiPolygon { 23 | ...geogMultipolygon 24 | } 25 | ... on GeographyPointZ { 26 | ...geogPointz 27 | } 28 | ... on GeographyLineStringZ { 29 | ...geogLinestringz 30 | } 31 | ... on GeographyPolygonZ { 32 | ...geogPolygonz 33 | } 34 | ... on GeographyMultiPointZ { 35 | ...geogMultipointz 36 | } 37 | ... on GeographyMultiLineStringZ { 38 | ...geogMultilinestringz 39 | } 40 | ... on GeographyMultiPolygonZ { 41 | ...geogMultipolygonz 42 | } 43 | ... on GeographyPointM { 44 | ...geogPointm 45 | } 46 | ... on GeographyLineStringM { 47 | ...geogLinestringm 48 | } 49 | ... on GeographyPolygonM { 50 | ...geogPolygonm 51 | } 52 | ... on GeographyMultiPointM { 53 | ...geogMultipointm 54 | } 55 | ... on GeographyMultiLineStringM { 56 | ...geogMultilinestringm 57 | } 58 | ... on GeographyMultiPolygonM { 59 | ...geogMultipolygonm 60 | } 61 | ... on GeographyPointZM { 62 | ...geogPointzm 63 | } 64 | ... on GeographyLineStringZM { 65 | ...geogLinestringzm 66 | } 67 | ... on GeographyPolygonZM { 68 | ...geogPolygonzm 69 | } 70 | ... on GeographyMultiPointZM { 71 | ...geogMultipointzm 72 | } 73 | ... on GeographyMultiLineStringZM { 74 | ...geogMultilinestringzm 75 | } 76 | ... on GeographyMultiPolygonZM { 77 | ...geogMultipolygonzm 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | fragment geogPoint on GeographyPoint { 85 | geojson 86 | latitude 87 | longitude 88 | } 89 | 90 | fragment geogLinestring on GeographyLineString { 91 | geojson 92 | points { 93 | ...geogPoint 94 | } 95 | } 96 | 97 | fragment geogPolygon on GeographyPolygon { 98 | exterior { 99 | ...geogLinestring 100 | } 101 | geojson 102 | interiors { 103 | ...geogLinestring 104 | } 105 | } 106 | 107 | fragment geogMultipoint on GeographyMultiPoint { 108 | geojson 109 | points { 110 | ...geogPoint 111 | } 112 | } 113 | 114 | fragment geogMultilinestring on GeographyMultiLineString { 115 | geojson 116 | lines { 117 | ...geogLinestring 118 | } 119 | } 120 | 121 | fragment geogMultipolygon on GeographyMultiPolygon { 122 | geojson 123 | polygons { 124 | ...geogPolygon 125 | } 126 | } 127 | 128 | fragment geogPointm on GeographyPointM { 129 | geojson 130 | latitude 131 | longitude 132 | } 133 | 134 | fragment geogLinestringm on GeographyLineStringM { 135 | geojson 136 | points { 137 | ...geogPointm 138 | } 139 | } 140 | 141 | fragment geogPolygonm on GeographyPolygonM { 142 | exterior { 143 | ...geogLinestringm 144 | } 145 | geojson 146 | interiors { 147 | ...geogLinestringm 148 | } 149 | } 150 | 151 | fragment geogMultipointm on GeographyMultiPointM { 152 | geojson 153 | points { 154 | ...geogPointm 155 | } 156 | } 157 | 158 | fragment geogMultilinestringm on GeographyMultiLineStringM { 159 | geojson 160 | lines { 161 | ...geogLinestringm 162 | } 163 | } 164 | 165 | fragment geogMultipolygonm on GeographyMultiPolygonM { 166 | geojson 167 | polygons { 168 | ...geogPolygonm 169 | } 170 | } 171 | 172 | fragment geogPointz on GeographyPointZ { 173 | geojson 174 | latitude 175 | longitude 176 | height 177 | } 178 | 179 | fragment geogLinestringz on GeographyLineStringZ { 180 | geojson 181 | points { 182 | ...geogPointz 183 | } 184 | } 185 | 186 | fragment geogPolygonz on GeographyPolygonZ { 187 | exterior { 188 | ...geogLinestringz 189 | } 190 | geojson 191 | interiors { 192 | ...geogLinestringz 193 | } 194 | } 195 | 196 | fragment geogMultipointz on GeographyMultiPointZ { 197 | geojson 198 | points { 199 | ...geogPointz 200 | } 201 | } 202 | 203 | fragment geogMultilinestringz on GeographyMultiLineStringZ { 204 | geojson 205 | lines { 206 | ...geogLinestringz 207 | } 208 | } 209 | 210 | fragment geogMultipolygonz on GeographyMultiPolygonZ { 211 | geojson 212 | polygons { 213 | ...geogPolygonz 214 | } 215 | } 216 | 217 | fragment geogPointzm on GeographyPointZM { 218 | geojson 219 | latitude 220 | longitude 221 | height 222 | } 223 | 224 | fragment geogLinestringzm on GeographyLineStringZM { 225 | geojson 226 | points { 227 | ...geogPointzm 228 | } 229 | } 230 | 231 | fragment geogPolygonzm on GeographyPolygonZM { 232 | exterior { 233 | ...geogLinestringzm 234 | } 235 | geojson 236 | interiors { 237 | ...geogLinestringzm 238 | } 239 | } 240 | 241 | fragment geogMultipointzm on GeographyMultiPointZM { 242 | geojson 243 | points { 244 | ...geogPointzm 245 | } 246 | } 247 | 248 | fragment geogMultilinestringzm on GeographyMultiLineStringZM { 249 | geojson 250 | lines { 251 | ...geogLinestringzm 252 | } 253 | } 254 | 255 | fragment geogMultipolygonzm on GeographyMultiPolygonZM { 256 | geojson 257 | polygons { 258 | ...geogPolygonzm 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_geometry.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogGeometry { 5 | __typename 6 | geojson 7 | ... on GeographyPoint { 8 | ...geogPoint 9 | } 10 | ... on GeographyLineString { 11 | ...geogLinestring 12 | } 13 | ... on GeographyPolygon { 14 | ...geogPolygon 15 | } 16 | ... on GeographyMultiPoint { 17 | ...geogMultipoint 18 | } 19 | ... on GeographyMultiLineString { 20 | ...geogMultilinestring 21 | } 22 | ... on GeographyMultiPolygon { 23 | ...geogMultipolygon 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geogPoint on GeographyPoint { 31 | geojson 32 | latitude 33 | longitude 34 | } 35 | 36 | fragment geogLinestring on GeographyLineString { 37 | geojson 38 | points { 39 | ...geogPoint 40 | } 41 | } 42 | 43 | fragment geogPolygon on GeographyPolygon { 44 | exterior { 45 | ...geogLinestring 46 | } 47 | geojson 48 | interiors { 49 | ...geogLinestring 50 | } 51 | } 52 | 53 | fragment geogMultipoint on GeographyMultiPoint { 54 | geojson 55 | points { 56 | ...geogPoint 57 | } 58 | } 59 | 60 | fragment geogMultilinestring on GeographyMultiLineString { 61 | geojson 62 | lines { 63 | ...geogLinestring 64 | } 65 | } 66 | 67 | fragment geogMultipolygon on GeographyMultiPolygon { 68 | geojson 69 | polygons { 70 | ...geogPolygon 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_geometrym.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogGeometrym { 5 | __typename 6 | geojson 7 | ... on GeographyPointM { 8 | ...geogPointm 9 | } 10 | ... on GeographyLineStringM { 11 | ...geogLinestringm 12 | } 13 | ... on GeographyPolygonM { 14 | ...geogPolygonm 15 | } 16 | ... on GeographyMultiPointM { 17 | ...geogMultipointm 18 | } 19 | ... on GeographyMultiLineStringM { 20 | ...geogMultilinestringm 21 | } 22 | ... on GeographyMultiPolygonM { 23 | ...geogMultipolygonm 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geogPointm on GeographyPointM { 31 | geojson 32 | latitude 33 | longitude 34 | } 35 | 36 | fragment geogLinestringm on GeographyLineStringM { 37 | geojson 38 | points { 39 | ...geogPointm 40 | } 41 | } 42 | 43 | fragment geogPolygonm on GeographyPolygonM { 44 | exterior { 45 | ...geogLinestringm 46 | } 47 | geojson 48 | interiors { 49 | ...geogLinestringm 50 | } 51 | } 52 | 53 | fragment geogMultipointm on GeographyMultiPointM { 54 | geojson 55 | points { 56 | ...geogPointm 57 | } 58 | } 59 | 60 | fragment geogMultilinestringm on GeographyMultiLineStringM { 61 | geojson 62 | lines { 63 | ...geogLinestringm 64 | } 65 | } 66 | 67 | fragment geogMultipolygonm on GeographyMultiPolygonM { 68 | geojson 69 | polygons { 70 | ...geogPolygonm 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_geometryz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogGeometryz { 5 | __typename 6 | geojson 7 | ... on GeographyPointZ { 8 | ...geogPointz 9 | } 10 | ... on GeographyLineStringZ { 11 | ...geogLinestringz 12 | } 13 | ... on GeographyPolygonZ { 14 | ...geogPolygonz 15 | } 16 | ... on GeographyMultiPointZ { 17 | ...geogMultipointz 18 | } 19 | ... on GeographyMultiLineStringZ { 20 | ...geogMultilinestringz 21 | } 22 | ... on GeographyMultiPolygonZ { 23 | ...geogMultipolygonz 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geogPointz on GeographyPointZ { 31 | geojson 32 | latitude 33 | longitude 34 | height 35 | } 36 | 37 | fragment geogLinestringz on GeographyLineStringZ { 38 | geojson 39 | points { 40 | ...geogPointz 41 | } 42 | } 43 | 44 | fragment geogPolygonz on GeographyPolygonZ { 45 | exterior { 46 | ...geogLinestringz 47 | } 48 | geojson 49 | interiors { 50 | ...geogLinestringz 51 | } 52 | } 53 | 54 | fragment geogMultipointz on GeographyMultiPointZ { 55 | geojson 56 | points { 57 | ...geogPointz 58 | } 59 | } 60 | 61 | fragment geogMultilinestringz on GeographyMultiLineStringZ { 62 | geojson 63 | lines { 64 | ...geogLinestringz 65 | } 66 | } 67 | 68 | fragment geogMultipolygonz on GeographyMultiPolygonZ { 69 | geojson 70 | polygons { 71 | ...geogPolygonz 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_geometryzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogGeometryzm { 5 | __typename 6 | geojson 7 | ... on GeographyPointZM { 8 | ...geogPointzm 9 | } 10 | ... on GeographyLineStringZM { 11 | ...geogLinestringzm 12 | } 13 | ... on GeographyPolygonZM { 14 | ...geogPolygonzm 15 | } 16 | ... on GeographyMultiPointZM { 17 | ...geogMultipointzm 18 | } 19 | ... on GeographyMultiLineStringZM { 20 | ...geogMultilinestringzm 21 | } 22 | ... on GeographyMultiPolygonZM { 23 | ...geogMultipolygonzm 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geogPointzm on GeographyPointZM { 31 | geojson 32 | latitude 33 | longitude 34 | height 35 | } 36 | 37 | fragment geogLinestringzm on GeographyLineStringZM { 38 | geojson 39 | points { 40 | ...geogPointzm 41 | } 42 | } 43 | 44 | fragment geogPolygonzm on GeographyPolygonZM { 45 | exterior { 46 | ...geogLinestringzm 47 | } 48 | geojson 49 | interiors { 50 | ...geogLinestringzm 51 | } 52 | } 53 | 54 | fragment geogMultipointzm on GeographyMultiPointZM { 55 | geojson 56 | points { 57 | ...geogPointzm 58 | } 59 | } 60 | 61 | fragment geogMultilinestringzm on GeographyMultiLineStringZM { 62 | geojson 63 | lines { 64 | ...geogLinestringzm 65 | } 66 | } 67 | 68 | fragment geogMultipolygonzm on GeographyMultiPolygonZM { 69 | geojson 70 | polygons { 71 | ...geogPolygonzm 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_linestring.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogLinestring { 5 | ...geogLinestring 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPoint on GeographyPoint { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestring on GeographyLineString { 18 | geojson 19 | points { 20 | ...geogPoint 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_linestringm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogLinestringm { 5 | ...geogLinestringm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointm on GeographyPointM { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestringm on GeographyLineStringM { 18 | geojson 19 | points { 20 | ...geogPointm 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_linestringz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogLinestringz { 5 | ...geogLinestringz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointz on GeographyPointZ { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringz on GeographyLineStringZ { 19 | geojson 20 | points { 21 | ...geogPointz 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_linestringzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogLinestringzm { 5 | ...geogLinestringzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointzm on GeographyPointZM { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringzm on GeographyLineStringZM { 19 | geojson 20 | points { 21 | ...geogPointzm 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multilinestring.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultilinestring { 5 | ...geogMultilinestring 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPoint on GeographyPoint { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestring on GeographyLineString { 18 | geojson 19 | points { 20 | ...geogPoint 21 | } 22 | } 23 | 24 | fragment geogMultilinestring on GeographyMultiLineString { 25 | geojson 26 | lines { 27 | ...geogLinestring 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multilinestringm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultilinestringm { 5 | ...geogMultilinestringm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointm on GeographyPointM { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestringm on GeographyLineStringM { 18 | geojson 19 | points { 20 | ...geogPointm 21 | } 22 | } 23 | 24 | fragment geogMultilinestringm on GeographyMultiLineStringM { 25 | geojson 26 | lines { 27 | ...geogLinestringm 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multilinestringz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultilinestringz { 5 | ...geogMultilinestringz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointz on GeographyPointZ { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringz on GeographyLineStringZ { 19 | geojson 20 | points { 21 | ...geogPointz 22 | } 23 | } 24 | 25 | fragment geogMultilinestringz on GeographyMultiLineStringZ { 26 | geojson 27 | lines { 28 | ...geogLinestringz 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multilinestringzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultilinestringzm { 5 | ...geogMultilinestringzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointzm on GeographyPointZM { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringzm on GeographyLineStringZM { 19 | geojson 20 | points { 21 | ...geogPointzm 22 | } 23 | } 24 | 25 | fragment geogMultilinestringzm on GeographyMultiLineStringZM { 26 | geojson 27 | lines { 28 | ...geogLinestringzm 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipoint.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipoint { 5 | ...geogMultipoint 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPoint on GeographyPoint { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogMultipoint on GeographyMultiPoint { 18 | geojson 19 | points { 20 | ...geogPoint 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipointm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipointm { 5 | ...geogMultipointm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointm on GeographyPointM { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogMultipointm on GeographyMultiPointM { 18 | geojson 19 | points { 20 | ...geogPointm 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipointz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipointz { 5 | ...geogMultipointz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointz on GeographyPointZ { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogMultipointz on GeographyMultiPointZ { 19 | geojson 20 | points { 21 | ...geogPointz 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipointzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipointzm { 5 | ...geogMultipointzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointzm on GeographyPointZM { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogMultipointzm on GeographyMultiPointZM { 19 | geojson 20 | points { 21 | ...geogPointzm 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipolygon.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipolygon { 5 | ...geogMultipolygon 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPoint on GeographyPoint { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestring on GeographyLineString { 18 | geojson 19 | points { 20 | ...geogPoint 21 | } 22 | } 23 | 24 | fragment geogPolygon on GeographyPolygon { 25 | exterior { 26 | ...geogLinestring 27 | } 28 | geojson 29 | interiors { 30 | ...geogLinestring 31 | } 32 | } 33 | 34 | fragment geogMultipolygon on GeographyMultiPolygon { 35 | geojson 36 | polygons { 37 | ...geogPolygon 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipolygonm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipolygonm { 5 | ...geogMultipolygonm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointm on GeographyPointM { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestringm on GeographyLineStringM { 18 | geojson 19 | points { 20 | ...geogPointm 21 | } 22 | } 23 | 24 | fragment geogPolygonm on GeographyPolygonM { 25 | exterior { 26 | ...geogLinestringm 27 | } 28 | geojson 29 | interiors { 30 | ...geogLinestringm 31 | } 32 | } 33 | 34 | fragment geogMultipolygonm on GeographyMultiPolygonM { 35 | geojson 36 | polygons { 37 | ...geogPolygonm 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipolygonz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipolygonz { 5 | ...geogMultipolygonz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointz on GeographyPointZ { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringz on GeographyLineStringZ { 19 | geojson 20 | points { 21 | ...geogPointz 22 | } 23 | } 24 | 25 | fragment geogPolygonz on GeographyPolygonZ { 26 | exterior { 27 | ...geogLinestringz 28 | } 29 | geojson 30 | interiors { 31 | ...geogLinestringz 32 | } 33 | } 34 | 35 | fragment geogMultipolygonz on GeographyMultiPolygonZ { 36 | geojson 37 | polygons { 38 | ...geogPolygonz 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_multipolygonzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogMultipolygonzm { 5 | ...geogMultipolygonzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointzm on GeographyPointZM { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringzm on GeographyLineStringZM { 19 | geojson 20 | points { 21 | ...geogPointzm 22 | } 23 | } 24 | 25 | fragment geogPolygonzm on GeographyPolygonZM { 26 | exterior { 27 | ...geogLinestringzm 28 | } 29 | geojson 30 | interiors { 31 | ...geogLinestringzm 32 | } 33 | } 34 | 35 | fragment geogMultipolygonzm on GeographyMultiPolygonZM { 36 | geojson 37 | polygons { 38 | ...geogPolygonzm 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_point.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPoint { 5 | ...geogPoint 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPoint on GeographyPoint { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_pointm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPointm { 5 | ...geogPointm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointm on GeographyPointM { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_pointz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPointz { 5 | ...geogPointz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointz on GeographyPointZ { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_pointzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPointzm { 5 | ...geogPointzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointzm on GeographyPointZM { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_polygon.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPolygon { 5 | ...geogPolygon 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPoint on GeographyPoint { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestring on GeographyLineString { 18 | geojson 19 | points { 20 | ...geogPoint 21 | } 22 | } 23 | 24 | fragment geogPolygon on GeographyPolygon { 25 | exterior { 26 | ...geogLinestring 27 | } 28 | geojson 29 | interiors { 30 | ...geogLinestring 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_polygonm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPolygonm { 5 | ...geogPolygonm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointm on GeographyPointM { 12 | geojson 13 | latitude 14 | longitude 15 | } 16 | 17 | fragment geogLinestringm on GeographyLineStringM { 18 | geojson 19 | points { 20 | ...geogPointm 21 | } 22 | } 23 | 24 | fragment geogPolygonm on GeographyPolygonM { 25 | exterior { 26 | ...geogLinestringm 27 | } 28 | geojson 29 | interiors { 30 | ...geogLinestringm 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_polygonz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPolygonz { 5 | ...geogPolygonz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointz on GeographyPointZ { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringz on GeographyLineStringZ { 19 | geojson 20 | points { 21 | ...geogPointz 22 | } 23 | } 24 | 25 | fragment geogPolygonz on GeographyPolygonZ { 26 | exterior { 27 | ...geogLinestringz 28 | } 29 | geojson 30 | interiors { 31 | ...geogLinestringz 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geog_polygonzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geogPolygonzm { 5 | ...geogPolygonzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geogPointzm on GeographyPointZM { 12 | geojson 13 | latitude 14 | longitude 15 | height 16 | } 17 | 18 | fragment geogLinestringzm on GeographyLineStringZM { 19 | geojson 20 | points { 21 | ...geogPointzm 22 | } 23 | } 24 | 25 | fragment geogPolygonzm on GeographyPolygonZM { 26 | exterior { 27 | ...geogLinestringzm 28 | } 29 | geojson 30 | interiors { 31 | ...geogLinestringzm 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geom { 5 | __typename 6 | geojson 7 | ... on GeometryPoint { 8 | ...geomPoint 9 | } 10 | ... on GeometryLineString { 11 | ...geomLinestring 12 | } 13 | ... on GeometryPolygon { 14 | ...geomPolygon 15 | } 16 | ... on GeometryMultiPoint { 17 | ...geomMultipoint 18 | } 19 | ... on GeometryMultiLineString { 20 | ...geomMultilinestring 21 | } 22 | ... on GeometryMultiPolygon { 23 | ...geomMultipolygon 24 | } 25 | ... on GeometryPointZ { 26 | ...geomPointz 27 | } 28 | ... on GeometryLineStringZ { 29 | ...geomLinestringz 30 | } 31 | ... on GeometryPolygonZ { 32 | ...geomPolygonz 33 | } 34 | ... on GeometryMultiPointZ { 35 | ...geomMultipointz 36 | } 37 | ... on GeometryMultiLineStringZ { 38 | ...geomMultilinestringz 39 | } 40 | ... on GeometryMultiPolygonZ { 41 | ...geomMultipolygonz 42 | } 43 | ... on GeometryPointM { 44 | ...geomPointm 45 | } 46 | ... on GeometryLineStringM { 47 | ...geomLinestringm 48 | } 49 | ... on GeometryPolygonM { 50 | ...geomPolygonm 51 | } 52 | ... on GeometryMultiPointM { 53 | ...geomMultipointm 54 | } 55 | ... on GeometryMultiLineStringM { 56 | ...geomMultilinestringm 57 | } 58 | ... on GeometryMultiPolygonM { 59 | ...geomMultipolygonm 60 | } 61 | ... on GeometryPointZM { 62 | ...geomPointzm 63 | } 64 | ... on GeometryLineStringZM { 65 | ...geomLinestringzm 66 | } 67 | ... on GeometryPolygonZM { 68 | ...geomPolygonzm 69 | } 70 | ... on GeometryMultiPointZM { 71 | ...geomMultipointzm 72 | } 73 | ... on GeometryMultiLineStringZM { 74 | ...geomMultilinestringzm 75 | } 76 | ... on GeometryMultiPolygonZM { 77 | ...geomMultipolygonzm 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | fragment geomPoint on GeometryPoint { 85 | geojson 86 | x 87 | y 88 | } 89 | 90 | fragment geomLinestring on GeometryLineString { 91 | geojson 92 | points { 93 | ...geomPoint 94 | } 95 | } 96 | 97 | fragment geomPolygon on GeometryPolygon { 98 | exterior { 99 | ...geomLinestring 100 | } 101 | geojson 102 | interiors { 103 | ...geomLinestring 104 | } 105 | } 106 | 107 | fragment geomMultipoint on GeometryMultiPoint { 108 | geojson 109 | points { 110 | ...geomPoint 111 | } 112 | } 113 | 114 | fragment geomMultilinestring on GeometryMultiLineString { 115 | geojson 116 | lines { 117 | ...geomLinestring 118 | } 119 | } 120 | 121 | fragment geomMultipolygon on GeometryMultiPolygon { 122 | geojson 123 | polygons { 124 | ...geomPolygon 125 | } 126 | } 127 | 128 | fragment geomPointm on GeometryPointM { 129 | geojson 130 | x 131 | y 132 | } 133 | 134 | fragment geomLinestringm on GeometryLineStringM { 135 | geojson 136 | points { 137 | ...geomPointm 138 | } 139 | } 140 | 141 | fragment geomPolygonm on GeometryPolygonM { 142 | exterior { 143 | ...geomLinestringm 144 | } 145 | geojson 146 | interiors { 147 | ...geomLinestringm 148 | } 149 | } 150 | 151 | fragment geomMultipointm on GeometryMultiPointM { 152 | geojson 153 | points { 154 | ...geomPointm 155 | } 156 | } 157 | 158 | fragment geomMultilinestringm on GeometryMultiLineStringM { 159 | geojson 160 | lines { 161 | ...geomLinestringm 162 | } 163 | } 164 | 165 | fragment geomMultipolygonm on GeometryMultiPolygonM { 166 | geojson 167 | polygons { 168 | ...geomPolygonm 169 | } 170 | } 171 | 172 | fragment geomPointz on GeometryPointZ { 173 | geojson 174 | x 175 | y 176 | z 177 | } 178 | 179 | fragment geomLinestringz on GeometryLineStringZ { 180 | geojson 181 | points { 182 | ...geomPointz 183 | } 184 | } 185 | 186 | fragment geomPolygonz on GeometryPolygonZ { 187 | exterior { 188 | ...geomLinestringz 189 | } 190 | geojson 191 | interiors { 192 | ...geomLinestringz 193 | } 194 | } 195 | 196 | fragment geomMultipointz on GeometryMultiPointZ { 197 | geojson 198 | points { 199 | ...geomPointz 200 | } 201 | } 202 | 203 | fragment geomMultilinestringz on GeometryMultiLineStringZ { 204 | geojson 205 | lines { 206 | ...geomLinestringz 207 | } 208 | } 209 | 210 | fragment geomMultipolygonz on GeometryMultiPolygonZ { 211 | geojson 212 | polygons { 213 | ...geomPolygonz 214 | } 215 | } 216 | 217 | fragment geomPointzm on GeometryPointZM { 218 | geojson 219 | x 220 | y 221 | z 222 | } 223 | 224 | fragment geomLinestringzm on GeometryLineStringZM { 225 | geojson 226 | points { 227 | ...geomPointzm 228 | } 229 | } 230 | 231 | fragment geomPolygonzm on GeometryPolygonZM { 232 | exterior { 233 | ...geomLinestringzm 234 | } 235 | geojson 236 | interiors { 237 | ...geomLinestringzm 238 | } 239 | } 240 | 241 | fragment geomMultipointzm on GeometryMultiPointZM { 242 | geojson 243 | points { 244 | ...geomPointzm 245 | } 246 | } 247 | 248 | fragment geomMultilinestringzm on GeometryMultiLineStringZM { 249 | geojson 250 | lines { 251 | ...geomLinestringzm 252 | } 253 | } 254 | 255 | fragment geomMultipolygonzm on GeometryMultiPolygonZM { 256 | geojson 257 | polygons { 258 | ...geomPolygonzm 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_geometry.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomGeometry { 5 | __typename 6 | geojson 7 | ... on GeometryPoint { 8 | ...geomPoint 9 | } 10 | ... on GeometryLineString { 11 | ...geomLinestring 12 | } 13 | ... on GeometryPolygon { 14 | ...geomPolygon 15 | } 16 | ... on GeometryMultiPoint { 17 | ...geomMultipoint 18 | } 19 | ... on GeometryMultiLineString { 20 | ...geomMultilinestring 21 | } 22 | ... on GeometryMultiPolygon { 23 | ...geomMultipolygon 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geomPoint on GeometryPoint { 31 | geojson 32 | x 33 | y 34 | } 35 | 36 | fragment geomLinestring on GeometryLineString { 37 | geojson 38 | points { 39 | ...geomPoint 40 | } 41 | } 42 | 43 | fragment geomPolygon on GeometryPolygon { 44 | exterior { 45 | ...geomLinestring 46 | } 47 | geojson 48 | interiors { 49 | ...geomLinestring 50 | } 51 | } 52 | 53 | fragment geomMultipoint on GeometryMultiPoint { 54 | geojson 55 | points { 56 | ...geomPoint 57 | } 58 | } 59 | 60 | fragment geomMultilinestring on GeometryMultiLineString { 61 | geojson 62 | lines { 63 | ...geomLinestring 64 | } 65 | } 66 | 67 | fragment geomMultipolygon on GeometryMultiPolygon { 68 | geojson 69 | polygons { 70 | ...geomPolygon 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_geometrym.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomGeometrym { 5 | __typename 6 | geojson 7 | ... on GeometryPointM { 8 | ...geomPointm 9 | } 10 | ... on GeometryLineStringM { 11 | ...geomLinestringm 12 | } 13 | ... on GeometryPolygonM { 14 | ...geomPolygonm 15 | } 16 | ... on GeometryMultiPointM { 17 | ...geomMultipointm 18 | } 19 | ... on GeometryMultiLineStringM { 20 | ...geomMultilinestringm 21 | } 22 | ... on GeometryMultiPolygonM { 23 | ...geomMultipolygonm 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geomPointm on GeometryPointM { 31 | geojson 32 | x 33 | y 34 | } 35 | 36 | fragment geomLinestringm on GeometryLineStringM { 37 | geojson 38 | points { 39 | ...geomPointm 40 | } 41 | } 42 | 43 | fragment geomPolygonm on GeometryPolygonM { 44 | exterior { 45 | ...geomLinestringm 46 | } 47 | geojson 48 | interiors { 49 | ...geomLinestringm 50 | } 51 | } 52 | 53 | fragment geomMultipointm on GeometryMultiPointM { 54 | geojson 55 | points { 56 | ...geomPointm 57 | } 58 | } 59 | 60 | fragment geomMultilinestringm on GeometryMultiLineStringM { 61 | geojson 62 | lines { 63 | ...geomLinestringm 64 | } 65 | } 66 | 67 | fragment geomMultipolygonm on GeometryMultiPolygonM { 68 | geojson 69 | polygons { 70 | ...geomPolygonm 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_geometryz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomGeometryz { 5 | __typename 6 | geojson 7 | ... on GeometryPointZ { 8 | ...geomPointz 9 | } 10 | ... on GeometryLineStringZ { 11 | ...geomLinestringz 12 | } 13 | ... on GeometryPolygonZ { 14 | ...geomPolygonz 15 | } 16 | ... on GeometryMultiPointZ { 17 | ...geomMultipointz 18 | } 19 | ... on GeometryMultiLineStringZ { 20 | ...geomMultilinestringz 21 | } 22 | ... on GeometryMultiPolygonZ { 23 | ...geomMultipolygonz 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geomPointz on GeometryPointZ { 31 | geojson 32 | x 33 | y 34 | z 35 | } 36 | 37 | fragment geomLinestringz on GeometryLineStringZ { 38 | geojson 39 | points { 40 | ...geomPointz 41 | } 42 | } 43 | 44 | fragment geomPolygonz on GeometryPolygonZ { 45 | exterior { 46 | ...geomLinestringz 47 | } 48 | geojson 49 | interiors { 50 | ...geomLinestringz 51 | } 52 | } 53 | 54 | fragment geomMultipointz on GeometryMultiPointZ { 55 | geojson 56 | points { 57 | ...geomPointz 58 | } 59 | } 60 | 61 | fragment geomMultilinestringz on GeometryMultiLineStringZ { 62 | geojson 63 | lines { 64 | ...geomLinestringz 65 | } 66 | } 67 | 68 | fragment geomMultipolygonz on GeometryMultiPolygonZ { 69 | geojson 70 | polygons { 71 | ...geomPolygonz 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_geometryzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomGeometryzm { 5 | __typename 6 | geojson 7 | ... on GeometryPointZM { 8 | ...geomPointzm 9 | } 10 | ... on GeometryLineStringZM { 11 | ...geomLinestringzm 12 | } 13 | ... on GeometryPolygonZM { 14 | ...geomPolygonzm 15 | } 16 | ... on GeometryMultiPointZM { 17 | ...geomMultipointzm 18 | } 19 | ... on GeometryMultiLineStringZM { 20 | ...geomMultilinestringzm 21 | } 22 | ... on GeometryMultiPolygonZM { 23 | ...geomMultipolygonzm 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | fragment geomPointzm on GeometryPointZM { 31 | geojson 32 | x 33 | y 34 | z 35 | } 36 | 37 | fragment geomLinestringzm on GeometryLineStringZM { 38 | geojson 39 | points { 40 | ...geomPointzm 41 | } 42 | } 43 | 44 | fragment geomPolygonzm on GeometryPolygonZM { 45 | exterior { 46 | ...geomLinestringzm 47 | } 48 | geojson 49 | interiors { 50 | ...geomLinestringzm 51 | } 52 | } 53 | 54 | fragment geomMultipointzm on GeometryMultiPointZM { 55 | geojson 56 | points { 57 | ...geomPointzm 58 | } 59 | } 60 | 61 | fragment geomMultilinestringzm on GeometryMultiLineStringZM { 62 | geojson 63 | lines { 64 | ...geomLinestringzm 65 | } 66 | } 67 | 68 | fragment geomMultipolygonzm on GeometryMultiPolygonZM { 69 | geojson 70 | polygons { 71 | ...geomPolygonzm 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_linestring.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomLinestring { 5 | ...geomLinestring 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPoint on GeometryPoint { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestring on GeometryLineString { 18 | geojson 19 | points { 20 | ...geomPoint 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_linestringm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomLinestringm { 5 | ...geomLinestringm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointm on GeometryPointM { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestringm on GeometryLineStringM { 18 | geojson 19 | points { 20 | ...geomPointm 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_linestringz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomLinestringz { 5 | ...geomLinestringz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointz on GeometryPointZ { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringz on GeometryLineStringZ { 19 | geojson 20 | points { 21 | ...geomPointz 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_linestringzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomLinestringzm { 5 | ...geomLinestringzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointzm on GeometryPointZM { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringzm on GeometryLineStringZM { 19 | geojson 20 | points { 21 | ...geomPointzm 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multilinestring.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultilinestring { 5 | ...geomMultilinestring 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPoint on GeometryPoint { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestring on GeometryLineString { 18 | geojson 19 | points { 20 | ...geomPoint 21 | } 22 | } 23 | 24 | fragment geomMultilinestring on GeometryMultiLineString { 25 | geojson 26 | lines { 27 | ...geomLinestring 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multilinestringm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultilinestringm { 5 | ...geomMultilinestringm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointm on GeometryPointM { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestringm on GeometryLineStringM { 18 | geojson 19 | points { 20 | ...geomPointm 21 | } 22 | } 23 | 24 | fragment geomMultilinestringm on GeometryMultiLineStringM { 25 | geojson 26 | lines { 27 | ...geomLinestringm 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multilinestringz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultilinestringz { 5 | ...geomMultilinestringz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointz on GeometryPointZ { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringz on GeometryLineStringZ { 19 | geojson 20 | points { 21 | ...geomPointz 22 | } 23 | } 24 | 25 | fragment geomMultilinestringz on GeometryMultiLineStringZ { 26 | geojson 27 | lines { 28 | ...geomLinestringz 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multilinestringzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultilinestringzm { 5 | ...geomMultilinestringzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointzm on GeometryPointZM { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringzm on GeometryLineStringZM { 19 | geojson 20 | points { 21 | ...geomPointzm 22 | } 23 | } 24 | 25 | fragment geomMultilinestringzm on GeometryMultiLineStringZM { 26 | geojson 27 | lines { 28 | ...geomLinestringzm 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipoint.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipoint { 5 | ...geomMultipoint 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPoint on GeometryPoint { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomMultipoint on GeometryMultiPoint { 18 | geojson 19 | points { 20 | ...geomPoint 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipointm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipointm { 5 | ...geomMultipointm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointm on GeometryPointM { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomMultipointm on GeometryMultiPointM { 18 | geojson 19 | points { 20 | ...geomPointm 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipointz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipointz { 5 | ...geomMultipointz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointz on GeometryPointZ { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomMultipointz on GeometryMultiPointZ { 19 | geojson 20 | points { 21 | ...geomPointz 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipointzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipointzm { 5 | ...geomMultipointzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointzm on GeometryPointZM { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomMultipointzm on GeometryMultiPointZM { 19 | geojson 20 | points { 21 | ...geomPointzm 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipolygon.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipolygon { 5 | ...geomMultipolygon 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPoint on GeometryPoint { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestring on GeometryLineString { 18 | geojson 19 | points { 20 | ...geomPoint 21 | } 22 | } 23 | 24 | fragment geomPolygon on GeometryPolygon { 25 | exterior { 26 | ...geomLinestring 27 | } 28 | geojson 29 | interiors { 30 | ...geomLinestring 31 | } 32 | } 33 | 34 | fragment geomMultipolygon on GeometryMultiPolygon { 35 | geojson 36 | polygons { 37 | ...geomPolygon 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipolygonm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipolygonm { 5 | ...geomMultipolygonm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointm on GeometryPointM { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestringm on GeometryLineStringM { 18 | geojson 19 | points { 20 | ...geomPointm 21 | } 22 | } 23 | 24 | fragment geomPolygonm on GeometryPolygonM { 25 | exterior { 26 | ...geomLinestringm 27 | } 28 | geojson 29 | interiors { 30 | ...geomLinestringm 31 | } 32 | } 33 | 34 | fragment geomMultipolygonm on GeometryMultiPolygonM { 35 | geojson 36 | polygons { 37 | ...geomPolygonm 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipolygonz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipolygonz { 5 | ...geomMultipolygonz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointz on GeometryPointZ { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringz on GeometryLineStringZ { 19 | geojson 20 | points { 21 | ...geomPointz 22 | } 23 | } 24 | 25 | fragment geomPolygonz on GeometryPolygonZ { 26 | exterior { 27 | ...geomLinestringz 28 | } 29 | geojson 30 | interiors { 31 | ...geomLinestringz 32 | } 33 | } 34 | 35 | fragment geomMultipolygonz on GeometryMultiPolygonZ { 36 | geojson 37 | polygons { 38 | ...geomPolygonz 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_multipolygonzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomMultipolygonzm { 5 | ...geomMultipolygonzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointzm on GeometryPointZM { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringzm on GeometryLineStringZM { 19 | geojson 20 | points { 21 | ...geomPointzm 22 | } 23 | } 24 | 25 | fragment geomPolygonzm on GeometryPolygonZM { 26 | exterior { 27 | ...geomLinestringzm 28 | } 29 | geojson 30 | interiors { 31 | ...geomLinestringzm 32 | } 33 | } 34 | 35 | fragment geomMultipolygonzm on GeometryMultiPolygonZM { 36 | geojson 37 | polygons { 38 | ...geomPolygonzm 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_point.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPoint { 5 | ...geomPoint 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPoint on GeometryPoint { 12 | geojson 13 | x 14 | y 15 | } 16 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_pointm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPointm { 5 | ...geomPointm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointm on GeometryPointM { 12 | geojson 13 | x 14 | y 15 | } 16 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_pointz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPointz { 5 | ...geomPointz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointz on GeometryPointZ { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_pointzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPointzm { 5 | ...geomPointzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointzm on GeometryPointZM { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_polygon.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPolygon { 5 | ...geomPolygon 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPoint on GeometryPoint { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestring on GeometryLineString { 18 | geojson 19 | points { 20 | ...geomPoint 21 | } 22 | } 23 | 24 | fragment geomPolygon on GeometryPolygon { 25 | exterior { 26 | ...geomLinestring 27 | } 28 | geojson 29 | interiors { 30 | ...geomLinestring 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_polygonm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPolygonm { 5 | ...geomPolygonm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointm on GeometryPointM { 12 | geojson 13 | x 14 | y 15 | } 16 | 17 | fragment geomLinestringm on GeometryLineStringM { 18 | geojson 19 | points { 20 | ...geomPointm 21 | } 22 | } 23 | 24 | fragment geomPolygonm on GeometryPolygonM { 25 | exterior { 26 | ...geomLinestringm 27 | } 28 | geojson 29 | interiors { 30 | ...geomLinestringm 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_polygonz.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPolygonz { 5 | ...geomPolygonz 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointz on GeometryPointZ { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringz on GeometryLineStringZ { 19 | geojson 20 | points { 21 | ...geomPointz 22 | } 23 | } 24 | 25 | fragment geomPolygonz on GeometryPolygonZ { 26 | exterior { 27 | ...geomLinestringz 28 | } 29 | geojson 30 | interiors { 31 | ...geomLinestringz 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/geom_polygonzm.graphql: -------------------------------------------------------------------------------- 1 | query { 2 | allGisDebugs { 3 | nodes { 4 | geomPolygonzm { 5 | ...geomPolygonzm 6 | } 7 | } 8 | } 9 | } 10 | 11 | fragment geomPointzm on GeometryPointZM { 12 | geojson 13 | x 14 | y 15 | z 16 | } 17 | 18 | fragment geomLinestringzm on GeometryLineStringZM { 19 | geojson 20 | points { 21 | ...geomPointzm 22 | } 23 | } 24 | 25 | fragment geomPolygonzm on GeometryPolygonZM { 26 | exterior { 27 | ...geomLinestringzm 28 | } 29 | geojson 30 | interiors { 31 | ...geomLinestringzm 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/srid.geography.graphql: -------------------------------------------------------------------------------- 1 | { 2 | allGisDebugs { 3 | nodes { 4 | geog { 5 | ...geogGeometry 6 | ...geogGeometryz 7 | ...geogGeometrym 8 | ...geogGeometryzm 9 | } 10 | geogGeometry { 11 | ...geogGeometry 12 | } 13 | geogGeometrycollection { 14 | ...geogGeometrycollection 15 | } 16 | geogGeometrycollectionm { 17 | ...geogGeometrycollectionm 18 | } 19 | geogGeometrycollectionz { 20 | ...geogGeometrycollectionz 21 | } 22 | geogGeometrycollectionzm { 23 | ...geogGeometrycollectionzm 24 | } 25 | geogGeometrym { 26 | ...geogGeometrym 27 | } 28 | geogGeometryz { 29 | ...geogGeometryz 30 | } 31 | geogGeometryzm { 32 | ...geogGeometryzm 33 | } 34 | geogLinestring { 35 | ...geogLinestring 36 | } 37 | geogLinestringm { 38 | ...geogLinestringm 39 | } 40 | geogLinestringz { 41 | ...geogLinestringz 42 | } 43 | geogLinestringzm { 44 | ...geogLinestringzm 45 | } 46 | geogMultilinestring { 47 | ...geogMultilinestring 48 | } 49 | geogMultilinestringm { 50 | ...geogMultilinestringm 51 | } 52 | geogMultilinestringz { 53 | ...geogMultilinestringz 54 | } 55 | geogMultilinestringzm { 56 | ...geogMultilinestringzm 57 | } 58 | geogMultipoint { 59 | ...geogMultipoint 60 | } 61 | geogMultipointm { 62 | ...geogMultipointm 63 | } 64 | geogMultipointz { 65 | ...geogMultipointz 66 | } 67 | geogMultipointzm { 68 | ...geogMultipointzm 69 | } 70 | geogMultipolygon { 71 | ...geogMultipolygon 72 | } 73 | geogMultipolygonm { 74 | ...geogMultipolygonm 75 | } 76 | geogMultipolygonz { 77 | ...geogMultipolygonz 78 | } 79 | geogMultipolygonzm { 80 | ...geogMultipolygonzm 81 | } 82 | geogPoint { 83 | ...geogPoint 84 | } 85 | geogPointm { 86 | ...geogPointm 87 | } 88 | geogPointz { 89 | ...geogPointz 90 | } 91 | geogPointzm { 92 | ...geogPointzm 93 | } 94 | geogPolygon { 95 | ...geogPolygon 96 | } 97 | geogPolygonm { 98 | ...geogPolygonm 99 | } 100 | geogPolygonz { 101 | ...geogPolygonz 102 | } 103 | geogPolygonzm { 104 | ...geogPolygonzm 105 | } 106 | } 107 | } 108 | } 109 | 110 | fragment geogPoint on GeographyPoint { 111 | srid 112 | } 113 | 114 | fragment geogPointz on GeographyPointZ { 115 | srid 116 | } 117 | 118 | fragment geogPointm on GeographyPointM { 119 | srid 120 | } 121 | 122 | fragment geogPointzm on GeographyPointZM { 123 | srid 124 | } 125 | 126 | fragment geogLinestring on GeographyLineString { 127 | points { 128 | ...geogPoint 129 | } 130 | srid 131 | } 132 | 133 | fragment geogLinestringz on GeographyLineStringZ { 134 | points { 135 | ...geogPointz 136 | } 137 | srid 138 | } 139 | fragment geogLinestringm on GeographyLineStringM { 140 | points { 141 | ...geogPointm 142 | } 143 | srid 144 | } 145 | fragment geogLinestringzm on GeographyLineStringZM { 146 | points { 147 | ...geogPointzm 148 | } 149 | srid 150 | } 151 | 152 | fragment geogPolygon on GeographyPolygon { 153 | exterior { 154 | ...geogLinestring 155 | } 156 | interiors { 157 | ...geogLinestring 158 | } 159 | srid 160 | } 161 | fragment geogPolygonz on GeographyPolygonZ { 162 | exterior { 163 | ...geogLinestringz 164 | } 165 | interiors { 166 | ...geogLinestringz 167 | } 168 | srid 169 | } 170 | fragment geogPolygonm on GeographyPolygonM { 171 | exterior { 172 | ...geogLinestringm 173 | } 174 | interiors { 175 | ...geogLinestringm 176 | } 177 | srid 178 | } 179 | 180 | fragment geogPolygonzm on GeographyPolygonZM { 181 | exterior { 182 | ...geogLinestringzm 183 | } 184 | interiors { 185 | ...geogLinestringzm 186 | } 187 | srid 188 | } 189 | 190 | fragment geogMultipoint on GeographyMultiPoint { 191 | points { 192 | ...geogPoint 193 | } 194 | srid 195 | } 196 | 197 | fragment geogMultipointz on GeographyMultiPointZ { 198 | points { 199 | ...geogPointz 200 | } 201 | srid 202 | } 203 | 204 | fragment geogMultipointm on GeographyMultiPointM { 205 | points { 206 | ...geogPointm 207 | } 208 | srid 209 | } 210 | 211 | fragment geogMultipointzm on GeographyMultiPointZM { 212 | points { 213 | ...geogPointzm 214 | } 215 | srid 216 | } 217 | 218 | fragment geogMultilinestring on GeographyMultiLineString { 219 | lines { 220 | ...geogLinestring 221 | } 222 | srid 223 | } 224 | 225 | fragment geogMultilinestringz on GeographyMultiLineStringZ { 226 | lines { 227 | ...geogLinestringz 228 | } 229 | srid 230 | } 231 | 232 | fragment geogMultilinestringm on GeographyMultiLineStringM { 233 | lines { 234 | ...geogLinestringm 235 | } 236 | srid 237 | } 238 | 239 | fragment geogMultilinestringzm on GeographyMultiLineStringZM { 240 | lines { 241 | ...geogLinestringzm 242 | } 243 | srid 244 | } 245 | 246 | fragment geogMultipolygon on GeographyMultiPolygon { 247 | polygons { 248 | ...geogPolygon 249 | } 250 | srid 251 | } 252 | 253 | fragment geogMultipolygonz on GeographyMultiPolygonZ { 254 | polygons { 255 | ...geogPolygonz 256 | } 257 | srid 258 | } 259 | 260 | fragment geogMultipolygonm on GeographyMultiPolygonM { 261 | polygons { 262 | ...geogPolygonm 263 | } 264 | srid 265 | } 266 | 267 | fragment geogMultipolygonzm on GeographyMultiPolygonZM { 268 | polygons { 269 | ...geogPolygonzm 270 | } 271 | srid 272 | } 273 | 274 | fragment geogGeometrycollection on GeographyGeometryCollection { 275 | geometries { 276 | ... on GeographyPoint { 277 | ...geogPoint 278 | } 279 | ... on GeographyLineString { 280 | ...geogLinestring 281 | } 282 | ... on GeographyPolygon { 283 | ...geogPolygon 284 | } 285 | ... on GeographyMultiPoint { 286 | ...geogMultipoint 287 | } 288 | ... on GeographyMultiLineString { 289 | ...geogMultilinestring 290 | } 291 | ... on GeographyMultiPolygon { 292 | ...geogMultipolygon 293 | } 294 | # Cannot spread fragment "geogGeometrycollection" within itself. 295 | #... on GeographyGeometryCollection { 296 | # ...geogGeometrycollection 297 | #} 298 | } 299 | srid 300 | } 301 | 302 | fragment geogGeometrycollectionz on GeographyGeometryCollectionZ { 303 | geometries { 304 | ... on GeographyPointZ { 305 | ...geogPointz 306 | } 307 | ... on GeographyLineStringZ { 308 | ...geogLinestringz 309 | } 310 | ... on GeographyPolygonZ { 311 | ...geogPolygonz 312 | } 313 | ... on GeographyMultiPointZ { 314 | ...geogMultipointz 315 | } 316 | ... on GeographyMultiLineStringZ { 317 | ...geogMultilinestringz 318 | } 319 | ... on GeographyMultiPolygonZ { 320 | ...geogMultipolygonz 321 | } 322 | # Cannot spread fragment "geogGeometrycollectionz" within itself. 323 | #... on GeographyGeometryCollectionZ { 324 | # ...geogGeometrycollectionz 325 | #} 326 | } 327 | srid 328 | } 329 | 330 | fragment geogGeometrycollectionm on GeographyGeometryCollectionM { 331 | geometries { 332 | ... on GeographyPointM { 333 | ...geogPointm 334 | } 335 | ... on GeographyLineStringM { 336 | ...geogLinestringm 337 | } 338 | ... on GeographyPolygonM { 339 | ...geogPolygonm 340 | } 341 | ... on GeographyMultiPointM { 342 | ...geogMultipointm 343 | } 344 | ... on GeographyMultiLineStringM { 345 | ...geogMultilinestringm 346 | } 347 | ... on GeographyMultiPolygonM { 348 | ...geogMultipolygonm 349 | } 350 | # Cannot spread fragment "geogGeometrycollectionm" within itself. 351 | #... on GeographyGeometryCollectionM { 352 | # ...geogGeometrycollectionm 353 | #} 354 | } 355 | srid 356 | } 357 | 358 | fragment geogGeometrycollectionzm on GeographyGeometryCollectionZM { 359 | geometries { 360 | ... on GeographyPointZM { 361 | ...geogPointzm 362 | } 363 | ... on GeographyLineStringZM { 364 | ...geogLinestringzm 365 | } 366 | ... on GeographyPolygonZM { 367 | ...geogPolygonzm 368 | } 369 | ... on GeographyMultiPointZM { 370 | ...geogMultipointzm 371 | } 372 | ... on GeographyMultiLineStringZM { 373 | ...geogMultilinestringzm 374 | } 375 | ... on GeographyMultiPolygonZM { 376 | ...geogMultipolygonzm 377 | } 378 | # Cannot spread fragment "geogGeometrycollectionm" within itself. 379 | #... on GeographyGeometryCollectionZM { 380 | # ...geogGeometrycollectionzm 381 | #} 382 | } 383 | srid 384 | } 385 | 386 | fragment geogGeometry on GeographyGeometry { 387 | ... on GeographyPoint { 388 | ...geogPoint 389 | } 390 | ... on GeographyLineString { 391 | ...geogLinestring 392 | } 393 | ... on GeographyPolygon { 394 | ...geogPolygon 395 | } 396 | ... on GeographyMultiPoint { 397 | ...geogMultipoint 398 | } 399 | ... on GeographyMultiLineString { 400 | ...geogMultilinestring 401 | } 402 | ... on GeographyMultiPolygon { 403 | ...geogMultipolygon 404 | } 405 | ... on GeographyGeometryCollection { 406 | ...geogGeometrycollection 407 | } 408 | } 409 | 410 | fragment geogGeometryz on GeographyGeometryZ { 411 | ... on GeographyPointZ { 412 | ...geogPointz 413 | } 414 | ... on GeographyLineStringZ { 415 | ...geogLinestringz 416 | } 417 | ... on GeographyPolygonZ { 418 | ...geogPolygonz 419 | } 420 | ... on GeographyMultiPointZ { 421 | ...geogMultipointz 422 | } 423 | ... on GeographyMultiLineStringZ { 424 | ...geogMultilinestringz 425 | } 426 | ... on GeographyMultiPolygonZ { 427 | ...geogMultipolygonz 428 | } 429 | ... on GeographyGeometryCollectionZ { 430 | ...geogGeometrycollectionz 431 | } 432 | } 433 | 434 | fragment geogGeometrym on GeographyGeometryM { 435 | ... on GeographyPointM { 436 | ...geogPointm 437 | } 438 | ... on GeographyLineStringM { 439 | ...geogLinestringm 440 | } 441 | ... on GeographyPolygonM { 442 | ...geogPolygonm 443 | } 444 | ... on GeographyMultiPointM { 445 | ...geogMultipointm 446 | } 447 | ... on GeographyMultiLineStringM { 448 | ...geogMultilinestringm 449 | } 450 | ... on GeographyMultiPolygonM { 451 | ...geogMultipolygonm 452 | } 453 | ... on GeographyGeometryCollectionM { 454 | ...geogGeometrycollectionm 455 | } 456 | } 457 | 458 | fragment geogGeometryzm on GeographyGeometryZM { 459 | ... on GeographyPointZM { 460 | ...geogPointzm 461 | } 462 | ... on GeographyLineStringZM { 463 | ...geogLinestringzm 464 | } 465 | ... on GeographyPolygonZM { 466 | ...geogPolygonzm 467 | } 468 | ... on GeographyMultiPointZM { 469 | ...geogMultipointzm 470 | } 471 | ... on GeographyMultiLineStringZM { 472 | ...geogMultilinestringzm 473 | } 474 | ... on GeographyMultiPolygonZM { 475 | ...geogMultipolygonzm 476 | } 477 | ... on GeographyGeometryCollectionZM { 478 | ...geogGeometrycollectionzm 479 | } 480 | } 481 | -------------------------------------------------------------------------------- /__tests__/fixtures/queries/srid.geometry.graphql: -------------------------------------------------------------------------------- 1 | { 2 | allGisDebugs { 3 | nodes { 4 | geom { 5 | ...geomGeometry 6 | ...geomGeometryz 7 | ...geomGeometrym 8 | ...geomGeometryzm 9 | } 10 | geomGeometry { 11 | ...geomGeometry 12 | } 13 | geomGeometrycollection { 14 | ...geomGeometrycollection 15 | } 16 | geomGeometrycollectionm { 17 | ...geomGeometrycollectionm 18 | } 19 | geomGeometrycollectionz { 20 | ...geomGeometrycollectionz 21 | } 22 | geomGeometrycollectionzm { 23 | ...geomGeometrycollectionzm 24 | } 25 | geomGeometrym { 26 | ...geomGeometrym 27 | } 28 | geomGeometryz { 29 | ...geomGeometryz 30 | } 31 | geomGeometryzm { 32 | ...geomGeometryzm 33 | } 34 | geomLinestring { 35 | ...geomLinestring 36 | } 37 | geomLinestringm { 38 | ...geomLinestringm 39 | } 40 | geomLinestringz { 41 | ...geomLinestringz 42 | } 43 | geomLinestringzm { 44 | ...geomLinestringzm 45 | } 46 | geomMultilinestring { 47 | ...geomMultilinestring 48 | } 49 | geomMultilinestringm { 50 | ...geomMultilinestringm 51 | } 52 | geomMultilinestringz { 53 | ...geomMultilinestringz 54 | } 55 | geomMultilinestringzm { 56 | ...geomMultilinestringzm 57 | } 58 | geomMultipoint { 59 | ...geomMultipoint 60 | } 61 | geomMultipointm { 62 | ...geomMultipointm 63 | } 64 | geomMultipointz { 65 | ...geomMultipointz 66 | } 67 | geomMultipointzm { 68 | ...geomMultipointzm 69 | } 70 | geomMultipolygon { 71 | ...geomMultipolygon 72 | } 73 | geomMultipolygonm { 74 | ...geomMultipolygonm 75 | } 76 | geomMultipolygonz { 77 | ...geomMultipolygonz 78 | } 79 | geomMultipolygonzm { 80 | ...geomMultipolygonzm 81 | } 82 | geomPoint { 83 | ...geomPoint 84 | } 85 | geomPointm { 86 | ...geomPointm 87 | } 88 | geomPointz { 89 | ...geomPointz 90 | } 91 | geomPointzm { 92 | ...geomPointzm 93 | } 94 | geomPolygon { 95 | ...geomPolygon 96 | } 97 | geomPolygonm { 98 | ...geomPolygonm 99 | } 100 | geomPolygonz { 101 | ...geomPolygonz 102 | } 103 | geomPolygonzm { 104 | ...geomPolygonzm 105 | } 106 | } 107 | } 108 | } 109 | 110 | fragment geomPoint on GeometryPoint { 111 | srid 112 | } 113 | 114 | fragment geomPointz on GeometryPointZ { 115 | srid 116 | } 117 | 118 | fragment geomPointm on GeometryPointM { 119 | srid 120 | } 121 | 122 | fragment geomPointzm on GeometryPointZM { 123 | srid 124 | } 125 | 126 | fragment geomLinestring on GeometryLineString { 127 | points { 128 | ...geomPoint 129 | } 130 | srid 131 | } 132 | 133 | fragment geomLinestringz on GeometryLineStringZ { 134 | points { 135 | ...geomPointz 136 | } 137 | srid 138 | } 139 | fragment geomLinestringm on GeometryLineStringM { 140 | points { 141 | ...geomPointm 142 | } 143 | srid 144 | } 145 | fragment geomLinestringzm on GeometryLineStringZM { 146 | points { 147 | ...geomPointzm 148 | } 149 | srid 150 | } 151 | 152 | fragment geomPolygon on GeometryPolygon { 153 | exterior { 154 | ...geomLinestring 155 | } 156 | interiors { 157 | ...geomLinestring 158 | } 159 | srid 160 | } 161 | fragment geomPolygonz on GeometryPolygonZ { 162 | exterior { 163 | ...geomLinestringz 164 | } 165 | interiors { 166 | ...geomLinestringz 167 | } 168 | srid 169 | } 170 | fragment geomPolygonm on GeometryPolygonM { 171 | exterior { 172 | ...geomLinestringm 173 | } 174 | interiors { 175 | ...geomLinestringm 176 | } 177 | srid 178 | } 179 | 180 | fragment geomPolygonzm on GeometryPolygonZM { 181 | exterior { 182 | ...geomLinestringzm 183 | } 184 | interiors { 185 | ...geomLinestringzm 186 | } 187 | srid 188 | } 189 | 190 | fragment geomMultipoint on GeometryMultiPoint { 191 | points { 192 | ...geomPoint 193 | } 194 | srid 195 | } 196 | 197 | fragment geomMultipointz on GeometryMultiPointZ { 198 | points { 199 | ...geomPointz 200 | } 201 | srid 202 | } 203 | 204 | fragment geomMultipointm on GeometryMultiPointM { 205 | points { 206 | ...geomPointm 207 | } 208 | srid 209 | } 210 | 211 | fragment geomMultipointzm on GeometryMultiPointZM { 212 | points { 213 | ...geomPointzm 214 | } 215 | srid 216 | } 217 | 218 | fragment geomMultilinestring on GeometryMultiLineString { 219 | lines { 220 | ...geomLinestring 221 | } 222 | srid 223 | } 224 | 225 | fragment geomMultilinestringz on GeometryMultiLineStringZ { 226 | lines { 227 | ...geomLinestringz 228 | } 229 | srid 230 | } 231 | 232 | fragment geomMultilinestringm on GeometryMultiLineStringM { 233 | lines { 234 | ...geomLinestringm 235 | } 236 | srid 237 | } 238 | 239 | fragment geomMultilinestringzm on GeometryMultiLineStringZM { 240 | lines { 241 | ...geomLinestringzm 242 | } 243 | srid 244 | } 245 | 246 | fragment geomMultipolygon on GeometryMultiPolygon { 247 | polygons { 248 | ...geomPolygon 249 | } 250 | srid 251 | } 252 | 253 | fragment geomMultipolygonz on GeometryMultiPolygonZ { 254 | polygons { 255 | ...geomPolygonz 256 | } 257 | srid 258 | } 259 | 260 | fragment geomMultipolygonm on GeometryMultiPolygonM { 261 | polygons { 262 | ...geomPolygonm 263 | } 264 | srid 265 | } 266 | 267 | fragment geomMultipolygonzm on GeometryMultiPolygonZM { 268 | polygons { 269 | ...geomPolygonzm 270 | } 271 | srid 272 | } 273 | 274 | fragment geomGeometrycollection on GeometryGeometryCollection { 275 | geometries { 276 | ... on GeometryPoint { 277 | ...geomPoint 278 | } 279 | ... on GeometryLineString { 280 | ...geomLinestring 281 | } 282 | ... on GeometryPolygon { 283 | ...geomPolygon 284 | } 285 | ... on GeometryMultiPoint { 286 | ...geomMultipoint 287 | } 288 | ... on GeometryMultiLineString { 289 | ...geomMultilinestring 290 | } 291 | ... on GeometryMultiPolygon { 292 | ...geomMultipolygon 293 | } 294 | # Cannot spread fragment "geomGeometrycollection" within itself. 295 | #... on GeometryGeometryCollection { 296 | # ...geomGeometrycollection 297 | #} 298 | } 299 | srid 300 | } 301 | 302 | fragment geomGeometrycollectionz on GeometryGeometryCollectionZ { 303 | geometries { 304 | ... on GeometryPointZ { 305 | ...geomPointz 306 | } 307 | ... on GeometryLineStringZ { 308 | ...geomLinestringz 309 | } 310 | ... on GeometryPolygonZ { 311 | ...geomPolygonz 312 | } 313 | ... on GeometryMultiPointZ { 314 | ...geomMultipointz 315 | } 316 | ... on GeometryMultiLineStringZ { 317 | ...geomMultilinestringz 318 | } 319 | ... on GeometryMultiPolygonZ { 320 | ...geomMultipolygonz 321 | } 322 | # Cannot spread fragment "geomGeometrycollectionz" within itself. 323 | #... on GeometryGeometryCollectionZ { 324 | # ...geomGeometrycollectionz 325 | #} 326 | } 327 | srid 328 | } 329 | 330 | fragment geomGeometrycollectionm on GeometryGeometryCollectionM { 331 | geometries { 332 | ... on GeometryPointM { 333 | ...geomPointm 334 | } 335 | ... on GeometryLineStringM { 336 | ...geomLinestringm 337 | } 338 | ... on GeometryPolygonM { 339 | ...geomPolygonm 340 | } 341 | ... on GeometryMultiPointM { 342 | ...geomMultipointm 343 | } 344 | ... on GeometryMultiLineStringM { 345 | ...geomMultilinestringm 346 | } 347 | ... on GeometryMultiPolygonM { 348 | ...geomMultipolygonm 349 | } 350 | # Cannot spread fragment "geomGeometrycollectionm" within itself. 351 | #... on GeometryGeometryCollectionM { 352 | # ...geomGeometrycollectionm 353 | #} 354 | } 355 | srid 356 | } 357 | 358 | fragment geomGeometrycollectionzm on GeometryGeometryCollectionZM { 359 | geometries { 360 | ... on GeometryPointZM { 361 | ...geomPointzm 362 | } 363 | ... on GeometryLineStringZM { 364 | ...geomLinestringzm 365 | } 366 | ... on GeometryPolygonZM { 367 | ...geomPolygonzm 368 | } 369 | ... on GeometryMultiPointZM { 370 | ...geomMultipointzm 371 | } 372 | ... on GeometryMultiLineStringZM { 373 | ...geomMultilinestringzm 374 | } 375 | ... on GeometryMultiPolygonZM { 376 | ...geomMultipolygonzm 377 | } 378 | # Cannot spread fragment "geomGeometrycollectionm" within itself. 379 | #... on GeometryGeometryCollectionZM { 380 | # ...geomGeometrycollectionzm 381 | #} 382 | } 383 | srid 384 | } 385 | 386 | fragment geomGeometry on GeometryGeometry { 387 | ... on GeometryPoint { 388 | ...geomPoint 389 | } 390 | ... on GeometryLineString { 391 | ...geomLinestring 392 | } 393 | ... on GeometryPolygon { 394 | ...geomPolygon 395 | } 396 | ... on GeometryMultiPoint { 397 | ...geomMultipoint 398 | } 399 | ... on GeometryMultiLineString { 400 | ...geomMultilinestring 401 | } 402 | ... on GeometryMultiPolygon { 403 | ...geomMultipolygon 404 | } 405 | ... on GeometryGeometryCollection { 406 | ...geomGeometrycollection 407 | } 408 | } 409 | 410 | fragment geomGeometryz on GeometryGeometryZ { 411 | ... on GeometryPointZ { 412 | ...geomPointz 413 | } 414 | ... on GeometryLineStringZ { 415 | ...geomLinestringz 416 | } 417 | ... on GeometryPolygonZ { 418 | ...geomPolygonz 419 | } 420 | ... on GeometryMultiPointZ { 421 | ...geomMultipointz 422 | } 423 | ... on GeometryMultiLineStringZ { 424 | ...geomMultilinestringz 425 | } 426 | ... on GeometryMultiPolygonZ { 427 | ...geomMultipolygonz 428 | } 429 | ... on GeometryGeometryCollectionZ { 430 | ...geomGeometrycollectionz 431 | } 432 | } 433 | 434 | fragment geomGeometrym on GeometryGeometryM { 435 | ... on GeometryPointM { 436 | ...geomPointm 437 | } 438 | ... on GeometryLineStringM { 439 | ...geomLinestringm 440 | } 441 | ... on GeometryPolygonM { 442 | ...geomPolygonm 443 | } 444 | ... on GeometryMultiPointM { 445 | ...geomMultipointm 446 | } 447 | ... on GeometryMultiLineStringM { 448 | ...geomMultilinestringm 449 | } 450 | ... on GeometryMultiPolygonM { 451 | ...geomMultipolygonm 452 | } 453 | ... on GeometryGeometryCollectionM { 454 | ...geomGeometrycollectionm 455 | } 456 | } 457 | 458 | fragment geomGeometryzm on GeometryGeometryZM { 459 | ... on GeometryPointZM { 460 | ...geomPointzm 461 | } 462 | ... on GeometryLineStringZM { 463 | ...geomLinestringzm 464 | } 465 | ... on GeometryPolygonZM { 466 | ...geomPolygonzm 467 | } 468 | ... on GeometryMultiPointZM { 469 | ...geomMultipointzm 470 | } 471 | ... on GeometryMultiLineStringZM { 472 | ...geomMultilinestringzm 473 | } 474 | ... on GeometryMultiPolygonZM { 475 | ...geomMultipolygonzm 476 | } 477 | ... on GeometryGeometryCollectionZM { 478 | ...geomGeometrycollectionzm 479 | } 480 | } 481 | -------------------------------------------------------------------------------- /__tests__/helpers.ts: -------------------------------------------------------------------------------- 1 | import * as pg from "pg"; 2 | 3 | export async function withPgPool( 4 | cb: (pool: pg.Pool) => Promise 5 | ): Promise { 6 | const pool = new pg.Pool({ 7 | connectionString: process.env.TEST_DATABASE_URL, 8 | }); 9 | try { 10 | return await cb(pool); 11 | } finally { 12 | pool.end(); 13 | } 14 | } 15 | 16 | export async function withPgClient( 17 | cb: (client: pg.PoolClient) => Promise 18 | ): Promise { 19 | return withPgPool(async pool => { 20 | const client = await pool.connect(); 21 | try { 22 | return await cb(client); 23 | } finally { 24 | client.release(); 25 | } 26 | }); 27 | } 28 | 29 | export async function withTransaction( 30 | cb: (client: pg.PoolClient) => Promise, 31 | closeCommand = "rollback" 32 | ): Promise { 33 | return withPgClient(async client => { 34 | await client.query("begin"); 35 | try { 36 | return await cb(client); 37 | } finally { 38 | await client.query(closeCommand); 39 | } 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /__tests__/integration/queries.test.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | import * as path from "path"; 3 | import * as pg from "pg"; 4 | import { promisify } from "util"; 5 | import { GraphQLSchema, graphql } from "graphql"; 6 | import { withPgClient } from "../helpers"; 7 | import { createPostGraphileSchema } from "postgraphile-core"; 8 | import PostgisPlugin from "../../src/index"; 9 | 10 | const readFile = promisify(fs.readFile); 11 | 12 | const queriesDir = `${__dirname}/../fixtures/queries`; 13 | const queryFileNames = fs.readdirSync(queriesDir); 14 | 15 | const schemas = ["graphile_postgis"]; 16 | const options = { 17 | appendPlugins: [PostgisPlugin], 18 | }; 19 | 20 | let gqlSchema: GraphQLSchema; 21 | 22 | beforeAll(async () => { 23 | await withPgClient(async (client: pg.PoolClient) => { 24 | gqlSchema = await createPostGraphileSchema(client, schemas, options); 25 | }); 26 | }); 27 | 28 | for (const queryFileName of queryFileNames) { 29 | test(queryFileName, async () => { 30 | const query = await readFile( 31 | path.resolve(queriesDir, queryFileName), 32 | "utf8" 33 | ); 34 | const result = await withPgClient(async (client: pg.PoolClient) => 35 | graphql(gqlSchema, query, null, { pgClient: client }) 36 | ); 37 | expect(result).toMatchSnapshot(); 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /__tests__/schema.minimal_dimensional.test.ts: -------------------------------------------------------------------------------- 1 | import * as pg from "pg"; 2 | import { withPgClient } from "./helpers"; 3 | import { createPostGraphileSchema } from "postgraphile-core"; 4 | import PostgisPlugin from "../src/index"; 5 | import { lexicographicSortSchema } from "graphql"; 6 | 7 | const schemas = ["graphile_postgis_minimal_dimensional"]; 8 | const options = { 9 | appendPlugins: [PostgisPlugin], 10 | }; 11 | 12 | test("prints a schema with this plugin", () => 13 | withPgClient(async (client: pg.PoolClient) => { 14 | const gqlSchema = await createPostGraphileSchema(client, schemas, options); 15 | expect(lexicographicSortSchema(gqlSchema)).toMatchSnapshot(); 16 | })); 17 | -------------------------------------------------------------------------------- /__tests__/schema.minimal_type.test.ts: -------------------------------------------------------------------------------- 1 | import * as pg from "pg"; 2 | import { withPgClient } from "./helpers"; 3 | import { createPostGraphileSchema } from "postgraphile-core"; 4 | import PostgisPlugin from "../src/index"; 5 | import { lexicographicSortSchema } from "graphql"; 6 | 7 | const schemas = ["graphile_postgis_minimal_type"]; 8 | const options = { 9 | appendPlugins: [PostgisPlugin], 10 | }; 11 | 12 | test("prints a schema with this plugin", () => 13 | withPgClient(async (client: pg.PoolClient) => { 14 | const gqlSchema = await createPostGraphileSchema(client, schemas, options); 15 | expect(lexicographicSortSchema(gqlSchema)).toMatchSnapshot(); 16 | })); 17 | -------------------------------------------------------------------------------- /__tests__/schema.minimal_type_and_srid.test.ts: -------------------------------------------------------------------------------- 1 | import * as pg from "pg"; 2 | import { withPgClient } from "./helpers"; 3 | import { createPostGraphileSchema } from "postgraphile-core"; 4 | import PostgisPlugin from "../src/index"; 5 | import { lexicographicSortSchema } from "graphql"; 6 | 7 | const schemas = ["graphile_postgis_minimal_type_and_srid"]; 8 | const options = { 9 | appendPlugins: [PostgisPlugin], 10 | }; 11 | 12 | test("prints a schema with this plugin", () => 13 | withPgClient(async (client: pg.PoolClient) => { 14 | const gqlSchema = await createPostGraphileSchema(client, schemas, options); 15 | expect(lexicographicSortSchema(gqlSchema)).toMatchSnapshot(); 16 | })); 17 | -------------------------------------------------------------------------------- /__tests__/schema.minimal_unconstrained.test.ts: -------------------------------------------------------------------------------- 1 | import * as pg from "pg"; 2 | import { withPgClient } from "./helpers"; 3 | import { createPostGraphileSchema } from "postgraphile-core"; 4 | import PostgisPlugin from "../src/index"; 5 | import { lexicographicSortSchema } from "graphql"; 6 | 7 | const schemas = ["graphile_postgis_minimal_unconstrained"]; 8 | const options = { 9 | appendPlugins: [PostgisPlugin], 10 | }; 11 | 12 | test("prints a schema with this plugin", () => 13 | withPgClient(async (client: pg.PoolClient) => { 14 | const gqlSchema = await createPostGraphileSchema(client, schemas, options); 15 | expect(lexicographicSortSchema(gqlSchema)).toMatchSnapshot(); 16 | })); 17 | -------------------------------------------------------------------------------- /__tests__/schema.sql: -------------------------------------------------------------------------------- 1 | drop schema if exists graphile_postgis cascade; 2 | create schema graphile_postgis; 3 | 4 | drop extension if exists postgis cascade; 5 | create extension if not exists postgis with schema public; 6 | 7 | --insert into spatial_ref_sys (srid, auth_name, auth_srid, proj4text, srtext) values 8 | -- (4979, 'epsg', 4979, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ', 'GEOGCS["WGS 84",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137.0,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS["Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AXIS["Ellipsoidal height",UP],AUTHORITY["EPSG","4979"]]'); 9 | 10 | create table graphile_postgis.gis_debug ( 11 | id serial primary key, 12 | 13 | --------------- 14 | -- GEOGRAPHY -- 15 | --------------- 16 | 17 | geog geography, 18 | 19 | -- XY 20 | geog_geometry geography(geometry), 21 | geog_point geography(point), 22 | geog_linestring geography(linestring), 23 | geog_polygon geography(polygon), 24 | geog_multipoint geography(multipoint), 25 | geog_multilinestring geography(multilinestring), 26 | geog_multipolygon geography(multipolygon), 27 | geog_geometrycollection geography(geometrycollection), 28 | 29 | -- XYZ 30 | geog_geometryz geography(geometryz), 31 | geog_pointz geography(pointz), 32 | geog_linestringz geography(linestringz), 33 | geog_polygonz geography(polygonz), 34 | geog_multipointz geography(multipointz), 35 | geog_multilinestringz geography(multilinestringz), 36 | geog_multipolygonz geography(multipolygonz), 37 | geog_geometrycollectionz geography(geometrycollectionz), 38 | 39 | -- XYM 40 | geog_geometrym geography(geometrym), 41 | geog_pointm geography(pointm), 42 | geog_linestringm geography(linestringm), 43 | geog_polygonm geography(polygonm), 44 | geog_multipointm geography(multipointm), 45 | geog_multilinestringm geography(multilinestringm), 46 | geog_multipolygonm geography(multipolygonm), 47 | geog_geometrycollectionm geography(geometrycollectionm), 48 | 49 | -- XYZM 50 | geog_geometryzm geography(geometryzm), 51 | geog_pointzm geography(pointzm), 52 | geog_linestringzm geography(linestringzm), 53 | geog_polygonzm geography(polygonzm), 54 | geog_multipointzm geography(multipointzm), 55 | geog_multilinestringzm geography(multilinestringzm), 56 | geog_multipolygonzm geography(multipolygonzm), 57 | geog_geometrycollectionzm geography(geometrycollectionzm), 58 | 59 | -- EPSG:4326 (WGS 84) [deg,deg] 60 | 61 | --geog_point_4326 geography(point,4326), 62 | --geog_linestring_4326 geography(linestring,4326), 63 | --geog_polygon_4326 geography(polygon,4326), 64 | --geog_multipoint_4326 geography(multipoint,4326), 65 | --geog_multilinestring_4326 geography(multilinestring,4326), 66 | --geog_multipolygon_4326 geography(multipolygon,4326), 67 | --geog_geometrycollection_4326 geography(geometrycollection,4326), 68 | 69 | -- EPSG:4979 (WGS 84) [deg,deg,m] 70 | 71 | --geog_pointz_4979 geography(pointz,4979), 72 | --geog_linestringz_4979 geography(linestringz,4979), 73 | --geog_polygonz_4979 geography(polygonz,4979), 74 | --geog_multipointz_4979 geography(multipointz,4979), 75 | --geog_multilinestringz_4979 geography(multilinestringz,4979), 76 | --geog_multipolygonz_4979 geography(multipolygonz,4979), 77 | --geog_geometrycollectionz_4979 geography(geometrycollectionz,4979), 78 | 79 | -------------- 80 | -- GEOMETRY -- 81 | -------------- 82 | 83 | geom geometry, 84 | 85 | -- XY 86 | geom_geometry geometry(geometry), 87 | geom_point geometry(point), 88 | geom_linestring geometry(linestring), 89 | geom_polygon geometry(polygon), 90 | geom_multipoint geometry(multipoint), 91 | geom_multilinestring geometry(multilinestring), 92 | geom_multipolygon geometry(multipolygon), 93 | geom_geometrycollection geometry(geometrycollection), 94 | 95 | -- XYZ 96 | geom_geometryz geometry(geometryz), 97 | geom_pointz geometry(pointz), 98 | geom_linestringz geometry(linestringz), 99 | geom_polygonz geometry(polygonz), 100 | geom_multipointz geometry(multipointz), 101 | geom_multilinestringz geometry(multilinestringz), 102 | geom_multipolygonz geometry(multipolygonz), 103 | geom_geometrycollectionz geometry(geometrycollectionz), 104 | 105 | -- XYM 106 | geom_geometrym geometry(geometrym), 107 | geom_pointm geometry(pointm), 108 | geom_linestringm geometry(linestringm), 109 | geom_polygonm geometry(polygonm), 110 | geom_multipointm geometry(multipointm), 111 | geom_multilinestringm geometry(multilinestringm), 112 | geom_multipolygonm geometry(multipolygonm), 113 | geom_geometrycollectionm geometry(geometrycollectionm), 114 | 115 | -- XYZM 116 | geom_geometryzm geometry(geometryzm), 117 | geom_pointzm geometry(pointzm), 118 | geom_linestringzm geometry(linestringzm), 119 | geom_polygonzm geometry(polygonzm), 120 | geom_multipointzm geometry(multipointzm), 121 | geom_multilinestringzm geometry(multilinestringzm), 122 | geom_multipolygonzm geometry(multipolygonzm), 123 | geom_geometrycollectionzm geometry(geometrycollectionzm) 124 | 125 | -- EPSG:27700 (OSGB 1936 / British National Grid) [m,m] 126 | 127 | --geom_point_27700 geometry(point,27700), 128 | --geom_linestring_27700 geometry(linestring,27700), 129 | --geom_polygon_27700 geometry(polygon,27700), 130 | --geom_multipoint_27700 geometry(multipoint,27700), 131 | --geom_multilinestring_27700 geometry(multilinestring,27700), 132 | --geom_multipolygon_27700 geometry(multipolygon,27700), 133 | --geom_geometrycollection_27700 geometry(geometrycollection,27700), 134 | 135 | -- EPSG:7405 (OSGB 1936 / British National Grid + ODN height) [m,m,m] 136 | 137 | --geom_pointz_7405 geometry(pointz,7405), 138 | --geom_linestringz_7405 geometry(linestringz,7405), 139 | --geom_polygonz_7405 geometry(polygonz,7405), 140 | --geom_multipointz_7405 geometry(multipointz,7405), 141 | --geom_multilinestringz_7405 geometry(multilinestringz,7405), 142 | --geom_multipolygonz_7405 geometry(multipolygonz,7405), 143 | --geom_geometrycollectionz_7405 geometry(geometrycollectionz,7405) 144 | ); 145 | 146 | insert into graphile_postgis.gis_debug ( 147 | geog, 148 | 149 | geog_geometry, 150 | geog_point, 151 | geog_linestring, 152 | geog_polygon, 153 | geog_multipoint, 154 | geog_multilinestring, 155 | geog_multipolygon, 156 | geog_geometrycollection, 157 | 158 | geog_geometryz, 159 | geog_pointz, 160 | geog_linestringz, 161 | geog_polygonz, 162 | geog_multipointz, 163 | geog_multilinestringz, 164 | geog_multipolygonz, 165 | geog_geometrycollectionz, 166 | 167 | geog_geometrym, 168 | geog_pointm, 169 | geog_linestringm, 170 | geog_polygonm, 171 | geog_multipointm, 172 | geog_multilinestringm, 173 | geog_multipolygonm, 174 | geog_geometrycollectionm, 175 | 176 | geog_geometryzm, 177 | geog_pointzm, 178 | geog_linestringzm, 179 | geog_polygonzm, 180 | geog_multipointzm, 181 | geog_multilinestringzm, 182 | geog_multipolygonzm, 183 | geog_geometrycollectionzm, 184 | 185 | geom, 186 | 187 | geom_geometry, 188 | geom_point, 189 | geom_linestring, 190 | geom_polygon, 191 | geom_multipoint, 192 | geom_multilinestring, 193 | geom_multipolygon, 194 | geom_geometrycollection, 195 | 196 | geom_geometryz, 197 | geom_pointz, 198 | geom_linestringz, 199 | geom_polygonz, 200 | geom_multipointz, 201 | geom_multilinestringz, 202 | geom_multipolygonz, 203 | geom_geometrycollectionz, 204 | 205 | geom_geometrym, 206 | geom_pointm, 207 | geom_linestringm, 208 | geom_polygonm, 209 | geom_multipointm, 210 | geom_multilinestringm, 211 | geom_multipolygonm, 212 | geom_geometrycollectionm, 213 | 214 | geom_geometryzm, 215 | geom_pointzm, 216 | geom_linestringzm, 217 | geom_polygonzm, 218 | geom_multipointzm, 219 | geom_multilinestringzm, 220 | geom_multipolygonzm, 221 | geom_geometrycollectionzm 222 | ) values ( 223 | ST_GeographyFromText('GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))'), 224 | 225 | ST_GeographyFromText('POINT (30 10)'), 226 | ST_GeographyFromText('POINT (30 10)'), 227 | ST_GeographyFromText('LINESTRING (30 10, 10 30, 40 40)'), 228 | ST_GeographyFromText('POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))'), 229 | ST_GeographyFromText('MULTIPOINT (10 40, 40 30, 20 20, 30 10)'), 230 | ST_GeographyFromText('MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))'), 231 | ST_GeographyFromText('MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))'), 232 | ST_GeographyFromText('GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))'), 233 | 234 | ST_GeographyFromText('POINT Z (30 10 80)'), 235 | ST_GeographyFromText('POINT Z (30 10 80)'), 236 | ST_GeographyFromText('LINESTRING Z (30 10 80, 10 30 80, 40 40 80)'), 237 | ST_GeographyFromText('POLYGON Z ((35 10 80, 45 45 80, 15 40 80, 10 20 80, 35 10 80), (20 30 80, 35 35 80, 30 20 80, 20 30 80))'), 238 | ST_GeographyFromText('MULTIPOINT Z (10 40 80, 40 30 80, 20 20 80, 30 10 80)'), 239 | ST_GeographyFromText('MULTILINESTRING Z ((10 10 80, 20 20 80, 10 40 80), (40 40 80, 30 30 80, 40 20 80, 30 10 80))'), 240 | ST_GeographyFromText('MULTIPOLYGON Z (((40 40 80, 20 45 80, 45 30 80, 40 40 80)), ((20 35 80, 10 30 80, 10 10 80, 30 5 80, 45 20 80, 20 35 80), (30 20 80, 20 15 80, 20 25 80, 30 20 80)))'), 241 | ST_GeographyFromText('GEOMETRYCOLLECTION Z (POINT Z (4 6 80),LINESTRING Z (4 6 80,7 10 80))'), 242 | 243 | ST_GeographyFromText('POINT M (30 10 99)'), 244 | ST_GeographyFromText('POINT M (30 10 99)'), 245 | ST_GeographyFromText('LINESTRING M (30 10 99, 10 30 99, 40 40 99)'), 246 | ST_GeographyFromText('POLYGON M ((35 10 99, 45 45 99, 15 40 99, 10 20 99, 35 10 99), (20 30 99, 35 35 99, 30 20 99, 20 30 99))'), 247 | ST_GeographyFromText('MULTIPOINT M (10 40 99, 40 30 99, 20 20 99, 30 10 99)'), 248 | ST_GeographyFromText('MULTILINESTRING M ((10 10 99, 20 20 99, 10 40 99), (40 40 99, 30 30 99, 40 20 99, 30 10 99))'), 249 | ST_GeographyFromText('MULTIPOLYGON M (((40 40 99, 20 45 99, 45 30 99, 40 40 99)), ((20 35 99, 10 30 99, 10 10 99, 30 5 99, 45 20 99, 20 35 99), (30 20 99, 20 15 99, 20 25 99, 30 20 99)))'), 250 | ST_GeographyFromText('GEOMETRYCOLLECTION M (POINT M (4 6 99),LINESTRING M (4 6 99,7 10 99))'), 251 | 252 | ST_GeographyFromText('POINT ZM (30 10 80 99)'), 253 | ST_GeographyFromText('POINT ZM (30 10 80 99)'), 254 | ST_GeographyFromText('LINESTRING ZM (30 10 80 99, 10 30 80 99, 40 40 80 99)'), 255 | ST_GeographyFromText('POLYGON ZM ((35 10 80 99, 45 45 80 99, 15 40 80 99, 10 20 80 99, 35 10 80 99), (20 30 80 99, 35 35 80 99, 30 20 80 99, 20 30 80 99))'), 256 | ST_GeographyFromText('MULTIPOINT ZM (10 40 80 99, 40 30 80 99, 20 20 80 99, 30 10 80 99)'), 257 | ST_GeographyFromText('MULTILINESTRING ZM ((10 10 80 99, 20 20 80 99, 10 40 80 99), (40 40 80 99, 30 30 80 99, 40 20 80 99, 30 10 80 99))'), 258 | ST_GeographyFromText('MULTIPOLYGON ZM (((40 40 80 99, 20 45 80 99, 45 30 80 99, 40 40 80 99)), ((20 35 80 99, 10 30 80 99, 10 10 80 99, 30 5 80 99, 45 20 80 99, 20 35 80 99), (30 20 80 99, 20 15 80 99, 20 25 80 99, 30 20 80 99)))'), 259 | ST_GeographyFromText('GEOMETRYCOLLECTION ZM (POINT ZM (4 6 80 99),LINESTRING ZM (4 6 80 99,7 10 80 99))'), 260 | 261 | ST_GeometryFromText('GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))'), 262 | 263 | ST_GeometryFromText('POINT (30 10)'), 264 | ST_GeometryFromText('POINT (30 10)'), 265 | ST_GeometryFromText('LINESTRING (30 10, 10 30, 40 40)'), 266 | ST_GeometryFromText('POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))'), 267 | ST_GeometryFromText('MULTIPOINT (10 40, 40 30, 20 20, 30 10)'), 268 | ST_GeometryFromText('MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))'), 269 | ST_GeometryFromText('MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))'), 270 | ST_GeometryFromText('GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))'), 271 | 272 | ST_GeometryFromText('POINT Z (30 10 80)'), 273 | ST_GeometryFromText('POINT Z (30 10 80)'), 274 | ST_GeometryFromText('LINESTRING Z (30 10 80, 10 30 80, 40 40 80)'), 275 | ST_GeometryFromText('POLYGON Z ((35 10 80, 45 45 80, 15 40 80, 10 20 80, 35 10 80), (20 30 80, 35 35 80, 30 20 80, 20 30 80))'), 276 | ST_GeometryFromText('MULTIPOINT Z (10 40 80, 40 30 80, 20 20 80, 30 10 80)'), 277 | ST_GeometryFromText('MULTILINESTRING Z ((10 10 80, 20 20 80, 10 40 80), (40 40 80, 30 30 80, 40 20 80, 30 10 80))'), 278 | ST_GeometryFromText('MULTIPOLYGON Z (((40 40 80, 20 45 80, 45 30 80, 40 40 80)), ((20 35 80, 10 30 80, 10 10 80, 30 5 80, 45 20 80, 20 35 80), (30 20 80, 20 15 80, 20 25 80, 30 20 80)))'), 279 | ST_GeometryFromText('GEOMETRYCOLLECTION Z (POINT Z (4 6 80),LINESTRING Z (4 6 80,7 10 80))'), 280 | 281 | ST_GeometryFromText('POINT M (30 10 99)'), 282 | ST_GeometryFromText('POINT M (30 10 99)'), 283 | ST_GeometryFromText('LINESTRING M (30 10 99, 10 30 99, 40 40 99)'), 284 | ST_GeometryFromText('POLYGON M ((35 10 99, 45 45 99, 15 40 99, 10 20 99, 35 10 99), (20 30 99, 35 35 99, 30 20 99, 20 30 99))'), 285 | ST_GeometryFromText('MULTIPOINT M (10 40 99, 40 30 99, 20 20 99, 30 10 99)'), 286 | ST_GeometryFromText('MULTILINESTRING M ((10 10 99, 20 20 99, 10 40 99), (40 40 99, 30 30 99, 40 20 99, 30 10 99))'), 287 | ST_GeometryFromText('MULTIPOLYGON M (((40 40 99, 20 45 99, 45 30 99, 40 40 99)), ((20 35 99, 10 30 99, 10 10 99, 30 5 99, 45 20 99, 20 35 99), (30 20 99, 20 15 99, 20 25 99, 30 20 99)))'), 288 | ST_GeometryFromText('GEOMETRYCOLLECTION M (POINT M (4 6 99),LINESTRING M (4 6 99,7 10 99))'), 289 | 290 | ST_GeometryFromText('POINT ZM (30 10 80 99)'), 291 | ST_GeometryFromText('POINT ZM (30 10 80 99)'), 292 | ST_GeometryFromText('LINESTRING ZM (30 10 80 99, 10 30 80 99, 40 40 80 99)'), 293 | ST_GeometryFromText('POLYGON ZM ((35 10 80 99, 45 45 80 99, 15 40 80 99, 10 20 80 99, 35 10 80 99), (20 30 80 99, 35 35 80 99, 30 20 80 99, 20 30 80 99))'), 294 | ST_GeometryFromText('MULTIPOINT ZM (10 40 80 99, 40 30 80 99, 20 20 80 99, 30 10 80 99)'), 295 | ST_GeometryFromText('MULTILINESTRING ZM ((10 10 80 99, 20 20 80 99, 10 40 80 99), (40 40 80 99, 30 30 80 99, 40 20 80 99, 30 10 80 99))'), 296 | ST_GeometryFromText('MULTIPOLYGON ZM (((40 40 80 99, 20 45 80 99, 45 30 80 99, 40 40 80 99)), ((20 35 80 99, 10 30 80 99, 10 10 80 99, 30 5 80 99, 45 20 80 99, 20 35 80 99), (30 20 80 99, 20 15 80 99, 20 25 80 99, 30 20 80 99)))'), 297 | ST_GeometryFromText('GEOMETRYCOLLECTION ZM (POINT ZM (4 6 80 99),LINESTRING ZM (4 6 80 99,7 10 80 99))') 298 | ); 299 | 300 | -- SCHEMA: graphile_postgis_minimal_unconstrained 301 | -- one geometry column with no constraints 302 | 303 | drop schema if exists graphile_postgis_minimal_unconstrained cascade; 304 | create schema graphile_postgis_minimal_unconstrained; 305 | create table graphile_postgis_minimal_unconstrained.foo ( 306 | id serial primary key, 307 | geom geometry 308 | ); 309 | insert into graphile_postgis_minimal_unconstrained.foo (geom) values 310 | (GeomFromEWKT('SRID=27700;POINT (437300 115500)')); 311 | 312 | -- SCHEMA: graphile_postgis_minimal_dimensional 313 | -- one geometry column with a dimensional constraint 314 | 315 | drop schema if exists graphile_postgis_minimal_dimensional cascade; 316 | create schema graphile_postgis_minimal_dimensional; 317 | create table graphile_postgis_minimal_dimensional.foo ( 318 | id serial primary key, 319 | geom_geometry geometry(geometry) 320 | ); 321 | insert into graphile_postgis_minimal_dimensional.foo (geom_geometry) values 322 | (GeomFromEWKT('SRID=27700;POINT (437300 115500)')); 323 | 324 | -- SCHEMA: graphile_postgis_minimal_type 325 | -- one geometry column with a type constraint 326 | 327 | drop schema if exists graphile_postgis_minimal_type cascade; 328 | create schema graphile_postgis_minimal_type; 329 | create table graphile_postgis_minimal_type.foo ( 330 | id serial primary key, 331 | geom_point geometry(point) 332 | ); 333 | insert into graphile_postgis_minimal_type.foo (geom_point) values 334 | (GeomFromEWKT('SRID=27700;POINT (437300 115500)')); 335 | 336 | -- SCHEMA: graphile_postgis_minimal_type_and_srid 337 | -- one geometry column with a type constraint and an SRID constraint 338 | 339 | drop schema if exists graphile_postgis_minimal_type_and_srid cascade; 340 | create schema graphile_postgis_minimal_type_and_srid; 341 | create table graphile_postgis_minimal_type_and_srid.foo ( 342 | id serial primary key, 343 | geom_point_27700 geometry(point,27700) 344 | ); 345 | insert into graphile_postgis_minimal_type_and_srid.foo (geom_point_27700) values 346 | (GeomFromEWKT('SRID=27700;POINT (437300 115500)')); 347 | -------------------------------------------------------------------------------- /__tests__/schema.test.ts: -------------------------------------------------------------------------------- 1 | import * as pg from "pg"; 2 | import { withPgClient } from "./helpers"; 3 | import { createPostGraphileSchema } from "postgraphile-core"; 4 | import PostgisPlugin from "../src/index"; 5 | import { lexicographicSortSchema } from "graphql"; 6 | 7 | const schemas = ["graphile_postgis"]; 8 | const options = { 9 | appendPlugins: [PostgisPlugin], 10 | }; 11 | 12 | test("prints a schema with this plugin", () => 13 | withPgClient(async (client: pg.PoolClient) => { 14 | const gqlSchema = await createPostGraphileSchema(client, schemas, options); 15 | expect(lexicographicSortSchema(gqlSchema)).toMatchSnapshot(); 16 | })); 17 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ["/src", "/__tests__"], 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | testRegex: "(/__tests__/.*\\.(test|spec))\\.[tj]sx?$", 7 | moduleFileExtensions: ["ts", "js", "json"], 8 | snapshotSerializers: ["jest-serializer-graphql-schema"], 9 | }; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@graphile/postgis", 3 | "version": "0.2.0", 4 | "description": "PostGIS support for PostGraphile", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "tsc", 8 | "watch": "tsc --watch", 9 | "test": "scripts/test", 10 | "lint": "prettier --list-different 'src/**/*' && tslint --config tslint.json --project tsconfig.json", 11 | "postgraphile": "nodemon --watch dist -x 'postgraphile --append-plugins `pwd`/dist/index.js -c graphile_test -s graphile_postgis -p 5123 --enhance-graphiql --watch --dynamic-json --show-error-stack --extended-errors severity,code,detail,hint,position,internalPosition,internalQuery,where,schema,table,column,dataType,constraint,file,line,routine'", 12 | "dev": "psql -f __tests__/schema.sql graphile_test && concurrently --kill-others 'npm run watch' 'npm run postgraphile'", 13 | "prepack": "rm -Rf dist && npm run build" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/graphile/postgis.git" 18 | }, 19 | "keywords": [ 20 | "postgraphile", 21 | "graphile", 22 | "plugin", 23 | "postgis", 24 | "gis", 25 | "postgresql", 26 | "graphql" 27 | ], 28 | "author": "Benjie Gillam ", 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/graphile/postgis/issues" 32 | }, 33 | "homepage": "https://github.com/graphile/postgis#readme", 34 | "peerDependencies": { 35 | "graphile-build": "^4.4.0", 36 | "graphile-build-pg": "^4.4.0", 37 | "graphql": ">=0.6 <16", 38 | "pg-sql2": ">=2.2.1 <5" 39 | }, 40 | "devDependencies": { 41 | "@types/debug": "^4.1.5", 42 | "@types/jest": "^26.0.22", 43 | "concurrently": "^6.0.2", 44 | "graphql": "^15", 45 | "jest": "^26.6.3", 46 | "nodemon": "^1.19.1", 47 | "postgraphile": "^4.9.0", 48 | "postgraphile-core": "^4.9.0", 49 | "prettier": "1.18.2", 50 | "ts-jest": "^26.5.4", 51 | "tslint": "^5.19.0", 52 | "tslint-config-prettier": "^1.18.0", 53 | "typescript": "^3.5.3" 54 | }, 55 | "dependencies": { 56 | "debug": "^4.1.1", 57 | "jest-serializer-graphql-schema": "^5.0.0-1.1", 58 | "tslib": "^1.10.0" 59 | }, 60 | "resolutions": { 61 | "graphql": "^15" 62 | }, 63 | "files": [ 64 | "dist" 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /scripts/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ -x ".env" ]; then 5 | set -a 6 | . ./.env 7 | set +a 8 | fi; 9 | 10 | if [ "$TEST_DATABASE_URL" == "" ]; then 11 | echo "ERROR: No test database configured; aborting" 12 | echo 13 | echo "To resolve this, ensure environmental variable TEST_DATABASE_URL is set" 14 | exit 1; 15 | fi; 16 | 17 | # Import latest schema (throw on error) 18 | psql -Xqv ON_ERROR_STOP=1 -f __tests__/schema.sql "$TEST_DATABASE_URL" 19 | echo "Database reset successfully ✅" 20 | 21 | # Now run the tests 22 | jest -i $@ 23 | -------------------------------------------------------------------------------- /src/NOTES.md: -------------------------------------------------------------------------------- 1 | ## GEOGRAPHY(type, srid) 2 | 3 | All the GEOGRAPHY types are stored as one type in PostgreSQL and they use the 4 | type modifier (a 4 byte integer) to determine the subtype. For example: 5 | 6 | ```sql 7 | geography(point, 4326) 8 | ``` 9 | 10 | These results in the PostgreSQL type modifier value (stored in pg_attribute) 11 | of `1107460`: 12 | 13 | ``` 14 | atttypmod: 1107460 15 | ``` 16 | 17 | We can extract the `srid` from this 4-byte integer as follows: 18 | 19 | ``` 20 | (1107460 >> 8) & (2 ** 16 - 1): 4326 21 | ``` 22 | 23 | So the SRID is `4326`. 24 | 25 | We can extract the type of geography as follows: 26 | 27 | ``` 28 | (atttypmod && 255) >> 2: 1 29 | ``` 30 | 31 | The meanings of this value are as follows: 32 | 33 | ``` 34 | 1 - point 35 | 2 - linestr 36 | 3 - polygon 37 | 4 - multipoint 38 | 5 - multilinestr 39 | 6 - multipolygon 40 | 7 - geometrycollection 41 | ``` 42 | -------------------------------------------------------------------------------- /src/PostgisExtensionDetectionPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { PgExtension, PgType } from "graphile-build-pg"; 3 | import debug from "./debug"; 4 | 5 | const plugin: Plugin = builder => { 6 | builder.hook("build", build => { 7 | const { pgIntrospectionResultsByKind: introspectionResultsByKind } = build; 8 | const pgGISExtension = introspectionResultsByKind.extension.find( 9 | (e: PgExtension) => e.name === "postgis" 10 | ); 11 | // Check we have the postgis extension 12 | if (!pgGISExtension) { 13 | debug("PostGIS extension not found in database; skipping"); 14 | return build; 15 | } 16 | // Extract the geography and geometry types 17 | const pgGISGeometryType = introspectionResultsByKind.type.find( 18 | (t: PgType) => 19 | t.name === "geometry" && t.namespaceId === pgGISExtension.namespaceId 20 | ); 21 | const pgGISGeographyType = introspectionResultsByKind.type.find( 22 | (t: PgType) => 23 | t.name === "geography" && t.namespaceId === pgGISExtension.namespaceId 24 | ); 25 | if (!pgGISGeographyType || !pgGISGeometryType) { 26 | throw new Error( 27 | "PostGIS is installed, but we couldn't find the geometry/geography types!" 28 | ); 29 | } 30 | return build.extend(build, { 31 | pgGISGraphQLTypesByTypeAndSubtype: {}, 32 | pgGISGraphQLInterfaceTypesByType: {}, 33 | pgGISGeometryType, 34 | pgGISGeographyType, 35 | pgGISExtension, 36 | }); 37 | }); 38 | }; 39 | 40 | export default plugin; 41 | -------------------------------------------------------------------------------- /src/PostgisInflectionPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { PgType } from "graphile-build-pg"; 3 | import { Subtype } from "./interfaces"; 4 | import { SUBTYPE_STRING_BY_SUBTYPE } from "./constants"; 5 | 6 | const plugin: Plugin = builder => { 7 | builder.hook("inflection", inflection => { 8 | return { 9 | ...inflection, 10 | gisType(type: PgType, subtype: Subtype, hasZ: boolean, hasM: boolean) { 11 | return this.upperCamelCase( 12 | [ 13 | type.name, 14 | SUBTYPE_STRING_BY_SUBTYPE[subtype], 15 | hasZ ? "z" : null, 16 | hasM ? "m" : null, 17 | ] 18 | .filter(_ => _) 19 | .join("-") 20 | ); 21 | }, 22 | gisInterfaceName(type: PgType) { 23 | return this.upperCamelCase(`${type.name}-interface`); 24 | }, 25 | gisDimensionInterfaceName(type: PgType, hasZ: boolean, hasM: boolean) { 26 | return this.upperCamelCase( 27 | [ 28 | type.name, 29 | SUBTYPE_STRING_BY_SUBTYPE[0], 30 | hasZ ? "z" : null, 31 | hasM ? "m" : null, 32 | ] 33 | .filter(_ => _) 34 | .join("-") 35 | ); 36 | }, 37 | geojsonFieldName() { 38 | return `geojson`; 39 | }, 40 | gisXFieldName(type: PgType) { 41 | return type.name === "geography" ? "longitude" : "x"; 42 | }, 43 | gisYFieldName(type: PgType) { 44 | return type.name === "geography" ? "latitude" : "y"; 45 | }, 46 | gisZFieldName(type: PgType) { 47 | return type.name === "geography" ? "height" : "z"; 48 | }, 49 | }; 50 | }); 51 | }; 52 | 53 | export default plugin; 54 | -------------------------------------------------------------------------------- /src/PostgisRegisterTypesPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import debug from "./debug"; 3 | import { PgType } from "graphile-build-pg"; 4 | import { GraphQLResolveInfo, GraphQLType, GraphQLNamedType } from "graphql"; 5 | import { Subtype } from "./interfaces"; 6 | import { getGISTypeDetails, getGISTypeModifier, getGISTypeName } from "./utils"; 7 | import { SQL } from "pg-sql2"; 8 | import makeGeoJSONType from "./makeGeoJSONType"; 9 | 10 | function identity(input: T): T { 11 | return input; 12 | } 13 | 14 | const plugin: Plugin = builder => { 15 | builder.hook("build", build => { 16 | const GeoJSON = makeGeoJSONType( 17 | build.graphql, 18 | build.inflection.builtin("GeoJSON") 19 | ); 20 | build.addType(GeoJSON); 21 | 22 | return build.extend(build, { 23 | getPostgisTypeByGeometryType( 24 | pgGISType: PgType, 25 | subtype: Subtype, 26 | hasZ: boolean = false, 27 | hasM: boolean = false, 28 | srid: number = 0 29 | ) { 30 | const typeModifier = getGISTypeModifier(subtype, hasZ, hasM, srid); 31 | return this.pgGetGqlTypeByTypeIdAndModifier(pgGISType.id, typeModifier); 32 | }, 33 | pgGISIncludedTypes: [], 34 | pgGISIncludeType(Type: GraphQLNamedType) { 35 | this.pgGISIncludedTypes.push(Type); 36 | }, 37 | }); 38 | }); 39 | 40 | builder.hook( 41 | "init", 42 | (_, build) => { 43 | const { 44 | newWithHooks, 45 | pgIntrospectionResultsByKind: introspectionResultsByKind, 46 | graphql: { 47 | GraphQLInt, 48 | GraphQLNonNull, 49 | GraphQLInterfaceType, 50 | GraphQLObjectType, 51 | }, 52 | pgRegisterGqlTypeByTypeId, 53 | pgRegisterGqlInputTypeByTypeId, 54 | pgTweaksByTypeIdAndModifer, 55 | getTypeByName, 56 | pgSql: sql, 57 | pg2gql, 58 | pg2GqlMapper, 59 | inflection, 60 | pgGISGraphQLTypesByTypeAndSubtype: constructedTypes, 61 | pgGISGraphQLInterfaceTypesByType: _interfaces, 62 | pgGISGeometryType: GEOMETRY_TYPE, 63 | pgGISGeographyType: GEOGRAPHY_TYPE, 64 | pgGISExtension: POSTGIS, 65 | pgGISIncludeType: includeType, 66 | } = build; 67 | if (!GEOMETRY_TYPE || !GEOGRAPHY_TYPE) { 68 | return _; 69 | } 70 | debug("PostGIS plugin enabled"); 71 | 72 | const GeoJSON = getTypeByName(inflection.builtin("GeoJSON")); 73 | const geojsonFieldName = inflection.geojsonFieldName(); 74 | 75 | function getGisInterface(type: PgType) { 76 | const zmflag = -1; // no dimensional constraint; could be xy/xyz/xym/xyzm 77 | if (!_interfaces[type.id]) { 78 | _interfaces[type.id] = {}; 79 | } 80 | if (!_interfaces[type.id][zmflag]) { 81 | _interfaces[type.id][zmflag] = newWithHooks( 82 | GraphQLInterfaceType, 83 | { 84 | name: inflection.gisInterfaceName(type), 85 | fields: { 86 | [geojsonFieldName]: { 87 | type: GeoJSON, 88 | description: "Converts the object to GeoJSON", 89 | }, 90 | srid: { 91 | type: new GraphQLNonNull(GraphQLInt), 92 | description: "Spatial reference identifier (SRID)", 93 | }, 94 | }, 95 | resolveType(value: any, _info?: GraphQLResolveInfo) { 96 | const Type = 97 | constructedTypes[type.id] && 98 | constructedTypes[type.id][value.__gisType]; 99 | return Type; 100 | }, 101 | description: `All ${type.name} types implement this interface`, 102 | }, 103 | { 104 | isPgGISInterface: true, 105 | pgGISType: type, 106 | pgGISZMFlag: zmflag, 107 | } 108 | ); 109 | // Force creation of all GraphQL types that could be resolved from this interface 110 | const subtypes: Array = [1, 2, 3, 4, 5, 6, 7]; 111 | for (const subtype of subtypes) { 112 | for (const hasZ of [false, true]) { 113 | for (const hasM of [false, true]) { 114 | const typeModifier = getGISTypeModifier(subtype, hasZ, hasM, 0); 115 | const Type = getGisType(type, typeModifier); 116 | includeType(Type); 117 | } 118 | } 119 | } 120 | } 121 | return _interfaces[type.id][zmflag]; 122 | } 123 | function getGisDimensionInterface( 124 | type: PgType, 125 | hasZ: boolean, 126 | hasM: boolean 127 | ) { 128 | const zmflag = (hasZ ? 2 : 0) + (hasM ? 1 : 0); // Equivalent to ST_Zmflag: https://postgis.net/docs/ST_Zmflag.html 129 | const coords = { 0: "XY", 1: "XYM", 2: "XYZ", 3: "XYZM" }[zmflag]; 130 | if (!_interfaces[type.id]) { 131 | _interfaces[type.id] = {}; 132 | } 133 | if (!_interfaces[type.id][zmflag]) { 134 | _interfaces[type.id][zmflag] = newWithHooks( 135 | GraphQLInterfaceType, 136 | { 137 | name: inflection.gisDimensionInterfaceName(type, hasZ, hasM), 138 | fields: { 139 | [geojsonFieldName]: { 140 | type: GeoJSON, 141 | description: "Converts the object to GeoJSON", 142 | }, 143 | srid: { 144 | type: new GraphQLNonNull(GraphQLInt), 145 | description: "Spatial reference identifier (SRID)", 146 | }, 147 | }, 148 | resolveType(value: any, _info?: GraphQLResolveInfo) { 149 | const Type = 150 | constructedTypes[type.id] && 151 | constructedTypes[type.id][value.__gisType]; 152 | return Type; 153 | }, 154 | description: `All ${type.name} ${coords} types implement this interface`, 155 | }, 156 | { 157 | isPgGISDimensionInterface: true, 158 | pgGISType: type, 159 | pgGISZMFlag: zmflag, 160 | } 161 | ); 162 | // Force creation of all GraphQL types that could be resolved from this interface 163 | const subtypes: Array = [1, 2, 3, 4, 5, 6, 7]; 164 | for (const subtype of subtypes) { 165 | const typeModifier = getGISTypeModifier(subtype, hasZ, hasM, 0); 166 | const Type = getGisType(type, typeModifier); 167 | includeType(Type); 168 | } 169 | } 170 | return _interfaces[type.id][zmflag]; 171 | } 172 | function getGisType(type: PgType, typeModifier: number) { 173 | const typeId = type.id; 174 | const typeDetails = getGISTypeDetails(typeModifier); 175 | const { subtype, hasZ, hasM, srid } = typeDetails; 176 | debug( 177 | `Getting ${type.name} type ${type.id}|${typeModifier}|${subtype}|${hasZ}|${hasM}|${srid}` 178 | ); 179 | if (!constructedTypes[type.id]) { 180 | constructedTypes[type.id] = {}; 181 | } 182 | const typeModifierKey = typeModifier != null ? typeModifier : -1; 183 | if (!pgTweaksByTypeIdAndModifer[typeId]) { 184 | pgTweaksByTypeIdAndModifer[typeId] = {}; 185 | } 186 | if (!pgTweaksByTypeIdAndModifer[typeId][typeModifierKey]) { 187 | pgTweaksByTypeIdAndModifer[typeId][typeModifierKey] = ( 188 | fragment: SQL, 189 | _resolveData: any 190 | ) => { 191 | const params = [ 192 | sql.literal("__gisType"), 193 | sql.fragment`${sql.identifier( 194 | POSTGIS.namespaceName || "public", 195 | "postgis_type_name" // MUST be lowercase! 196 | )}( 197 | ${sql.identifier( 198 | POSTGIS.namespaceName || "public", 199 | "geometrytype" // MUST be lowercase! 200 | )}(${fragment}), 201 | ${sql.identifier( 202 | POSTGIS.namespaceName || "public", 203 | "st_coorddim" // MUST be lowercase! 204 | )}(${fragment}::text) 205 | )`, 206 | sql.literal("__srid"), 207 | sql.fragment`${sql.identifier( 208 | POSTGIS.namespaceName || "public", 209 | "st_srid" // MUST be lowercase! 210 | )}(${fragment})`, 211 | sql.literal("__geojson"), 212 | sql.fragment`${sql.identifier( 213 | POSTGIS.namespaceName || "public", 214 | "st_asgeojson" // MUST be lowercase! 215 | )}(${fragment})::JSON`, 216 | ]; 217 | return sql.fragment`(case when ${fragment} is null then null else json_build_object( 218 | ${sql.join(params, ", ")} 219 | ) end)`; 220 | }; 221 | } 222 | const gisTypeKey = 223 | typeModifier != null ? getGISTypeName(subtype, hasZ, hasM) : -1; 224 | if (!constructedTypes[type.id][gisTypeKey]) { 225 | if (typeModifierKey === -1) { 226 | constructedTypes[type.id][gisTypeKey] = getGisInterface(type); 227 | } else if (subtype === 0) { 228 | constructedTypes[type.id][gisTypeKey] = getGisDimensionInterface( 229 | type, 230 | hasZ, 231 | hasM 232 | ); 233 | } else { 234 | const intType = introspectionResultsByKind.type.find( 235 | (t: PgType) => 236 | t.name === "int4" && t.namespaceName === "pg_catalog" 237 | ); 238 | const jsonType = introspectionResultsByKind.type.find( 239 | (t: PgType) => 240 | t.name === "json" && t.namespaceName === "pg_catalog" 241 | ); 242 | 243 | constructedTypes[type.id][gisTypeKey] = newWithHooks( 244 | GraphQLObjectType, 245 | { 246 | name: inflection.gisType(type, subtype, hasZ, hasM, srid), 247 | interfaces: () => [ 248 | getGisInterface(type), 249 | getGisDimensionInterface(type, hasZ, hasM), 250 | ], 251 | fields: { 252 | [geojsonFieldName]: { 253 | type: GeoJSON, 254 | resolve: ( 255 | data: any, 256 | _args: any, 257 | _context: any, 258 | _resolveInfo: GraphQLResolveInfo 259 | ) => { 260 | return pg2gql(data.__geojson, jsonType); 261 | }, 262 | }, 263 | srid: { 264 | type: new GraphQLNonNull(GraphQLInt), 265 | resolve: ( 266 | data: any, 267 | _args: any, 268 | _context: any, 269 | _resolveInfo: GraphQLResolveInfo 270 | ) => { 271 | return pg2gql(data.__srid, intType); 272 | }, 273 | }, 274 | }, 275 | }, 276 | { 277 | isPgGISType: true, 278 | pgGISType: type, 279 | pgGISTypeDetails: typeDetails, 280 | } 281 | ); 282 | } 283 | } 284 | return constructedTypes[type.id][gisTypeKey]; 285 | } 286 | 287 | debug(`Registering handler for ${GEOGRAPHY_TYPE.id}`); 288 | 289 | pgRegisterGqlInputTypeByTypeId(GEOGRAPHY_TYPE.id, () => GeoJSON); 290 | pg2GqlMapper[GEOGRAPHY_TYPE.id] = { 291 | map: identity, 292 | unmap: (o: any) => 293 | sql.fragment`st_geomfromgeojson(${sql.value( 294 | JSON.stringify(o) 295 | )}::text)::${sql.identifier( 296 | POSTGIS.namespaceName || "public", 297 | "geography" 298 | )}`, 299 | }; 300 | 301 | pgRegisterGqlTypeByTypeId( 302 | GEOGRAPHY_TYPE.id, 303 | (_set: (type: GraphQLType) => void, typeModifier: number) => { 304 | return getGisType(GEOGRAPHY_TYPE, typeModifier); 305 | } 306 | ); 307 | 308 | debug(`Registering handler for ${GEOMETRY_TYPE.id}`); 309 | 310 | pgRegisterGqlInputTypeByTypeId(GEOMETRY_TYPE.id, () => GeoJSON); 311 | pg2GqlMapper[GEOMETRY_TYPE.id] = { 312 | map: identity, 313 | unmap: (o: any) => 314 | sql.fragment`st_geomfromgeojson(${sql.value( 315 | JSON.stringify(o) 316 | )}::text)`, 317 | }; 318 | 319 | pgRegisterGqlTypeByTypeId( 320 | GEOMETRY_TYPE.id, 321 | (_set: (type: GraphQLType) => void, typeModifier: number) => { 322 | return getGisType(GEOMETRY_TYPE, typeModifier); 323 | } 324 | ); 325 | return _; 326 | }, 327 | ["PostgisTypes"], 328 | ["PgTables"], 329 | ["PgTypes"] 330 | ); 331 | 332 | builder.hook("GraphQLSchema", (schema, build) => { 333 | if (!schema.types) { 334 | schema.types = []; 335 | } 336 | schema.types = [...schema.types, ...build.pgGISIncludedTypes]; 337 | return schema; 338 | }); 339 | }; 340 | 341 | export default plugin; 342 | -------------------------------------------------------------------------------- /src/PostgisVersionPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | 3 | const plugin: Plugin = builder => { 4 | builder.hook("build", build => { 5 | const pkg = require("./../package.json"); 6 | 7 | // Check dependencies 8 | if (!build.versions) { 9 | throw new Error( 10 | `Plugin ${pkg.name}@${pkg.version} requires graphile-build@^4.1.0 in order to check dependencies (current version: ${build.graphileBuildVersion})` 11 | ); 12 | } 13 | const depends = (name: string, range: string) => { 14 | if (!build.hasVersion(name, range)) { 15 | throw new Error( 16 | `Plugin ${pkg.name}@${pkg.version} requires ${name}@${range} (${ 17 | build.versions[name] 18 | ? `current version: ${build.versions[name]}` 19 | : "not found" 20 | })` 21 | ); 22 | } 23 | }; 24 | depends("graphile-build-pg", "^4.4.0"); 25 | 26 | // Register this plugin 27 | build.versions = build.extend(build.versions, { [pkg.name]: pkg.version }); 28 | 29 | return build; 30 | }); 31 | }; 32 | 33 | export default plugin; 34 | -------------------------------------------------------------------------------- /src/Postgis_GeometryCollection_GeometriesPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import debug from "./debug"; 3 | import { GIS_SUBTYPE } from "./constants"; 4 | import { getGISTypeName } from "./utils"; 5 | 6 | const plugin: Plugin = builder => { 7 | builder.hook( 8 | "GraphQLObjectType:fields", 9 | function AddGeometriesToGeometryCollection(fields, build, context) { 10 | const { 11 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 12 | } = context; 13 | if ( 14 | !isPgGISType || 15 | !pgGISTypeDetails || 16 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.GeometryCollection 17 | ) { 18 | return fields; 19 | } 20 | const { 21 | extend, 22 | pgGISGraphQLInterfaceTypesByType, 23 | graphql: { GraphQLList }, 24 | } = build; 25 | const { hasZ, hasM } = pgGISTypeDetails; 26 | const zmflag = (hasZ ? 2 : 0) + (hasM ? 1 : 0); // Equivalent to ST_Zmflag: https://postgis.net/docs/ST_Zmflag.html 27 | const Interface = pgGISGraphQLInterfaceTypesByType[pgGISType.id][zmflag]; 28 | if (!Interface) { 29 | debug("Unexpectedly couldn't find the interface"); 30 | return fields; 31 | } 32 | 33 | return extend(fields, { 34 | geometries: { 35 | type: new GraphQLList(Interface), 36 | resolve(data: any) { 37 | return data.__geojson.geometries.map((geom: any) => { 38 | return { 39 | __gisType: getGISTypeName(GIS_SUBTYPE[geom.type], hasZ, hasM), 40 | __srid: data.__srid, 41 | __geojson: geom, 42 | }; 43 | }); 44 | }, 45 | }, 46 | }); 47 | } 48 | ); 49 | }; 50 | export default plugin; 51 | -------------------------------------------------------------------------------- /src/Postgis_LineString_PointsPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { GIS_SUBTYPE } from "./constants"; 3 | import { getGISTypeName } from "./utils"; 4 | 5 | const plugin: Plugin = builder => { 6 | builder.hook("GraphQLObjectType:fields", (fields, build, context) => { 7 | const { 8 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 9 | } = context; 10 | if ( 11 | !isPgGISType || 12 | !pgGISTypeDetails || 13 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.LineString 14 | ) { 15 | return fields; 16 | } 17 | const { 18 | extend, 19 | getPostgisTypeByGeometryType, 20 | graphql: { GraphQLList }, 21 | } = build; 22 | const { hasZ, hasM, srid } = pgGISTypeDetails; 23 | const Point = getPostgisTypeByGeometryType( 24 | pgGISType, 25 | GIS_SUBTYPE.Point, 26 | hasZ, 27 | hasM, 28 | srid 29 | ); 30 | 31 | return extend(fields, { 32 | points: { 33 | type: new GraphQLList(Point), 34 | resolve(data: any) { 35 | return data.__geojson.coordinates.map((coord: any) => { 36 | return { 37 | __gisType: getGISTypeName(GIS_SUBTYPE.Point, hasZ, hasM), 38 | __srid: data.__srid, 39 | __geojson: { 40 | type: "Point", 41 | coordinates: coord, 42 | }, 43 | }; 44 | }); 45 | }, 46 | }, 47 | }); 48 | }); 49 | }; 50 | export default plugin; 51 | -------------------------------------------------------------------------------- /src/Postgis_MultiLineString_LineStringsPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { GIS_SUBTYPE } from "./constants"; 3 | import { getGISTypeName } from "./utils"; 4 | 5 | const plugin: Plugin = builder => { 6 | builder.hook("GraphQLObjectType:fields", (fields, build, context) => { 7 | const { 8 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 9 | } = context; 10 | if ( 11 | !isPgGISType || 12 | !pgGISTypeDetails || 13 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.MultiLineString 14 | ) { 15 | return fields; 16 | } 17 | const { 18 | extend, 19 | getPostgisTypeByGeometryType, 20 | graphql: { GraphQLList }, 21 | } = build; 22 | const { hasZ, hasM, srid } = pgGISTypeDetails; 23 | const LineString = getPostgisTypeByGeometryType( 24 | pgGISType, 25 | GIS_SUBTYPE.LineString, 26 | hasZ, 27 | hasM, 28 | srid 29 | ); 30 | 31 | return extend(fields, { 32 | lines: { 33 | type: new GraphQLList(LineString), 34 | resolve(data: any) { 35 | return data.__geojson.coordinates.map((coord: any) => ({ 36 | __gisType: getGISTypeName(GIS_SUBTYPE.LineString, hasZ, hasM), 37 | __srid: data.__srid, 38 | __geojson: { 39 | type: "LineString", 40 | coordinates: coord, 41 | }, 42 | })); 43 | }, 44 | }, 45 | }); 46 | }); 47 | }; 48 | export default plugin; 49 | -------------------------------------------------------------------------------- /src/Postgis_MultiPoint_PointsPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { GIS_SUBTYPE } from "./constants"; 3 | import { getGISTypeName } from "./utils"; 4 | 5 | const plugin: Plugin = builder => { 6 | builder.hook("GraphQLObjectType:fields", (fields, build, context) => { 7 | const { 8 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 9 | } = context; 10 | if ( 11 | !isPgGISType || 12 | !pgGISTypeDetails || 13 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.MultiPoint 14 | ) { 15 | return fields; 16 | } 17 | const { 18 | extend, 19 | getPostgisTypeByGeometryType, 20 | graphql: { GraphQLList }, 21 | } = build; 22 | const { hasZ, hasM, srid } = pgGISTypeDetails; 23 | const Point = getPostgisTypeByGeometryType( 24 | pgGISType, 25 | GIS_SUBTYPE.Point, 26 | hasZ, 27 | hasM, 28 | srid 29 | ); 30 | 31 | return extend(fields, { 32 | points: { 33 | type: new GraphQLList(Point), 34 | resolve(data: any) { 35 | return data.__geojson.coordinates.map((coord: any) => ({ 36 | __gisType: getGISTypeName(GIS_SUBTYPE.Point, hasZ, hasM), 37 | __srid: data.__srid, 38 | __geojson: { 39 | type: "Point", 40 | coordinates: coord, 41 | }, 42 | })); 43 | }, 44 | }, 45 | }); 46 | }); 47 | }; 48 | export default plugin; 49 | -------------------------------------------------------------------------------- /src/Postgis_MultiPolygon_PolygonsPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { GIS_SUBTYPE } from "./constants"; 3 | import { getGISTypeName } from "./utils"; 4 | 5 | const plugin: Plugin = builder => { 6 | builder.hook("GraphQLObjectType:fields", (fields, build, context) => { 7 | const { 8 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 9 | } = context; 10 | if ( 11 | !isPgGISType || 12 | !pgGISTypeDetails || 13 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.MultiPolygon 14 | ) { 15 | return fields; 16 | } 17 | const { 18 | extend, 19 | getPostgisTypeByGeometryType, 20 | graphql: { GraphQLList }, 21 | } = build; 22 | const { hasZ, hasM, srid } = pgGISTypeDetails; 23 | const Polygon = getPostgisTypeByGeometryType( 24 | pgGISType, 25 | GIS_SUBTYPE.Polygon, 26 | hasZ, 27 | hasM, 28 | srid 29 | ); 30 | 31 | return extend(fields, { 32 | polygons: { 33 | type: new GraphQLList(Polygon), 34 | resolve(data: any) { 35 | return data.__geojson.coordinates.map((coord: any) => ({ 36 | __gisType: getGISTypeName(GIS_SUBTYPE.Polygon, hasZ, hasM), 37 | __srid: data.__srid, 38 | __geojson: { 39 | type: "Polygon", 40 | coordinates: coord, 41 | }, 42 | })); 43 | }, 44 | }, 45 | }); 46 | }); 47 | }; 48 | export default plugin; 49 | -------------------------------------------------------------------------------- /src/Postgis_Point_LatitudeLongitudePlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { GIS_SUBTYPE } from "./constants"; 3 | 4 | const plugin: Plugin = builder => { 5 | builder.hook("GraphQLObjectType:fields", (fields, build, context) => { 6 | const { 7 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 8 | } = context; 9 | if ( 10 | !isPgGISType || 11 | !pgGISTypeDetails || 12 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.Point 13 | ) { 14 | return fields; 15 | } 16 | const { 17 | extend, 18 | graphql: { GraphQLNonNull, GraphQLFloat }, 19 | inflection, 20 | } = build; 21 | const xFieldName = inflection.gisXFieldName(pgGISType); 22 | const yFieldName = inflection.gisYFieldName(pgGISType); 23 | const zFieldName = inflection.gisZFieldName(pgGISType); 24 | return extend(fields, { 25 | [xFieldName]: { 26 | type: new GraphQLNonNull(GraphQLFloat), 27 | resolve(data: any) { 28 | return data.__geojson.coordinates[0]; 29 | }, 30 | }, 31 | [yFieldName]: { 32 | type: new GraphQLNonNull(GraphQLFloat), 33 | resolve(data: any) { 34 | return data.__geojson.coordinates[1]; 35 | }, 36 | }, 37 | ...(pgGISTypeDetails.hasZ 38 | ? { 39 | [zFieldName]: { 40 | type: new GraphQLNonNull(GraphQLFloat), 41 | resolve(data: any) { 42 | return data.__geojson.coordinates[2]; 43 | }, 44 | }, 45 | } 46 | : {}), 47 | }); 48 | }); 49 | }; 50 | export default plugin; 51 | -------------------------------------------------------------------------------- /src/Postgis_Polygon_RingsPlugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import { GIS_SUBTYPE } from "./constants"; 3 | import { getGISTypeName } from "./utils"; 4 | 5 | const plugin: Plugin = builder => { 6 | builder.hook("GraphQLObjectType:fields", (fields, build, context) => { 7 | const { 8 | scope: { isPgGISType, pgGISType, pgGISTypeDetails }, 9 | } = context; 10 | if ( 11 | !isPgGISType || 12 | !pgGISTypeDetails || 13 | pgGISTypeDetails.subtype !== GIS_SUBTYPE.Polygon 14 | ) { 15 | return fields; 16 | } 17 | const { 18 | extend, 19 | getPostgisTypeByGeometryType, 20 | graphql: { GraphQLList }, 21 | } = build; 22 | const { hasZ, hasM, srid } = pgGISTypeDetails; 23 | const LineString = getPostgisTypeByGeometryType( 24 | pgGISType, 25 | GIS_SUBTYPE.LineString, 26 | hasZ, 27 | hasM, 28 | srid 29 | ); 30 | 31 | return extend(fields, { 32 | exterior: { 33 | type: LineString, 34 | resolve(data: any) { 35 | return { 36 | __gisType: getGISTypeName(GIS_SUBTYPE.LineString, hasZ, hasM), 37 | __srid: data.__srid, 38 | __geojson: { 39 | type: "LineString", 40 | coordinates: data.__geojson.coordinates[0], 41 | }, 42 | }; 43 | }, 44 | }, 45 | interiors: { 46 | type: new GraphQLList(LineString), 47 | resolve(data: any) { 48 | return data.__geojson.coordinates.slice(1).map((coord: any) => ({ 49 | __gisType: getGISTypeName(GIS_SUBTYPE.LineString, hasZ, hasM), 50 | __srid: data.__srid, 51 | __geojson: { 52 | type: "LineString", 53 | coordinates: coord, 54 | }, 55 | })); 56 | }, 57 | }, 58 | }); 59 | }); 60 | }; 61 | export default plugin; 62 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const SUBTYPE_STRING_BY_SUBTYPE = { 2 | 0: "geometry", 3 | 1: "point", 4 | 2: "line-string", 5 | 3: "polygon", 6 | 4: "multi-point", 7 | 5: "multi-line-string", 8 | 6: "multi-polygon", 9 | 7: "geometry-collection", 10 | }; 11 | 12 | export const GIS_SUBTYPE: { 13 | Geometry: 0; 14 | Point: 1; 15 | LineString: 2; 16 | Polygon: 3; 17 | MultiPoint: 4; 18 | MultiLineString: 5; 19 | MultiPolygon: 6; 20 | GeometryCollection: 7; 21 | } = { 22 | Geometry: 0, 23 | Point: 1, 24 | LineString: 2, 25 | Polygon: 3, 26 | MultiPoint: 4, 27 | MultiLineString: 5, 28 | MultiPolygon: 6, 29 | GeometryCollection: 7, 30 | }; 31 | 32 | export const GIS_SUBTYPE_NAME: { 33 | 0: "Geometry"; 34 | 1: "Point"; 35 | 2: "LineString"; 36 | 3: "Polygon"; 37 | 4: "MultiPoint"; 38 | 5: "MultiLineString"; 39 | 6: "MultiPolygon"; 40 | 7: "GeometryCollection"; 41 | } = { 42 | 0: "Geometry", 43 | 1: "Point", 44 | 2: "LineString", 45 | 3: "Polygon", 46 | 4: "MultiPoint", 47 | 5: "MultiLineString", 48 | 6: "MultiPolygon", 49 | 7: "GeometryCollection", 50 | }; 51 | -------------------------------------------------------------------------------- /src/debug.ts: -------------------------------------------------------------------------------- 1 | import debugFactory from "debug"; 2 | 3 | export default debugFactory("graphile-postgis"); 4 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from "graphile-build"; 2 | import PostgisVersionPlugin from "./PostgisVersionPlugin"; 3 | import PostgisInflectionPlugin from "./PostgisInflectionPlugin"; 4 | import PostgisExtensionDetectionPlugin from "./PostgisExtensionDetectionPlugin"; 5 | import PostgisRegisterTypesPlugin from "./PostgisRegisterTypesPlugin"; 6 | import Postgis_Point_LatitudeLongitudePlugin from "./Postgis_Point_LatitudeLongitudePlugin"; 7 | import Postgis_GeometryCollection_GeometriesPlugin from "./Postgis_GeometryCollection_GeometriesPlugin"; 8 | import Postgis_LineString_PointsPlugin from "./Postgis_LineString_PointsPlugin"; 9 | import Postgis_Polygon_RingsPlugin from "./Postgis_Polygon_RingsPlugin"; 10 | import Postgis_MultiPoint_PointsPlugin from "./Postgis_MultiPoint_PointsPlugin"; 11 | import Postgis_MultiLineString_LineStringsPlugin from "./Postgis_MultiLineString_LineStringsPlugin"; 12 | import Postgis_MultiPolygon_PolygonsPlugin from "./Postgis_MultiPolygon_PolygonsPlugin"; 13 | 14 | const PostgisPlugin: Plugin = async (builder, options) => { 15 | await PostgisVersionPlugin(builder, options); 16 | await PostgisInflectionPlugin(builder, options); 17 | await PostgisExtensionDetectionPlugin(builder, options); 18 | await PostgisRegisterTypesPlugin(builder, options); 19 | 20 | // Enhancing the `Point` type: 21 | await Postgis_Point_LatitudeLongitudePlugin(builder, options); 22 | 23 | // Enhancing the `LineString` type: 24 | await Postgis_LineString_PointsPlugin(builder, options); 25 | 26 | // Enhancing the `Polygon` type: 27 | await Postgis_Polygon_RingsPlugin(builder, options); 28 | 29 | // Enhancing the `MultiPoint` type: 30 | await Postgis_MultiPoint_PointsPlugin(builder, options); 31 | 32 | // Enhancing the `MultiLineString` type: 33 | await Postgis_MultiLineString_LineStringsPlugin(builder, options); 34 | 35 | // Enhancing the `MultiLineString` type: 36 | await Postgis_MultiPolygon_PolygonsPlugin(builder, options); 37 | 38 | // Enhancing the `GeometryCollection` type: 39 | await Postgis_GeometryCollection_GeometriesPlugin(builder, options); 40 | }; 41 | export default PostgisPlugin; 42 | -------------------------------------------------------------------------------- /src/interfaces.ts: -------------------------------------------------------------------------------- 1 | export type Subtype = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; 2 | 3 | export interface GISTypeDetails { 4 | subtype: Subtype; 5 | hasZ: boolean; 6 | hasM: boolean; 7 | srid: number; 8 | } 9 | -------------------------------------------------------------------------------- /src/makeGeoJSONType.ts: -------------------------------------------------------------------------------- 1 | import * as GraphQL from "graphql"; 2 | type Maybe = null | undefined | T; 3 | 4 | // This file is based on 5 | // https://github.com/taion/graphql-type-json/blob/6e45ae4ee0a60f8f3565c8c980a82c7d9b98d3f5/src/index.js 6 | /* 7 | The MIT License (MIT) 8 | 9 | Copyright (c) 2016 Jimmy Jia 10 | Copyright (c) 2019 Benjie Gillam 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in all 20 | copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | SOFTWARE. 29 | */ 30 | export default function makeGeoJSONType(graphql: any, name = "GeoJSON") { 31 | const Kind: typeof GraphQL.Kind = graphql.Kind; 32 | const GraphQLScalarType: typeof GraphQL.GraphQLScalarType = 33 | graphql.GraphQLScalarType; 34 | 35 | function identity(value: T): T { 36 | return value; 37 | } 38 | 39 | function parseLiteral( 40 | ast: GraphQL.ValueNode, 41 | variables: Maybe<{ [key: string]: any }> 42 | ): any { 43 | switch (ast.kind) { 44 | case Kind.STRING: 45 | case Kind.BOOLEAN: 46 | return ast.value; 47 | 48 | case Kind.INT: 49 | case Kind.FLOAT: 50 | return parseFloat(ast.value); 51 | case Kind.OBJECT: { 52 | const value = Object.create(null); 53 | ast.fields.forEach(field => { 54 | value[field.name.value] = parseLiteral(field.value, variables); 55 | }); 56 | 57 | return value; 58 | } 59 | case Kind.LIST: 60 | return ast.values.map(n => parseLiteral(n, variables)); 61 | case Kind.NULL: 62 | return null; 63 | case Kind.VARIABLE: { 64 | const variableName = ast.name.value; 65 | return variables ? variables[variableName] : undefined; 66 | } 67 | default: 68 | return undefined; 69 | } 70 | } 71 | 72 | return new GraphQLScalarType({ 73 | name, 74 | description: 75 | `The \`${name}\` scalar type represents GeoJSON values as specified by` + 76 | "[RFC 7946](https://tools.ietf.org/html/rfc7946).", 77 | serialize: identity, 78 | parseValue: identity, 79 | parseLiteral, 80 | }); 81 | } 82 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import { GISTypeDetails, Subtype } from "./interfaces"; 2 | import { GIS_SUBTYPE_NAME } from "./constants"; 3 | 4 | export const getGISTypeDetails = (modifier: number): GISTypeDetails => { 5 | const allZeroesHopefully = modifier >> 24; 6 | if (allZeroesHopefully !== 0) { 7 | throw new Error("Unsupported PostGIS modifier"); 8 | } 9 | 10 | // Ref: https://github.com/postgis/postgis/blob/2.5.2/liblwgeom/liblwgeom.h.in#L156-L173 11 | // #define TYPMOD_GET_SRID(typmod) ((((typmod) & 0x0FFFFF00) - ((typmod) & 0x10000000)) >> 8) 12 | // #define TYPMOD_GET_TYPE(typmod) ((typmod & 0x000000FC)>>2) 13 | // #define TYPMOD_GET_Z(typmod) ((typmod & 0x00000002)>>1) 14 | // #define TYPMOD_GET_M(typmod) (typmod & 0x00000001) 15 | const srid = ((modifier & 0x0fffff00) - (modifier & 0x10000000)) >> 8; 16 | const subtype = (modifier & 0x000000fc) >> 2; 17 | const hasZ = (modifier & 0x00000002) >> 1 === 1; 18 | const hasM = (modifier & 0x00000001) === 1; 19 | 20 | if ( 21 | subtype !== 0 && 22 | subtype !== 1 && 23 | subtype !== 2 && 24 | subtype !== 3 && 25 | subtype !== 4 && 26 | subtype !== 5 && 27 | subtype !== 6 && 28 | subtype !== 7 29 | ) { 30 | throw new Error( 31 | `Unsupported PostGIS modifier, expected 0-7, received ${subtype} (${modifier})` 32 | ); 33 | } 34 | 35 | return { 36 | subtype, 37 | hasZ, 38 | hasM, 39 | srid, 40 | }; 41 | }; 42 | 43 | export const getGISTypeModifier = ( 44 | subtype: Subtype, 45 | hasZ: boolean, 46 | hasM: boolean, 47 | srid: number 48 | ): number => { 49 | // Ref: https://github.com/postgis/postgis/blob/2.5.2/liblwgeom/liblwgeom.h.in#L156-L173 50 | // #define TYPMOD_SET_SRID(typmod, srid) ((typmod) = (((typmod) & 0xE00000FF) | ((srid & 0x001FFFFF)<<8))) 51 | // #define TYPMOD_SET_TYPE(typmod, type) ((typmod) = (typmod & 0xFFFFFF03) | ((type & 0x0000003F)<<2)) 52 | // #define TYPMOD_SET_Z(typmod) ((typmod) = typmod | 0x00000002) 53 | // #define TYPMOD_SET_M(typmod) ((typmod) = typmod | 0x00000001) 54 | return ( 55 | ((srid & 0x001fffff) << 8) + 56 | ((subtype & 0x0000003f) << 2) + 57 | (hasZ ? 0x00000002 : 0) + 58 | (hasM ? 0x00000001 : 0) 59 | ); 60 | }; 61 | 62 | export const getGISTypeName = ( 63 | subtype: Subtype, 64 | hasZ: boolean, 65 | hasM: boolean 66 | ): string => { 67 | return `${GIS_SUBTYPE_NAME[subtype]}${hasZ ? "Z" : ""}${hasM ? "M" : ""}`; 68 | }; 69 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": "src", 4 | "declarationDir": "./dist", 5 | "outDir": "./dist", 6 | "declaration": true, 7 | "allowJs": false, 8 | "target": "es2017", 9 | "module": "commonjs", 10 | "moduleResolution": "node", 11 | "sourceMap": true, 12 | "pretty": true, 13 | "importHelpers": true, 14 | "experimentalDecorators": true, 15 | "noImplicitAny": true, 16 | "suppressImplicitAnyIndexErrors": true, 17 | "strictNullChecks": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "noUnusedParameters": true, 20 | "noUnusedLocals": true, 21 | "preserveWatchOutput": true, 22 | "lib": ["es2018", "esnext.asynciterable"] 23 | }, 24 | "include": ["src/**/*"] 25 | } 26 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier"], 3 | "rules": { 4 | "object-literal-sort-keys": false, 5 | "only-arrow-functions": false, 6 | "ordered-imports": false, 7 | "array-type": [true, "generic"], 8 | "interface-name": [true, "never-prefix"], 9 | "variable-name": [ 10 | true, 11 | "ban-keywords", 12 | "check-format", 13 | "allow-leading-underscore", 14 | "allow-pascal-case" 15 | ], 16 | "no-implicit-dependencies": [true, "dev"], 17 | "no-empty": [false], 18 | "no-string-literal": [false], 19 | "no-bitwise": [false] 20 | } 21 | } 22 | --------------------------------------------------------------------------------