11import * as fs from 'fs-extra' ;
22import * as path from 'path' ;
33import debug from 'debug' ;
4- import simpleGit from 'simple-git ' ;
4+ import fetch from 'node-fetch ' ;
55import { createHash } from 'crypto' ;
66
77import { DefaultPaths } from './paths' ;
8+ import { getOctokit } from './utils/octokit' ;
89
910function hashString ( str : string ) : string {
1011 const md5sum = createHash ( 'md5' ) ;
@@ -32,10 +33,41 @@ export class Fiddle {
3233export type FiddleSource = Fiddle | string | Iterable < [ string , string ] > ;
3334
3435export class FiddleFactory {
36+ private readonly VALID_FILES : Array < string > = [
37+ 'main.js' ,
38+ 'renderer.js' ,
39+ 'index.html' ,
40+ 'preload.js' ,
41+ 'styles.css' ,
42+ ] ;
43+ // Thanks to https://serverfault.com/a/917253
44+ private readonly GITHUB_URL_REGEX = new RegExp (
45+ '^(https|git)(://|@)([^/:]+)[/:]([^/:]+)/(.+).git$' ,
46+ ) ;
47+
3548 constructor ( private readonly fiddles : string = DefaultPaths . fiddles ) { }
3649
37- public async fromGist ( gistId : string ) : Promise < Fiddle > {
38- return this . fromRepo ( `https://gist.github.com/${ gistId } .git` ) ;
50+ public async fromGist ( gistId : string ) {
51+ // stores in format [filename, content]
52+ const gistContents : [ string , string ] [ ] = [ ] ;
53+ const octokit = getOctokit ( process . env . FIDDLE_CORE_GITHUB_TOKEN ) ;
54+ const gist = await octokit . gists . get ( { gist_id : gistId } ) ;
55+
56+ if ( gist . data . files === undefined ) {
57+ return ;
58+ }
59+ // TODO(aryanshridhar): Avoid repetitive undefined/null checks
60+ for ( const [ , data ] of Object . entries ( gist . data . files ) ) {
61+ const fileName = data ?. filename ;
62+ if ( fileName !== undefined && this . VALID_FILES . includes ( fileName ) ) {
63+ if ( data ?. content === undefined ) {
64+ continue ;
65+ }
66+ gistContents . push ( [ fileName , data . content ] ) ;
67+ }
68+ }
69+
70+ return this . fromEntries ( gistContents ) ;
3971 }
4072
4173 public async fromFolder ( source : string ) : Promise < Fiddle > {
@@ -55,23 +87,44 @@ export class FiddleFactory {
5587 return new Fiddle ( path . join ( folder , 'main.js' ) , source ) ;
5688 }
5789
58- public async fromRepo ( url : string , checkout = 'master' ) : Promise < Fiddle > {
90+ public async fromRepo ( url : string ) {
5991 const d = debug ( 'fiddle-core:FiddleFactory:fromRepo' ) ;
60- const folder = path . join ( this . fiddles , hashString ( url ) ) ;
61- d ( { url, checkout, folder } ) ;
62-
63- // get the repo
64- if ( ! fs . existsSync ( folder ) ) {
65- d ( `cloning "${ url } " into "${ folder } "` ) ;
66- const git = simpleGit ( ) ;
67- await git . clone ( url , folder , { '--depth' : 1 } ) ;
92+ const match = this . GITHUB_URL_REGEX . exec ( url ) ;
93+ if ( match === null ) {
94+ throw new Error ( `Invalid github URL` ) ;
95+ }
96+ // TODO (aryanshridhar): better error handling in case of array out
97+ // of bounds (not sure). This has to be done because octokit expects
98+ // an owner and repo keys to be passed instead of just git link.
99+ const user = match [ 4 ] ;
100+ const repo = match [ 5 ] ;
101+ const repoContents : [ string , string ] [ ] = [ ] ;
102+
103+ d ( { url, user, repo } ) ;
104+ const octokit = getOctokit ( process . env . FIDDLE_CORE_GITHUB_TOKEN ) ;
105+ const folder = await octokit . repos . getContent ( {
106+ owner : user ,
107+ repo : repo ,
108+ path : '.' , // Look for in the base directory only
109+ } ) ;
110+
111+ if ( ! Array . isArray ( folder . data ) ) {
112+ return ;
68113 }
69114
70- const git = simpleGit ( folder ) ;
71- await git . checkout ( checkout ) ;
72- await git . pull ( 'origin' , checkout ) ;
115+ for ( const file of folder . data ) {
116+ if ( ! this . VALID_FILES . includes ( file . name ) ) {
117+ continue ;
118+ }
119+
120+ if ( file . download_url ) {
121+ const resp = await fetch ( file . download_url ) ;
122+ const content = await resp . text ( ) ;
123+ repoContents . push ( [ file . name , content ] ) ;
124+ }
125+ }
73126
74- return new Fiddle ( path . join ( folder , 'main.js' ) , url ) ;
127+ return this . fromEntries ( repoContents ) ;
75128 }
76129
77130 public async fromEntries ( src : Iterable < [ string , string ] > ) : Promise < Fiddle > {
0 commit comments