// IntrospectionSchemaProvider (http => IntrospectionResult => schema) import { NotificationHandler } from "vscode-languageserver"; import { execute as linkExecute, toPromise } from "apollo-link"; import { createHttpLink, HttpLink } from "apollo-link-http"; import { GraphQLSchema, buildClientSchema, getIntrospectionQuery, ExecutionResult, IntrospectionQuery, parse } from "graphql"; import { Agent } from "http"; import { fetch } from "apollo-env"; import { RemoteServiceConfig } from "../../config"; import { GraphQLSchemaProvider, SchemaChangeUnsubscribeHandler } from "./base"; export class IntrospectionSchemaProvider implements GraphQLSchemaProvider { private schema?: GraphQLSchema; constructor(private config: Exclude) {} async resolveSchema() { if (this.schema) return this.schema; const { skipSSLValidation, url, headers } = this.config; const options: HttpLink.Options = { uri: url, fetch, ...(skipSSLValidation && { fetchOptions: { agent: new Agent() } }) }; const { data, errors } = (await toPromise( linkExecute(createHttpLink(options), { query: parse(getIntrospectionQuery()), context: { headers } }) )) as ExecutionResult; if (errors && errors.length) { // XXX better error handling of GraphQL errors throw new Error(errors.map(({ message }: Error) => message).join("\n")); } if (!data) { throw new Error("No data received from server introspection."); } this.schema = buildClientSchema(data); return this.schema; } onSchemaChange( _handler: NotificationHandler ): SchemaChangeUnsubscribeHandler { throw new Error("Polling of endpoint not implemented yet"); return () => {}; } }