UNPKG

@graphql-codegen/typescript-operations

Version:

GraphQL Code Generator plugin for generating TypeScript types for GraphQL queries, mutations, subscriptions and fragments

73 lines (72 loc) 4.68 kB
import { BaseDocumentsVisitor, generateFragmentImportStatement, getConfigValue, normalizeAvoidOptionals, PreResolveTypesProcessor, SelectionSetToObject, wrapTypeWithModifiers, } from '@graphql-codegen/visitor-plugin-common'; import autoBind from 'auto-bind'; import { isEnumType, isNonNullType } from 'graphql'; import { TypeScriptOperationVariablesToObject } from './ts-operation-variables-to-object.js'; import { TypeScriptSelectionSetProcessor } from './ts-selection-set-processor.js'; export class TypeScriptDocumentsVisitor extends BaseDocumentsVisitor { constructor(schema, config, allFragments) { super(config, { arrayInputCoercion: getConfigValue(config.arrayInputCoercion, true), noExport: getConfigValue(config.noExport, false), avoidOptionals: normalizeAvoidOptionals(getConfigValue(config.avoidOptionals, false)), immutableTypes: getConfigValue(config.immutableTypes, false), nonOptionalTypename: getConfigValue(config.nonOptionalTypename, false), preResolveTypes: getConfigValue(config.preResolveTypes, true), mergeFragmentTypes: getConfigValue(config.mergeFragmentTypes, false), allowUndefinedQueryVariables: getConfigValue(config.allowUndefinedQueryVariables, false), }, schema); autoBind(this); const preResolveTypes = getConfigValue(config.preResolveTypes, true); const defaultMaybeValue = 'T | null'; const maybeValue = getConfigValue(config.maybeValue, defaultMaybeValue); const wrapOptional = (type) => { if (preResolveTypes === true) { return maybeValue.replace('T', type); } const prefix = this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : ''; return `${prefix}Maybe<${type}>`; }; const wrapArray = (type) => { const listModifier = this.config.immutableTypes ? 'ReadonlyArray' : 'Array'; return `${listModifier}<${type}>`; }; const formatNamedField = (name, type, isConditional = false, isOptional = false) => { const optional = isOptional || isConditional || (!this.config.avoidOptionals.field && !!type && !isNonNullType(type)); return (this.config.immutableTypes ? `readonly ${name}` : name) + (optional ? '?' : ''); }; const processorConfig = { namespacedImportName: this.config.namespacedImportName, convertName: this.convertName.bind(this), enumPrefix: this.config.enumPrefix, enumSuffix: this.config.enumSuffix, scalars: this.scalars, formatNamedField, wrapTypeWithModifiers(baseType, type) { return wrapTypeWithModifiers(baseType, type, { wrapOptional, wrapArray }); }, avoidOptionals: this.config.avoidOptionals, printFieldsOnNewLines: this.config.printFieldsOnNewLines, }; const processor = new (preResolveTypes ? PreResolveTypesProcessor : TypeScriptSelectionSetProcessor)(processorConfig); this.setSelectionSetHandler(new SelectionSetToObject(processor, this.scalars, this.schema, this.convertName.bind(this), this.getFragmentSuffix.bind(this), allFragments, this.config)); const enumsNames = Object.keys(schema.getTypeMap()).filter(typeName => isEnumType(schema.getType(typeName))); this.setVariablesTransformer(new TypeScriptOperationVariablesToObject(this.scalars, this.convertName.bind(this), this.config.avoidOptionals, this.config.immutableTypes, this.config.namespacedImportName, enumsNames, this.config.enumPrefix, this.config.enumSuffix, this.config.enumValues, this.config.arrayInputCoercion, undefined, 'InputMaybe')); this._declarationBlockConfig = { ignoreExport: this.config.noExport, }; } getImports() { return !this.config.globalNamespace && (this.config.inlineFragmentTypes === 'combine' || this.config.inlineFragmentTypes === 'mask') ? this.config.fragmentImports.map(fragmentImport => generateFragmentImportStatement(fragmentImport, 'type')) : []; } getPunctuation(_declarationKind) { return ';'; } applyVariablesWrapper(variablesBlock, operationType) { const prefix = this.config.namespacedImportName ? `${this.config.namespacedImportName}.` : ''; const extraType = this.config.allowUndefinedQueryVariables && operationType === 'Query' ? ' | undefined' : ''; return `${prefix}Exact<${variablesBlock === '{}' ? `{ [key: string]: never; }` : variablesBlock}>${extraType}`; } }