UNPKG

@cran/gql.core

Version:

Cran/GraphQL Core Utilities

61 lines (60 loc) 2.28 kB
import { PluginPhase } from "./Plugin"; import { MapperKind } from "@graphql-tools/utils"; import { createDirective } from "../utilities/createDirective"; import { isOutputType } from "graphql/type/definition"; import { patchField } from "../utilities/patchField"; import { __EnumValue, __Field, __InputValue, __Schema, __Type } from "graphql"; import { getExtension, setExtension } from "../utilities/extensions"; export const IntrospectionType = { [MapperKind.ROOT_OBJECT]: __Schema, [MapperKind.TYPE]: __Type, [MapperKind.OBJECT_FIELD]: __Field, [MapperKind.INPUT_OBJECT_FIELD]: __InputValue, [MapperKind.ENUM_VALUE]: __EnumValue, }; export function withMetadata(options) { const plugins = []; for (const key in options.fields) { if ("default" !== key) { const kind = key; plugins.push(createDirective(options.names?.[kind] || `${IntrospectionType[kind].name.slice(2)}Metadata`, { ...options.fields.default, ...options.fields[kind], }, { [kind]: directiveMapper, })); } } plugins.push({ transformer: { [PluginPhase.FINALIZE](schema) { for (const name in options.fields) { if ("default" !== name) { addFields(schema, name, options); } } return schema; }, }, }); return plugins; } function directiveMapper([directive,], type) { setExtension(type, "metadata", directive); } function addFields(schema, kind, options) { const field = options.fields[kind]; for (const key in field) { const type = schema.getType(field[key]); if (!type || !isOutputType(type)) { throw new TypeError(`MetadataPlugin expects "GraphQLOutputType" received "${type?.name}"`); } addField(kind, key, type, options); } } function addField(kind, key, type, options) { const fallback = options.fallbacks?.[kind] || alwaysNull; patchField(IntrospectionType[kind], key, { type, resolve(source) { const value = getExtension(source, "metadata")?.[key]; return value !== undefined ? value : fallback(source, key); }, }); } function alwaysNull() { return null; }