import { errors } from 'platforms' ; import { isEnterprise } from '.' ; function apiRateLimitExceeded ( content ) { return content ?. [ 'documentation_url' ] === 'https://developer.github.com/v3/#rate-limiting' ; } function isEmptyProject ( content ) { return content ?. [ 'message' ] === 'Git Repository is empty.' ; } function isBlockedProject ( content ) { return content ?. [ 'message' ] === 'Repository access blocked' ; } async function request ( url , { accessToken , } = { } ) { const headers = { } as HeadersInit & { Authorization ? : string ; } ; if ( accessToken ) { headers . Authorization = `token ${ accessToken }` ; } let res ; try { res = await fetch ( url , { headers } ) ; } catch ( err ) { throw new Error ( errors . CONNECTION_BLOCKED ) ; } const contentType = res . headers . get ( 'Content-Type' ) || res . headers . get ( 'content-type' ) ; const isJson = contentType ?. includes ( 'application/json' ) ; if ( res . ok ) { if ( isJson ) return res . json ( ) ; throw new Error ( `Response content type is "${ contentType }"` ) ; } else { if ( res . status === 404 || res . status === 401 ) throw new Error ( errors . NOT_FOUND ) ; else if ( res . status === 403 ) throw new Error ( errors . API_RATE_LIMIT ) ; else if ( res . status === 500 ) throw new Error ( errors . SERVER_FAULT ) ; else if ( isJson ) { const content = await res . json ( ) ; if ( apiRateLimitExceeded ( content ) ) throw new Error ( errors . API_RATE_LIMIT ) ; if ( isEmptyProject ( content ) ) throw new Error ( errors . EMPTY_PROJECT ) ; if ( isBlockedProject ( content ) ) throw new Error ( errors . BLOCKED_PROJECT ) ; throw new Error ( `Unknown message content "${ content ?. message }"` ) ; } else { throw new Error ( `Response content type is "${ contentType }"` ) ; } } } const API_ENDPOINT = isEnterprise ( ) ? `${ window . location . host }/api/v3` : 'api.github.com' ; export async function getRepoMeta ( userName , repoName , accessToken ? ) { const url = `https://${ API_ENDPOINT }/repos/${ userName }/${ repoName }` ; return await request ( url , { accessToken } ) ; } export async function getTreeData ( userName , repoName , branchName , recursive ? , accessToken ? ) { const search = new URLSearchParams ( ) ; if ( recursive ) search . set ( 'recursive' , '1' ) ; const url = `https://${ API_ENDPOINT }/repos/${ userName }/${ repoName }/git/trees/${ branchName }?` + search ; return await request ( url , { accessToken } ) ; } export async function getPullData ( userName , repoName , pullId , accessToken ? ) { const url = `https://${ API_ENDPOINT }/repos/${ userName }/${ repoName }/pulls/${ pullId }` ; return await request ( url , { accessToken } ) ; } export async function getPullTreeData ( userName , repoName , pullId , page , accessToken ? ) { const search = new URLSearchParams ( { page : page . toString ( ) } ) ; const url = `https://${ API_ENDPOINT }/repos/${ userName }/${ repoName }/pulls/${ pullId }/files?${ search }` ; return await request ( url , { accessToken } ) ; } export async function getPullComments ( userName , repoName , pullId , accessToken ? ) { const url = `https://${ API_ENDPOINT }/repos/${ userName }/${ repoName }/pulls/${ pullId }/comments` ; return await request ( url , { accessToken } ) ; } export async function getPullPageDocuments ( userName , repoName , pullId ) { const filesDOM = await getDOM ( `https://${ window . location . host }/${ userName }/${ repoName }/pull/${ pullId }/files?_pjax=%23js-repo-pjax-container` ) ; const hookElement = filesDOM . querySelector ( 'div.js-pull-refresh-on-pjax' ) ; const hookSearchParams = new URLSearchParams ( hookElement ?. dataset . url ) ; const [ baseSHA , headSHA ] = [ hookSearchParams . get ( 'start_commit_oid' ) , hookSearchParams . get ( 'end_commit_oid' ) , ] ; if ( ! baseSHA || ! headSHA ) throw new Error ( `Cannot fetch SHA for comparison` ) ; const search = new URLSearchParams ( window . location . search ) ; search . set ( 'sha1' , baseSHA ) ; search . set ( 'sha2' , headSHA ) ; let lines = 0 ; const diffsDOMs = [ ] ; while ( true ) { search . set ( 'lines' , lines . toString ( ) ) ; const diffsDOM = await getDOM ( `https://${ window . location . host }/${ userName }/${ repoName }/diffs?${ search }` ) ; diffsDOMs . push ( diffsDOM ) ; if ( diffsDOM . querySelector ( '.js-diff-progressive-container' ) ) { lines += 3000 ; } else { break ; } } return diffsDOMs ; } async function getDOM ( url ) { return new DOMParser ( ) . parseFromString ( await ( await fetch ( url ) ) . text ( ) , 'text/html' ) ; } export async function getBlobData ( userName , repoName , sha , accessToken ? ) { const url = `https://${ API_ENDPOINT }/repos/${ userName }/${ repoName }/git/blobs/${ sha }` ; return await request ( url , { accessToken } ) ; } export async function OAuth ( code ) { try { const endpoint = `https://gitako.now.sh/oauth/github?` ; const res = await fetch ( endpoint + new URLSearchParams ( { code } ) . toString ( ) , { method : 'post' , } ) ; if ( res . ok ) { const body = await res . json ( ) ; const accessToken = body ?. accessToken ; if ( typeof accessToken === 'string' ) return accessToken ; } return null ; } catch ( err ) { return null ; } }