diff --git a/package-lock.json b/package-lock.json index b0a5211..a0946f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@tago-io/sdk": "^10.3.19", + "@tago-io/sdk": "^10.7.1", "axios": "0.24.0", "luxon": "^2.1.1" }, @@ -1161,6 +1161,19 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@socket.io/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", + "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -1361,28 +1374,29 @@ } }, "node_modules/@tago-io/sdk": { - "version": "10.3.19", - "resolved": "https://registry.npmjs.org/@tago-io/sdk/-/sdk-10.3.19.tgz", - "integrity": "sha512-Ktcefr7AEzDTwbBwXaOyf9XZ2KdX541o/arnRamXv7WH/Ck/IoqSdHXTLC2Rwj6b5B4BbabbKPL5vmL9H6iJEQ==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/@tago-io/sdk/-/sdk-10.7.1.tgz", + "integrity": "sha512-NTYnUp3NQ6wUPOxP0bqSAzgvNRC8y/DT5gGby5gFQ8fx7c9nbEXczPPOgHHTu5T8oPRKUkECBrSGUshJluqQOg==", "dependencies": { - "axios": "0.21.1", + "axios": "0.25.0", "form-data": "4.0.0", "lodash.chunk": "4.2.0", - "nanoid": "3.1.28", - "papaparse": "5.3.0", - "qs": "6.10.1", - "socket.io-client": "4.0.1" + "nanoid": "3.2.0", + "papaparse": "5.3.1", + "qs": "6.10.3", + "socket.io-client": "4.4.1" }, "engines": { - "node": ">= 12.0" + "node": ">=14.0.0", + "npm": ">=6.0.0" } }, "node_modules/@tago-io/sdk/node_modules/axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", "dependencies": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.7" } }, "node_modules/@tootallnate/once": { @@ -1459,11 +1473,6 @@ "@babel/types": "^7.3.0" } }, - "node_modules/@types/component-emitter": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", - "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -3085,14 +3094,6 @@ "node": ">=0.10.0" } }, - "node_modules/base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -3778,7 +3779,8 @@ "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", @@ -4370,30 +4372,50 @@ } }, "node_modules/engine.io-client": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-5.0.1.tgz", - "integrity": "sha512-CQtGN3YwfvbxVwpPugcsHe5rHT4KgT49CEcQppNtu9N7WxbPN0MAG27lGaem7bvtCFtGNLSL+GEqXsFSz36jTg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", + "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", "dependencies": { - "base64-arraybuffer": "0.1.4", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.0.0", "debug": "~4.3.1", - "engine.io-parser": "~4.0.1", + "engine.io-parser": "~5.0.0", "has-cors": "1.1.0", "parseqs": "0.0.6", "parseuri": "0.0.6", - "ws": "~7.4.2", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0", "yeast": "0.1.2" } }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/engine.io-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", - "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", + "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", "dependencies": { - "base64-arraybuffer": "0.1.4" + "@socket.io/base64-arraybuffer": "~1.0.2" }, "engines": { - "node": ">=8.0.0" + "node": ">=10.0.0" } }, "node_modules/enhanced-resolve": { @@ -5453,9 +5475,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", "funding": [ { "type": "individual", @@ -8036,9 +8058,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.1.28", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.28.tgz", - "integrity": "sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -8508,9 +8530,9 @@ "dev": true }, "node_modules/papaparse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.0.tgz", - "integrity": "sha512-Lb7jN/4bTpiuGPrYy4tkKoUS8sTki8zacB5ke1p5zolhcSE4TlWgrlsxjrDTbG/dFVh07ck7X36hUf/b5V68pg==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.1.tgz", + "integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA==" }, "node_modules/parallel-transform": { "version": "1.2.0", @@ -8910,9 +8932,9 @@ } }, "node_modules/qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "dependencies": { "side-channel": "^1.0.4" }, @@ -9642,29 +9664,27 @@ } }, "node_modules/socket.io-client": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.0.1.tgz", - "integrity": "sha512-6AkaEG5zrVuSVW294cH1chioag9i1OqnCYjKwTc3EBGXbnyb98Lw7yMa40ifLjFj3y6fsFKsd0llbUZUCRf3Qw==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", + "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", "dependencies": { - "@types/component-emitter": "^1.2.10", + "@socket.io/component-emitter": "~3.0.0", "backo2": "~1.0.2", - "component-emitter": "~1.3.0", - "debug": "~4.3.1", - "engine.io-client": "~5.0.0", + "debug": "~4.3.2", + "engine.io-client": "~6.1.1", "parseuri": "0.0.6", - "socket.io-parser": "~4.0.4" + "socket.io-parser": "~4.1.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-parser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", - "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", + "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", "dependencies": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.0.0", "debug": "~4.3.1" }, "engines": { @@ -11818,6 +11838,7 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, "engines": { "node": ">=8.3.0" }, @@ -11855,6 +11876,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -12790,6 +12819,16 @@ "@sinonjs/commons": "^1.7.0" } }, + "@socket.io/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==" + }, + "@socket.io/component-emitter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz", + "integrity": "sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==" + }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", @@ -12939,25 +12978,25 @@ } }, "@tago-io/sdk": { - "version": "10.3.19", - "resolved": "https://registry.npmjs.org/@tago-io/sdk/-/sdk-10.3.19.tgz", - "integrity": "sha512-Ktcefr7AEzDTwbBwXaOyf9XZ2KdX541o/arnRamXv7WH/Ck/IoqSdHXTLC2Rwj6b5B4BbabbKPL5vmL9H6iJEQ==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/@tago-io/sdk/-/sdk-10.7.1.tgz", + "integrity": "sha512-NTYnUp3NQ6wUPOxP0bqSAzgvNRC8y/DT5gGby5gFQ8fx7c9nbEXczPPOgHHTu5T8oPRKUkECBrSGUshJluqQOg==", "requires": { - "axios": "0.21.1", + "axios": "0.25.0", "form-data": "4.0.0", "lodash.chunk": "4.2.0", - "nanoid": "3.1.28", - "papaparse": "5.3.0", - "qs": "6.10.1", - "socket.io-client": "4.0.1" + "nanoid": "3.2.0", + "papaparse": "5.3.1", + "qs": "6.10.3", + "socket.io-client": "4.4.1" }, "dependencies": { "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", + "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.7" } } } @@ -13033,11 +13072,6 @@ "@babel/types": "^7.3.0" } }, - "@types/component-emitter": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", - "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" - }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -14421,11 +14455,6 @@ } } }, - "base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -14978,7 +15007,8 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -15481,27 +15511,35 @@ } }, "engine.io-client": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-5.0.1.tgz", - "integrity": "sha512-CQtGN3YwfvbxVwpPugcsHe5rHT4KgT49CEcQppNtu9N7WxbPN0MAG27lGaem7bvtCFtGNLSL+GEqXsFSz36jTg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.1.1.tgz", + "integrity": "sha512-V05mmDo4gjimYW+FGujoGmmmxRaDsrVr7AXA3ZIfa04MWM1jOfZfUwou0oNqhNwy/votUDvGDt4JA4QF4e0b4g==", "requires": { - "base64-arraybuffer": "0.1.4", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.0.0", "debug": "~4.3.1", - "engine.io-parser": "~4.0.1", + "engine.io-parser": "~5.0.0", "has-cors": "1.1.0", "parseqs": "0.0.6", "parseuri": "0.0.6", - "ws": "~7.4.2", + "ws": "~8.2.3", + "xmlhttprequest-ssl": "~2.0.0", "yeast": "0.1.2" + }, + "dependencies": { + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "requires": {} + } } }, "engine.io-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.3.tgz", - "integrity": "sha512-xEAAY0msNnESNPc00e19y5heTPX4y/TJ36gr8t1voOaNmTojP9b3oK3BbJLFufW2XFPQaaijpFewm2g2Um3uqA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz", + "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==", "requires": { - "base64-arraybuffer": "0.1.4" + "@socket.io/base64-arraybuffer": "~1.0.2" } }, "enhanced-resolve": { @@ -16320,9 +16358,9 @@ } }, "follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" }, "for-in": { "version": "1.0.2", @@ -18292,9 +18330,9 @@ "optional": true }, "nanoid": { - "version": "3.1.28", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.28.tgz", - "integrity": "sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==" }, "nanomatch": { "version": "1.2.13", @@ -18664,9 +18702,9 @@ "dev": true }, "papaparse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.0.tgz", - "integrity": "sha512-Lb7jN/4bTpiuGPrYy4tkKoUS8sTki8zacB5ke1p5zolhcSE4TlWgrlsxjrDTbG/dFVh07ck7X36hUf/b5V68pg==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.1.tgz", + "integrity": "sha512-Dbt2yjLJrCwH2sRqKFFJaN5XgIASO9YOFeFP8rIBRG2Ain8mqk5r1M6DkfvqEVozVcz3r3HaUGw253hA1nLIcA==" }, "parallel-transform": { "version": "1.2.0", @@ -18991,9 +19029,9 @@ } }, "qs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", - "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "requires": { "side-channel": "^1.0.4" } @@ -19559,26 +19597,24 @@ } }, "socket.io-client": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.0.1.tgz", - "integrity": "sha512-6AkaEG5zrVuSVW294cH1chioag9i1OqnCYjKwTc3EBGXbnyb98Lw7yMa40ifLjFj3y6fsFKsd0llbUZUCRf3Qw==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz", + "integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==", "requires": { - "@types/component-emitter": "^1.2.10", + "@socket.io/component-emitter": "~3.0.0", "backo2": "~1.0.2", - "component-emitter": "~1.3.0", - "debug": "~4.3.1", - "engine.io-client": "~5.0.0", + "debug": "~4.3.2", + "engine.io-client": "~6.1.1", "parseuri": "0.0.6", - "socket.io-parser": "~4.0.4" + "socket.io-parser": "~4.1.1" } }, "socket.io-parser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", - "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.1.2.tgz", + "integrity": "sha512-j3kk71QLJuyQ/hh5F/L2t1goqzdTL0gvDzuhTuNSwihfuFUrcSji0qFZmJJPtG6Rmug153eOPsUizeirf1IIog==", "requires": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.0.0", "debug": "~4.3.1" } }, @@ -21282,6 +21318,7 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, "requires": {} }, "xdg-basedir": { @@ -21302,6 +21339,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index e1b8bf8..0633ac0 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "typescript": "^4.5.2" }, "dependencies": { - "@tago-io/sdk": "^10.3.19", + "@tago-io/sdk": "^10.7.1", "axios": "0.24.0", "luxon": "^2.1.1" } diff --git a/src/cleanAnalysis.ts b/src/cleanAnalysis.ts new file mode 100644 index 0000000..2e7e1b2 --- /dev/null +++ b/src/cleanAnalysis.ts @@ -0,0 +1,122 @@ +import { Account, Analysis, Utils } from "@tago-io/sdk"; +import { Data } from "@tago-io/sdk/out/common/common.types"; +import { TagoContext } from "@tago-io/sdk/out/modules/Analysis/analysis.types"; +import { EntityType, IExport } from "./exportTypes"; +import auditLogSetup from "./lib/auditLogSetup"; +import validation from "./lib/validation"; + +const IMPORT_ORDER: EntityType = ["devices", "dictionaries", "accessManagement", "run_buttons", "analysis", "actions", "dictionaries", "dashboards"]; + +const config: IExport = { + // Export tag with unique ID's. Without tag bellow, entity will not be copied or updated. + export_tag: "export_id", + + // Entities that will be copied from the application. + // entities: ["dictionaries"], + entities: ["devices", "analysis", "dashboards", "accessManagement", "run_buttons", "actions", "dictionaries"], + data: ["list_devtype_id"], + + // Account that entities will be copied from. + export: { + token: "", // Development + }, + + // Account where the entities will be pasted to. + import: { + // token: "683d440e-4bf4-4950-aa60-3be553964fd9", // Sales + // token: "b8e6bd99-ca5d-48c3-90cc-7ec37608ea1b", // prod + token: "", // X-Talia + }, +}; + +async function startCleaner(context: TagoContext, scope: Data[]) { + const environment = Utils.envToJson(context.environment); + if (!environment) { + return; + } + + if (!environment.account_token) { + throw "Missing account_token environment var"; + } + const main_account = new Account({ token: environment.account_token }); + const config_dev = await Utils.getDevice(main_account, scope[0].device); + const validate = validation("cleaner_validation", config_dev); + + const target_token = scope.find((x) => x.variable === "cleaner_target_token"); + const entities = scope.find((x) => x.variable === "cleaner_entity_list" && x.metadata?.sentValues); + const export_tag = scope.find((x) => x.variable === "cleaner_export_tag"); + + config.import.token = target_token.value as string; + + if (!config.import.token) { + throw validate("Missing account application token field", "danger"); + } else if (config.import.token.length !== 36) { + throw validate('Invalid "account application token".', "danger"); + } + + if (entities?.metadata?.sentValues) { + const values = entities.metadata.sentValues.map((x) => (x.value as string).toLowerCase()); + config.entities = values as any; + } + const import_account = new Account({ token: config.import.token }); + const import_rule = IMPORT_ORDER.filter((entity) => config.entities.includes(entity)); + + if (export_tag?.value) { + config.export_tag = export_tag?.value as string; + } + const auditlog = auditLogSetup(main_account, config_dev, "cleaner_log"); + console.log(config.entities, import_rule); + auditlog(`Starting cleaning profile`); + console.info("====Clean started===="); + for (const item of import_rule) { + switch (item) { + case "devices": + console.info("Cleaning Devices"); + const device_list = await import_account.devices.list({ amount: 999, fields: ["id", "bucket"], filter: { tags: [{ key: config.export_tag }] } }); + auditlog(`Cleaning Devices: ${device_list.length} found.`); + await Promise.all(device_list.map(({ id }) => import_account.devices.delete(id))); + await Promise.all(device_list.map(({ bucket }) => import_account.buckets.delete(bucket))); + break; + case "dashboards": + console.info("Cleaning Dashboards"); + const dash_list = await import_account.dashboards.list({ amount: 999, fields: ["id"], filter: { tags: [{ key: config.export_tag }] } }); + auditlog(`Cleaning Dashboards: ${dash_list.length} found.`); + await Promise.all(dash_list.map(({ id }) => import_account.dashboards.delete(id))); + break; + case "accessManagement": + console.info("Cleaning Access Rules"); + const access_list = await import_account.accessManagement.list({ amount: 999, fields: ["id"], filter: { tags: [{ key: config.export_tag }] } }); + auditlog(`Cleaning Access Rules: ${dash_list.length} found.`); + await Promise.all(access_list.map(({ id }) => import_account.accessManagement.delete(id))); + break; + case "analysis": + console.info("Cleaning Analysis"); + const analysis = await import_account.analysis.list({ amount: 999, fields: ["id"], filter: { tags: [{ key: config.export_tag }] } }); + auditlog(`Cleaning Analysis: ${analysis.length} found.`); + await Promise.all(analysis.map(({ id }) => import_account.analysis.delete(id))); + break; + case "actions": + console.info("Cleaning Actions"); + const actions = await import_account.actions.list({ amount: 999, fields: ["id"], filter: { tags: [{ key: config.export_tag }] } }); + auditlog(`Cleaning Actions: ${actions.length} found.`); + await Promise.all(actions.map(({ id }) => import_account.actions.delete(id))); + break; + case "dictionaries": + console.info("Cleaning Dictionaries"); + const dictionary = await import_account.dictionaries.list({ amount: 999, fields: ["id"] }); + auditlog(`Cleaning Dictionaries: ${dictionary.length} found.`); + await Promise.all(dictionary.map(({ id }) => import_account.dictionaries.delete(id))); + break; + default: + break; + } + } + + auditlog(`Cleaning finished with success.`); + validate("Account succesfully cleaned!", "success"); + console.info("====Clean ended with success===="); +} + +export default new Analysis(startCleaner, { + token: "46dd313d-ffb9-48a8-8677-0cdf65910480", +}); diff --git a/src/lib/data.logic.ts b/src/lib/data.logic.ts index d1adaee..9fd2296 100644 --- a/src/lib/data.logic.ts +++ b/src/lib/data.logic.ts @@ -8,16 +8,16 @@ interface GenericBody { [index: string]: any; } -function parseTagoObject(body: GenericBody, serie?: string): DataToSend[] { - if (!serie) { - serie = String(new Date().getTime()); +function parseTagoObject(body: GenericBody, group?: string): DataToSend[] { + if (!group) { + group = String(new Date().getTime()); } return Object.keys(body) .map((item) => { return { variable: item, value: body[item] instanceof Object ? body[item].value : body[item], - serie, + group, time: body[item] instanceof Object ? body[item].time : null, location: body[item] instanceof Object ? body[item].location : null, metadata: body[item] instanceof Object ? body[item].metadata : null, diff --git a/src/lib/filterExport.ts b/src/lib/filterExport.ts index 33ed7c1..ca16cc7 100644 --- a/src/lib/filterExport.ts +++ b/src/lib/filterExport.ts @@ -1,9 +1,7 @@ import { TagsObj } from "@tago-io/sdk/out/common/common.types"; function filterExport(dashboard: { [key: string]: any }) { - const export_tag = dashboard.tags.find( - (tag: TagsObj) => tag.key === "export_id" - ); + const export_tag = dashboard.tags.find((tag: TagsObj) => tag.key === "export_id"); if (!export_tag) { return false; diff --git a/src/services/actionsExport.ts b/src/services/actionsExport.ts index 91207c8..4ed5400 100644 --- a/src/services/actionsExport.ts +++ b/src/services/actionsExport.ts @@ -18,9 +18,15 @@ async function actionsExport(account: Account, import_account: Account, export_h const new_action = replaceObj(action, { ...export_holder.devices, ...export_holder.analysis }); for (const trigger of new_action.trigger) { - if (!trigger.value) delete trigger.value; - if (!trigger.second_value) delete trigger.second_value; - if (trigger.tag_key) delete trigger.unlock; + if (!trigger.value) { + delete trigger.value; + } + if (!trigger.second_value) { + delete trigger.second_value; + } + if (trigger.tag_key) { + delete trigger.unlock; + } } if (!target_id) { diff --git a/src/services/analysisExport.ts b/src/services/analysisExport.ts index 7b0823b..f2506e9 100644 --- a/src/services/analysisExport.ts +++ b/src/services/analysisExport.ts @@ -26,7 +26,6 @@ async function analysisExport(account: Account, import_account: Account, export_ tags: new_analysis.tags, active: new_analysis.active, variables: new_analysis.variables, - }); } const script = await account.analysis.downloadScript(analysis_id); diff --git a/src/services/dashboardsExport.ts b/src/services/dashboardsExport.ts index 8d5b02d..7466b06 100644 --- a/src/services/dashboardsExport.ts +++ b/src/services/dashboardsExport.ts @@ -57,7 +57,9 @@ async function dashboardExport(account: Account, import_account: Account, export console.info(`Exporting dashboard ${label}...`); const dashboard = await account.dashboards.info(dash_id); const export_id = dashboard.tags.find((tag) => tag.key === "export_id")?.value; - if (!export_id) continue; + if (!export_id) { + continue; + } const dash_target = await resolveDashboardTarget(import_account, export_id, import_list, dashboard); diff --git a/src/services/devicesExport.ts b/src/services/devicesExport.ts index e23f37f..7d31587 100644 --- a/src/services/devicesExport.ts +++ b/src/services/devicesExport.ts @@ -9,7 +9,7 @@ async function deviceExport(account: Account, import_account: Account, export_ho const list = await account.devices.list({ amount: 99, - fields: ["id", "name", "tags"], + fields: ["id", "name", "tags", "type"], filter: { tags: [{ key: "export_id" }] }, }); const import_list = await import_account.devices.list({ @@ -21,7 +21,6 @@ async function deviceExport(account: Account, import_account: Account, export_ho for (const { id: device_id, tags: device_tags, name } of list) { console.info(`Exporting devices ${name}`); const device = await account.devices.info(device_id); - delete device.bucket; const export_id = device.tags.find((tag) => tag.key === "export_id")?.value; @@ -31,6 +30,11 @@ async function deviceExport(account: Account, import_account: Account, export_ho let new_token: string; const new_device = replaceObj(device, export_holder.devices); + + new_device.last_input = undefined; + new_device.last_output = undefined; + new_device.bucket = undefined; + if (!target_id) { ({ device_id: target_id, token: new_token } = await import_account.devices.create(new_device)); diff --git a/src/startAnalysis.tago-io.js b/src/startAnalysis.tago-io.js new file mode 100644 index 0000000..b2a4fb9 --- /dev/null +++ b/src/startAnalysis.tago-io.js @@ -0,0 +1,586 @@ +/* + * TagoIO (https://tago.io/) + * TagoIO Builder V3.0.3 (https://git.io/JJ8Si) + * ------------------- + * Generated by :: vitorfdl + * Generated at :: Wednesday, April 13, 2022, 6:55 PM Coordinated Universal Time + * Machine :: DESKTOP-AAAF60B - Node.js v16.13.2 + * Origin file :: src/startAnalysis.ts + * Destination file :: src/startAnalysis.tago-io.js + * ------------------- +*/ + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __reExport = (target, module2, copyDefault, desc) => { + if (module2 && typeof module2 === "object" || typeof module2 === "function") { + for (let key of __getOwnPropNames(module2)) + if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default")) + __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); + } + return target; +}; +var __toESM = (module2, isNodeMode) => { + return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); +}; +var __toCommonJS = /* @__PURE__ */ ((cache) => { + return (module2, temp) => { + return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp); + }; +})(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0); + +// src/startAnalysis.ts +var startAnalysis_exports = {}; +__export(startAnalysis_exports, { + default: () => startAnalysis_default +}); +var import_sdk3 = require("@tago-io/sdk"); +var import_axios2 = __toESM(require("axios")); + +// src/lib/data.logic.ts +function parseTagoObject(body, group) { + if (!group) { + group = String(new Date().getTime()); + } + return Object.keys(body).map((item) => { + return { + variable: item, + value: body[item] instanceof Object ? body[item].value : body[item], + group, + time: body[item] instanceof Object ? body[item].time : null, + location: body[item] instanceof Object ? body[item].location : null, + metadata: body[item] instanceof Object ? body[item].metadata : null + }; + }).filter((item) => item.value !== null && item.value !== void 0); +} + +// src/lib/auditLogSetup.ts +function auditLogSetup(account, device, log_variable) { + if (!log_variable) { + log_variable = "auditlog"; + } + return async function _(description) { + if (!description) { + throw "Missing description"; + } + device.sendData(parseTagoObject({ + [log_variable]: { value: description } + }, String(new Date().getTime()))); + return description; + }; +} + +// src/lib/validation.ts +function validation(validation_var, device, show_markdown) { + return function _(message, type) { + if (!message || !type) { + throw "Missing message or type"; + } + device.sendData({ + variable: validation_var, + value: message, + metadata: { + type: ["success", "danger", "warning"].includes(type) ? type : null, + color: !["success", "danger", "warning"].includes(type) ? type : null, + show_markdown + } + }); + return message; + }; +} + +// src/lib/replaceObj.ts +function replaceObj(original, replacer) { + let string_obj = JSON.stringify(original); + for (const key in replacer) { + string_obj = string_obj.replace(new RegExp(key, "g"), replacer[key]); + } + return JSON.parse(string_obj); +} +var replaceObj_default = replaceObj; + +// src/services/accessExport.ts +async function accessExport(account, import_account, export_holder) { + console.info("Exporting access rules: started"); + const list = await account.accessManagement.list({ amount: 99, fields: ["id", "name", "tags"], filter: { tags: [{ key: "export_id" }] } }); + const import_list = await import_account.accessManagement.list({ amount: 99, fields: ["id", "tags"], filter: { tags: [{ key: "export_id" }] } }); + for (const { id: access_id, tags: access_tags, name } of list) { + console.info(`Exporting access rule ${name}`); + const access = await account.accessManagement.info(access_id); + const export_id = access.tags.find((tag) => tag.key === "export_id")?.value; + let { id: target_id } = import_list.find((access2) => access2.tags.find((tag) => tag.key === "export_id" && tag.value == export_id)) || { id: null }; + const new_access = replaceObj_default(access, { ...export_holder.devices, ...export_holder.dashboards }); + if (!target_id) { + ({ am_id: target_id } = await import_account.accessManagement.create(new_access)); + } else { + await import_account.accessManagement.edit(target_id, new_access); + } + } + console.info("Exporting access rules: finished"); + return export_holder; +} +var accessExport_default = accessExport; + +// src/services/actionsExport.ts +async function actionsExport(account, import_account, export_holder) { + console.info("Exporting actions: started"); + const list = await account.actions.list({ amount: 99, fields: ["id", "name", "tags"], filter: { tags: [{ key: "export_id" }] } }); + const import_list = await import_account.actions.list({ amount: 99, fields: ["id", "tags"], filter: { tags: [{ key: "export_id" }] } }); + for (const { id: action_id, tags: action_tags, name } of list) { + console.info(`Exporting action ${name}`); + const action = await account.actions.info(action_id); + const export_id = action.tags.find((tag) => tag.key === "export_id")?.value; + let { id: target_id } = import_list.find((action2) => action2.tags.find((tag) => tag.key === "export_id" && tag.value == export_id)) || { id: null }; + const new_action = replaceObj_default(action, { ...export_holder.devices, ...export_holder.analysis }); + for (const trigger of new_action.trigger) { + if (!trigger.value) { + delete trigger.value; + } + if (!trigger.second_value) { + delete trigger.second_value; + } + if (trigger.tag_key) { + delete trigger.unlock; + } + } + if (!target_id) { + ({ action: target_id } = await import_account.actions.create(new_action)); + } else { + await import_account.actions.edit(target_id, new_action); + } + } + console.info("Exporting actions: finished"); + return export_holder; +} +var actionsExport_default = actionsExport; + +// src/services/analysisExport.ts +var import_zlib = __toESM(require("zlib")); +var import_axios = __toESM(require("axios")); +async function analysisExport(account, import_account, export_holder) { + console.info("Exporting analysis: started"); + const list = await account.analysis.list({ amount: 99, fields: ["id", "name", "tags"], filter: { tags: [{ key: "export_id" }] } }); + const import_list = await import_account.analysis.list({ amount: 99, fields: ["id", "tags"], filter: { tags: [{ key: "export_id" }] } }); + for (const { id: analysis_id, name } of list) { + console.info(`Exporting dashboard ${name}...`); + const analysis = await account.analysis.info(analysis_id); + const export_id = analysis.tags.find((tag) => tag.key === "export_id")?.value; + let { id: target_id } = import_list.find((analysis2) => analysis2.tags.find((tag) => tag.key === "export_id" && tag.value == export_id)) || { id: null }; + const new_analysis = replaceObj_default(analysis, { ...export_holder.devices, ...export_holder.tokens }); + if (!target_id) { + ({ id: target_id } = await import_account.analysis.create(new_analysis)); + } else { + await import_account.analysis.edit(target_id, { + name: new_analysis.name, + tags: new_analysis.tags, + active: new_analysis.active, + variables: new_analysis.variables + }); + } + const script = await account.analysis.downloadScript(analysis_id); + const script_base64 = await import_axios.default.get(script.url, { + responseType: "arraybuffer" + }).then((response) => import_zlib.default.gunzipSync(response.data).toString("base64")); + await import_account.analysis.uploadScript(target_id, { content: script_base64, language: "node", name: "script.js" }); + export_holder.analysis[analysis_id] = target_id; + } + console.info("Exporting analysis: finished"); + return export_holder; +} +var analysisExport_default = analysisExport; + +// src/services/collectIDs.ts +var import_sdk = require("@tago-io/sdk"); +async function collectIDs(account, import_account, entity, export_holder) { + const list = await account[entity].list({ + page: 1, + amount: 99, + fields: ["id", "tags"], + filter: { tags: [{ key: "export_id" }] } + }); + const import_list = await import_account[entity].list({ + page: 1, + amount: 99, + fields: ["id", "tags"], + filter: { tags: [{ key: "export_id" }] } + }); + for (const item of list) { + const export_id = item.tags.find((tag) => tag.key === "export_id")?.value; + if (!export_id) { + continue; + } + const { id: target_id } = import_list.find((a) => a.tags.find((tag) => tag.key === "export_id" && tag.value == export_id)) || { + id: null + }; + if (!target_id) { + continue; + } + if (entity === "devices") { + const token = await import_sdk.Utils.getTokenByName(account, item.id); + const target_token = await import_sdk.Utils.getTokenByName(import_account, target_id); + if (token && target_token) { + export_holder.tokens[token] = target_token; + } + } + export_holder[entity][item.id] = target_id; + } + return export_holder; +} +var collectIDs_default = collectIDs; + +// src/services/widgetsExport.ts +async function insertWidgets(account, import_account, dashboard, target, export_holder) { + const widget_ids = dashboard.arrangement.map((x) => x.widget_id); + const widgets = await Promise.all(widget_ids.map((x) => account.dashboards.widgets.info(dashboard.id, x))); + const hidden_tabs = dashboard.tabs.filter((tab) => !tab.hidden).map((tab) => tab.key); + const arrangement = dashboard.arrangement.sort((a) => hidden_tabs.includes(a.tab) ? 1 : -1); + const new_arrangement = []; + const widget_holder = {}; + for (const widget_arrangement of arrangement) { + const widget = widgets.find((wdgt) => widget_arrangement.widget_id === wdgt.id); + const new_widget = replaceObj_default(widget, { ...export_holder.analysis, ...export_holder.devices, ...widget_holder }); + if (new_widget.data) { + new_widget.data = new_widget.data.map((x) => { + if (x.qty) { + x.qty = Number(x.qty); + } + return x; + }); + } + const { widget: new_id } = await import_account.dashboards.widgets.create(target.id, new_widget); + new_arrangement.push({ ...widget_arrangement, widget_id: new_id }); + widget_holder[widget.id] = new_id; + } + await import_account.dashboards.edit(target.id, { arrangement: new_arrangement }); +} +async function removeAllWidgets(import_account, dashboard) { + await Promise.all(dashboard.arrangement.map((widget) => import_account.dashboards.widgets.delete(dashboard.id, widget.widget_id))); +} + +// src/services/dashboardsExport.ts +async function resolveDashboardTarget(import_account, export_id, import_list, content) { + const import_dashboard = import_list.find((dash) => { + const import_id = dash.tags?.find((tag) => tag.key === "export_id")?.value; + return import_id && import_id === export_id; + }); + if (import_dashboard) { + const dashboard = await import_account.dashboards.info(import_dashboard.id); + return dashboard; + } + const { dashboard: dashboard_id } = await import_account.dashboards.create({ ...content, arrangement: null }); + await import_account.dashboards.edit(dashboard_id, { ...content, arrangement: null }); + return import_account.dashboards.info(dashboard_id); +} +async function dashboardExport(account, import_account, export_holder) { + console.info("Exporting dashboard: started"); + const list = await account.dashboards.list({ page: 1, amount: 99, fields: ["id", "label", "tags"], filter: { tags: [{ key: "export_id" }] } }); + const import_list = await import_account.dashboards.list({ page: 1, amount: 99, fields: ["id", "label", "tags"], filter: { tags: [{ key: "export_id" }] } }); + for (const { id: dash_id, label } of list) { + console.info(`Exporting dashboard ${label}...`); + const dashboard = await account.dashboards.info(dash_id); + const export_id = dashboard.tags.find((tag) => tag.key === "export_id")?.value; + if (!export_id) { + continue; + } + const dash_target = await resolveDashboardTarget(import_account, export_id, import_list, dashboard); + await removeAllWidgets(import_account, dash_target); + dash_target.arrangement = []; + await insertWidgets(account, import_account, dashboard, dash_target, export_holder); + export_holder.dashboards[dash_id] = dash_target.id; + } + console.info("Exporting dashboard: finished"); + return export_holder; +} +var dashboardsExport_default = dashboardExport; + +// src/services/devicesExport.ts +var import_sdk2 = require("@tago-io/sdk"); + +// src/config.ts +var config = { + export_tag: "export_id", + entities: ["devices", "analysis", "dashboards", "accessManagement", "run_buttons", "actions", "dictionaries"], + export: { + token: "" + }, + import: { + token: "7ec20119-e7e4-4605-a913-51c74dd78614" + } +}; +var config_default = config; + +// src/services/devicesExport.ts +async function deviceExport(account, import_account, export_holder) { + console.info("Exporting devices: started"); + const list = await account.devices.list({ + amount: 99, + fields: ["id", "name", "tags", "type"], + filter: { tags: [{ key: "export_id" }] } + }); + const import_list = await import_account.devices.list({ + amount: 99, + fields: ["id", "tags"], + filter: { tags: [{ key: "export_id" }] } + }); + for (const { id: device_id, tags: device_tags, name } of list) { + console.info(`Exporting devices ${name}`); + const device = await account.devices.info(device_id); + const export_id = device.tags.find((tag) => tag.key === "export_id")?.value; + const token = await import_sdk2.Utils.getTokenByName(account, device_id); + let { id: target_id } = import_list.find((device2) => device2.tags.find((tag) => tag.key === "export_id" && tag.value == export_id)) || { id: null }; + let new_token; + const new_device = replaceObj_default(device, export_holder.devices); + new_device.last_input = void 0; + new_device.last_output = void 0; + new_device.bucket = void 0; + if (!target_id) { + ({ device_id: target_id, token: new_token } = await import_account.devices.create(new_device)); + if (config_default.data && config_default.data.length) { + const device2 = new import_sdk2.Device({ token: new_token }); + const old_device = new import_sdk2.Device({ token }); + const data = await old_device.getData({ + variables: config_default.data, + qty: 9999 + }); + if (data.length) { + device2.sendData(data); + } + } + } else { + await import_account.devices.edit(target_id, { + ...new_device, + connector: null, + network: null + }); + new_token = await import_sdk2.Utils.getTokenByName(import_account, target_id); + } + export_holder.devices[device_id] = target_id; + export_holder.tokens[token] = new_token; + } + console.info("Exporting devices: finished"); + return export_holder; +} +var devicesExport_default = deviceExport; + +// src/services/dictionaryExport.ts +async function dictionaryExport(account, import_account, export_holder) { + console.info("Exporting dictionaries: started"); + const list = await account.dictionaries.list({ amount: 99, fields: ["id", "slug", "languages", "name", "fallback"] }); + const import_list = await import_account.dictionaries.list({ amount: 99, fields: ["id", "slug", "languages", "name", "fallback"] }); + for (const item of list) { + console.info(`Exporting dictionary ${item.name}`); + let { id: target_id } = import_list.find((dict) => dict.slug === item.slug) || { id: null }; + if (!target_id) { + ({ dictionary: target_id } = await import_account.dictionaries.create(item)); + } else { + const new_item = { ...item }; + delete new_item.id; + await import_account.dictionaries.edit(target_id, new_item); + } + for (const lang of item.languages) { + const dictionary = await account.dictionaries.languageInfo(item.id, lang.code); + import_account.dictionaries.languageEdit(target_id, lang.code, { dictionary, active: true }); + } + } + console.info("Exporting dictionaries: finished"); + return export_holder; +} +var dictionaryExport_default = dictionaryExport; + +// src/services/runButtonsExport.ts +async function runButtonsExport(account, import_account, export_holder) { + console.info("Run Buttons: started"); + const run_info = await account.run.info(); + const import_run_info = await import_account.run.info(); + const sidebar_buttons = run_info.sidebar_buttons; + for (const btn of sidebar_buttons) { + if (btn.type !== "dashboard") { + continue; + } + btn.value = export_holder.dashboards[btn.value]; + } + import_run_info.sidebar_buttons = sidebar_buttons; + for (const template_name of Object.keys(run_info.email_templates)) { + const email_obj = run_info.email_templates[template_name]; + import_run_info.email_templates[template_name] = email_obj; + } + await import_account.run.edit(import_run_info); + console.info("Run Buttons: finished"); + return export_holder; +} +var runButtonsExport_default = runButtonsExport; + +// src/startAnalysis.ts +var config2 = { + export_tag: "export_id", + entities: ["devices", "analysis", "dashboards", "accessManagement", "run_buttons", "actions", "dictionaries"], + data: ["list_devtype_id"], + export: { + token: "" + }, + import: { + token: "" + } +}; +var IMPORT_ORDER = ["devices", "analysis", "dashboards", "accessManagement", "run_buttons", "actions", "dictionaries"]; +async function sendNotification(token, message) { + (0, import_axios2.default)({ + method: "POST", + url: "https://api.tago.io/notification", + data: { + title: "Importing application", + message + }, + headers: { Authorization: config2.import.token } + }); +} +async function startImport(context, scope) { + const environment = import_sdk3.Utils.envToJson(context.environment); + if (!environment) { + return; + } + if (!environment.account_token) { + throw "Missing account_token environment var"; + } + const main_account = new import_sdk3.Account({ token: environment.account_token }); + const config_dev = await import_sdk3.Utils.getDevice(main_account, scope[0].device); + const validate = validation("export_validation", config_dev); + const export_token = scope.find((x) => x.variable === "export_token"); + const target_token = scope.find((x) => x.variable === "target_token"); + const entities = scope.find((x) => x.variable === "entity_list" && x.metadata?.sentValues); + const data_list = scope.find((x) => x.variable === "data_list"); + const export_tag = scope.find((x) => x.variable === "export_tag"); + config2.export.token = export_token.value; + config2.import.token = target_token.value; + if (!config2.export.token) { + throw validate("Missing account application token field", "danger"); + } else if (config2.export.token.length !== 36) { + throw validate('Invalid "account application token".', "danger"); + } + if (!config2.import.token) { + throw validate("Missing account token field", "danger"); + } else if (config2.import.token.length !== 36) { + throw validate('Invalid "account token".', "danger"); + } + const account = new import_sdk3.Account({ token: config2.export.token }); + const import_account = new import_sdk3.Account({ token: config2.import.token }); + if (entities?.metadata?.sentValues) { + const values = entities.metadata.sentValues.map((x) => x.value); + config2.entities = values; + } + if (data_list?.value) { + const data = data_list.value.replace(/ /g, "").split(","); + config2.data = data; + } + if (export_tag?.value) { + config2.export_tag = export_tag?.value; + } + const import_rule = IMPORT_ORDER.filter((entity) => config2.entities.includes(entity)); + let export_holder = { + devices: {}, + analysis: {}, + dashboards: {}, + tokens: { [config2.export.token]: config2.import.token } + }; + console.info("====Exporting started===="); + console.log(import_rule); + if (import_rule.includes("run_buttons")) { + const run = await import_account.run.info(); + if (!run || !run.name) { + throw validate("The account doesn't have RUN enabled. Not possible to import RUN Buttons.", "danger"); + } + } + const import_acc_info = await import_account.info(); + if (import_acc_info.plan === "free") { + throw validate("The account is free, can't import the application.", "danger"); + } + const auditlog = auditLogSetup(account, config_dev, "export_log"); + auditlog(`Starting export to: ${import_acc_info.name}`); + sendNotification(config2.import.token, "Starting the import proccess. Please await, it can take up to 5 minutes."); + try { + validate("Exporting the application, this proccess can take several minutes...", "warning"); + const idCollection = []; + for (const entity of import_rule) { + switch (entity) { + case "devices": + export_holder = await devicesExport_default(account, import_account, export_holder); + idCollection.push("devices"); + break; + case "dashboards": + if (!idCollection.includes("analysis")) { + idCollection.push("analysis"); + export_holder = await collectIDs_default(account, import_account, "analysis", export_holder); + } + if (!idCollection.includes("devices")) { + idCollection.push("devices"); + export_holder = await collectIDs_default(account, import_account, "devices", export_holder); + } + export_holder = await dashboardsExport_default(account, import_account, export_holder); + idCollection.push("dashboards"); + break; + case "accessManagement": + if (!idCollection.includes("devices")) { + idCollection.push("devices"); + export_holder = await collectIDs_default(account, import_account, "devices", export_holder); + } + if (!idCollection.includes("dashboards")) { + idCollection.push("dashboards"); + export_holder = await collectIDs_default(account, import_account, "dashboards", export_holder); + } + export_holder = await accessExport_default(account, import_account, export_holder); + break; + case "analysis": + if (!idCollection.includes("devices")) { + idCollection.push("devices"); + export_holder = await collectIDs_default(account, import_account, "devices", export_holder); + } + export_holder = await analysisExport_default(account, import_account, export_holder); + idCollection.push("analysis"); + break; + case "actions": + if (!idCollection.includes("devices")) { + idCollection.push("devices"); + export_holder = await collectIDs_default(account, import_account, "devices", export_holder); + } + export_holder = await actionsExport_default(account, import_account, export_holder); + idCollection.push("actions"); + break; + case "dictionaries": + export_holder = await dictionaryExport_default(account, import_account, export_holder); + break; + case "run_buttons": + if (!idCollection.includes("dashboards")) { + idCollection.push("dashboards"); + export_holder = await collectIDs_default(account, import_account, "dashboards", export_holder); + } + export_holder = await runButtonsExport_default(account, import_account, export_holder); + idCollection.push("run_buttons"); + break; + default: + break; + } + } + } catch (e) { + auditlog(`Error while exporting: ${e}`); + throw validate(e, "danger"); + } + sendNotification(config2.import.token, "The application was succesfully imported."); + auditlog(`Export finished with success for: ${import_acc_info.name}`); + validate("Application succesfully exported!", "success"); + console.info("====Exporting ended with success===="); +} +var startAnalysis_default = new import_sdk3.Analysis(startImport, { + token: "f16369eb-5a59-4f9d-919b-0a5bc63fc7da" +}); +module.exports = __toCommonJS(startAnalysis_exports); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = {}); diff --git a/src/startAnalysis.ts b/src/startAnalysis.ts index 9e349a9..834e09a 100644 --- a/src/startAnalysis.ts +++ b/src/startAnalysis.ts @@ -62,12 +62,12 @@ async function startImport(context: TagoContext, scope: Data[]): Promise { const main_account = new Account({ token: environment.account_token }); - const config_dev = await Utils.getDevice(main_account, scope[0].origin); + const config_dev = await Utils.getDevice(main_account, scope[0].device); const validate = validation("export_validation", config_dev); const export_token = scope.find((x) => x.variable === "export_token"); const target_token = scope.find((x) => x.variable === "target_token"); - const entities = scope.find((x) => x.variable === "entity_list" && x.metadata?.sentValues); + const entities = scope.find((x) => x.variable === "entities" && x.metadata?.sentValues); const data_list = scope.find((x) => x.variable === "data_list"); const export_tag = scope.find((x) => x.variable === "export_tag"); @@ -208,5 +208,5 @@ async function startImport(context: TagoContext, scope: Data[]): Promise { } export default new Analysis(startImport, { - token: "9a37a7d2-964e-4806-b8dd-06822c0f335c", + token: "f16369eb-5a59-4f9d-919b-0a5bc63fc7da", }); diff --git a/tsconfig.json b/tsconfig.json index 5c9ba6c..51ece57 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "outDir": "./out", - "noImplicitAny": true, + "noImplicitAny": false, "module": "commonjs", "target": "ES2019", "lib": ["ES2019"],