11import fs from "fs" ;
22import path from "path" ;
3+ import * as https from "https" ;
34import { fileURLToPath } from "url" ;
45import { ExternalExtension , RawOptions , SolidityFramework } from "../types" ;
5- import { CURATED_EXTENSIONS } from "../curated- extensions" ;
6+ import curatedExtension from "../extensions.json " ;
67import { SOLIDITY_FRAMEWORKS } from "./consts" ;
78
9+ type ExtensionJSON = {
10+ extensionFlagValue : string ;
11+ repository : string ;
12+ branch ?: string ;
13+ // fields usefull for scaffoldeth.io
14+ description : string ;
15+ version ?: string ; // if not present we default to latest
16+ name ?: string ; // human redable name, if not present we default to branch or extensionFlagValue on UI
17+ } ;
18+
19+ const TRUSTED_GITHUB_ORGANIZATIONS = [ "scaffold-eth" , "buidlguidl" ] ;
20+
21+ const extensions : ExtensionJSON [ ] = curatedExtension ;
22+ const CURATED_EXTENSIONS = extensions . reduce < Record < string , ExternalExtension > > ( ( acc , ext ) => {
23+ if ( ! ext . repository ) {
24+ throw new Error ( `Extension must have 'repository': ${ JSON . stringify ( ext ) } ` ) ;
25+ }
26+ if ( ! ext . extensionFlagValue ) {
27+ throw new Error ( `Extension must have 'extensionFlagValue': ${ JSON . stringify ( ext ) } ` ) ;
28+ }
29+
30+ acc [ ext . extensionFlagValue ] = {
31+ repository : ext . repository ,
32+ branch : ext . branch ,
33+ } ;
34+ return acc ;
35+ } , { } ) ;
36+
837function deconstructGithubUrl ( url : string ) {
938 const urlParts = url . split ( "/" ) ;
1039 const ownerName = urlParts [ 3 ] ;
@@ -14,6 +43,47 @@ function deconstructGithubUrl(url: string) {
1443 return { ownerName, repoName, branch } ;
1544}
1645
46+ export const validateExternalExtension = async (
47+ extensionName : string ,
48+ dev : boolean ,
49+ ) : Promise < { repository : string ; branch ?: string ; isTrusted : boolean } | string > => {
50+ if ( dev ) {
51+ // Check externalExtensions/${extensionName} exists
52+ try {
53+ const currentFileUrl = import . meta. url ;
54+ const externalExtensionsDirectory = path . resolve (
55+ decodeURI ( fileURLToPath ( currentFileUrl ) ) ,
56+ "../../externalExtensions" ,
57+ ) ;
58+ await fs . promises . access ( `${ externalExtensionsDirectory } /${ extensionName } ` ) ;
59+ } catch {
60+ throw new Error ( `Extension not found in "externalExtensions/${ extensionName } "` ) ;
61+ }
62+
63+ return extensionName ;
64+ }
65+
66+ const { githubUrl, githubBranchUrl, branch, owner } = getDataFromExternalExtensionArgument ( extensionName ) ;
67+ const isTrusted = TRUSTED_GITHUB_ORGANIZATIONS . includes ( owner . toLowerCase ( ) ) || ! ! CURATED_EXTENSIONS [ extensionName ] ;
68+
69+ // Check if repository exists
70+ await new Promise ( ( resolve , reject ) => {
71+ https
72+ . get ( githubBranchUrl , res => {
73+ if ( res . statusCode !== 200 ) {
74+ reject ( new Error ( `Extension not found: ${ githubUrl } ` ) ) ;
75+ } else {
76+ resolve ( null ) ;
77+ }
78+ } )
79+ . on ( "error" , err => {
80+ reject ( err ) ;
81+ } ) ;
82+ } ) ;
83+
84+ return { repository : githubUrl , branch, isTrusted } ;
85+ } ;
86+
1787// Gets the data from the argument passed to the `--extension` option.
1888export const getDataFromExternalExtensionArgument = ( externalExtension : string ) => {
1989 if ( CURATED_EXTENSIONS [ externalExtension ] ) {
0 commit comments