Open
Description
Sometimes the old way is more convenient :)
import { GraphQLScalarType } from "graphql"
import type { SchemaBuilder, Build } from "graphile-build"
import type { PgType } from "graphile-build-pg"
/**
* This plugin switches the expression of range types back to Postgres' native
* `[lower,upper)` formats instead of Postgraphile's more verbose nested-object
* `{start: {value, inclusive}, end: {...}` version.
*/
export default function TranslateRangesPlugin(builder: SchemaBuilder) {
builder.hook("build", (build: Build) => {
const {
pgIntrospectionResultsByKind,
pgRegisterGqlInputTypeByTypeId,
pgRegisterGqlTypeByTypeId,
pg2GqlMapper,
pgSql: sql,
} = build
// find our target type oid. If you want to change the behavior for a
// built-in range type, you can use one of the following default oids:
//
// 3904 int4range
// 3906 numrange
// 3908 tsrange
// 3910 tstzrange
// 3912 daterange
// 3926 int8range
const myRange = pgIntrospectionResultsByKind.type.find(
(t: PgType) => t.namespaceName === "my_schema" && t.name === "my_range"
)
if (!myRange) {
return build // something went horribly wrong, abort
}
// declare a new kind of scalar
const MyRangeType = new GraphQLScalarType({
name: "MyRange",
description: "An int8range dedicated to a more specific purpose",
serialize: (a: string) => a,
parseValue: (a: string) => a,
})
// register input and output types for the oid
pgRegisterGqlInputTypeByTypeId(myRange.id, () => MyRangeType)
pgRegisterGqlTypeByTypeId(myRange.id, () => MyRangeType)
// define mappings to and from
pg2GqlMapper[myRange.id] = {
// SQL -> GQL
map: (output: string) => output,
// GQL -> SQL; substitute your target range type for `int8range` as necessary
unmap: (input: string) => sql.fragment`${sql.value(input)}::int8range`,
}
return build // pass the build object back for the next stage
})
}
Metadata
Metadata
Assignees
Labels
No labels
Activity