96 lines
2.9 KiB
JavaScript
96 lines
2.9 KiB
JavaScript
import gql from 'graphql-tag'
|
|
import { mergeQueries } from '../../core/base-service/graphql.js'
|
|
import { BaseGraphqlService, BaseJsonService } from '../index.js'
|
|
|
|
function createRequestFetcher(context) {
|
|
const { requestFetcher, githubApiProvider } = context
|
|
return githubApiProvider.fetch.bind(githubApiProvider, requestFetcher)
|
|
}
|
|
|
|
class GithubAuthV3Service extends BaseJsonService {
|
|
constructor(context, config) {
|
|
super(context, config)
|
|
this._requestFetcher = createRequestFetcher(context)
|
|
this.staticAuthConfigured = true
|
|
}
|
|
}
|
|
|
|
// Use Github auth, but only when static auth is configured. By using this
|
|
// class, in production it will behave like GithubAuthV3Service, and in self-
|
|
// hosting (i.e. with a configured token) like BaseJsonService. This is
|
|
// useful when consuming GitHub endpoints which are not rate-limited: it
|
|
// avoids wasting API quota on them in production.
|
|
class ConditionalGithubAuthV3Service extends BaseJsonService {
|
|
constructor(context, config) {
|
|
super(context, config)
|
|
if (context.githubApiProvider.globalToken) {
|
|
this._requestFetcher = createRequestFetcher(context)
|
|
this.staticAuthConfigured = true
|
|
} else {
|
|
this.staticAuthConfigured = false
|
|
}
|
|
}
|
|
}
|
|
|
|
class GithubAuthV4Service extends BaseGraphqlService {
|
|
constructor(context, config) {
|
|
super(context, config)
|
|
this._requestFetcher = createRequestFetcher(context)
|
|
this.staticAuthConfigured = true
|
|
}
|
|
|
|
async _requestGraphql(attrs) {
|
|
const url = '/graphql'
|
|
|
|
/*
|
|
The Github v4 API requires us to query the rateLimit object to return
|
|
rate limit info in the query body instead of the headers:
|
|
https://developer.github.com/v4/guides/resource-limitations/#returning-a-calls-rate-limit-status
|
|
This appends the relevant rateLimit query clause to each
|
|
call to the GH v4 API so we can keep track of token usage.
|
|
*/
|
|
const query = mergeQueries(
|
|
attrs.query,
|
|
gql`
|
|
query {
|
|
rateLimit {
|
|
limit
|
|
cost
|
|
remaining
|
|
resetAt
|
|
}
|
|
}
|
|
`,
|
|
)
|
|
|
|
return super._requestGraphql({
|
|
...attrs,
|
|
...{
|
|
url,
|
|
query,
|
|
httpErrorMessages: { 401: 'auth required for graphql api' },
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
/*
|
|
Choosing between the Github V3 and V4 APIs when creating a new badge:
|
|
|
|
With the V3 API, one request = one point off the usage limit.
|
|
With the V4 API one request may be many points off the usage limit depending
|
|
on the query (but will be a minimum of one).
|
|
https://developer.github.com/v4/guides/resource-limitations/#calculating-nodes-in-a-call
|
|
|
|
If we can save ourselves some usage limit it may be worth going with a
|
|
REST (V3) call over a graphql query.
|
|
All other things being equal, a graphql query will almost always be a smaller
|
|
number of bytes over the wire and a smaller/simpler object to parse.
|
|
*/
|
|
|
|
export {
|
|
GithubAuthV3Service,
|
|
ConditionalGithubAuthV3Service,
|
|
GithubAuthV4Service,
|
|
}
|