@@ -61,12 +61,13 @@ export class NoirPluginClient extends PluginClient {
6161 }
6262 }
6363
64- async setupNargoToml ( ) : Promise < void > {
64+ async setupNargoToml ( projectRoot : string ) : Promise < void > {
65+ const tomlPath = projectRoot === '/' ? 'Nargo.toml' : `${ projectRoot } /Nargo.toml`
6566 // @ts -ignore
66- const nargoTomlExists = await this . call ( 'fileManager' , 'exists' , 'Nargo.toml' )
67+ const nargoTomlExists = await this . call ( 'fileManager' , 'exists' , tomlPath )
6768
6869 if ( ! nargoTomlExists ) {
69- await this . call ( 'fileManager' , 'writeFile' , 'Nargo.toml' , DEFAULT_TOML_CONFIG )
70+ await this . call ( 'fileManager' , 'writeFile' , tomlPath , DEFAULT_TOML_CONFIG )
7071 }
7172 }
7273
@@ -77,6 +78,29 @@ export class NoirPluginClient extends PluginClient {
7778 return `req_${ timestamp } _${ random } `
7879 }
7980
81+ async findProjectRoot ( filePath : string ) : Promise < string | null > {
82+ const srcIndex = filePath . lastIndexOf ( '/src/' )
83+
84+ if ( srcIndex === - 1 ) {
85+ console . error ( `File is not located within a 'src' directory: ${ filePath } ` )
86+ return null
87+ }
88+
89+ const potentialRoot = filePath . substring ( 0 , srcIndex )
90+ const tomlPath = potentialRoot ? `${ potentialRoot } /Nargo.toml` : 'Nargo.toml'
91+
92+ // @ts -ignore
93+ const tomlExists = await this . call ( 'fileManager' , 'exists' , tomlPath )
94+
95+ if ( tomlExists ) {
96+ const projectRoot = potentialRoot || '/'
97+ return projectRoot
98+ } else {
99+ console . error ( `'Nargo.toml' not found at the expected project root: '${ potentialRoot || '/' } '.` )
100+ return null
101+ }
102+ }
103+
80104 async compile ( path : string ) : Promise < void > {
81105 try {
82106 const requestID = this . generateRequestID ( )
@@ -86,15 +110,28 @@ export class NoirPluginClient extends PluginClient {
86110 path,
87111 id : requestID
88112 }
113+
89114 if ( this . ws . readyState === WebSocket . OPEN ) {
115+ const projectRoot = await this . findProjectRoot ( path )
116+
117+ if ( projectRoot === null ) {
118+ const errorMsg = `Invalid project structure for '${ path } '. A '.nr' file must be inside a 'src' folder, and a 'Nargo.toml' file must exist in the project root directory.`
119+ this . call ( 'terminal' , 'log' , { type : 'error' , value : errorMsg } )
120+ this . emit ( 'statusChanged' , { key : 'error' , title : 'Invalid project structure' , type : 'error' } )
121+ this . internalEvents . emit ( 'noir_compiling_errored' , new Error ( errorMsg ) )
122+ return
123+ }
124+
90125 this . ws . send ( JSON . stringify ( { requestId : requestID } ) )
91126 this . internalEvents . emit ( 'noir_compiling_start' )
92127 this . emit ( 'statusChanged' , { key : 'loading' , title : 'Compiling Noir Program...' , type : 'info' } )
93128 // @ts -ignore
94129 this . call ( 'terminal' , 'log' , { type : 'log' , value : 'Compiling ' + path } )
95- await this . setupNargoToml ( )
130+
131+ await this . setupNargoToml ( projectRoot )
132+
96133 // @ts -ignore
97- const zippedProject : Blob = await this . call ( 'fileManager' , 'download' , '/' , false , [ 'build' ] )
134+ const zippedProject : Blob = await this . call ( 'fileManager' , 'download' , projectRoot , false , [ 'build' ] )
98135 const formData = new FormData ( )
99136
100137 formData . append ( 'file' , zippedProject , `${ extractNameFromKey ( path ) } .zip` )
@@ -108,8 +145,11 @@ export class NoirPluginClient extends PluginClient {
108145 } else {
109146 const { compiledJson, proverToml } = response . data
110147
111- this . call ( 'fileManager' , 'writeFile' , 'build/program.json' , compiledJson )
112- this . call ( 'fileManager' , 'writeFile' , 'build/prover.toml' , proverToml )
148+ const buildPath = projectRoot === '/' ? 'build' : `${ projectRoot } /build`
149+
150+ this . call ( 'fileManager' , 'writeFile' , `${ buildPath } /program.json` , compiledJson )
151+ this . call ( 'fileManager' , 'writeFile' , `${ buildPath } /prover.toml` , proverToml )
152+
113153 this . internalEvents . emit ( 'noir_compiling_done' )
114154 this . emit ( 'statusChanged' , { key : 'succeed' , title : 'Noir circuit compiled successfully' , type : 'success' } )
115155 // @ts -ignore
0 commit comments