From 1cc5539e34ad7a0bead5f882625c66ccefc84b7a Mon Sep 17 00:00:00 2001 From: Ashi Krishnan Date: Fri, 1 Feb 2019 13:32:54 -0800 Subject: [PATCH 1/3] Detect GraphQL support by trying to actually make a query. --- package.json | 1 + src/github/credentials.ts | 35 +++++++++++++++++++++---------- src/github/githubRepository.ts | 9 ++++---- src/github/pullRequestManager.ts | 6 +++--- src/github/pullRequestOverview.ts | 2 +- src/view/reviewManager.ts | 2 +- 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 81b4c3bb62..0e7bf58327 100644 --- a/package.json +++ b/package.json @@ -421,6 +421,7 @@ "devDependencies": { "@types/chai": "^4.1.4", "@types/debounce": "^3.0.0", + "@types/graphql": "^14.0.5", "@types/keytar": "^4.0.1", "@types/lodash": "^4.14.106", "@types/markdown-it": "^0.0.5", diff --git a/src/github/credentials.ts b/src/github/credentials.ts index b34d38c1ed..4d89a0adab 100644 --- a/src/github/credentials.ts +++ b/src/github/credentials.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as Octokit from '@octokit/rest'; -import { ApolloClient, InMemoryCache, NormalizedCacheObject } from 'apollo-boost'; +import { ApolloClient, InMemoryCache, NormalizedCacheObject, gql } from 'apollo-boost'; import { setContext } from 'apollo-link-context'; import * as vscode from 'vscode'; import { agent } from '../common/net'; @@ -25,7 +25,7 @@ const AUTH_INPUT_TOKEN_CMD = 'auth.inputTokenCallback'; export interface GitHub { octokit: Octokit; - graphql: ApolloClient; + graphql: ApolloClient | null; } export class CredentialStore { @@ -187,17 +187,30 @@ export class CredentialStore { token: creds.token || '', }); - return { - octokit, - graphql: new ApolloClient({ - link: link(baseUrl, creds.token || ''), - cache: new InMemoryCache, - defaultOptions: { - query: { - fetchPolicy: 'no-cache' - } + const graphql = new ApolloClient({ + link: link(baseUrl, creds.token || ''), + cache: new InMemoryCache, + defaultOptions: { + query: { + fetchPolicy: 'no-cache' } + } + }); + + let supportsGraphQL = true; + graphql.query({ query: gql `query { viewer { login } }` }) + .then(result => { + Logger.appendLine(`${baseUrl}: GraphQL support detected`); + Logger.appendLine(JSON.stringify(result, null, 2)); }) + .catch(err => { + Logger.appendLine(`${baseUrl}: GraphQL not supported (${err.message})`); + supportsGraphQL = false; + }); + + return { + octokit, + graphql: supportsGraphQL ? graphql : null, }; } diff --git a/src/github/githubRepository.ts b/src/github/githubRepository.ts index 324fec5301..df3af1efc0 100644 --- a/src/github/githubRepository.ts +++ b/src/github/githubRepository.ts @@ -53,7 +53,7 @@ export class GitHubRepository implements IGitHubRepository, vscode.Disposable { } await this.ensure(); - this.commentsProvider = this.supportsGraphQl() ? new PRDocumentCommentProviderGraphQL() : new PRDocumentCommentProvider(); + this.commentsProvider = this.supportsGraphQl ? new PRDocumentCommentProviderGraphQL() : new PRDocumentCommentProvider(); this._toDispose.push(vscode.workspace.registerDocumentCommentProvider(this.commentsProvider)); } catch (e) { console.log(e); @@ -72,7 +72,8 @@ export class GitHubRepository implements IGitHubRepository, vscode.Disposable { constructor(public remote: Remote, private readonly _credentialStore: CredentialStore) { } - supportsGraphQl(): boolean { + get supportsGraphQl(): boolean { + Logger.appendLine(`supportsGraphQL(): ${!!(this.hub && this.hub.graphql)}`); return !!(this.hub && this.hub.graphql); } @@ -279,7 +280,7 @@ export class GitHubRepository implements IGitHubRepository, vscode.Disposable { async getPullRequest(id: number): Promise { try { Logger.debug(`Fetch pull request ${id} - enter`, GitHubRepository.ID); - const { octokit, query, remote } = await this.ensure(); + const { octokit, query, remote, supportsGraphQl } = await this.ensure(); let prsResult = await octokit.pullRequests.get({ owner: remote.owner, repo: remote.repositoryName, @@ -292,7 +293,7 @@ export class GitHubRepository implements IGitHubRepository, vscode.Disposable { return; } - if (this.supportsGraphQl()) { + if (supportsGraphQl) { const { data } = await query({ query: queries.PullRequest, variables: { diff --git a/src/github/pullRequestManager.ts b/src/github/pullRequestManager.ts index 3e3ed9684e..727bd24c16 100644 --- a/src/github/pullRequestManager.ts +++ b/src/github/pullRequestManager.ts @@ -666,10 +666,10 @@ export class PullRequestManager { async getTimelineEvents(pullRequest: PullRequestModel): Promise { Logger.debug(`Fetch timeline events of PR #${pullRequest.prNumber} - enter`, PullRequestManager.ID); - const { octokit, query, remote } = await pullRequest.githubRepository.ensure(); + const { octokit, query, remote, supportsGraphQl } = await pullRequest.githubRepository.ensure(); let ret = []; - if (pullRequest.githubRepository.supportsGraphQl()) { + if (supportsGraphQl) { try { const { data } = await query({ query: queries.TimelineEvents, @@ -794,7 +794,7 @@ export class PullRequestManager { return undefined; } - if (!pullRequest.githubRepository.supportsGraphQl()) { + if (!pullRequest.githubRepository.supportsGraphQl) { return; } diff --git a/src/github/pullRequestOverview.ts b/src/github/pullRequestOverview.ts index 0c0757d313..c8a068adaa 100644 --- a/src/github/pullRequestOverview.ts +++ b/src/github/pullRequestOverview.ts @@ -163,7 +163,7 @@ export class PullRequestOverviewPanel { const isCurrentlyCheckedOut = pullRequestModel.equals(this._pullRequestManager.activePullRequest); const canEdit = this._pullRequestManager.canEditPullRequest(this._pullRequest); const defaultMergeMethod = vscode.workspace.getConfiguration('githubPullRequests').get('defaultMergeMethod'); - const supportsGraphQl = pullRequestModel.githubRepository.supportsGraphQl(); + const supportsGraphQl = pullRequestModel.githubRepository.supportsGraphQl; this._postMessage({ command: 'pr.initialize', diff --git a/src/view/reviewManager.ts b/src/view/reviewManager.ts index 1d6856a0fc..77dacd2fac 100644 --- a/src/view/reviewManager.ts +++ b/src/view/reviewManager.ts @@ -900,7 +900,7 @@ export class ReviewManager implements vscode.DecorationProvider { } private registerCommentProvider() { - const supportsGraphQL = this._prManager.activePullRequest && (this._prManager.activePullRequest as PullRequestModel).githubRepository.supportsGraphQl(); + const supportsGraphQL = this._prManager.activePullRequest && (this._prManager.activePullRequest as PullRequestModel).githubRepository.supportsGraphQl; if (supportsGraphQL) { this._localToDispose.push(onDidSubmitReview(submittedComments => { this.updateCommentPendingState(submittedComments); From cf8c9a1501575839d16a588d70bc6011ec8943ea Mon Sep 17 00:00:00 2001 From: Ashi Krishnan Date: Fri, 1 Feb 2019 13:50:33 -0800 Subject: [PATCH 2/3] We should probably await that query. --- src/github/credentials.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/github/credentials.ts b/src/github/credentials.ts index 4d89a0adab..cd0c133c62 100644 --- a/src/github/credentials.ts +++ b/src/github/credentials.ts @@ -74,7 +74,7 @@ export class CredentialStore { if (token) { if (await server.validate(token)) { - octokit = this.createHub({ host, token }); + octokit = await this.createHub({ host, token }); } else { Logger.debug(`Token is no longer valid for host ${host}.`, 'Authentication'); } @@ -137,7 +137,7 @@ export class CredentialStore { this.willStartLogin(authority); const login = await server.login(); if (login && login.token) { - octokit = this.createHub(login); + octokit = await this.createHub(login); await setToken(login.host, login.token, { emit: false }); vscode.window.showInformationMessage(`You are now signed in to ${authority}`); } @@ -174,7 +174,7 @@ export class CredentialStore { return octokit && (octokit as any).currentUser && (octokit as any).currentUser.login === username; } - private createHub(creds: IHostConfiguration): GitHub { + private async createHub(creds: IHostConfiguration): Promise { const baseUrl = `${HostHelper.getApiHost(creds).toString().slice(0, -1)}${HostHelper.getApiPath(creds, '')}`; let octokit = new Octokit({ agent, @@ -198,7 +198,7 @@ export class CredentialStore { }); let supportsGraphQL = true; - graphql.query({ query: gql `query { viewer { login } }` }) + await graphql.query({ query: gql `query { viewer { login } }` }) .then(result => { Logger.appendLine(`${baseUrl}: GraphQL support detected`); Logger.appendLine(JSON.stringify(result, null, 2)); From b75e8e13e77bf888854af530881271763047cfd5 Mon Sep 17 00:00:00 2001 From: Ashi Krishnan Date: Fri, 1 Feb 2019 13:55:52 -0800 Subject: [PATCH 3/3] Remove extraneous Logger message. --- src/github/githubRepository.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/github/githubRepository.ts b/src/github/githubRepository.ts index df3af1efc0..a7321df251 100644 --- a/src/github/githubRepository.ts +++ b/src/github/githubRepository.ts @@ -73,7 +73,6 @@ export class GitHubRepository implements IGitHubRepository, vscode.Disposable { } get supportsGraphQl(): boolean { - Logger.appendLine(`supportsGraphQL(): ${!!(this.hub && this.hub.graphql)}`); return !!(this.hub && this.hub.graphql); }