graphql-language-service
Version:
The official, runtime independent Language Service for GraphQL
102 lines (89 loc) • 2.56 kB
text/typescript
/**
* Copyright (c) 2021 GraphQL Contributors.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { parse, visit } from 'graphql';
import { collectVariables } from './collectVariables';
import type { VariableToType } from './collectVariables';
import type {
GraphQLSchema,
DocumentNode,
OperationDefinitionNode,
} from 'graphql';
export type OperationASTFacts = {
variableToType?: VariableToType;
operations: OperationDefinitionNode[];
};
/**
* extract all operation nodes, and if schema is present, variable definitions, in a map
*
* @param documentAST {DocumentNode} a graphql-js compatible AST node
* @param schema {GraphQLSchema} optional schema
* @returns {OperationASTFacts}
* @example
*
* ```ts
* const { variablesToType, operations } = getOperationASTFacts(
* parse('documentString'),
* );
* operations.forEach(op => {
* console.log(op.name, op.operation, op.loc);
* });
* Object.entries(variablesToType).forEach(([variableName, type]) => {
* console.log(variableName, type);
* });
* ```
*/
export function getOperationASTFacts(
documentAST: DocumentNode,
schema?: GraphQLSchema | null,
): OperationASTFacts {
const variableToType = schema
? collectVariables(schema, documentAST)
: undefined;
// Collect operations by their names.
const operations: OperationDefinitionNode[] = [];
visit(documentAST, {
OperationDefinition(node) {
operations.push(node);
},
});
return { variableToType, operations };
}
export type OperationFacts = {
documentAST: DocumentNode;
} & OperationASTFacts;
export type QueryFacts = OperationFacts;
/**
* Provided previous "queryFacts", a GraphQL schema, and a query document
* string, return a set of facts about that query useful for GraphiQL features.
*
* If the query cannot be parsed, returns undefined.
* @param schema {GraphQLSchema} (optional)
* @param documentString {string} the document you want to parse for operations (optional)
*
* @returns {OperationFacts | undefined}
*/
export default function getOperationFacts(
schema?: GraphQLSchema | null,
documentString?: string | null,
): OperationFacts | undefined {
if (!documentString) {
return;
}
try {
const documentAST = parse(documentString);
return {
...getOperationASTFacts(documentAST, schema),
documentAST,
};
} catch {
return;
}
}
/**
* for backwards compatibility
*/
export const getQueryFacts = getOperationFacts;