From c5868228e3db5fd3fa98cecc3cbe48e27d551a80 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 13 Jul 2018 16:58:42 +0200 Subject: [PATCH 1/5] automatically unsubscribe to upload, download and configure subjects --- package.json | 141 ++++++++++++++++++++++++++------------ src/boardConfiguration.js | 20 +++--- src/daemon.js | 16 +++-- src/socket-daemon.js | 19 +++-- 4 files changed, 137 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index 52f2fe3a..be9c97ea 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,77 @@ { - "name": "arduino-create-agent-js-client", - "version": "1.0.4", - "description": "JS module providing discovery of the Arduino Create Plugin and communication with it", - "main": "./src/index.js", - "module": "es/index.js", - "jsnext:main": "es/index.js", - "files": [ - "dist", - "lib", - "es", - "src" + "_from": "arduino-create-agent-js-client@^1.0.3", + "_id": "arduino-create-agent-js-client@1.0.3", + "_inBundle": false, + "_integrity": "sha512-EOFDmI6Qe0YpEFzkZUwntS/kW9+tb5D7El8YroXQOA2Tw5q/ntSxT4awybqAjOerWCf9BfHuBYwOP7XMFveLOw==", + "_location": "/arduino-create-agent-js-client", + "_phantomChildren": { + "after": "0.8.2", + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "has-binary": "0.1.7", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "json3": "3.3.2", + "object-component": "0.0.3", + "options": "0.0.6", + "parsejson": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "to-array": "0.1.4", + "wtf-8": "1.0.0", + "yeast": "0.1.2" + }, + "_requested": { + "type": "range", + "registry": true, + "raw": "arduino-create-agent-js-client@^1.0.3", + "name": "arduino-create-agent-js-client", + "escapedName": "arduino-create-agent-js-client", + "rawSpec": "^1.0.3", + "saveSpec": null, + "fetchSpec": "^1.0.3" + }, + "_requiredBy": [ + "/" ], - "directories": { - "lib": "lib" + "_resolved": "https://registry.npmjs.org/arduino-create-agent-js-client/-/arduino-create-agent-js-client-1.0.3.tgz", + "_shasum": "c33caef538f1001ffa43a0cb6a11f40a990a9518", + "_spec": "arduino-create-agent-js-client@^1.0.3", + "_where": "/home/alberto/work/create-gettingstarted-site", + "bugs": { + "url": "https://github.com/arduino/arduino-create-agent-js-client/issues" }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Stefania Mellai", + "email": "s.mellai@arduino.cc" + }, + { + "name": "Fabrizio Mirabito", + "email": "f.mirabito@arduino.cc" + }, + { + "name": "Alberto Iannaccone", + "email": "a.iannaccone@arduino.cc" + }, + { + "name": "Gabriele Destefanis", + "email": "g.destefanis@topsolution.it" + } + ], "dependencies": { "detect-browser": "^2.5.1", "rxjs": "^6.2.1", "semver-compare": "^1.0.0", "socket.io-client": "1.7.4" }, + "deprecated": false, + "description": "JS module providing discovery of the Arduino Create Plugin and communication with it", "devDependencies": { "babel-cli": "^6.26.0", "babel-core": "^6.26.3", @@ -48,42 +100,47 @@ "webpack-cli": "^3.0.8", "webpack-dev-server": "^2.11.1" }, - "scripts": { - "test": "", - "dev": "webpack-dev-server", - "lint": "./node_modules/.bin/eslint src", - "lint-fix": "./node_modules/.bin/eslint --fix src --ext .js", - "clean": "rimraf lib dist es", - "build": "npm run build:commonjs && npm run build:umd && npm run build:umd:min && npm run build:es", - "build:watch": "echo 'build && watch the COMMONJS version of the package - for other version, run specific tasks' && npm run build:commonjs:watch", - "build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib", - "build:commonjs:watch": "npm run build:commonjs -- --watch", - "build:es": "cross-env BABEL_ENV=es babel src --out-dir es", - "build:es:watch": "npm run build:es -- --watch", - "build:umd": "cross-env BABEL_ENV=es NODE_ENV=development node_modules/.bin/rollup src/index.js --config --sourcemap --output dist/create-plugin.js", - "build:umd:watch": "npm run build:umd -- --watch", - "build:umd:min": "cross-env BABEL_ENV=es NODE_ENV=production rollup src/index.js --config --output dist/create-plugin.min.js", - "prepare": "npm run clean && npm test && npm run build" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/arduino/arduino-create-agent-js-client.git" + "directories": { + "lib": "lib" }, + "files": [ + "dist", + "lib", + "es", + "src" + ], + "homepage": "https://github.com/arduino/arduino-create-agent-js-client#readme", + "jsnext:main": "es/index.js", "keywords": [ "arduino", "create", "agent", "plugin" ], - "contributors": [ - "Stefania Mellai ", - "Fabrizio Mirabito ", - "Alberto Iannaccone ", - "Gabriele Destefanis " - ], "license": "GPLv3", - "bugs": { - "url": "https://github.com/arduino/arduino-create-agent-js-client/issues" + "main": "./src/index.js", + "module": "es/index.js", + "name": "arduino-create-agent-js-client", + "repository": { + "type": "git", + "url": "git+https://github.com/arduino/arduino-create-agent-js-client.git" + }, + "scripts": { + "build": "npm run build:commonjs && npm run build:umd && npm run build:umd:min && npm run build:es", + "build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib", + "build:commonjs:watch": "npm run build:commonjs -- --watch", + "build:es": "cross-env BABEL_ENV=es babel src --out-dir es", + "build:es:watch": "npm run build:es -- --watch", + "build:umd": "cross-env BABEL_ENV=es NODE_ENV=development node_modules/.bin/rollup src/index.js --config --sourcemap --output dist/create-plugin.js", + "build:umd:min": "cross-env BABEL_ENV=es NODE_ENV=production rollup src/index.js --config --output dist/create-plugin.min.js", + "build:umd:watch": "npm run build:umd -- --watch", + "build:watch": "echo 'build && watch the COMMONJS version of the package - for other version, run specific tasks' && npm run build:commonjs:watch", + "clean": "rimraf lib dist es", + "dev": "webpack-dev-server", + "lint": "eslint src", + "lint-fix": "eslint --fix src --ext .js", + "prepare": "npm run clean && npm test && npm run build", + "test": "" }, - "homepage": "https://github.com/arduino/arduino-create-agent-js-client#readme" + "version": "1.0.3" } diff --git a/src/boardConfiguration.js b/src/boardConfiguration.js index 6b29aab5..f58cd325 100644 --- a/src/boardConfiguration.js +++ b/src/boardConfiguration.js @@ -33,8 +33,12 @@ export default class BoardConfiguration { this.daemon = daemon; this.serialMonitorContent = ''; this.configuring = new BehaviorSubject({ status: this.CONFIGURE_NOPE }); - this.configureDone = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_DONE)); - this.configureInProgress = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_IN_PROGRESS)); + this.configureDone = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_DONE)) + .pipe(first()) + .pipe(takeUntil(this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_ERROR)))); + this.configureInProgress = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_IN_PROGRESS)) + .pipe(first()) + .pipe(takeUntil(this.configureDone)); this.configureError = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_ERROR)); this.daemon.serialMonitorMessages.subscribe(message => { this.serialMonitorContent += message; @@ -45,8 +49,8 @@ export default class BoardConfiguration { this.configuring.next({ status: this.CONFIGURE_IN_PROGRESS, msg: 'Starting board configuration...' }); } - notifyError(msg) { - this.configuring.next({ status: this.CONFIGURE_ERROR, msg: msg, err: msg}); + notifyError(err, msg) { + this.configuring.next({ status: this.CONFIGURE_ERROR, err, msg }); } /** @@ -189,7 +193,7 @@ export default class BoardConfiguration { return; } - this.daemon.uploadingDone.pipe(first()).subscribe(() => { + this.daemon.uploadingDone.subscribe(() => { this.configuring.next({ status: this.CONFIGURE_IN_PROGRESS, msg: 'Provisioning sketch uploaded successfully. Opening serial monitor...' @@ -206,7 +210,7 @@ export default class BoardConfiguration { status: this.CONFIGURE_IN_PROGRESS, msg: 'CSR generated. Creating device...' }); - return createDeviceCb(csr) + return createDeviceCb(csr); }) .then(data => { this.configuring.next({ @@ -230,10 +234,10 @@ export default class BoardConfiguration { err: error.toString() }); }); - this.daemon.openSerialMonitor(board.port, BAUDRATE); + this.daemon.openSerialMonitor(board.port, BAUDRATE); }); - this.daemon.uploadingError.pipe(first()).subscribe(upload => { + this.daemon.uploadingError.subscribe(upload => { this.configuring.next({ status: this.CONFIGURE_ERROR, err: `Couldn't configure board at port ${board.port}. Upload failed with error: ${upload.err}` }); }); diff --git a/src/daemon.js b/src/daemon.js index d0692089..daaa38e6 100644 --- a/src/daemon.js +++ b/src/daemon.js @@ -39,9 +39,13 @@ export default class Daemon { this.serialMonitorOpened = new BehaviorSubject(false); this.serialMonitorMessages = new Subject(); this.uploading = new BehaviorSubject({ status: this.UPLOAD_NOPE }); - this.uploadingDone = this.uploading.pipe(filter(upload => upload.status === this.UPLOAD_DONE)); + this.uploadingDone = this.uploading.pipe(filter(upload => upload.status === this.UPLOAD_DONE)) + .pipe(first()) + .pipe(takeUntil(this.uploading.pipe(filter(upload => upload.status === this.UPLOAD_ERROR)))); + this.uploadingError = this.uploading.pipe(filter(upload => upload.status === this.UPLOAD_ERROR)) + .pipe(first()) + .pipe(takeUntil(this.uploadingDone)); this.uploadInProgress = this.uploading.pipe(filter(upload => upload.status === this.UPLOAD_IN_PROGRESS)); - this.uploadingError = this.uploading.pipe(filter(upload => upload.status === this.UPLOAD_ERROR)); this.devicesList = new BehaviorSubject({ serial: [], network: [] @@ -57,6 +61,10 @@ export default class Daemon { .subscribe(() => this.closeAllPorts()); } + notifyUploadError(err, msg) { + this.uploading.next({ status: this.UPLOAD_ERROR, err, msg }); + } + openChannel(cb) { this.channelOpen .subscribe(open => { @@ -111,9 +119,7 @@ export default class Daemon { if (typeof this.stopUploadCommand === 'function') { this.stopUploadCommand(); } - else { - throw new Error('Stop Upload not supported on Chrome OS'); - } + throw new Error('Stop Upload not supported on Chrome OS'); } initUpload() { diff --git a/src/socket-daemon.js b/src/socket-daemon.js index c298d021..19777cac 100644 --- a/src/socket-daemon.js +++ b/src/socket-daemon.js @@ -65,8 +65,12 @@ export default class SocketDaemon extends Daemon { this.pluginURL = null; this.downloading = new BehaviorSubject({ status: DOWNLOAD_NOPE }); - this.downloadingDone = this.downloading.pipe(filter(download => download.status === DOWNLOAD_DONE)); - this.downloadingError = this.downloading.pipe(filter(download => download.status === DOWNLOAD_ERROR)); + this.downloadingDone = this.downloading.pipe(filter(download => download.status === DOWNLOAD_DONE)) + .pipe(first()) + .pipe(takeUntil(this.downloading.pipe(filter(download => download.status === this.DOWNLOAD_ERROR)))); + this.downloadingError = this.downloading.pipe(filter(download => download.status === DOWNLOAD_ERROR)) + .pipe(first()) + .pipe(takeUntil(this.downloadingDone)); this.openChannel(() => this.socket.emit('command', 'list')); @@ -92,6 +96,10 @@ export default class SocketDaemon extends Daemon { }); } + notifyDownloadError(err, msg) { + this.downloading.next({ status: this.DOWNLOAD_ERROR, err, msg }); + } + /** * Look for the agent endpoint. * First search in http://LOOPBACK_ADDRESS, after in https://LOOPBACK_HOSTNAME if in Chrome or Firefox, otherwise vice versa. @@ -443,7 +451,6 @@ export default class SocketDaemon extends Daemon { this.serialMonitorOpened.pipe(filter(open => !open)) .pipe(first()) .subscribe(() => { - fetch(`${this.pluginURL}/upload`, { method: 'POST', headers: { @@ -473,7 +480,11 @@ export default class SocketDaemon extends Daemon { * Interrupt upload */ stopUploadCommand() { - this.uploading.next(false); + this.uploading.next({ + status: this.UPLOAD_ERROR, + err: 'upload stopped', + msg: 'Upload stopped' + }); this.socket.emit('command', 'killprogrammer'); } } From fa3ebdcd7af6cd50b3eea6ba52c9690f61f4c95f Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 13 Jul 2018 17:11:17 +0200 Subject: [PATCH 2/5] minor fixes --- src/boardConfiguration.js | 4 ++-- src/daemon.js | 8 +++++--- src/socket-daemon.js | 7 +++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/boardConfiguration.js b/src/boardConfiguration.js index f58cd325..2c843157 100644 --- a/src/boardConfiguration.js +++ b/src/boardConfiguration.js @@ -36,10 +36,10 @@ export default class BoardConfiguration { this.configureDone = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_DONE)) .pipe(first()) .pipe(takeUntil(this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_ERROR)))); - this.configureInProgress = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_IN_PROGRESS)) + this.configureError = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_ERROR)) .pipe(first()) .pipe(takeUntil(this.configureDone)); - this.configureError = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_ERROR)); + this.configureInProgress = this.configuring.pipe(filter(configure => configure.status === this.CONFIGURE_IN_PROGRESS)); this.daemon.serialMonitorMessages.subscribe(message => { this.serialMonitorContent += message; }); diff --git a/src/daemon.js b/src/daemon.js index daaa38e6..21423e13 100644 --- a/src/daemon.js +++ b/src/daemon.js @@ -61,8 +61,8 @@ export default class Daemon { .subscribe(() => this.closeAllPorts()); } - notifyUploadError(err, msg) { - this.uploading.next({ status: this.UPLOAD_ERROR, err, msg }); + notifyUploadError(err) { + this.uploading.next({ status: this.UPLOAD_ERROR, err }); } openChannel(cb) { @@ -119,7 +119,9 @@ export default class Daemon { if (typeof this.stopUploadCommand === 'function') { this.stopUploadCommand(); } - throw new Error('Stop Upload not supported on Chrome OS'); + else { + throw new Error('Stop Upload not supported on Chrome OS'); + } } initUpload() { diff --git a/src/socket-daemon.js b/src/socket-daemon.js index 19777cac..f8607530 100644 --- a/src/socket-daemon.js +++ b/src/socket-daemon.js @@ -96,8 +96,8 @@ export default class SocketDaemon extends Daemon { }); } - notifyDownloadError(err, msg) { - this.downloading.next({ status: this.DOWNLOAD_ERROR, err, msg }); + notifyDownloadError(err) { + this.downloading.next({ status: this.DOWNLOAD_ERROR, err }); } /** @@ -482,8 +482,7 @@ export default class SocketDaemon extends Daemon { stopUploadCommand() { this.uploading.next({ status: this.UPLOAD_ERROR, - err: 'upload stopped', - msg: 'Upload stopped' + err: 'upload stopped' }); this.socket.emit('command', 'killprogrammer'); } From cb6d398f6edfa2d4200c0fd591351b05dbdc3b00 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 13 Jul 2018 17:18:24 +0200 Subject: [PATCH 3/5] 1.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be9c97ea..072f7272 100644 --- a/package.json +++ b/package.json @@ -142,5 +142,5 @@ "prepare": "npm run clean && npm test && npm run build", "test": "" }, - "version": "1.0.3" + "version": "1.0.4" } From a815e5bd5ea5bb7df931beb8642e70bb23cfcdf7 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 13 Jul 2018 17:19:41 +0200 Subject: [PATCH 4/5] 1.0.5 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a2db6220..45d14ec5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "arduino-create-agent-js-client", - "version": "1.0.4", + "version": "1.0.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 072f7272..96a2331d 100644 --- a/package.json +++ b/package.json @@ -142,5 +142,5 @@ "prepare": "npm run clean && npm test && npm run build", "test": "" }, - "version": "1.0.4" + "version": "1.0.5" } From 62d3f45f2aa40b4d62f48ac9361701638ad32c67 Mon Sep 17 00:00:00 2001 From: Alberto Iannaccone Date: Fri, 13 Jul 2018 17:28:43 +0200 Subject: [PATCH 5/5] restore package.json --- package.json | 141 +++++++++++++++------------------------------------ 1 file changed, 42 insertions(+), 99 deletions(-) diff --git a/package.json b/package.json index 96a2331d..d163a7d5 100644 --- a/package.json +++ b/package.json @@ -1,77 +1,25 @@ { - "_from": "arduino-create-agent-js-client@^1.0.3", - "_id": "arduino-create-agent-js-client@1.0.3", - "_inBundle": false, - "_integrity": "sha512-EOFDmI6Qe0YpEFzkZUwntS/kW9+tb5D7El8YroXQOA2Tw5q/ntSxT4awybqAjOerWCf9BfHuBYwOP7XMFveLOw==", - "_location": "/arduino-create-agent-js-client", - "_phantomChildren": { - "after": "0.8.2", - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "has-binary": "0.1.7", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "json3": "3.3.2", - "object-component": "0.0.3", - "options": "0.0.6", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "to-array": "0.1.4", - "wtf-8": "1.0.0", - "yeast": "0.1.2" - }, - "_requested": { - "type": "range", - "registry": true, - "raw": "arduino-create-agent-js-client@^1.0.3", - "name": "arduino-create-agent-js-client", - "escapedName": "arduino-create-agent-js-client", - "rawSpec": "^1.0.3", - "saveSpec": null, - "fetchSpec": "^1.0.3" - }, - "_requiredBy": [ - "/" + "name": "arduino-create-agent-js-client", + "version": "1.0.5", + "description": "JS module providing discovery of the Arduino Create Plugin and communication with it", + "main": "./src/index.js", + "module": "es/index.js", + "jsnext:main": "es/index.js", + "files": [ + "dist", + "lib", + "es", + "src" ], - "_resolved": "https://registry.npmjs.org/arduino-create-agent-js-client/-/arduino-create-agent-js-client-1.0.3.tgz", - "_shasum": "c33caef538f1001ffa43a0cb6a11f40a990a9518", - "_spec": "arduino-create-agent-js-client@^1.0.3", - "_where": "/home/alberto/work/create-gettingstarted-site", - "bugs": { - "url": "https://github.com/arduino/arduino-create-agent-js-client/issues" + "directories": { + "lib": "lib" }, - "bundleDependencies": false, - "contributors": [ - { - "name": "Stefania Mellai", - "email": "s.mellai@arduino.cc" - }, - { - "name": "Fabrizio Mirabito", - "email": "f.mirabito@arduino.cc" - }, - { - "name": "Alberto Iannaccone", - "email": "a.iannaccone@arduino.cc" - }, - { - "name": "Gabriele Destefanis", - "email": "g.destefanis@topsolution.it" - } - ], "dependencies": { "detect-browser": "^2.5.1", "rxjs": "^6.2.1", "semver-compare": "^1.0.0", "socket.io-client": "1.7.4" }, - "deprecated": false, - "description": "JS module providing discovery of the Arduino Create Plugin and communication with it", "devDependencies": { "babel-cli": "^6.26.0", "babel-core": "^6.26.3", @@ -100,47 +48,42 @@ "webpack-cli": "^3.0.8", "webpack-dev-server": "^2.11.1" }, - "directories": { - "lib": "lib" - }, - "files": [ - "dist", - "lib", - "es", - "src" - ], - "homepage": "https://github.com/arduino/arduino-create-agent-js-client#readme", - "jsnext:main": "es/index.js", - "keywords": [ - "arduino", - "create", - "agent", - "plugin" - ], - "license": "GPLv3", - "main": "./src/index.js", - "module": "es/index.js", - "name": "arduino-create-agent-js-client", - "repository": { - "type": "git", - "url": "git+https://github.com/arduino/arduino-create-agent-js-client.git" - }, "scripts": { + "test": "", + "dev": "webpack-dev-server", + "lint": "./node_modules/.bin/eslint src", + "lint-fix": "./node_modules/.bin/eslint --fix src --ext .js", + "clean": "rimraf lib dist es", "build": "npm run build:commonjs && npm run build:umd && npm run build:umd:min && npm run build:es", + "build:watch": "echo 'build && watch the COMMONJS version of the package - for other version, run specific tasks' && npm run build:commonjs:watch", "build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib", "build:commonjs:watch": "npm run build:commonjs -- --watch", "build:es": "cross-env BABEL_ENV=es babel src --out-dir es", "build:es:watch": "npm run build:es -- --watch", "build:umd": "cross-env BABEL_ENV=es NODE_ENV=development node_modules/.bin/rollup src/index.js --config --sourcemap --output dist/create-plugin.js", - "build:umd:min": "cross-env BABEL_ENV=es NODE_ENV=production rollup src/index.js --config --output dist/create-plugin.min.js", "build:umd:watch": "npm run build:umd -- --watch", - "build:watch": "echo 'build && watch the COMMONJS version of the package - for other version, run specific tasks' && npm run build:commonjs:watch", - "clean": "rimraf lib dist es", - "dev": "webpack-dev-server", - "lint": "eslint src", - "lint-fix": "eslint --fix src --ext .js", - "prepare": "npm run clean && npm test && npm run build", - "test": "" + "build:umd:min": "cross-env BABEL_ENV=es NODE_ENV=production rollup src/index.js --config --output dist/create-plugin.min.js", + "prepare": "npm run clean && npm test && npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/arduino/arduino-create-agent-js-client.git" + }, + "keywords": [ + "arduino", + "create", + "agent", + "plugin" + ], + "contributors": [ + "Stefania Mellai ", + "Fabrizio Mirabito ", + "Alberto Iannaccone ", + "Gabriele Destefanis " + ], + "license": "GPLv3", + "bugs": { + "url": "https://github.com/arduino/arduino-create-agent-js-client/issues" }, - "version": "1.0.5" + "homepage": "https://github.com/arduino/arduino-create-agent-js-client#readme" }