Created
February 27, 2025 18:43
-
-
Save hos/017c0790e617064a659db0b73db0572a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { PgCodec } from '@dataplan/pg'; | |
import { EXPORTABLE } from 'graphile-build'; | |
import { sql } from 'pg-sql2'; | |
import { Geometry } from 'wkx'; | |
interface State { | |
geometryCodec: PgCodec<string, any, any, any, undefined, any, any>; | |
} | |
declare global { | |
namespace GraphileConfig { | |
interface Plugins { | |
PgGeometryPlugin: true; | |
} | |
} | |
} | |
export const PgGeometryPlugin: GraphileConfig.Plugin = { | |
name: 'PgGeometryPlugin', | |
gather: { | |
initialState(): State { | |
const geometryCodec: PgCodec<string, any, any, any, undefined, any, any> = EXPORTABLE( | |
(sql) => ({ | |
name: 'geometry', | |
sqlType: sql`geometry`, | |
toPg(str) { | |
return str; | |
}, | |
fromPg(str) { | |
return Geometry.parse(Buffer.from(str, 'hex')).toGeoJSON(); | |
}, | |
executor: null, | |
attributes: undefined, | |
}), | |
[sql] | |
); | |
return { geometryCodec }; | |
}, | |
hooks: { | |
async pgCodecs_findPgCodec(info, event) { | |
// If another plugin has already supplied a codec; skip | |
if (event.pgCodec) return; | |
const { serviceName, pgType } = event; | |
const geometryExt = await info.helpers.pgIntrospection.getExtensionByName( | |
serviceName, | |
'postgis' | |
); | |
if (!geometryExt || pgType.typnamespace !== geometryExt.extnamespace) { | |
return; | |
} | |
if (pgType.typname === 'geometry') { | |
event.pgCodec = info.state.geometryCodec; | |
} | |
}, | |
}, | |
}, | |
schema: { | |
hooks: { | |
init(_, build) { | |
const codec = build.input.pgRegistry.pgCodecs.geometry; | |
if (codec) { | |
const geometryTypeName = build.inflection.builtin('Geometry'); | |
build.registerScalarType( | |
geometryTypeName, | |
{ pgCodec: codec }, | |
() => ({ | |
description: | |
'Represents an `geometry` type https://postgis.net/workshops/postgis-intro/geometries.html', | |
}), | |
'Adding "Geometry" scalar type from PgGeometryPlugin.' | |
); | |
build.setGraphQLTypeForPgCodec(codec, 'output', geometryTypeName); | |
build.setGraphQLTypeForPgCodec(codec, 'input', geometryTypeName); | |
} | |
return _; | |
}, | |
}, | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment