11/* eslint-disable prefer-const */
2- import { Compiler , Project , SchemaComposer } from "../lib" ;
2+ import {
3+ Compiler ,
4+ Project ,
5+ SchemaComposer ,
6+ Watcher ,
7+ WatchEvent ,
8+ watchEventName ,
9+ } from "../lib" ;
310import { fixParameters } from "../lib/helpers/parameters" ;
411import { publishToIPFS } from "../lib/publishers/ipfs-publisher" ;
512
613import chalk from "chalk" ;
714import axios from "axios" ;
15+ import readline from "readline" ;
816import { GluegunToolbox } from "gluegun" ;
917
1018const HELP = `
@@ -15,11 +23,9 @@ Options:
1523 -i, --ipfs [<node>] Upload build results to an IPFS node (default: dev-server's node)
1624 -o, --output-dir <path> Output directory for build results (default: build/)
1725 -e, --test-ens <[address,]domain> Publish the package to a test ENS domain locally (requires --ipfs)
26+ -w, --watch Automatically rebuild when changes are made (default: false)
1827` ;
1928
20- // TODO: add to the above options when implemented
21- // -w, --watch Regenerate types when web3api files change (default: false)
22-
2329export default {
2430 alias : [ "b" ] ,
2531 description : "Builds a Web3API and (optionally) uploads it to IPFS" ,
@@ -145,56 +151,117 @@ export default {
145151 schemaComposer,
146152 } ) ;
147153
148- let result = false ;
154+ const execute = async ( ) : Promise < boolean > => {
155+ compiler . clearCache ( ) ;
156+ const result = await compiler . compile ( ) ;
149157
150- /*if (watch) {
151- // TODO: https://github.com/Web3-API/prototype/issues/98
152- // compiler.watchAndCompile();
153- } else*/ {
154- result = await compiler . compile ( ) ;
155- if ( result === false ) {
156- process . exitCode = 1 ;
157- return ;
158+ if ( ! result ) {
159+ return result ;
158160 }
159- }
160161
161- const uris : string [ ] [ ] = [ ] ;
162+ const uris : string [ ] [ ] = [ ] ;
163+
164+ // publish to IPFS
165+ if ( ipfs ) {
166+ const cid = await publishToIPFS ( outputDir , ipfs ) ;
167+
168+ print . success ( `IPFS { ${ cid } }` ) ;
169+ uris . push ( [ "Web3API IPFS" , `ipfs://${ cid } ` ] ) ;
170+
171+ if ( testEns ) {
172+ if ( ! ensAddress ) {
173+ uris . push ( [ "ENS Registry" , `${ ethProvider } /${ ensAddress } ` ] ) ;
174+ }
162175
163- // publish to IPFS
164- if ( ipfs ) {
165- const cid = await publishToIPFS ( outputDir , ipfs ) ;
176+ // ask the dev server to publish the CID to ENS
177+ const { data } = await axios . get (
178+ "http://localhost:4040/register-ens" ,
179+ {
180+ params : {
181+ domain : ensDomain ,
182+ cid,
183+ } ,
184+ }
185+ ) ;
166186
167- print . success ( `IPFS { ${ cid } }` ) ;
168- uris . push ( [ "Web3API IPFS" , `ipfs://${ cid } ` ] ) ;
187+ if ( data . success ) {
188+ uris . push ( [ "Web3API ENS" , `${ testEns } => ${ cid } ` ] ) ;
189+ } else {
190+ print . error (
191+ `ENS Resolution Failed { ${ testEns } => ${ cid } }\n` +
192+ `Ethereum Provider: ${ ethProvider } \n` +
193+ `ENS Address: ${ ensAddress } `
194+ ) ;
195+ }
169196
170- if ( testEns ) {
171- if ( ! ensAddress ) {
172- uris . push ( [ "ENS Registry" , `${ ethProvider } /${ ensAddress } ` ] ) ;
197+ return data . success ;
173198 }
199+ }
174200
175- // ask the dev server to publish the CID to ENS
176- const { data } = await axios . get ( "http://localhost:4040/register-ens" , {
177- params : {
178- domain : ensDomain ,
179- cid,
180- } ,
201+ if ( uris . length ) {
202+ print . success ( "URI Viewers:" ) ;
203+ print . table ( uris ) ;
204+ return true ;
205+ } else {
206+ return false ;
207+ }
208+ } ;
209+
210+ if ( ! watch ) {
211+ const result = await execute ( ) ;
212+
213+ if ( ! result ) {
214+ process . exitCode = 1 ;
215+ return ;
216+ }
217+ } else {
218+ // Execute
219+ await execute ( ) ;
220+
221+ const keyPressListener = ( ) => {
222+ // Watch for escape key presses
223+ print . info ( `Watching: ${ project . manifestDir } ` ) ;
224+ print . info ( "Exit: [CTRL + C], [ESC], or [Q]" ) ;
225+ readline . emitKeypressEvents ( process . stdin ) ;
226+ process . stdin . on ( "keypress" , async ( str , key ) => {
227+ if (
228+ key . name == "escape" ||
229+ key . name == "q" ||
230+ ( key . name == "c" && key . ctrl )
231+ ) {
232+ await watcher . stop ( ) ;
233+ process . kill ( process . pid , "SIGINT" ) ;
234+ }
181235 } ) ;
182236
183- if ( data . success ) {
184- uris . push ( [ "Web3API ENS" , `${ testEns } => ${ cid } ` ] ) ;
185- } else {
186- print . error (
187- `ENS Resolution Failed { ${ testEns } => ${ cid } }\n` +
188- `Ethereum Provider: ${ ethProvider } \n` +
189- `ENS Address: ${ ensAddress } `
190- ) ;
237+ if ( process . stdin . setRawMode ) {
238+ process . stdin . setRawMode ( true ) ;
191239 }
192- }
193- }
194240
195- if ( uris . length ) {
196- print . success ( "URI Viewers:" ) ;
197- print . table ( uris ) ;
241+ process . stdin . resume ( ) ;
242+ } ;
243+
244+ keyPressListener ( ) ;
245+
246+ // Watch the directory
247+ const watcher = new Watcher ( ) ;
248+
249+ watcher . start ( project . manifestDir , {
250+ ignored : [ outputDir + "/**" , project . manifestDir + "/**/w3/**" ] ,
251+ ignoreInitial : true ,
252+ execute : async ( events : WatchEvent [ ] ) => {
253+ // Log all of the events encountered
254+ for ( const event of events ) {
255+ print . info ( `${ watchEventName ( event . type ) } : ${ event . path } ` ) ;
256+ }
257+
258+ // Execute the build
259+ await execute ( ) ;
260+
261+ // Process key presses
262+ keyPressListener ( ) ;
263+ } ,
264+ } ) ;
198265 }
199266
200267 process . exitCode = 0 ;
0 commit comments