UNPKG

@pothos/plugin-directives

Version:

Directive plugin for Pothos, enables using graphql-tools based directives with Pothos

171 lines (145 loc) 4.64 kB
import './global-types'; import SchemaBuilder, { BasePlugin, type PothosEnumValueConfig, type PothosInputFieldConfig, type PothosOutputFieldConfig, type PothosTypeConfig, type SchemaTypes, } from '@pothos/core'; import type { GraphQLSchema } from 'graphql'; import mockAst from './mock-ast'; import type { DirectiveList } from './types'; export * from './types'; const pluginName = 'directives'; export default pluginName; export class PothosDirectivesPlugin<Types extends SchemaTypes> extends BasePlugin<Types> { override onOutputFieldConfig(fieldConfig: PothosOutputFieldConfig<Types>) { const options = fieldConfig.pothosOptions; if (!options.directives && !fieldConfig.extensions?.directives) { return fieldConfig; } return { ...fieldConfig, extensions: { ...fieldConfig.extensions, directives: this.normalizeDirectives( this.mergeDirectives( fieldConfig.extensions?.directives as Record<string, object>, options.directives as unknown as Record<string, object>, ), ), }, }; } override onInputFieldConfig(fieldConfig: PothosInputFieldConfig<Types>) { const options = fieldConfig.pothosOptions; if (!options.directives && !fieldConfig.extensions?.directives) { return fieldConfig; } return { ...fieldConfig, extensions: { ...fieldConfig.extensions, directives: this.normalizeDirectives( this.mergeDirectives( fieldConfig.extensions?.directives as Record<string, object>, options.directives as unknown as Record<string, object>, ), ), }, }; } override onEnumValueConfig(valueConfig: PothosEnumValueConfig<Types>) { const options = valueConfig.pothosOptions; if (!options.directives && !valueConfig.extensions?.directives) { return valueConfig; } return { ...valueConfig, extensions: { ...valueConfig.extensions, directives: this.normalizeDirectives( this.mergeDirectives( valueConfig.extensions?.directives as Record<string, object>, options.directives as unknown as Record<string, object>, ), ), }, }; } override onTypeConfig(typeConfig: PothosTypeConfig) { const options = typeConfig.pothosOptions; if (!options.directives && !typeConfig.extensions?.directives) { return typeConfig; } return { ...typeConfig, extensions: { ...typeConfig.extensions, directives: this.normalizeDirectives( this.mergeDirectives( typeConfig.extensions?.directives as Record<string, object>, options.directives as unknown as Record<string, object>, ), ), }, }; } override afterBuild(schema: GraphQLSchema) { schema.extensions = { ...schema.extensions, directives: this.normalizeDirectives( this.mergeDirectives( (schema.extensions?.directives as Record<string, object>) ?? {}, this.options.schemaDirectives as unknown as Record<string, object>, ), ), }; mockAst(schema); return schema; } mergeDirectives( left: DirectiveList | Record<string, object>, right: DirectiveList | Record<string, object>, ) { if (!(left && right)) { return left || right; } return [ ...(Array.isArray(left) ? left : Object.keys(left).map((name) => ({ name, args: left[name] }))), ...(Array.isArray(right) ? right : Object.keys(right).map((name) => ({ name, args: right[name] }))), ]; } normalizeDirectives(directives: DirectiveList | Record<string, object>) { if (this.builder.options.directives?.useGraphQLToolsUnorderedDirectives) { if (!Array.isArray(directives)) { return directives; } return directives.reduce<Record<string, {}[]>>((obj, directive) => { if (obj[directive.name]) { obj[directive.name].push(directive.args ?? {}); } else { obj[directive.name] = [directive.args ?? {}]; } return obj; }, {}); } if (Array.isArray(directives)) { return directives; } return Object.keys(directives).map((name) => ({ name, args: directives[name] })); } } SchemaBuilder.registerPlugin(pluginName, PothosDirectivesPlugin, { v3: (options) => ({ useGraphQLToolsUnorderedDirectives: undefined, directives: { useGraphQLToolsUnorderedDirectives: options.useGraphQLToolsUnorderedDirectives, }, }), });