diff --git a/package-lock.json b/package-lock.json index c6db0ab..9a6f1a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ucr-tool", - "version": "2.4.0", + "version": "2.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ucr-tool", - "version": "2.4.0", + "version": "2.4.3", "dependencies": { "@angular/animations": "^18.2.6", "@angular/cdk": "^18.2.3", @@ -17,6 +17,7 @@ "@angular/platform-browser": "^18.2.6", "@angular/platform-browser-dynamic": "^18.2.6", "@angular/router": "^18.2.6", + "cookie-parser": "^1.4.7", "file-saver-es": "^2.0.5", "ngx-json-viewer": "^3.2.1", "primeflex": "^3.3.1", @@ -56,13 +57,13 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1802.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.11.tgz", - "integrity": "sha512-p+XIc/j51aI83ExNdeZwvkm1F4wkuKMGUUoj0MVUUi5E6NoiMlXYm6uU8+HbRvPBzGy5+3KOiGp3Fks0UmDSAA==", + "version": "0.1802.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", + "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.11", + "@angular-devkit/core": "18.2.12", "rxjs": "7.8.1" }, "engines": { @@ -72,17 +73,17 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.11.tgz", - "integrity": "sha512-09Ln3NAdlMw/wMLgnwYU5VgWV5TPBEHolZUIvE9D8b6SFWBCowk3B3RWeAMgg7Peuf9SKwqQHBz2b1C7RTP/8g==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.12.tgz", + "integrity": "sha512-quVUi7eqTq9OHumQFNl9Y8t2opm8miu4rlYnuF6rbujmmBDvdUvR6trFChueRczl2p5HWqTOr6NPoDGQm8AyNw==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.11", - "@angular-devkit/build-webpack": "0.1802.11", - "@angular-devkit/core": "18.2.11", - "@angular/build": "18.2.11", + "@angular-devkit/architect": "0.1802.12", + "@angular-devkit/build-webpack": "0.1802.12", + "@angular-devkit/core": "18.2.12", + "@angular/build": "18.2.12", "@babel/core": "7.25.2", "@babel/generator": "7.25.0", "@babel/helper-annotate-as-pure": "7.24.7", @@ -93,7 +94,7 @@ "@babel/preset-env": "7.25.3", "@babel/runtime": "7.25.0", "@discoveryjs/json-ext": "0.6.1", - "@ngtools/webpack": "18.2.11", + "@ngtools/webpack": "18.2.12", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.20", @@ -208,13 +209,13 @@ "license": "0BSD" }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1802.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.11.tgz", - "integrity": "sha512-G76rNsyn1iQk7qjyr+K4rnDzfalmEswmwXQorypSDGaHYzIDY1SZXMoP4225WMq5fJNBOJrk82FA0PSfnPE+zQ==", + "version": "0.1802.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.12.tgz", + "integrity": "sha512-0Z3fdbZVRnjYWE2/VYyfy+uieY+6YZyEp4ylzklVkc+fmLNsnz4Zw6cK1LzzcBqAwKIyh1IdW20Cg7o8b0sONA==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1802.11", + "@angular-devkit/architect": "0.1802.12", "rxjs": "7.8.1" }, "engines": { @@ -228,9 +229,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.11.tgz", - "integrity": "sha512-H9P1shRGigORWJHUY2BRa2YurT+DVminrhuaYHsbhXBRsPmgB2Dx/30YLTnC1s5XmR9QIRUCsg/d3kyT1wd5Zg==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", + "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -256,13 +257,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.11.tgz", - "integrity": "sha512-efRK3FotTFp4KD5u42jWfXpHUALXB9kJNsWiB4wEImKFH6CN+vjBspJQuLqk2oeBFh/7D2qRMc5P+2tZHM5hdw==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz", + "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.11", + "@angular-devkit/core": "18.2.12", "jsonc-parser": "3.3.1", "magic-string": "0.30.11", "ora": "5.4.1", @@ -275,9 +276,9 @@ } }, "node_modules/@angular/animations": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.10.tgz", - "integrity": "sha512-LT5+CocFZJ4t5jXsXLx5w/sBuWSxOEjmNTYga13usRcLOblrAB902pjUdFCHEZyrCUgm4MH8vov9fMS+Ks2GCw==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.12.tgz", + "integrity": "sha512-XcWH/VFQ1Rddhdqi/iU8lW3Qg96yVx1NPfrO5lhcSSvVUzYWTZ5r+jh3GqYqUgPWyEp1Kpw3FLsOgVcGcBWQkQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -286,18 +287,18 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.10" + "@angular/core": "18.2.12" } }, "node_modules/@angular/build": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.11.tgz", - "integrity": "sha512-AgirvSCmqUKiDE3C0rl3JA68OkOqQWDKUvjqRHXCkhxldLVOVoeIl87+jBYK/v9gcmk+K+ju+5wbGEfu1FjhiQ==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.12.tgz", + "integrity": "sha512-4Ohz+OSILoL+cCAQ4UTiCT5v6pctu3fXNoNpTEUK46OmxELk9jDITO5rNyNS7TxBn9wY69kjX5VcDf7MenquFQ==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.11", + "@angular-devkit/architect": "0.1802.12", "@babel/core": "7.25.2", "@babel/helper-annotate-as-pure": "7.24.7", "@babel/helper-split-export-declaration": "7.24.7", @@ -359,9 +360,9 @@ } }, "node_modules/@angular/cdk": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.11.tgz", - "integrity": "sha512-FuvfhrSz2ch0gyOVHrkWq2C/I2PnOzKYSXlG/VEG+ize/WNrvlYy//5WVrTh/hv+HD9sdoWPr9ULXsfFfgbo7w==", + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.14.tgz", + "integrity": "sha512-vDyOh1lwjfVk9OqoroZAP8pf3xxKUvyl+TVR8nJxL4c5fOfUFkD7l94HaanqKSRwJcI2xiztuu92IVoHn8T33Q==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -376,18 +377,18 @@ } }, "node_modules/@angular/cli": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.11.tgz", - "integrity": "sha512-0JI1xjOLRemBPjdT/yVlabxc3Zkjqa/lhvVxxVC1XhKoW7yGxIGwNrQ4pka4CcQtCuktO6KPMmTGIu8YgC3cpw==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.12.tgz", + "integrity": "sha512-xhuZ/b7IhqNw1MgXf+arWf4x+GfUSt/IwbdWU4+CO8A7h0Y46zQywouP/KUK3cMQZfVdHdciTBvlpF3vFacA6Q==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1802.11", - "@angular-devkit/core": "18.2.11", - "@angular-devkit/schematics": "18.2.11", + "@angular-devkit/architect": "0.1802.12", + "@angular-devkit/core": "18.2.12", + "@angular-devkit/schematics": "18.2.12", "@inquirer/prompts": "5.3.8", "@listr2/prompt-adapter-inquirer": "2.0.15", - "@schematics/angular": "18.2.11", + "@schematics/angular": "18.2.12", "@yarnpkg/lockfile": "1.1.0", "ini": "4.1.3", "jsonc-parser": "3.3.1", @@ -410,9 +411,9 @@ } }, "node_modules/@angular/common": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.10.tgz", - "integrity": "sha512-YzTCmuqLiOuT+Yv07vuKymDWiebOVZ8BuXakJiz4EM7FMoOw5gICHJ04jepZSjDNWpA16e7kJSdt5ucnmvCFDQ==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.12.tgz", + "integrity": "sha512-gI5o8Bccsi8ow8Wk2vG4Tw/Rw9LoHEA9j8+qHKNR/55SCBsz68Syg310dSyxy+sApJO2WiqIadr5VP36dlSUFw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -421,14 +422,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.10", + "@angular/core": "18.2.12", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.10.tgz", - "integrity": "sha512-cu+Uq1nnyl00Glg0+2uvm+Xpaq5b4YvWpaLGGtit7uGETAJ4L/frlBVeaTRhEoaIAGBI+RRlyuFLae+etQDA0w==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.12.tgz", + "integrity": "sha512-D5d5dLrjQal5DbAXJJNSsCC3UxzjOI2wbc+Iv+LOpRM1gpNwuYfZMX5W7cj62Ce4G2++78CJSppdKBp8D4HErQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -437,7 +438,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.10" + "@angular/core": "18.2.12" }, "peerDependenciesMeta": { "@angular/core": { @@ -446,9 +447,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.10.tgz", - "integrity": "sha512-CNFStKWMB89MFKAZZFUOhoQi+fHqRLgNOOrI73LjizXixvngEh3BDZJRtK9hbSGG+giujBrummEA60CWAw69MA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.12.tgz", + "integrity": "sha512-IWimTNq5Q+i2Wxev6HLqnN4iYbPvLz04W1BBycT1LfGUsHcjFYLuUqbeUzHbk2snmBAzXkixgVpo8SF6P4Y5Pg==", "dev": true, "license": "MIT", "dependencies": { @@ -470,14 +471,44 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.2.10", + "@angular/compiler": "18.2.12", "typescript": ">=5.4 <5.6" } }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/core": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.10.tgz", - "integrity": "sha512-EfxVz0pLaxnOppOYkdhnaUkk8HZT+uxaAGpJD3ppAa7YAWTE9xIGoNJmtS33cZNNOnvriMkdv7yn6pDtV4ct+Q==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.12.tgz", + "integrity": "sha512-wCf/OObwS6bpM60rk6bpMpCRGp0DlMLB1WNAMtfcaPNyqimVV5Bm98mWRhkOuRyvU3fU7iHhM/10ePVaoyu9+A==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -491,9 +522,9 @@ } }, "node_modules/@angular/forms": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.10.tgz", - "integrity": "sha512-2VprGB+enJIeqfz2oALmP/G/UiFzpZW6PHgyZXhk/0J/UMsa26JoYxwDFvfdm/WGTrB+VaQEG7in5xwiFPAFtQ==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.12.tgz", + "integrity": "sha512-FsukBJEU6jfAmht7TrODTkct/o4iwCZvGozuThOp0tYUPD/E1rZZzuKjEyTnT5Azpfkf0Wqx1nmpz80cczELOQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -502,16 +533,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.10", - "@angular/core": "18.2.10", - "@angular/platform-browser": "18.2.10", + "@angular/common": "18.2.12", + "@angular/core": "18.2.12", + "@angular/platform-browser": "18.2.12", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/platform-browser": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.10.tgz", - "integrity": "sha512-zKyRKFr3AaEA4SE/DEeb5FWHJutT26avHZog6ZGDkMeMN12zMtSqjPuTSgmDXCWleoOkzbb+nhAQ+fK/EyGyPA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.12.tgz", + "integrity": "sha512-DRSMznuxuecrs+v5BRyd60/R4vjkQtuYUEPfzdo+rqxM83Dmr3PGtnqPRgd5oAFUbATxf02hQXijRD27K7rZRg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -520,9 +551,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "18.2.10", - "@angular/common": "18.2.10", - "@angular/core": "18.2.10" + "@angular/animations": "18.2.12", + "@angular/common": "18.2.12", + "@angular/core": "18.2.12" }, "peerDependenciesMeta": { "@angular/animations": { @@ -531,9 +562,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.10.tgz", - "integrity": "sha512-syKyOTgfQnMxfpDRP1khTSPZ5dsMgA8YQwNF6KsB3eZQl15CKSka7bzjMOUWeZ8M3WShOp1AzTf0MfwNeh0UBA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.12.tgz", + "integrity": "sha512-dv1QEjYpcFno6+oUeGEDRWpB5g2Ufb0XkUbLJQIgrOk1Qbyzb8tmpDpTjok8jcKdquigMRWolr6Y1EOicfRlLw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -542,16 +573,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.10", - "@angular/compiler": "18.2.10", - "@angular/core": "18.2.10", - "@angular/platform-browser": "18.2.10" + "@angular/common": "18.2.12", + "@angular/compiler": "18.2.12", + "@angular/core": "18.2.12", + "@angular/platform-browser": "18.2.12" } }, "node_modules/@angular/router": { - "version": "18.2.10", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.10.tgz", - "integrity": "sha512-ZqJgOGOfvW0epsc7pIo7DffZqYHo3O9aUCVepZAhOxqtjF/sfhX2fy+A0xopTIiR0eM3LrT823V+2hjlBHj+CA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.12.tgz", + "integrity": "sha512-cz/1YWOZadAT35PPPYmpK3HSzKOE56nlUHue5bFkw73VSZr2iBn03ALLpd9YKzWgRmx3y7DqnlQtCkDu9JPGKQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -560,9 +591,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.10", - "@angular/core": "18.2.10", - "@angular/platform-browser": "18.2.10", + "@angular/common": "18.2.12", + "@angular/core": "18.2.12", + "@angular/platform-browser": "18.2.12", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -796,9 +827,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, "license": "MIT", "dependencies": { @@ -3017,9 +3048,9 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.7.tgz", - "integrity": "sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", "dev": true, "license": "MIT", "engines": { @@ -3578,9 +3609,9 @@ ] }, "node_modules/@ngtools/webpack": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.11.tgz", - "integrity": "sha512-iTdUGJ5O7yMm1DyCzyoMDMxBJ68emUSSXPWbQzEEdcqmtifRebn+VAq4vHN8OmtGM1mtuKeLEsbiZP8ywrw7Ug==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.12.tgz", + "integrity": "sha512-FFJAwtWbtpncMOVNuULPBwFJB7GSjiUwO93eGTzRp8O4EPQ8lCQeFbezQm/NP34+T0+GBLGzPSuQT+muob8YKw==", "dev": true, "license": "MIT", "engines": { @@ -4145,14 +4176,14 @@ ] }, "node_modules/@schematics/angular": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.11.tgz", - "integrity": "sha512-jT54mc9+hPOwie9bji/g2krVuK1kkNh2PNFGwfgCg3Ofmt3hcyOBai1DKuot5uLTX4VCCbvfwiVR/hJniQl2SA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.12.tgz", + "integrity": "sha512-sIoeipsisK5eTLW3XuNZYcal83AfslBbgI7LnV+3VrXwpasKPGHwo2ZdwhCd2IXAkuJ02Iyu7MyV0aQRM9i/3g==", "dev": true, "license": "MIT", "dependencies": { - "@angular-devkit/core": "18.2.11", - "@angular-devkit/schematics": "18.2.11", + "@angular-devkit/core": "18.2.12", + "@angular-devkit/schematics": "18.2.12", "jsonc-parser": "3.3.1" }, "engines": { @@ -4391,9 +4422,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", - "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", "dev": true, "license": "MIT", "dependencies": { @@ -4472,9 +4503,9 @@ } }, "node_modules/@types/node": { - "version": "22.8.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz", - "integrity": "sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==", + "version": "22.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", + "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", "dev": true, "license": "MIT", "dependencies": { @@ -4492,9 +4523,9 @@ } }, "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", "dev": true, "license": "MIT" }, @@ -4563,9 +4594,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "dev": true, "license": "MIT", "dependencies": { @@ -4586,73 +4617,73 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, "license": "MIT", "dependencies": { @@ -4660,9 +4691,9 @@ } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4670,79 +4701,79 @@ } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -5091,14 +5122,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -5130,13 +5161,13 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5265,9 +5296,9 @@ "license": "MIT" }, "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "dev": true, "license": "MIT", "dependencies": { @@ -5506,9 +5537,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001676", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz", - "integrity": "sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==", + "version": "1.0.30001684", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", + "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", "dev": true, "funding": [ { @@ -5551,19 +5582,41 @@ "license": "MIT" }, "node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/chownr": { @@ -5929,17 +5982,28 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", + "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", + "license": "MIT", + "dependencies": { + "cookie": "0.7.2", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true, "license": "MIT" }, "node_modules/copy-anything": { @@ -6060,9 +6124,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -6436,9 +6500,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.50", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", - "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", + "version": "1.5.64", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.64.tgz", + "integrity": "sha512-IXEuxU+5ClW2IGEYFC2T7szbyVgehupCWQe5GNh+H065CD6U6IFN0s4KeAMFGNmQolRU4IV7zGBWSYMmZ8uuqQ==", "dev": true, "license": "ISC" }, @@ -7176,9 +7240,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true, "license": "ISC" }, @@ -8625,31 +8689,6 @@ "source-map-support": "^0.5.5" } }, - "node_modules/karma/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -8669,19 +8708,6 @@ "dev": true, "license": "MIT" }, - "node_modules/karma/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/karma/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -8692,32 +8718,6 @@ "node": ">=8" } }, - "node_modules/karma/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/karma/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -9944,9 +9944,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, "license": "MIT", "optional": true, @@ -10240,9 +10240,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", "engines": { @@ -10402,9 +10402,9 @@ "license": "ISC" }, "node_modules/ordered-binary": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.2.tgz", - "integrity": "sha512-JTo+4+4Fw7FreyAvlSLjb1BBVaxEQAacmjD3jjuyPZclpbEghTvQZbXBb2qPd2LeIMxiHwXBZUcpmG2Gl/mDEA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", "dev": true, "license": "MIT" }, @@ -10467,9 +10467,9 @@ } }, "node_modules/p-retry": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", - "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10853,14 +10853,14 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", - "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz", + "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==", "dev": true, "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -10871,13 +10871,13 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", - "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dev": true, "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -10903,9 +10903,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10936,9 +10936,9 @@ "license": "MIT" }, "node_modules/primeng": { - "version": "17.18.11", - "resolved": "https://registry.npmjs.org/primeng/-/primeng-17.18.11.tgz", - "integrity": "sha512-LzV0fFZmb3GdnaRqi1+GP+RPtW0a+jztL5pH1zRWY7+7pyQ0n1YNyTXzmqVcdks/CmoyjNhutWEmexwi6vFVeA==", + "version": "17.18.12", + "resolved": "https://registry.npmjs.org/primeng/-/primeng-17.18.12.tgz", + "integrity": "sha512-zElkv9c3209e1j2yNXalfv71gGJeo8c7bUuW3nsvtQZcYsXjdsJvBEhTThVghBdpCUoFYD3cNmTzg3t807cL6A==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -11127,17 +11127,29 @@ } }, "node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">= 14.16.0" + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/reflect-metadata": { @@ -11192,16 +11204,16 @@ "license": "MIT" }, "node_modules/regexpu-core": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", - "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", - "regjsparser": "^0.11.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -11217,9 +11229,9 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", - "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -11570,70 +11582,6 @@ } } }, - "node_modules/sass/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/sass/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sass/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/sass/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -13583,9 +13531,9 @@ } }, "node_modules/vite/node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -13604,7 +13552,7 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -13809,31 +13757,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/webpack-dev-server/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -13855,19 +13778,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/webpack-dev-server/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", @@ -13909,32 +13819,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/webpack-dev-server/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/webpack-dev-server/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/webpack-dev-server/node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", diff --git a/package.json b/package.json index fd6a8bd..d3ddbbb 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@angular/platform-browser": "^18.2.6", "@angular/platform-browser-dynamic": "^18.2.6", "@angular/router": "^18.2.6", + "cookie-parser": "^1.4.7", "file-saver-es": "^2.0.5", "ngx-json-viewer": "^3.2.1", "primeflex": "^3.3.1", diff --git a/server/RC2Model.js b/server/RC2Model.ts similarity index 63% rename from server/RC2Model.js rename to server/RC2Model.ts index e26dea5..ab5ea0b 100644 --- a/server/RC2Model.js +++ b/server/RC2Model.ts @@ -1,20 +1,25 @@ import fs from 'node:fs'; import path from 'path'; +export interface Entity { + name: any; + type: string; + entity_type: string; +} export class RC2Model { - entities_catalog = {}; + entities_catalog: any = {}; // {activity_id: {name, entities:[{entity_id, name, integration}], buttons:[{button, entity_id, short_press:True/False}]}} - activities = {}; + activities: any = {}; // {profile_id : {name, pages:[{page_id, name, entities: [entity_id]]}} - profiles = {} - activities_entities = {}; + profiles: any = {} + activities_entities: any = {}; // activity_entities: [activity_ids] // activity_buttons: [{ activity_id, button, short_press:boolean}] // activity_interface: [{page_id, entity_id, command}] // pages: [{profile_id, page_id}] - entities_usage = {}; + entities_usage: any = {}; constructor() { } @@ -27,26 +32,9 @@ export class RC2Model this.entities_usage = {}; } - getOrphans() + getEntity(entityNameOrId: string): {[entityId: string]: Entity} { - const orphans = []; - for (let entity_id in this.entities_usage) - { - const entity = this.entities_usage[entity_id]; - if (entity["activity_entities"].length === 0 && - entity["activity_buttons"].length === 0 && - entity["pages"].length === 0) - { - const entity_ref = this.entities_catalog[entity_id]; - orphans.push({"entity_id": entity_id, "name": entity_ref['name'], "type": entity_ref['type']}); - } - } - return orphans; - } - - getEntity(entityNameOrId) - { - const found_entities = {} + const found_entities: any = {} if (entityNameOrId in this.entities_catalog || entityNameOrId.toLowerCase() in this.entities_catalog) { found_entities[entityNameOrId] = {"name": this.entities_catalog[entityNameOrId]['name'], @@ -73,7 +61,7 @@ export class RC2Model return found_entities; } - loadFromPath(folderName) + loadFromPath(folderName: string) { this.init(); if (fs.existsSync(path.join(folderName, 'integrations'))) { @@ -139,64 +127,8 @@ export class RC2Model } } - build_entity_usage() - { - const entities_usage = {}; - for (let entity_id in this.entities_catalog) - { - const entity = this.entities_catalog[entity_id]; - let entity_usage = {"name": entity['name'], - "type": entity["type"], - "activity_entities": [], "activity_buttons": [], "activity_interface": [], - "pages": [], "activity_sequences": []}; - entities_usage[entity_id] = entity_usage - for (let profile_id in this.profiles) - { - const profile = this.profiles[profile_id]; - for (let page_index in profile['pages']) - { - const page = profile['pages'][page_index]; - if (page['entities'].includes(entity_id)) - { - entity_usage['pages'].push({"profile_id": profile_id, - "page_id": page['page_id'], - "name": page['name']}); - } - } - } - for (let activity_id in this.activities) - { - const activity = this.activities[activity_id]; - const activity_name = activity['name']; - if (activity['entities'].find(activity_entity => activity_entity['entity_id'] === entity_id)) - { - entity_usage["activity_entities"].push({"activity_id": activity_id, "name": activity_name}); - } - const buttons = activity['buttons'].filter(activity_button => activity_button['entity_id'] === entity_id); - buttons.forEach(button => { - entity_usage["activity_buttons"].push({"activity_id": activity_id, "name": activity_name, - "button": button['button'], - "short_press": button['short_press']}); - }); - //activity_interface - activity["interface"].forEach(page => { - page["items"].forEach(item => { - if (item["entity_id"] === entity_id) - { - entity_usage["activity_interface"].push({"activity_id": activity_id, "name": activity_name, - "page_id": page["page_id"], "page_name": page["name"], - "command": item["command"]}); - } - }) - }); - entity_usage["activity_sequences"].push(...activity["sequences"].filter(sequence => sequence.entity_id === entity_id)); - } - } - return entities_usage; - } - - parse_entities_folder(entities_path, type) { - const entities = {} + parse_entities_folder(entities_path: string, type: string): {[type: string]: any} { + const entities:{[type: string]: any} = {}; fs.readdirSync(entities_path).map(fileName => { fileName = path.join(entities_path, fileName); if (fs.lstatSync(fileName).isDirectory() || !fileName.endsWith('.json')) diff --git a/server/app.js b/server/app.ts similarity index 90% rename from server/app.js rename to server/app.ts index dca4802..21c9030 100644 --- a/server/app.js +++ b/server/app.ts @@ -10,16 +10,16 @@ import {rimraf} from 'rimraf'; import path from 'path'; // import indexRouter from './routes/index.js'; // import usersRouter from './routes/users.js'; -import {RC2Model} from './RC2Model.js' +import {RC2Model} from './RC2Model'; import fs from "node:fs"; -import {Remote} from "./remote.js"; -import {getConfigFile, writeConfigFile} from "./config.js"; +import {Remote} from "./remote"; +import {getConfigFile, writeConfigFile} from './config'; import {program} from 'commander'; import cors from 'cors'; // import expressws from 'express-ws'; let LISTEN_PORT = "8000"; -const DATA_DIR = process.env.DATA_DIR || '.'; +const DATA_DIR = process.env['DATA_DIR'] || '.'; const UPLOAD_DIR = path.join(DATA_DIR, 'uploads'); const RESOURCES_DIR = path.join(DATA_DIR, 'resources'); const app = express(); @@ -41,9 +41,9 @@ program .option('-p, --port ', 'Listen on given port', '8000') .parse(process.argv); const options = program.opts(); -if (options.port) +if (options['port']) { - LISTEN_PORT = options.port; + LISTEN_PORT = options['port']; } const upload = multer({storage: storage}) @@ -68,17 +68,36 @@ const TEMP_FOLDER = 'temp'; const REMOTE_USER = 'web-configurator'; let rc2Model = new RC2Model(); +export interface ConfigRemote +{ + remote_name?: string; + address: string; + port: number; + user: string; + token: string; + mac_address: string; + api_key?: string; + api_key_name?: string; + api_valid_to?: string; +} + +export interface Config +{ + remotes?: ConfigRemote[]; +} + // Against 304 // app.disable('etag'); app.get('/server/api', (req, res, next) => { - let url = req.headers.destinationurl; - let headers = {} + let url = req.headers['destinationurl']; + if (!url || typeof url !== 'string') return; + let headers: any = {}; for (let key in req.headers) { headers[key] = req.headers[key]; } if (!url.startsWith('http://')) url = 'http://'+url; - headers['host'] = (new URL(url)).host; + headers['host'] = (new URL(url!)).host; headers['User-Agent'] = ''; const options = { headers: headers, @@ -104,8 +123,9 @@ app.get('/server/api', (req, res, next) => { }) app.delete('/server/api', (req, res, next) => { - let url = req.headers.destinationurl; - let headers = {} + let url = req.headers['destinationurl']; + if (!url || typeof url !== 'string') return; + let headers: any = {} for (let key in req.headers) { headers[key] = req.headers[key]; } @@ -132,8 +152,9 @@ app.delete('/server/api', (req, res, next) => { }) app.post('/server/api', (req, res, next) => { - let url = req.headers.destinationurl; - let headers = {} + let url = req.headers['destinationurl']; + if (!url || typeof url !== 'string') return; + let headers: any = {} for (let key in req.headers) { headers[key] = req.headers[key]; } @@ -162,8 +183,9 @@ app.post('/server/api', (req, res, next) => { }) app.patch('/server/api', (req, res, next) => { - let url = req.headers.destinationurl; - let headers = {} + let url = req.headers['destinationurl']; + if (!url || typeof url !== 'string') return; + let headers: any = {} for (let key in req.headers) { headers[key] = req.headers[key]; console.log(key, req.headers[key]); @@ -193,8 +215,9 @@ app.patch('/server/api', (req, res, next) => { }) app.put('/server/api', (req, res, next) => { - let url = req.headers.destinationurl; - let headers = {} + let url = req.headers['destinationurl']; + if (!url || typeof url !== 'string') return; + let headers: any = {} for (let key in req.headers) { headers[key] = req.headers[key]; } @@ -254,7 +277,7 @@ app.post('/api/config/remote', async (req, res, next) => { await remote.unregister(api_key_name); await remote.register(api_key_name); await remote.getRemoteName(); - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); if (!configFile.remotes) configFile.remotes = [] configFile.remotes = configFile.remotes.filter(local_remote => !(remote.address === local_remote.address @@ -274,7 +297,7 @@ app.get('/api/config/remote/:address', async (req, res, next) => { if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -297,7 +320,7 @@ app.get('/api/config/remote/:address/key', async (req, res, next) => { if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -312,7 +335,7 @@ app.delete('/api/config/remote/:address', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -321,14 +344,15 @@ app.delete('/api/config/remote/:address', async (req, res, next) => { } const remote = new Remote(remoteEntry.address, remoteEntry.port, remoteEntry.user, remoteEntry.token, remoteEntry.api_key); try { - await remote.unregister(remoteEntry.api_key_name); + if (remoteEntry.api_key_name) + await remote.unregister(remoteEntry.api_key_name) res.status(200).json(address); } catch (error) { errorHandler(error, req, res, next); } finally { - configFile.remotes = configFile.remotes.filter(local_remote => remote.address !== local_remote.address); + configFile.remotes = configFile.remotes?.filter(local_remote => remote.address !== local_remote.address); writeConfigFile(configFile); } }) @@ -339,8 +363,8 @@ app.post('/api/remote/:address/wake', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - let broadcast = req.query.broadcast; - const configFile = getConfigFile(); + let broadcast = req.query?.['broadcast'] ? req.query['broadcast'].toString(): undefined; + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -364,8 +388,8 @@ app.post('/api/remote/:address/system', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - let power = req.query.cmd; - const configFile = getConfigFile(); + let power = req.query["cmd"]?.toString(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -374,7 +398,8 @@ app.post('/api/remote/:address/system', async (req, res, next) => { } const remote = new Remote(remoteEntry.address, remoteEntry.port, remoteEntry.user, remoteEntry.token, remoteEntry.api_key); try { - res.status(200).json(await remote.powerRemote(power)); + if (power) + res.status(200).json(await remote.powerRemote(power)); } catch (error) { errorHandler(error, req, res, next); @@ -386,7 +411,7 @@ app.put('/api/remote/:address/system/logs/web', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -407,7 +432,7 @@ app.get('/api/remote/:address/system/logs/web', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -428,7 +453,7 @@ app.get('/api/remote/:address/version', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -449,7 +474,7 @@ app.get('/api/remote/:address/system/power/battery', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -470,7 +495,7 @@ app.get('/api/remote/:address/entities', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -491,7 +516,7 @@ app.get('/api/remote/:address/activities', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -513,7 +538,7 @@ app.get('/api/remote/:address/activities/:activity_id', async (req, res, next) = let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -538,7 +563,7 @@ app.delete('/api/remote/:address/activities/:activity_id', async (req, res, next let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -564,7 +589,7 @@ app.delete('/api/remote/:address/activities/:activity_id/ui/pages/:page_id', asy let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -590,7 +615,7 @@ app.get('/api/remote/:address/entities/:entity_id', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -612,7 +637,7 @@ app.delete('/api/remote/:address/entities/:entity_id', async (req, res, next) => let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -637,7 +662,7 @@ app.get('/api/remote/:address/resources/:type', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -676,7 +701,7 @@ app.get('/api/remote/:address/local/resources/:type', async (req, res, next) => let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -694,7 +719,7 @@ app.get('/api/remote/:address/local/resources/:type', async (req, res, next) => app.get('/api/remote/:address/profiles', async (req, res, next) => { const address = req.params.address; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -713,7 +738,7 @@ app.get('/api/remote/:address/profiles', async (req, res, next) => { app.get('/api/remote/:address/profiles/:profileid/pages', async (req, res, next) => { const address = req.params.address; const profileId = req.params.profileid; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -732,7 +757,7 @@ app.get('/api/remote/:address/profiles/:profileid/pages', async (req, res, next) app.get('/api/remote/:address/profiles/:profileid/groups', async (req, res, next) => { const address = req.params.address; const profileId = req.params.profileid; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -750,7 +775,7 @@ app.get('/api/remote/:address/profiles/:profileid/groups', async (req, res, next app.get('/api/remote/:address/system/backup/export', async (req, res, next) => { const address = req.params.address; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -769,7 +794,7 @@ app.get('/api/remote/:address/system/backup/export', async (req, res, next) => { app.get('/api/remote/:address/cfg/entity/commands', async (req, res, next) => { const address = req.params.address; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -787,7 +812,7 @@ app.get('/api/remote/:address/cfg/entity/commands', async (req, res, next) => { app.get('/api/remote/:address/cfg/device/screen_layout', async (req, res, next) => { const address = req.params.address; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -809,7 +834,7 @@ app.get('/api/remote/:address/macros', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -831,7 +856,7 @@ app.get('/api/remote/:address/macros/:macroid', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -852,7 +877,7 @@ app.get('/api/remote/:address/intg/drivers', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -873,7 +898,7 @@ app.get('/api/remote/:address/intg/instances', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -892,12 +917,12 @@ app.get('/api/remote/:address/intg/instances', async (req, res, next) => { app.get('/api/remote/:address/intg/instances/:intgid/entities', async (req, res, next) => { const address = req.params.address; const intgId = req.params.intgid; - let filter = req.query.filter; + let filter = req.query["filter"]?.toString(); if (filter === undefined) filter = "NEW"; let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -914,11 +939,11 @@ app.get('/api/remote/:address/intg/instances/:intgid/entities', async (req, res, }) app.post('/api/remote/:address/intg/install', upload.single('file'),async (req, res, next) => { - const address = req.params.address; + const address = req.params["address"]; let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -934,7 +959,8 @@ app.post('/api/remote/:address/intg/install', upload.single('file'),async (req, errorHandler(error, req, res, next); } try { - fs.rmSync(req.file.path) + if (req["file"]?.["path"]) + fs.rmSync(req["file"]["path"]) } catch (error) { console.error("Error while deleting uploaded integration", req.file, error); @@ -947,7 +973,7 @@ app.delete('/api/remote/:address/intg/drivers/:driverid', async (req, res, next) let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -969,7 +995,7 @@ app.delete('/api/remote/:address/intg/instances/:integrationid', async (req, res let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -991,7 +1017,7 @@ app.get('/api/remote/:address/pub/status', async (req, res, next) => { let user = REMOTE_USER if (req.body?.user) user = req.body?.user; - const configFile = getConfigFile(); + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -1013,8 +1039,8 @@ app.put('/api/remote/:address/entities/:entity_id/command', async (req, res, nex let user = REMOTE_USER; if (req.body?.user) user = req.body?.user; - let power = req.query.cmd; - const configFile = getConfigFile(); + let power = req.query["cmd"]; + const configFile: Config = getConfigFile(); const remoteEntry = configFile?.remotes?.find(remote => remote.address === address); if (!remoteEntry) { @@ -1036,10 +1062,11 @@ app.get('/api/proxy', async (req, res) => { isStream: true, throwHttpErrors: false }; - console.log("Proxy get", decodeURI(req.query.url), options); + const url = req.query["url"] ? req.query["url"].toString() : ""; + console.log("Proxy get", decodeURI(url), options); await streamPipeline( - got.get(encodeURI(decodeURI(req.query.url)), options), + got.get(encodeURI(decodeURI(url)), options) as any, res ); res.end(); @@ -1047,7 +1074,8 @@ app.get('/api/proxy', async (req, res) => { app.post('/upload',upload.single('file'),(req,res)=>{ console.log(req.file, req.body.name); - res.status(200).json(req.file.filename) + if (req["file"]?.["filename"]) + res.status(200).json(req["file"]["filename"]) }) app.get('/download/:url', (req, res, next) => { @@ -1089,7 +1117,7 @@ app.post('/api/load/path/:path', (req, res, next) => { return; } try { - zip.file(filename).async('nodebuffer').then(content => { + zip.file(filename)?.async('nodebuffer').then(content => { if (filename.includes(':')) { console.log(`${zipFile} : renaming file ${filename} to ${filename.replaceAll(":", "_")}`); @@ -1120,8 +1148,8 @@ app.post('/api/load/path/:path', (req, res, next) => { }) }); } catch (exception) { - next(error); - console.log(error); + next(exception); + console.log(exception); } }) @@ -1175,7 +1203,7 @@ app.get('/api/profiles', (req, res, next) => { app.get('/api/uploaded_files', (req, res, next) => { try { - const files = []; + const files: string[] = []; fs.readdirSync(UPLOAD_DIR).map(fileName => { files.push(fileName); }); @@ -1215,13 +1243,13 @@ app.listen(LISTEN_PORT, function () { }); -function errorHandler(error, req, res, next) { +function errorHandler(error: any, req: any, res:any, next: any) { if (error.response instanceof TypeError) { return res.status(400).json(error.name + ": " + error.message); } if (error.response) { - let message = {}; + let message: any = {}; message['headers'] = error.response.headers; message['statusCode'] = error.response.statusCode; message['code'] = error.response.code; diff --git a/server/config.js b/server/config.ts similarity index 86% rename from server/config.js rename to server/config.ts index 799e071..8ef14fc 100644 --- a/server/config.js +++ b/server/config.ts @@ -1,11 +1,11 @@ import path from "path"; import fs from "node:fs"; -const DATA_DIR = process.env.DATA_DIR || '.'; +const DATA_DIR = process.env["DATA_DIR"] || '.'; const CONFIG_FOLDER = DATA_DIR; const CONFIG_FILE = 'config.json'; -export function writeConfigFile(config) +export function writeConfigFile(config: any) { const filepath = path.join(CONFIG_FOLDER, CONFIG_FILE); console.log('Write config', filepath); diff --git a/server/package-lock.json b/server/package-lock.json index e8a1d21..2c07830 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -27,8 +27,13 @@ "ws": "^8.18.0" }, "devDependencies": { + "@types/cookie-parser": "^1.4.7", + "@types/got": "^9.6.12", + "@types/morgan": "^1.9.9", + "@types/multer": "^1.4.12", "esbuild": "^0.24.0", - "postject": "^1.0.0-alpha.6" + "postject": "^1.0.0-alpha.6", + "typescript": "^5.7.2" } }, "node_modules/@esbuild/aix-ppc64": { @@ -486,12 +491,169 @@ "node": ">=14.16" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookie-parser": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.7.tgz", + "integrity": "sha512-Fvuyi354Z+uayxzIGCwYTayFKocfV7TuDYZClCdIP9ckhvAu/ixDtCB6qx2TT0FKjPLf1f3P/J1rgf6lPs64mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.0.tgz", + "integrity": "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz", + "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/got": { + "version": "9.6.12", + "resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.12.tgz", + "integrity": "sha512-X4pj/HGHbXVLqTpKjA2ahI4rV/nNBc9mGO2I/0CgAra+F2dKgMXnENv2SRpemScBzBAI4vMelIVYViQxlSE6xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "license": "MIT" }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/morgan": { + "version": "1.9.9", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.9.tgz", + "integrity": "sha512-iRYSDKVaC6FkGSpEVVIvrRGw0DfJMiQzIn3qr2G5B3C//AWkulhXgaBd7tS9/J79GWSYMTHGs7PfI5b3Y8m+RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/multer": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.12.tgz", + "integrity": "sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/node": { + "version": "22.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", + "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -554,6 +716,13 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -765,6 +934,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -979,6 +1161,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1198,6 +1390,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", + "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, "node_modules/form-data-encoder": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.0.2.tgz", @@ -2681,12 +2889,33 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "license": "MIT" }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "license": "MIT" }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/server/package.json b/server/package.json index 6e02bda..42b3e77 100644 --- a/server/package.json +++ b/server/package.json @@ -22,11 +22,14 @@ "open": "^10.1.0", "process": "^0.11.10", "rimraf": "^6.0.1", - "wakeonlan": "^0.1.0", "ws": "^8.18.0" }, "devDependencies": { + "@types/cookie-parser": "^1.4.7", + "@types/morgan": "^1.9.9", + "@types/multer": "^1.4.12", "esbuild": "^0.24.0", - "postject": "^1.0.0-alpha.6" + "postject": "^1.0.0-alpha.6", + "typescript": "^5.7.2" } } diff --git a/server/remote.js b/server/remote.ts similarity index 85% rename from server/remote.js rename to server/remote.ts index 8f8692a..42f5eee 100644 --- a/server/remote.js +++ b/server/remote.ts @@ -1,34 +1,35 @@ -import got, {HTTPError, Options} from 'got' +import got from 'got'; import fs from "node:fs"; import { readdir } from 'node:fs/promises'; import path from "path"; import {pipeline as streamPipeline} from 'node:stream/promises'; -import wakeonlan from "wakeonlan"; -const SystemCommand = { - STANDBY: 'STANDBY', - REBOOT: 'REBOOT', - POWER_OFF: 'POWER_OFF', - RESTART: 'RESTART', - RESTART_UI: 'RESTART_UI', - RESTART_CORE: 'RESTART_CORE', -}; +import {send as wakeonlan} from './wakeonlan'; +// const SystemCommand = { +// STANDBY: 'STANDBY', +// REBOOT: 'REBOOT', +// POWER_OFF: 'POWER_OFF', +// RESTART: 'RESTART', +// RESTART_UI: 'RESTART_UI', +// RESTART_CORE: 'RESTART_CORE', +// }; export class Remote { - address; - port; - api_key; - api_key_name; - user; - token; - valid_to; - remote_name; + address: string|undefined; + port: number|undefined; + api_key: string|undefined; + api_key_name: string|undefined; + user: string|undefined; + token: string|undefined; + valid_to: string|undefined; + remote_name: string|undefined; protocol = 'http://'; resources_path = ''; - mac_address; + mac_address: string|undefined; + resources_directory: string|undefined; - constructor(address, port, user, token, api_key, mac_address) { + constructor(address: string, port:number, user: string, token: string, api_key?: string, mac_address?: string) { this.address = address; this.port = port; this.api_key = api_key; @@ -37,7 +38,8 @@ export class Remote this.mac_address = mac_address; } - async getResources(type, resources_directory) { + async getResources(type: string, resources_directory: string) { + if (!this.address) return; this.resources_directory = path.join(resources_directory, this.address); const target_path = path.join(this.resources_directory, type); if (!fs.existsSync(target_path)) @@ -45,8 +47,9 @@ export class Remote return await readdir(target_path); } - async loadResources(type, resources_directory) + async loadResources(type: string, resources_directory: string) { + if (!this.address) return; this.resources_directory = path.join(resources_directory, this.address); const target_path = path.join(this.resources_directory, type); if (fs.existsSync(target_path)) { @@ -66,8 +69,8 @@ export class Remote const global_list = []; const url = this.getURL() + `/api/resources/${type}`; let res = await got.get(url, options); - const count = res.headers['pagination-count']; - let icons = JSON.parse(res.body); + const count: any = res.headers['pagination-count']; + let icons: any = JSON.parse(res.body); for (let icon of icons) { global_list.push(icon['id']); await streamPipeline(got.stream(`${url}/${icon['id']}`, options), @@ -77,10 +80,10 @@ export class Remote options.searchParams.page = i; res = await got.get(url, options); icons = JSON.parse(res.body); - for (let icon of icons) - global_list.push(icon['id']);{ - await streamPipeline(got.stream(`${url}/${icon['id']}`, options), - fs.createWriteStream(path.join(target_path, icon['id']))); + for (let icon of icons) { + global_list.push(icon['id']); + await streamPipeline(got.stream(`${url}/${(icon as any)['id']}`, options), + fs.createWriteStream(path.join(target_path, (icon as any)['id']))); } } console.log('List of resources extracted', global_list); @@ -89,7 +92,7 @@ export class Remote toJson() { - const data = {address: this.address, port: this.port} + const data: any = {address: this.address, port: this.port} if (this.remote_name) data.remote_name = this.remote_name; if (this.user) data.user = this.user; if (this.token) data.token = this.token; @@ -200,7 +203,7 @@ export class Remote } } - async register(api_key_name) + async register(api_key_name: string) { let headers = this.getHeaders(); const options = { @@ -227,7 +230,7 @@ export class Remote } } - async unregister(api_key_name) + async unregister(api_key_name: string) { const options = this.getOptions(); let url = this.getURL() + '/api/auth/api_keys'; @@ -251,7 +254,7 @@ export class Remote } } - async getEntity(entityId) + async getEntity(entityId: string) { let headers = this.getHeaders(); const limit = 100; @@ -289,7 +292,7 @@ export class Remote let res = await got.head(url, options); const count = res.headers['pagination-count'] let entities = []; - for (let i=1; i<=Math.ceil(count/limit); i++) + for (let i=1; i<=Math.ceil((count as any)/limit); i++) { options.searchParams.page = i; res = await got.get(url, options); @@ -312,7 +315,7 @@ export class Remote let res = await got.head(url, options); const count = res.headers['pagination-count'] let entities = []; - for (let i=1; i<=Math.ceil(count/limit); i++) + for (let i=1; i<=Math.ceil((count as any)/limit); i++) { options.searchParams.page = i; res = await got.get(url, options); @@ -321,7 +324,7 @@ export class Remote return entities; } - async getActivity(activity_id) + async getActivity(activity_id: string) { const limit = 100; const options = { @@ -336,7 +339,7 @@ export class Remote return JSON.parse(res.body); } - async deleteActivity(activity_id) + async deleteActivity(activity_id: string) { const options = { ...this.getOptions() @@ -346,7 +349,7 @@ export class Remote return JSON.parse(res.body); } - async deleteActivityPage(activity_id, page_id) + async deleteActivityPage(activity_id: string, page_id: string) { const options = { ...this.getOptions() @@ -356,7 +359,7 @@ export class Remote return JSON.parse(res.body); } - async deleteEntity(entity_id) + async deleteEntity(entity_id: string) { const options = { ...this.getOptions() @@ -374,7 +377,7 @@ export class Remote return JSON.parse(res.body); } - async getProfilePages(profileId) + async getProfilePages(profileId: string) { const options = this.getOptions(); const url = this.getURL() + `/api/profiles/${profileId}/pages`; @@ -382,7 +385,7 @@ export class Remote return JSON.parse(res.body); } - async getProfileGroups(profileId) + async getProfileGroups(profileId: string) { const options = this.getOptions(); const url = this.getURL() + `/api/profiles/${profileId}/groups`; @@ -428,10 +431,10 @@ export class Remote return JSON.parse(res.body); } - async getMacro(macroid) + async getMacro(macroId: string) { const options = this.getOptions(); - const url = this.getURL() + `/api/macros/${macroid}`; + const url = this.getURL() + `/api/macros/${macroId}`; let res = await got.get(url, options); return JSON.parse(res.body); } @@ -466,7 +469,7 @@ export class Remote return JSON.parse(res.body); } - async getIntegrationEntities(intgId, filter) + async getIntegrationEntities(intgId: string, filter?: string) { const options = { ...this.getOptions(), @@ -479,7 +482,7 @@ export class Remote return JSON.parse(res.body); } - async deleteDriver(driverId) + async deleteDriver(driverId: string) { const options = this.getOptions(); const url = this.getURL() + `/api/intg/drivers/${driverId}`; @@ -487,7 +490,7 @@ export class Remote return JSON.parse(res.body); } - async uploadIntegration(fileData) + async uploadIntegration(fileData: any) { const formData = new FormData(); let buffer = fs.readFileSync(fileData.path); @@ -501,11 +504,11 @@ export class Remote }; const url = this.getURL() + `/api/intg/install`; console.log("Upload file to remote", url, formData, options); - let res = await got.post(url, options); + let res = await got.post(url, options as any); return JSON.parse(res.body); } - async deleteIntegration(integrationId) + async deleteIntegration(integrationId: string) { const options = this.getOptions(); const url = this.getURL() + `/api/intg/instances/${integrationId}`; @@ -513,7 +516,7 @@ export class Remote return JSON.parse(res.body); } - async executeCommand(entity_id, command) + async executeCommand(entity_id: string, command: string) { const options = { ...this.getOptions(), @@ -524,7 +527,7 @@ export class Remote return JSON.parse(res.body); } - async powerRemote(value) + async powerRemote(value: string) { const options = { headers: this.getHeaders(), @@ -539,7 +542,7 @@ export class Remote } - async configureLogStream(data) + async configureLogStream(data: any) { const options = { headers: this.getHeaders(), @@ -570,7 +573,7 @@ export class Remote return JSON.parse(res.body); } - async wakeOnLan(broadcast = null) + async wakeOnLan(broadcast: string|undefined = undefined) { if (!this.mac_address) { console.error("Cannot wakeonlan, no mac address defined"); @@ -583,7 +586,7 @@ export class Remote } } - async getBackup(response) + async getBackup(response: any) { const options = { headers: this.getHeaders(), throwHttpErrors: false}; const url = this.getURL() + `/api/system/backup/export`; diff --git a/server/wakeonlan.ts b/server/wakeonlan.ts new file mode 100644 index 0000000..8aef6ec --- /dev/null +++ b/server/wakeonlan.ts @@ -0,0 +1,79 @@ +'use strict' + +const os = require('os') +const net = require('net') +const dgram = require('dgram') + +let createWOLPacket = (mac:string) => { + mac = mac.replace(/:/g, '') + if (mac.length !== 12 || mac.match(/[^a-fA-F0-9]/)) throw new Error(`Invalid MAC address: ${mac}`) + return new Buffer('ff'.repeat(6) + mac.repeat(16), 'hex') +} + +let getBroadcastAddr = (ip: string, netmask: string) => { + let a = ip.split('.').map(s => parseInt(s, 10)) + let b = netmask.split('.').map(s => parseInt(s, 10)) + let c = [] + for (let i = 0; i < a.length; i++) c.push((a[i] & b[i]) | (b[i] ^ 255)) + return c.join('.') +} + +let sendToAll = (mac: string, opts: any) => { + let promises: Promise[] = [] + let ifaces = os.networkInterfaces(); + for (let p in ifaces) { + ifaces[p].forEach((iface: any) => { + if (iface.internal || !net.isIPv4(iface.address)) return + let ifaceOpts = Object.assign({}, opts) + ifaceOpts.from = iface.address + ifaceOpts.address = getBroadcastAddr(iface.address, iface.netmask) + promises.push(send(mac, ifaceOpts)) + }) + } + return Promise.all(promises) +} + +export function send(mac: string, opts: any = {}) { + if (!opts.from) return sendToAll(mac, opts) + + return new Promise((resolve, reject) => { + try { + let from = opts.from + let port = opts.port || 9 + let count = opts.count || 3 + let address = opts.address || '255.255.255.255' + let interval = opts.interval || 100 + let intervalId:any; + + let pkt = createWOLPacket(mac) + + let done = (err:any) => { + count-- + if (!count || err) { + socket.close() + clearInterval(intervalId) + if (err) return reject(err) + return resolve(true) + } + } + + let doSend = () => { + socket.send(pkt, 0, pkt.length, port, address, done) + } + + let socket = dgram.createSocket(net.isIPv6(address) ? 'udp6' : 'udp4') + socket.unref() + + socket.bind(0, from, (err:any) => { + if (err) return reject(err) + socket.setBroadcast(true) + socket.once('error', done) + doSend() + intervalId = setInterval(doSend, interval) + }) + } catch (err) { + return reject(err) + } + }) +} +