UNPKG

graphql-document-analyzer

Version:

Resilient analyzing and printing of GraphQL documents

78 lines (71 loc) 3.42 kB
import { ASTNode, Location, DefinitionNode, OperationTypeNode, NameNode, NamedTypeNode, ParseOptions } from 'graphql'; type ExtendedASTNode = ASTNode | ExtendedDocumentNode | InvalidOperationDefinitionNode | InvalidFragmentDefinitionNode | InvalidNode | IgnoredNode; interface ExtendedASTKindToNode { ExtendedDocument: ExtendedDocumentNode; InvalidOperationDefinition: InvalidOperationDefinitionNode; InvalidFragmentDefinition: InvalidFragmentDefinitionNode; Ignored: IgnoredNode; } /** * Store definitions with Invalid and Ignored nodes in `sections` array */ interface ExtendedDocumentNode { readonly kind: "ExtendedDocument"; readonly loc?: Location | undefined; readonly sections: ReadonlyArray<SectionNode>; } declare function isExtendedDocumentNode(node: unknown): node is ExtendedDocumentNode; type SectionNode = DefinitionNode | InvalidDefinitionNode | InvalidNode | IgnoredNode; type InvalidDefinitionNode = InvalidOperationDefinitionNode | InvalidFragmentDefinitionNode; interface InvalidOperationDefinitionNode { readonly kind: "InvalidOperationDefinition"; readonly loc?: Location | undefined; readonly operation: OperationTypeNode; readonly name?: NameNode | undefined; readonly value: string; } interface InvalidFragmentDefinitionNode { readonly kind: "InvalidFragmentDefinition"; readonly loc?: Location | undefined; readonly name: NameNode; readonly typeCondition: NamedTypeNode; readonly value: string; } interface InvalidNode { readonly kind: "Invalid"; readonly loc?: Location | undefined; readonly value: string; } interface IgnoredNode { readonly kind: "Ignored"; readonly loc?: Location | undefined; readonly value: string; } declare function analyze(source: string, options?: ParseOptions): ExtendedDocumentNode; /** * For a document with invalid operations or fragments, * interpolate valid nodes from a reference document * * Approach: * * 1. Conservatively, only interpolate if documents have same "outline" * (same number of operations / fragments) * 2. Anonymous operations are interpolated by "outline" index * 3. Named operations and fragments are interpolated by name */ declare function interpolate(document: ExtendedDocumentNode, reference: ExtendedDocumentNode): ExtendedDocumentNode; declare function print(ast: ASTNode | ExtendedDocumentNode): string; /** * Visit an Extended Document */ declare function visit(root: ExtendedASTNode, visitor: ExtendedASTVisitor): any; type ExtendedASTVisitor = EnterLeaveVisitor<ExtendedASTNode> | KindVisitor; type KindVisitor = { readonly [TNode in ExtendedASTNode as TNode["kind"]]?: VisitFn<TNode> | EnterLeaveVisitor<TNode>; }; interface EnterLeaveVisitor<TNode extends ExtendedASTNode> { readonly enter?: VisitFn<TNode> | undefined; readonly leave?: VisitFn<TNode> | undefined; } type VisitFn<TVisitedNode extends ExtendedASTNode> = (node: TVisitedNode, key: string | number | undefined, parent: ASTNode | ReadonlyArray<ASTNode> | undefined, path: ReadonlyArray<string | number>, ancestors: ReadonlyArray<ASTNode | ReadonlyArray<ASTNode>>) => any; export { ExtendedASTKindToNode, ExtendedASTNode, ExtendedASTVisitor, ExtendedDocumentNode, IgnoredNode, InvalidDefinitionNode, InvalidFragmentDefinitionNode, InvalidOperationDefinitionNode, SectionNode, analyze, interpolate, isExtendedDocumentNode, print, visit };