@@ -2,6 +2,7 @@ const async = require('async');
22const fs = require ( './fs.js' ) ;
33const path = require ( 'path' ) ;
44const request = require ( 'request' ) ;
5+ const utils = require ( '../utils/utils' ) ;
56
67class File {
78
@@ -13,28 +14,51 @@ class File {
1314 this . resolver = options . resolver ;
1415 }
1516
16- parseFileForImport ( content , callback ) {
17+ parseFileForImport ( content , isHttpContract , callback ) {
1718 const self = this ;
19+ if ( typeof isHttpContract === 'function' ) {
20+ callback = isHttpContract ;
21+ isHttpContract = false ;
22+ }
1823 if ( self . filename . indexOf ( '.sol' ) < 0 ) {
1924 // Only supported in Solidity
20- return callback ( ) ;
25+ return callback ( null , content ) ;
2126 }
22- const regex = / i m p o r t " ( [ a - z A - Z 0 - 9 _ \- . \\ \/ ] + ) " ; / g;
27+ const regex = / i m p o r t [ " | ' ] ( [ - a - z A - Z 0 - 9 @ : % _ + . ~ # ? & \/ = ] + ) [ " | ' ] ; / g;
2328 let matches ;
2429 const filesToDownload = [ ] ;
2530 const pathWithoutFile = path . dirname ( self . path ) ;
2631 while ( ( matches = regex . exec ( content ) ) ) {
27- filesToDownload . push ( {
32+ const httpFileObj = utils . getExternalContractUrl ( matches [ 1 ] ) ;
33+ const fileObj = {
2834 fileRelativePath : path . join ( path . dirname ( self . filename ) , matches [ 1 ] ) ,
2935 url : `${ pathWithoutFile } /${ matches [ 1 ] } `
30- } ) ;
36+ } ;
37+ if ( httpFileObj ) {
38+ // Replace http import by filePath import in content
39+ content = content . replace ( matches [ 1 ] , httpFileObj . filePath ) ;
40+
41+ fileObj . fileRelativePath = httpFileObj . filePath ;
42+ fileObj . url = httpFileObj . url ;
43+ } else if ( ! isHttpContract ) {
44+ // Just a normal import
45+ continue ;
46+ }
47+ filesToDownload . push ( fileObj ) ;
3148 }
3249
50+ if ( self . downloadedImports ) {
51+ // We already parsed this file
52+ return callback ( null , content ) ;
53+ }
54+ self . downloadedImports = true ;
3355 async . each ( filesToDownload , ( ( fileObj , eachCb ) => {
3456 self . downloadFile ( fileObj . fileRelativePath , fileObj . url , ( _content ) => {
3557 eachCb ( ) ;
3658 } ) ;
37- } ) , callback ) ;
59+ } ) , ( err ) => {
60+ callback ( err , content ) ;
61+ } ) ;
3862 }
3963
4064 downloadFile ( filename , url , callback ) {
@@ -63,7 +87,7 @@ class File {
6387 fs . readFile ( filename , next ) ;
6488 } ,
6589 function parseForImports ( content , next ) {
66- self . parseFileForImport ( content , ( err ) => {
90+ self . parseFileForImport ( content , true , ( err ) => {
6791 next ( err , content ) ;
6892 } ) ;
6993 }
@@ -77,14 +101,19 @@ class File {
77101 }
78102
79103 content ( callback ) {
104+ let content ;
80105 if ( this . type === File . types . embark_internal ) {
81- return callback ( fs . readFileSync ( fs . embarkPath ( this . path ) ) . toString ( ) ) ;
106+ content = fs . readFileSync ( fs . embarkPath ( this . path ) ) . toString ( ) ;
82107 } else if ( this . type === File . types . dapp_file ) {
83- return callback ( fs . readFileSync ( this . path ) . toString ( ) ) ;
108+ content = fs . readFileSync ( this . path ) . toString ( ) ;
84109 } else if ( this . type === File . types . custom ) {
85- return this . resolver ( callback ) ;
110+ return this . resolver ( ( theContent ) => {
111+ this . parseFileForImport ( theContent , ( err , newContent ) => {
112+ callback ( newContent ) ;
113+ } ) ;
114+ } ) ;
86115 } else if ( this . type === File . types . http ) {
87- this . downloadFile ( this . filename , this . path , ( content ) => {
116+ return this . downloadFile ( this . filename , this . path , ( content ) => {
88117 if ( ! content ) {
89118 return callback ( content ) ;
90119 }
@@ -95,6 +124,9 @@ class File {
95124 } else {
96125 throw new Error ( "unknown file: " + this . filename ) ;
97126 }
127+ return this . parseFileForImport ( content , ( err , newContent ) => {
128+ callback ( newContent ) ;
129+ } ) ;
98130 }
99131
100132}
0 commit comments