/**
 * The following implementation are adapted from create-next-app
 * See https://github.com/vercel/next.js for more information
 */ import { Global } from '@salesforce/core' ; import * as crypto from 'crypto' ; import * as fs from 'fs' ; import got from 'got' ; import * as path from 'path' ; import { Stream } from 'stream' ; import * as tar from 'tar' ; import { promisify } from 'util' ; import { nls } from '../i18n' ; interface RepoInfo { username : string ; name : string ; branch : string ; filePath : string ; } param repoUri export async function getRepoInfo ( repoUri ) { const [ , username , name , t , branch , ... file ] = repoUri . pathname . split ( '/' ) ; const filePath = `${ file . join ( '/' ) }` ; if ( t === undefined ) { const infoResponse = await got ( `https://api.github.com/repos/${ username }/${ name }` ) . catch ( e => e ) ; if ( infoResponse . statusCode !== 200 ) { throw new Error ( nls . localize ( 'customTemplatesCannotRetrieveDefaultBranch' , repoUri . href ) ) ; } const info = JSON . parse ( infoResponse . body ) ; return { username , name , branch : info [ 'default_branch' ] , filePath } ; } if ( username && name && branch && t === 'tree' ) { return { username , name , branch , filePath } ; } else { throw new Error ( nls . localize ( 'customTemplatesInvalidRepoUrl' , repoUri . href ) ) ; } } param repoUri returns export function getStoragePathForCustomTemplates ( repoUri ) { const folderHash = crypto . createHash ( 'md5' ) . update ( repoUri . href ) . digest ( 'hex' ) ; const customTemplatesPath = path . join ( Global . DIR , 'custom-templates' , folderHash ) ; return customTemplatesPath ; } param repoUri param forceLoadingRemoteRepo returns export async function loadCustomTemplatesGitRepo ( repoUri , forceLoadingRemoteRepo = false ) { const customTemplatesPath = getStoragePathForCustomTemplates ( repoUri ) ; if ( fs . existsSync ( customTemplatesPath ) && ! forceLoadingRemoteRepo ) { return customTemplatesPath ; } if ( repoUri . protocol !== 'https:' ) { throw new Error ( nls . localize ( 'customTemplatesShouldUseHttpsProtocol' , `"${ repoUri . protocol }"` ) ) ; } if ( repoUri . hostname !== 'github.com' ) { throw new Error ( nls . localize ( 'customTemplatesSupportsGitHubOnly' , repoUri . href ) ) ; } const { username , name , branch , filePath } = await getRepoInfo ( repoUri ) ; if ( ! fs . existsSync ( customTemplatesPath ) ) { fs . mkdirSync ( customTemplatesPath , { recursive : true } ) ; } const pipeline = promisify ( Stream . pipeline ) ; await pipeline ( got . stream ( `https://codeload.github.com/${ username }/${ name }/tar.gz/${ branch }` ) , tar . extract ( { cwd : customTemplatesPath , strip : filePath ? filePath . split ( '/' ) . length + 1 : 1 } , [ `${ name }-${ branch }${ filePath ? `/${ filePath }` : '' }` ] ) ) ; return customTemplatesPath ; }