graphql-document-analyzer
Version:
Resilient analyzing and printing of GraphQL documents
78 lines (71 loc) • 3.42 kB
text/typescript
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 };