diff --git a/README.md b/README.md index 5321f59..7c8b134 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# Teachable Machine Node v1.0.0 +# Teachable Machine Node ![teachable-machine-cover](https://media-blog.sashido.io/content/images/2020/09/teachable-machine-cover.png) # About -**Teachable Machine Node v.1.0.0** empowers you to load any image classification model trained with Google's Teachable Machine tool in a Node.Js project. +**Teachable Machine Node** empowers you to load any image classification model trained with Google's Teachable Machine tool in a Node.Js project. -[Teachable Machine](https://teachablemachine.withgoogle.com/) makes AI easy for everyone, by offering a fast and fun way to train a real TensorFlow.js Machine Learning Models without any coding required. You can train the computer to recognize images, sounds, & poses, using your camera or your own dataset. +[Teachable Machine](https://teachablemachine.withgoogle.com/) makes AI easy for everyone, by offering a fast and fun way to train a real TensorFlow.js Machine Learning Models without any coding required. You can train the computer to recognize images, sounds, & poses, using your camera or your own dataset. -For now, Teachable Machine Node v.1.0.0 holds suport only for image models, but we won't stop here. Check out the [Roadmap](#Roadmap) of what comes next! +For now, Teachable Machine Node holds suport only for image models, but we won't stop here. Check out the [Roadmap](#Roadmap) of what comes next! # Install @@ -31,7 +31,7 @@ yarn add @sashido/teachablemachine-node 1. [Gathering samples](https://youtu.be/DFBbSTvtpy4) is the fundamental first step to your Teachable Machine Model. Use your camera to collect data or upload some preselected images. -2. [Train your Teachable Machine Image Model](https://teachablemachine.withgoogle.com/train?action=onboardOpen&id=CO67EQ0ZWgA). +2. [Train your Teachable Machine Image Model](https://teachablemachine.withgoogle.com/train?action=onboardOpen&id=CO67EQ0ZWgA). ![](https://media-blog.sashido.io/content/images/2020/09/tm_export_model.png) @@ -117,15 +117,15 @@ app.listen(port, () => { In the long run, we will add more options, so you can train and load all kinds of Teachable Machine Models. - 1. Add support for Pose Models. - - 2. Add support for Audio Models. - - 3. Add support for Gifs. - + 1. Add support for Pose Models. + + 2. Add support for Audio Models. + + 3. Add support for Gifs. + 4. Add support for Videos. - -We would love to have your opinion which's the one you would like to see supported first. Don't be shy and drop us a line at hello@sashido.io. + +We would love to have your opinion which's the one you would like to see supported first. Don't be shy and drop us a line at hello@sashido.io. # Contribute diff --git a/index.js b/index.js index 78fe90b..7d0f975 100644 --- a/index.js +++ b/index.js @@ -1,32 +1,27 @@ +global.BigInt = require("bigint-polyfill"); +global.fetch = require("node-fetch"); + const tmImage = require("@teachablemachine/image"); const isImageUrl = require('is-image-url'); const canvas = require("canvas"); + const { JSDOM } = require("jsdom"); const dom = new JSDOM(""); - - -global.fetch = require("node-fetch"); global.document = dom.window.document; global.HTMLVideoElement = dom.window.HTMLVideoElement; const wait = ms => new Promise(r => setTimeout(r, ms)); - -const retryOperation = (operation, delay, times, retriesCounter = 0) => new Promise((resolve, reject) => { +const retryOperation = (operation, delay, times) => new Promise((resolve, reject) => { return operation() .then(({ cb }) => { return resolve(cb()); }) .catch(({ message }) => { - if (retriesCounter === 0) { - console.info("[@sashido/teachablemachine-node] -", message); - } - if (times - 1 > 0) { - retriesCounter++; return wait(delay) - .then(retryOperation.bind(null, operation, delay, times - 1, retriesCounter)) + .then(retryOperation.bind(null, operation, delay, times - 1)) .then(resolve) .catch(reject); } @@ -41,15 +36,17 @@ const byProbabilty = (predictionA, predictionB) => { return 0; } -class SashiDoTeachable { + +class SashiDoTeachableMachine { constructor(params) { this.loadModel(params); } - async loadModel({ modelUrl }) { if (!modelUrl || modelUrl === "") { console.error("[@sashido/teachablemachine-node] -", "Missing model URL!"); + this.error = "Missing model URL!"; + return null; } try { @@ -59,21 +56,32 @@ class SashiDoTeachable { } } + async checkModel(cb) { + const { model } = this; + + if (model) { + return Promise.resolve({ cb }); + } + + return Promise.reject({ message: "Loading model" }); + } + async classify(params) { - const { model } = this; const { imageUrl } = params; if (!isImageUrl(imageUrl)) { - console.error("[@sashido/teachablemachine-node] -", "Image URL is not valid!"); return Promise.reject({ error: "Image URL is not valid!" }); } - if (!model) { - console.error("[@sashido/teachablemachine-node] -", "Model is not ready!"); - return Promise.reject({ error: "Model is not ready!" }); + if (this.error) { + return Promise.reject({ error: this.error }); } + return retryOperation(() => this.checkModel(() => this.inference(params)), 1000, 20); // method, delay, retries + } + + async inference({ imageUrl }) { try { const image = new canvas.Image(); image.src = imageUrl; @@ -81,10 +89,9 @@ class SashiDoTeachable { const predictions = await this.model.predict(image); return predictions.sort(byProbabilty); } catch (error) { - console.error("[@sashido/teachablemachine-node] -", error); return Promise.reject({ error }); } } } -module.exports = SashiDoTeachable; +module.exports = SashiDoTeachableMachine; diff --git a/package-lock.json b/package-lock.json index 1d75da5..915ce77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@sashido/teachablemachine-node", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,16 +14,16 @@ } }, "@tensorflow/tfjs": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-2.3.0.tgz", - "integrity": "sha512-84vrkbktqnPYESZZOT2AN/LFm3qCF0UleGI7P+wgdsOYcwBoe8eZcVdhje/u9O4GYqwmn0+a8F+Kk4TmcFdrEw==", - "requires": { - "@tensorflow/tfjs-backend-cpu": "2.3.0", - "@tensorflow/tfjs-backend-webgl": "2.3.0", - "@tensorflow/tfjs-converter": "2.3.0", - "@tensorflow/tfjs-core": "2.3.0", - "@tensorflow/tfjs-data": "2.3.0", - "@tensorflow/tfjs-layers": "2.3.0", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-2.4.0.tgz", + "integrity": "sha512-V1XLtUDyhs1yodu9LinakSeIdT7SfFLBbHqCFPKaIWo9d9u3ZGFP/owzsWBk7Wqoh74bpm+kCF0gDg93Qx6ssw==", + "requires": { + "@tensorflow/tfjs-backend-cpu": "2.4.0", + "@tensorflow/tfjs-backend-webgl": "2.4.0", + "@tensorflow/tfjs-converter": "2.4.0", + "@tensorflow/tfjs-core": "2.4.0", + "@tensorflow/tfjs-data": "2.4.0", + "@tensorflow/tfjs-layers": "2.4.0", "argparse": "1.0.10", "chalk": "4.1.0", "core-js": "3.6.5", @@ -31,9 +31,9 @@ } }, "@tensorflow/tfjs-backend-cpu": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-2.3.0.tgz", - "integrity": "sha512-Ycf8mZywZYJrRIcZBqrloDxBc/lmV6aLLfj18wo8WE4aX9UxLNmSXF2iSs+x8icx7YmvLLglvTVST6tzL4sUSg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-2.4.0.tgz", + "integrity": "sha512-obA7IOL2teqoVguQ8EKSrfOu7ypAWQdGiTx/QfSmyaqXc9Z3YSZ1Nx0W4yWeLMJkNsp/EjYvBDeuNRenaFg0Gg==", "requires": { "@types/seedrandom": "2.4.27", "seedrandom": "2.4.3" @@ -47,11 +47,11 @@ } }, "@tensorflow/tfjs-backend-webgl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-2.3.0.tgz", - "integrity": "sha512-xTwAAASFPNHpIyShynCc+4Z2JtruJvEUosV28TDCNv9ZNuarxxpGimTBohjKFqzcjGIi4II0NyXbjMxTJcJkqw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-2.4.0.tgz", + "integrity": "sha512-/wh2CmZ3G7XrzsYIg7C2/Wt/QxKpVOfm0yDI5eDrOBoaC+kUsD4avJTS64pCWOdAYSN3yHHJxWO7IySuRlw4+Q==", "requires": { - "@tensorflow/tfjs-backend-cpu": "2.3.0", + "@tensorflow/tfjs-backend-cpu": "2.4.0", "@types/offscreencanvas": "2019.3.0", "@types/seedrandom": "2.4.27", "@types/webgl-ext": "0.0.30", @@ -67,14 +67,14 @@ } }, "@tensorflow/tfjs-converter": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-2.3.0.tgz", - "integrity": "sha512-Q6rXAhL4XN9jo8bnXnDoc3sB3dC5T/gIWnLX+DGmDfgIARBCKG+QZdemBvg64qw48gdK6oxd75aaTsvCjuQ6ww==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-2.4.0.tgz", + "integrity": "sha512-H16ydhoN/Ah7jd1NO4VUs8UGYbVs77yzUrTIGzras1ios2vsBMwFDC7+boIEekF+O/BcOgu26LtiU8n5hB4lrw==" }, "@tensorflow/tfjs-core": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-2.3.0.tgz", - "integrity": "sha512-XJ8B/VQexYVtyyoIUCqzIbEgwaWZzv9lq1E4LKafJeuT9DldJGHS7IWIkNnZDBfmQvfYHU+fAvGRRPdQPoYeRg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-2.4.0.tgz", + "integrity": "sha512-2SJ4PG56e1hixcwdT0oWcfaAe0tfJU+WAKHVeQP1xor4bzPDE8N7LCnRdYWTXbl5mNXRZ9h5qb+XtGEQrcUrJg==", "requires": { "@types/offscreencanvas": "2019.3.0", "@types/seedrandom": "2.4.27", @@ -97,9 +97,9 @@ } }, "@tensorflow/tfjs-data": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-2.3.0.tgz", - "integrity": "sha512-uDSZTDJaoR4axYVate22gspdNJC89iqW9IHf8wC9iMZ0xSBWoX9qChcI3xpTzP5couHxaBSUkFVXczuqvnFsfg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-2.4.0.tgz", + "integrity": "sha512-Ok1OyO2xIXBQ+XaSNf7LBldl89jgrX31wzsKPeV2SzzgOhA4A1YlhqS9WmRCnCbllnbnSGLGW829KlLCNos0AQ==", "requires": { "@types/node-fetch": "2.5.7", "node-fetch": "2.1.2" @@ -113,9 +113,9 @@ } }, "@tensorflow/tfjs-layers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-2.3.0.tgz", - "integrity": "sha512-8bXikhI/SvnOxRDELBxVB2kYKH78pQEEeXheMrSD38CA/QoKbH7sdPPmP7qpEz8kzU/k5sXnn8c5CIAFpO7sug==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-2.4.0.tgz", + "integrity": "sha512-+eBaClwS9MyCavFFW9x9DqiTAf2QoMWuCM3BtXkCNQxOG/bgb+9sfK63JvaUiHM/E/NgfzPyF95Pe4qkPCwBxg==" }, "@types/color-name": { "version": "1.1.1", @@ -123,16 +123,16 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, "@types/node": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz", - "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==" + "version": "14.11.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", + "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==" }, "@types/node-fetch": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz", "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==", "requires": { - "@types/node": "14.6.0", + "@types/node": "14.11.2", "form-data": "3.0.0" } }, @@ -157,9 +157,9 @@ "integrity": "sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw==" }, "abab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", - "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" }, "abbrev": { "version": "1.1.1", @@ -186,14 +186,14 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", + "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", "requires": { "fast-deep-equal": "3.1.3", "fast-json-stable-stringify": "2.1.0", "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "uri-js": "4.4.0" } }, "ansi-regex": { @@ -283,6 +283,19 @@ "tweetnacl": "0.14.5" } }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" + }, + "bigint-polyfill": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bigint-polyfill/-/bigint-polyfill-0.1.0.tgz", + "integrity": "sha512-Rk66dtfZzdBUcFZC4xjysOr/o1nvxVrxSVWCtXjLBFeGMH9xi+60myTQNhc3IazCTD0LQE+4awxQYawSvtYc6g==", + "requires": { + "big-integer": "1.6.48" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -313,9 +326,9 @@ } }, "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" }, "chalk": { "version": "4.1.0", @@ -323,7 +336,7 @@ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "requires": { "ansi-styles": "4.2.1", - "supports-color": "7.1.0" + "supports-color": "7.2.0" } }, "chownr": { @@ -421,9 +434,9 @@ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "requires": { - "abab": "2.0.4", + "abab": "2.0.5", "whatwg-mimetype": "2.3.0", - "whatwg-url": "8.1.0" + "whatwg-url": "8.2.2" } }, "debug": { @@ -478,6 +491,13 @@ "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "requires": { "webidl-conversions": "5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } } }, "ecc-jsbn": { @@ -615,7 +635,7 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "requires": { - "ajv": "6.12.4", + "ajv": "6.12.5", "har-schema": "2.0.0" } }, @@ -645,13 +665,6 @@ "caseless": "0.11.0", "concat-stream": "1.6.2", "http-response-object": "1.1.0" - }, - "dependencies": { - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" - } } }, "http-response-object": { @@ -771,11 +784,11 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.1.tgz", - "integrity": "sha512-3p0gHs5EfT7PxW9v8Phz3mrq//4Dy8MQenU/PoKxhdT+c45S7NjIjKbGT3Ph0nkICweE1r36+yaknXA5WfVNAg==", + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.4.0.tgz", + "integrity": "sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==", "requires": { - "abab": "2.0.4", + "abab": "2.0.5", "acorn": "7.4.0", "acorn-globals": "6.0.0", "cssom": "0.4.4", @@ -795,10 +808,10 @@ "tough-cookie": "3.0.1", "w3c-hr-time": "1.0.2", "w3c-xmlserializer": "2.0.0", - "webidl-conversions": "5.0.0", + "webidl-conversions": "6.1.0", "whatwg-encoding": "1.0.5", "whatwg-mimetype": "2.3.0", - "whatwg-url": "8.1.0", + "whatwg-url": "8.2.2", "ws": "7.3.1", "xml-name-validator": "3.0.0" } @@ -915,9 +928,9 @@ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" }, "needle": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", - "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", + "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", "requires": { "debug": "3.2.6", "iconv-lite": "0.4.24", @@ -925,9 +938,9 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-pre-gyp": { "version": "0.11.0", @@ -936,7 +949,7 @@ "requires": { "detect-libc": "1.0.3", "mkdirp": "0.5.5", - "needle": "2.5.0", + "needle": "2.5.2", "nopt": "4.0.3", "npm-packlist": "1.4.8", "npmlog": "4.1.2", @@ -1098,9 +1111,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" }, "rc": { "version": "1.2.8", @@ -1159,6 +1172,11 @@ "uuid": "3.4.0" }, "dependencies": { + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", @@ -1169,6 +1187,11 @@ "mime-types": "2.1.27" } }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -1348,9 +1371,9 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "4.0.0" } @@ -1395,14 +1418,7 @@ "http-basic": "2.5.1", "http-response-object": "1.1.0", "promise": "7.3.1", - "qs": "6.5.2" - }, - "dependencies": { - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" - } + "qs": "6.9.4" } }, "tough-cookie": { @@ -1450,9 +1466,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "2.1.1" } @@ -1494,9 +1510,9 @@ } }, "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "whatwg-encoding": { "version": "1.0.5", @@ -1512,13 +1528,13 @@ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, "whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-PcVnO6NiewhkmzV0qn7A+UZ9Xx4maNTI+O+TShmfE4pqjoCMwUMjkvoNhNHPTvgR7QH9Xt3R13iHuWy2sToFxQ==", "requires": { "lodash.sortby": "4.7.0", "tr46": "2.0.2", - "webidl-conversions": "5.0.0" + "webidl-conversions": "6.1.0" } }, "wide-align": { diff --git a/package.json b/package.json index 10818fe..646f4e0 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,21 @@ { "name": "@sashido/teachablemachine-node", - "version": "1.0.0", + "version": "1.1.0", "description": "Simplifies integration with Teachable Machine models from Google", - "author": "Team SashiDo ", + "author": { + "name": "Team SashiDo", + "email": "hello@sashido.io" + }, "license": "Apache-2.0", "repository": { "type": "git", - "url": "" + "url": "git+https://github.com/SashiDo/teachablemachine-node.git" + }, + "bugs": { + "url": "https://github.com/SashiDo/teachablemachine-node/issues" + }, + "engines": { + "node": ">= 10.2.1" }, "keywords": [ "tensorflow", @@ -19,9 +28,10 @@ "dependencies": { "@teachablemachine/image": "^0.8.4", "@tensorflow/tfjs": "^2.3.0", + "bigint-polyfill": "^0.1.0", "canvas": "2.6.1", "is-image-url": "^1.1.8", - "jsdom": "16.2.1", + "jsdom": "^16.4.0", "node-fetch": "^2.6.0" }, "devDependencies": {},