import mkdirp from 'mkdirp' ; import { spinner } from './index' ; import { existsSync , writeFileSync } from 'fs' ; import fetch , { Headers , Response } from 'node-fetch' ; import { parse as parsePath , ParsedPath , resolve as resolvePath } from 'path' ; export const githubApiBaseUrl = 'https://api.github.com' ; export const githubContentsEndpoint = `${ githubApiBaseUrl }/repos/%s/%s/contents` ; interface GitHubRequestHeaders extends Headers { Authorization ? : string ; } export async function getBlobs ( url , token ? ) { const headers = { } ; if ( token ) { headers . Authorization = `Bearer ${ token }` ; } const res = await fetch ( url , { headers : < GitHubRequestHeaders > headers , } ) ; if ( ! res . ok ) { spinner . stop ( ) ; console . error ( 'Something went wrong!' ) ; process . exit ( 1 ) ; } return res . json ( ) ; } export async function getContents ( url , token ? ) { const headers = { } ; if ( token ) { headers . Authorization = `Bearer ${ token }` ; } const res = await fetch ( url , { headers : < GitHubRequestHeaders > headers , } ) ; if ( ! res . ok ) { const error = await res . json ( ) ; spinner . stop ( ) ; if ( error . message === 'Bad credentials' ) { console . error ( 'Provided token is invalid' ) ; } else { console . error ( 'Something went wrong!' ) ; } process . exit ( 1 ) ; } const contents = await res . json ( ) ; if ( Array . isArray ( contents ) ) { return contents ; } return [ contents ] ; } export async function download ( baseUrl , path , branch , token ? ) { const url = `${ baseUrl }/${ path }?ref=${ branch }` ; const contents = await getContents ( url , token ) ; for ( const content of contents ) { if ( content . type === 'dir' ) { await download ( baseUrl , content . path , branch , token ) ; } else { spinner . text = `Downloading ${ content . path }` ; const blob = await getBlobs ( content . git_url , token ) ; const parsedPath = parsePath ( content . path ) ; const directoryPath = resolvePath ( `${ process . cwd ( ) }/${ parsedPath . dir }` ) ; const filePath = resolvePath ( `${ process . cwd ( ) }/${ content . path }` ) ; if ( ! existsSync ( directoryPath ) ) { mkdirp . sync ( directoryPath ) ; } const buffer = Buffer . from ( < string > blob . content , 'base64' ) ; writeFileSync ( filePath , buffer ) ; } } }