UNPKG

graphile-build-pg

Version:

Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build

114 lines (108 loc) 3.56 kB
// @flow import type { Plugin } from "graphile-build"; export default (function PgQueryProceduresPlugin( builder, { pgSimpleCollections, disableIssue641Fix = false } ) { builder.hook( "GraphQLObjectType:fields", (fields, build, context) => { const { extend, inflection, pgIntrospectionResultsByKind: introspectionResultsByKind, pgMakeProcField: makeProcField, pgOmit: omit, describePgEntity, sqlCommentByAddingTags, swallowError, } = build; const { scope: { isRootQuery }, fieldWithHooks, } = context; if (!isRootQuery) { return fields; } return extend( fields, introspectionResultsByKind.procedure.reduce((memo, proc) => { // PERFORMANCE: These used to be .filter(...) calls if (!proc.isStable) return memo; if (!proc.namespace) return memo; if (omit(proc, "execute")) return memo; const argTypes = proc.argTypeIds.reduce((prev, typeId, idx) => { if ( proc.argModes.length === 0 || // all args are `in` proc.argModes[idx] === "i" || // this arg is `in` proc.argModes[idx] === "b" // this arg is `inout` ) { prev.push(introspectionResultsByKind.typeById[typeId]); } return prev; }, []); if ( argTypes.some( type => type.type === "c" && type.class && type.class.isSelectable ) ) { // Selects a table, ignore! return memo; } const firstArgType = argTypes[0]; if ( firstArgType && firstArgType.type === "c" && firstArgType.class && firstArgType.namespaceId === proc.namespaceId && proc.name.startsWith(`${firstArgType.name}_`) ) { // It's a computed field, skip return memo; } function makeField(forceList) { const fieldName = forceList ? inflection.functionQueryNameList(proc) : inflection.functionQueryName(proc); try { memo = extend( memo, { [fieldName]: makeProcField(fieldName, proc, build, { fieldWithHooks, forceList, isRootQuery: !disableIssue641Fix, }), }, `Adding query field for ${describePgEntity( proc )}. You can rename this field with a 'Smart Comment':\n\n ${sqlCommentByAddingTags( proc, { name: "newNameHere", } )}` ); } catch (e) { swallowError(e); } } const simpleCollections = proc.tags.simpleCollections || pgSimpleCollections; const hasConnections = simpleCollections !== "only"; const hasSimpleCollections = simpleCollections === "only" || simpleCollections === "both"; if (!proc.returnsSet || hasConnections) { makeField(false); } if (proc.returnsSet && hasSimpleCollections) { makeField(true); } return memo; }, {}), `Adding query procedures to root Query type` ); }, ["PgQueryProcedures"] ); }: Plugin);