diff --git a/package-lock.json b/package-lock.json index 761138e..76f05e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,13 @@ "version": "0.0.3", "hasInstallScript": true, "dependencies": { - "@apollo/client": "^4.1.6", + "@apollo/client": "^4.2.0", "@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/utils": "^4.0.0", "@sentry/electron": "^7.8.0", "@sentry/vite-plugin": "^5.1.0", "axios": "^1.13.5", - "better-sqlite3": "^12.6.2", - "dayjs": "^1.11.19", + "dayjs": "^1.11.21", "electron-log": "^5.4.3", "electron-updater": "^6.8.3", "pngjs": "^7.0.0", @@ -31,10 +30,10 @@ "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/lodash": "^4.17.24", - "@types/node": "^25.3.0", + "@types/node": "^25.9.1", "@types/node-cron": "^3.0.11", "@types/pngjs": "^6.0.5", - "@types/react": "^19.2.14", + "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", "@types/source-map-support": "^0.5.10", "@types/xml2js": "^0.4.14", @@ -45,7 +44,7 @@ "cors": "^2.8.6", "cross-env": "^10.1.0", "dbffile": "^1.12.0", - "electron": "^40.6.0", + "electron": "^42.2.0", "electron-builder": "^26.8.1", "electron-store": "^11.0.2", "electron-vite": "^5.0.0", @@ -64,7 +63,7 @@ "prettier": "^3.8.1", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-error-boundary": "^6.1.1", + "react-error-boundary": "^6.1.2", "react-i18next": "^16.5.4", "react-redux": "^9.2.0", "react-router": "^7.13.1", @@ -176,9 +175,9 @@ } }, "node_modules/@apollo/client": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-4.1.9.tgz", - "integrity": "sha512-qfpkQD51tdU/7iAR6aLb4w9o/L7I475DluWHRb61U/3Q0AH29nNOxOBHjBbWDdf16ncPOoQuxne1sEs2NjqBFw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-4.2.0.tgz", + "integrity": "sha512-uZAiXwIRidDqQKZRcL88O01IVZjY6IhLio6g+XzX4N4++Ue9pVK9WCoZvBm1dvx+x2mH0oGfVUZvTvacCW4WcQ==", "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", @@ -712,24 +711,57 @@ } }, "node_modules/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-5.0.0.tgz", + "integrity": "sha512-pjoBpru1KdEtcExBnuHAP1cAc/5faoedw0hzJkL3o4/IJp7HNF1+fbrdxT3gMYRX2oJfvnA/WXeCTVQpYYxyJA==", "license": "MIT", "dependencies": { "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", + "env-paths": "^3.0.0", + "graceful-fs": "^4.2.11", "progress": "^2.0.3", - "semver": "^6.2.0", + "semver": "^7.6.3", "sumchecker": "^3.0.1" }, "engines": { - "node": ">=12" + "node": ">=22.12.0" }, "optionalDependencies": { - "global-agent": "^3.0.0" + "undici": "^7.24.4" + } + }, + "node_modules/@electron/get/node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/get/node_modules/undici": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.26.0.tgz", + "integrity": "sha512-3O9Tf67pGhgOv9jM35AbhkXAKi13f3oy3aE4CSgr+TckGeY+/iu97ZXN+J7DpHPzLbVApFd1IFhcnBjREYXYcg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.18.1" } }, "node_modules/@electron/notarize": { @@ -5020,6 +5052,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5046,6 +5079,7 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.0" @@ -5114,6 +5148,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, "license": "MIT", "dependencies": { "@types/http-cache-semantics": "*", @@ -5197,6 +5232,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true, "license": "MIT" }, "node_modules/@types/http-errors": { @@ -5217,6 +5253,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -5246,9 +5283,9 @@ } }, "node_modules/@types/node": { - "version": "25.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.0.tgz", - "integrity": "sha512-AOQwYUNolgy3VosiRqXrACUXTN8nJUtPl7FJXMqZVyxiiCLhQuG3jXKvCS1ALr+Y2OmZhzzLVlYPEqJaiqkaJQ==", + "version": "25.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", + "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", "license": "MIT", "dependencies": { "undici-types": ">=7.24.0 <7.24.7" @@ -5318,9 +5355,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz", + "integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -5341,6 +5378,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -6698,6 +6736,7 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, "funding": [ { "type": "github", @@ -6726,54 +6765,6 @@ "node": ">=6.0.0" } }, - "node_modules/better-sqlite3": { - "version": "12.10.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.10.0.tgz", - "integrity": "sha512-CyzaZRQKyHkB2ZInfTTl2nvT33EbDpjkLEbE8/Zck3Ll6O0qqvuGdrJ45HgtH+HykRg88ITY3AdreBGN70aBSQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bindings": "^1.5.0", - "prebuild-install": "^7.1.1" - }, - "engines": { - "node": "20.x || 22.x || 23.x || 24.x || 25.x || 26.x" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", @@ -6821,6 +6812,7 @@ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, "license": "MIT", "optional": true }, @@ -6873,6 +6865,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -6888,6 +6881,7 @@ } ], "license": "MIT", + "optional": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -7023,6 +7017,7 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10.6.0" @@ -7032,6 +7027,7 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, "license": "MIT", "dependencies": { "clone-response": "^1.0.2", @@ -7234,6 +7230,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^1.0.0" @@ -7626,9 +7623,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.20", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", - "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "version": "1.11.21", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.21.tgz", + "integrity": "sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==", "license": "MIT" }, "node_modules/dbffile": { @@ -7678,6 +7675,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -7693,6 +7691,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -7709,15 +7708,6 @@ "dev": true, "license": "MIT" }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -7729,6 +7719,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -7738,7 +7729,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -7756,7 +7747,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -7789,19 +7780,11 @@ "node": ">= 0.8" } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, "license": "MIT", "optional": true }, @@ -8044,21 +8027,21 @@ } }, "node_modules/electron": { - "version": "40.10.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-40.10.0.tgz", - "integrity": "sha512-e7XVcAfyWoFQGS7ZhgxeNn0AijHaqgRCa6uA6TYOrvBWv8smI6JILvMR/8DYBIn07oqvxDLRC90tu/xa2cJCow==", - "hasInstallScript": true, + "version": "42.2.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-42.2.0.tgz", + "integrity": "sha512-b2Tc7sIKiZEl0tBVwFM5GJ+FT5KYhmy9QJHjx8BGVZPVW2SctXWEvrE959ElB56qw7H05dBkhlikDA1DmpaAMw==", "license": "MIT", "dependencies": { - "@electron/get": "^2.0.0", + "@electron/get": "^5.0.0", "@types/node": "^24.9.0", "extract-zip": "^2.0.1" }, "bin": { - "electron": "cli.js" + "electron": "cli.js", + "install-electron": "install.js" }, "engines": { - "node": ">= 12.20.55" + "node": ">= 22.12.0" } }, "node_modules/electron-builder": { @@ -8401,6 +8384,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -8590,6 +8574,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, "license": "MIT", "optional": true }, @@ -8655,7 +8640,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -9030,15 +9015,6 @@ "bare-events": "^2.7.0" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/exponential-backoff": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", @@ -9226,12 +9202,6 @@ "node": ">=16.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, "node_modules/filelist": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", @@ -9497,26 +9467,6 @@ "node": ">= 0.8" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -9678,12 +9628,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, "node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", @@ -9718,6 +9662,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, "license": "BSD-3-Clause", "optional": true, "dependencies": { @@ -9736,6 +9681,7 @@ "version": "7.8.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, "license": "ISC", "optional": true, "bin": { @@ -9762,7 +9708,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "define-properties": "^1.2.1", @@ -9791,6 +9737,7 @@ "version": "11.8.6", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.0.0", @@ -9882,7 +9829,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -10010,6 +9957,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, "license": "BSD-2-Clause" }, "node_modules/http-errors": { @@ -10058,6 +10006,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", @@ -10166,6 +10115,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, "funding": [ { "type": "github", @@ -10261,12 +10211,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -10835,6 +10780,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -10862,6 +10808,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, "license": "ISC", "optional": true }, @@ -10891,6 +10838,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -10916,6 +10864,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -11067,6 +11016,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11094,6 +11044,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -11192,6 +11143,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -11216,6 +11168,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11257,12 +11210,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, "node_modules/module-details-from-path": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", @@ -11294,12 +11241,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11523,6 +11464,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -11558,7 +11500,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11713,6 +11655,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12085,57 +12028,6 @@ "node": "^12.20.0 || >=14" } }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/node-abi": { - "version": "3.92.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.92.0.tgz", - "integrity": "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/semver": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", - "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -12341,6 +12233,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -12392,30 +12285,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react": { "version": "19.2.6", "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", @@ -12440,9 +12309,9 @@ } }, "node_modules/react-error-boundary": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.1.tgz", - "integrity": "sha512-BrYwPOdXi5mqkk5lw+Uvt0ThHx32rCt3BkukS4X23A2AIWDPSGX6iaWTc0y9TU/mHDA/6qOSGel+B2ERkOvD1w==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.2.tgz", + "integrity": "sha512-3DpCr5HVdZ0caUjYE/kIHBEJN0mNP3ZCgf16c48uJ5TbWjorKVp+YG8W3XqlJ7vJAVNw6wNIImyPXmFydwmyng==", "dev": true, "license": "MIT", "peerDependencies": { @@ -12821,6 +12690,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, "license": "MIT" }, "node_modules/resolve-from": { @@ -12837,6 +12707,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, "license": "MIT", "dependencies": { "lowercase-keys": "^2.0.0" @@ -12931,6 +12802,7 @@ "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, "license": "BSD-3-Clause", "optional": true, "dependencies": { @@ -13048,6 +12920,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -13155,6 +13028,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, "license": "MIT", "optional": true }, @@ -13189,6 +13063,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -13205,6 +13080,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, "license": "(MIT OR CC0-1.0)", "optional": true, "engines": { @@ -13403,51 +13279,6 @@ "dev": true, "license": "ISC" }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -13535,6 +13366,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, "license": "BSD-3-Clause", "optional": true }, @@ -13588,6 +13420,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -13877,54 +13710,6 @@ "node": ">=18" } }, - "node_modules/tar-fs": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, - "node_modules/tar-fs/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar-fs/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tar-stream": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", @@ -14150,18 +13935,6 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14392,6 +14165,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -14468,6 +14242,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, "license": "MIT" }, "node_modules/vary": { diff --git a/package.json b/package.json index de3c4d7..a45e864 100644 --- a/package.json +++ b/package.json @@ -23,14 +23,13 @@ "build:mac": "node deploy/set-artifact-name.js electron-vite build --mode imex && node deploy/set-artifact-name.js electron-builder --mac" }, "dependencies": { - "@apollo/client": "^4.1.6", + "@apollo/client": "^4.2.0", "@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/utils": "^4.0.0", "@sentry/electron": "^7.8.0", "@sentry/vite-plugin": "^5.1.0", "axios": "^1.13.5", - "better-sqlite3": "^12.6.2", - "dayjs": "^1.11.19", + "dayjs": "^1.11.21", "electron-log": "^5.4.3", "electron-updater": "^6.8.3", "pngjs": "^7.0.0", @@ -45,12 +44,12 @@ "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/lodash": "^4.17.24", - "@types/node": "^25.3.0", + "@types/node": "^25.9.1", "@types/node-cron": "^3.0.11", - "@types/react": "^19.2.14", + "@types/pngjs": "^6.0.5", + "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", "@types/source-map-support": "^0.5.10", - "@types/pngjs": "^6.0.5", "@types/xml2js": "^0.4.14", "@vitejs/plugin-react": "^5.1.4", "antd": "^6.3.1", @@ -59,7 +58,7 @@ "cors": "^2.8.6", "cross-env": "^10.1.0", "dbffile": "^1.12.0", - "electron": "^40.6.0", + "electron": "^42.2.0", "electron-builder": "^26.8.1", "electron-store": "^11.0.2", "electron-vite": "^5.0.0", @@ -78,7 +77,7 @@ "prettier": "^3.8.1", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-error-boundary": "^6.1.1", + "react-error-boundary": "^6.1.2", "react-i18next": "^16.5.4", "react-redux": "^9.2.0", "react-router": "^7.13.1", diff --git a/serverless/src/handlers/scrub.ts b/serverless/src/handlers/scrub.ts index 8d3697d..1237691 100644 --- a/serverless/src/handlers/scrub.ts +++ b/serverless/src/handlers/scrub.ts @@ -1,7 +1,7 @@ import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; import axios from 'axios'; import FormData from 'form-data'; -import { gql, GraphQLClient } from 'graphql-request'; +import { GraphQLClient } from 'graphql-request'; import { ESJobObject, RawJobDataObject } from '../../../shared/types'; import { transformJobForEstimateScrubber } from '../lib/transformEstimate'; import { getVehicleType } from '../lib/vehicleTypes/vehicleType'; @@ -22,6 +22,7 @@ interface ScrubResponse { identified_item?: unknown; } +// noinspection JSUnusedGlobalSymbols export const handler = async (event: APIGatewayProxyEvent): Promise => { try { const { @@ -116,7 +117,7 @@ const uploadJobToHasura = async (rawJob: RawJobDataObject, esApiKey: string): Pr }); }; -const LATEST_VERSION_BY_CLM_NO = gql` +const LATEST_VERSION_BY_CLM_NO = ` query LATEST_VERSION_BY_CLM_NO($esApiKey: String!, $clm_no: String!) { jobs( where: { clm_no: { _eq: $clm_no }, shop: { es_api_key: { _eq: $esApiKey } } } @@ -130,7 +131,7 @@ const LATEST_VERSION_BY_CLM_NO = gql` } `; -const INSERT_JOB = gql` +const INSERT_JOB = ` mutation INSERT_JOB($job: jobs_insert_input!) { insert_jobs_one(object: $job) { id diff --git a/serverless/tsconfig.json b/serverless/tsconfig.json index fc508b7..9cb0ab4 100644 --- a/serverless/tsconfig.json +++ b/serverless/tsconfig.json @@ -4,7 +4,7 @@ "module": "commonjs", "lib": ["ES2022"], "moduleResolution": "node", - "rootDir": "./src", + "rootDir": "..", "outDir": "./dist", "strict": true, "esModuleInterop": true, diff --git a/shared/types/raw-job-data.interface.ts b/shared/types/raw-job-data.interface.ts index 4281599..2f6896a 100644 --- a/shared/types/raw-job-data.interface.ts +++ b/shared/types/raw-job-data.interface.ts @@ -228,6 +228,7 @@ export interface RawJobDataObject { vehicleid?: UUID; shopid?: UUID; + version?: number; } export interface JobLine { diff --git a/src/main/db/scrub-history-db.ts b/src/main/db/scrub-history-db.ts index 0777bd9..89de885 100644 --- a/src/main/db/scrub-history-db.ts +++ b/src/main/db/scrub-history-db.ts @@ -1,7 +1,7 @@ import { app } from "electron"; import log from "electron-log/main"; -import Database from "better-sqlite3"; import crypto from "crypto"; +import { DatabaseSync } from "node:sqlite"; import path from "path"; import type { RawJobDataObject } from "../decoder/decoder"; @@ -64,7 +64,7 @@ type IdentifiedItem = { LinkText?: unknown; }; -let db: Database.Database | undefined; +let db: DatabaseSync | undefined; function toNullableString(value: unknown): string | null { if (value === null || value === undefined) return null; @@ -84,15 +84,31 @@ function getDbPath(): string { return path.join(userDataDir, "scrub-history.sqlite3"); } -function getDb(): Database.Database { +function runTransaction(database: DatabaseSync, callback: () => T): T { + database.exec("BEGIN"); + try { + const result = callback(); + database.exec("COMMIT"); + return result; + } catch (error) { + try { + database.exec("ROLLBACK"); + } catch (rollbackError) { + log.error("[scrub-history-db] rollback failed", rollbackError); + } + throw error; + } +} + +function getDb(): DatabaseSync { if (db) return db; const dbPath = getDbPath(); log.info(`[scrub-history-db] opening sqlite db at ${dbPath}`); - db = new Database(dbPath); + db = new DatabaseSync(dbPath); - db.pragma("journal_mode = WAL"); - db.pragma("foreign_keys = ON"); + db.exec("PRAGMA journal_mode = WAL"); + db.exec("PRAGMA foreign_keys = ON"); db.exec(` CREATE TABLE IF NOT EXISTS jobs ( @@ -182,7 +198,7 @@ export function insertScrubRun(params: { ? [params.identifiedItems as IdentifiedItem] : []; - const insertTx = database.transaction(() => { + runTransaction(database, () => { database .prepare( "INSERT INTO jobs (id, created_at, ownr_name, vehicle, claim_number, pdf_url, report_issue_url) VALUES (?, ?, ?, ?, ?, ?, ?)", @@ -194,7 +210,7 @@ export function insertScrubRun(params: { jobRow.vehicle, jobRow.claim_number, jobRow.pdf_url, - jobRow.report_issue_url, + jobRow.report_issue_url ?? null, ); const stmt = database.prepare( @@ -215,7 +231,6 @@ export function insertScrubRun(params: { } }); - insertTx(); return { jobId: jobRow.id, createdAt, insertedResultsCount: items.length }; } @@ -379,24 +394,26 @@ export function deleteScrubHistoryJob(jobId: string): { deletedJobs: number } { const trimmed = jobId.trim(); if (!trimmed) return { deletedJobs: 0 }; - const tx = database.transaction(() => { - const res = database.prepare("DELETE FROM jobs WHERE id = ?").run(trimmed); - return res.changes; - }); - - return { deletedJobs: tx() }; + return { + deletedJobs: runTransaction(database, () => { + const res = database + .prepare("DELETE FROM jobs WHERE id = ?") + .run(trimmed); + return Number(res.changes); + }), + }; } export function clearScrubHistory(): { clearedJobs: number } { const database = getDb(); - const tx = database.transaction(() => { - const countBefore = database - .prepare("SELECT COUNT(1) as c FROM jobs") - .get() as { c: number }; - database.prepare("DELETE FROM jobs").run(); - return countBefore?.c ?? 0; - }); - - return { clearedJobs: tx() }; + return { + clearedJobs: runTransaction(database, () => { + const countBefore = database + .prepare("SELECT COUNT(1) as c FROM jobs") + .get() as { c: number }; + database.prepare("DELETE FROM jobs").run(); + return countBefore?.c ?? 0; + }), + }; } diff --git a/src/main/decoder/decode-lin.ts b/src/main/decoder/decode-lin.ts index cd0443c..6e62f1a 100644 --- a/src/main/decoder/decode-lin.ts +++ b/src/main/decoder/decode-lin.ts @@ -3,7 +3,6 @@ import log from "electron-log/main"; import _ from "lodash"; import deepLowerCaseKeys from "../../util/deepLowercaseKeys"; import errorTypeCheck from "../../util/errorTypeCheck"; -import store from "../store/store"; import { DecodedLin, DecodedLinLine } from "./decode-lin.interface"; import { platform } from "@electron-toolkit/utils"; import { findFileCaseInsensitive } from "./decoder-utils"; @@ -51,7 +50,6 @@ const DecodeLin = async ( //AD2 will always have only 1 row. //Commented lines have been cross referenced with existing partner fields. - const opCodeData = store.get("app.masterdata.opcodes"); //TODO: Type the op codes const rawLinData: DecodedLinLine[] = rawDBFRecord.map((record) => { const singleLineData: DecodedLinLine = deepLowerCaseKeys( diff --git a/src/main/decoder/decode-pfh.ts b/src/main/decoder/decode-pfh.ts index 6b7b356..70513b1 100644 --- a/src/main/decoder/decode-pfh.ts +++ b/src/main/decoder/decode-pfh.ts @@ -4,7 +4,7 @@ import _ from "lodash"; import deepLowerCaseKeys from "../../util/deepLowercaseKeys"; import errorTypeCheck from "../../util/errorTypeCheck"; import { DecodedPfh } from "./decode-pfh.interface"; -import { platform } from "os"; +import { platform } from "@electron-toolkit/utils"; import { findFileCaseInsensitive } from "./decoder-utils"; const DecodePfh = async ( @@ -48,7 +48,7 @@ const DecodePfh = async ( const rawDBFRecord = await dbf.readRecords(1); //AD2 will always have only 1 row. - //Commented lines have been cross referenced with existing partner fields. + //Commented lines have been cross-referenced with existing partner fields. const rawPfhData: DecodedPfh = deepLowerCaseKeys( _.pick(rawDBFRecord[0], [ @@ -76,7 +76,7 @@ const DecodePfh = async ( ]), ); - //Apply business logic transfomrations. + //Apply business logic transformations. //Standardize some of the numbers and divide by 100. diff --git a/src/main/decoder/decoder-utils.ts b/src/main/decoder/decoder-utils.ts index 73bf777..29b84b8 100644 --- a/src/main/decoder/decoder-utils.ts +++ b/src/main/decoder/decoder-utils.ts @@ -37,11 +37,4 @@ const findFileCaseInsensitive = async ( return null; }; -const getFilePathWithoutExtension = (filePath: string): string => { - return path.join( - path.dirname(filePath), - path.basename(filePath, path.extname(filePath)), - ); -}; - export { findFileCaseInsensitive }; diff --git a/src/main/decoder/decoder.ts b/src/main/decoder/decoder.ts index 0628de3..59ccba7 100644 --- a/src/main/decoder/decoder.ts +++ b/src/main/decoder/decoder.ts @@ -1,6 +1,5 @@ import { platform } from "@electron-toolkit/utils"; import { UUID } from "crypto"; -import { Notification, shell } from "electron"; import log from "electron-log/main"; import fs from "fs"; import _ from "lodash"; @@ -38,6 +37,7 @@ import { DecodedVeh } from "./decode-veh.interface"; import UploadEmsToS3 from "./emsbackup"; import getMainWindow from "../../util/getMainWindow"; import newWindow from "../../util/newWindow"; +import { createNotification, showNotification } from "../util/notification"; async function ImportJob(filepath: string): Promise { const parsedFilePath = path.parse(filepath); @@ -151,7 +151,7 @@ async function ImportJob(filepath: string): Promise { }); setAppProgressbar(-1); - const uploadNotification = new Notification({ + const uploadNotification = createNotification({ title: "Job Scrubbed", body: `${newAvailableJob.ownr_name} - ${newAvailableJob.vehicle_info}.`, actions: [ @@ -175,12 +175,10 @@ async function ImportJob(filepath: string): Promise { uploadNotification.show(); } catch (error) { log.error("Error encountered while decoding job. ", errorTypeCheck(error)); - const uploadNotificationFailure = new Notification({ + showNotification({ title: "Job Scrub Failure", body: errorTypeCheck(error).message, //TODO: Remove after debug. }); - - uploadNotificationFailure.show(); } } @@ -203,6 +201,7 @@ export interface RawJobDataObject DecodedPfp { vehicleid?: UUID; shopid: UUID; + source_system?: string | null; } export interface AvailableJobSchema { diff --git a/src/main/decoder/emsbackup.ts b/src/main/decoder/emsbackup.ts index 3c72c1e..4e28ce0 100644 --- a/src/main/decoder/emsbackup.ts +++ b/src/main/decoder/emsbackup.ts @@ -5,8 +5,6 @@ import errorTypeCheck from "../../util/errorTypeCheck"; import fs from "fs"; import path from "path"; import stream from "stream"; -import { getTokenFromRenderer } from "../graphql/graphql-client"; -import store from "../store/store"; async function UploadEmsToS3({ extensionlessFilePath, diff --git a/src/main/estimate-scrubber/es-job-object.interface.ts b/src/main/estimate-scrubber/es-job-object.interface.ts index 8787a59..744ac60 100644 --- a/src/main/estimate-scrubber/es-job-object.interface.ts +++ b/src/main/estimate-scrubber/es-job-object.interface.ts @@ -164,6 +164,7 @@ export interface ESJobObject extends Omit< | "v_model_desc" | "shopid" | "est_system" + | "id_pro_nam" // Object fields | "owner" diff --git a/src/main/estimate-scrubber/estimate-scrubber.ts b/src/main/estimate-scrubber/estimate-scrubber.ts index 69db4a1..cb40b0a 100644 --- a/src/main/estimate-scrubber/estimate-scrubber.ts +++ b/src/main/estimate-scrubber/estimate-scrubber.ts @@ -1,5 +1,4 @@ import axios, { AxiosError } from "axios"; -import { BrowserWindow } from "electron"; import log from "electron-log"; import { autoUpdater } from "electron-updater"; import { promises as fsPromises } from "fs"; @@ -8,8 +7,21 @@ import { RawJobDataObject } from "../decoder/decoder"; import store from "../store/store"; import ipcTypes from "../../util/ipcTypes.json"; import { insertScrubRun } from "../db/scrub-history-db"; -import { Notification } from "electron/main"; import getMainWindow from "../../util/getMainWindow"; +import { showNotification } from "../util/notification"; + +function getErrorMessage(responseMessage: string | undefined): string | null { + if (!responseMessage) { + return null; + } + + try { + const parsedResponse = JSON.parse(responseMessage) as { message?: string }; + return parsedResponse.message ?? null; + } catch { + return responseMessage; + } +} // Function to write job object to logs subfolder async function writeJobToLogsFolder(job, fileName): Promise { @@ -75,13 +87,11 @@ async function ScrubEstimate({ const esApiKey = store.get("settings.esApiKey") as string; if (!esApiKey || esApiKey.trim() === "") { - const notificationError = new Notification({ + showNotification({ title: "No API Key Set", body: "You must have a valid and active API key set in order to scrub estimates.", }); - notificationError.show(); - mainWindow?.webContents.send(ipcTypes.toRenderer.scrub.scrubError, { message: "You must have a valid and active API key set in order to scrub estimates.", @@ -127,7 +137,6 @@ async function ScrubEstimate({ report_issue_url: typeof report_issue_url === "string" ? report_issue_url : null, }); - const mainWindow = BrowserWindow.getAllWindows()[0]; if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.webContents.send(ipcTypes.toRenderer.scrub.historyUpdated); } @@ -158,27 +167,24 @@ async function ScrubEstimate({ : responseData ? JSON.stringify(responseData) : undefined; + const scrubErrorMessage = getErrorMessage(responseMessage); if (status === 400) { mainWindow?.webContents.send(ipcTypes.toRenderer.scrub.scrubError, { message: - JSON.parse(responseMessage).message || + scrubErrorMessage || "Error encountered sending estimate to Estimate Scrubber.", }); } else if (status === 401) { - const notificationError = new Notification({ + showNotification({ title: "Error scrubbing estimate", body: - JSON.parse(responseMessage).message || - "Authentication with Estimate Scrubber failed.", + scrubErrorMessage || "Authentication with Estimate Scrubber failed.", }); - notificationError.show(); - mainWindow?.webContents.send(ipcTypes.toRenderer.scrub.scrubError, { message: - JSON.parse(responseMessage).message || - "Authentication with Estimate Scrubber failed.", + scrubErrorMessage || "Authentication with Estimate Scrubber failed.", }); } return "Error: Unable to scrub estimate."; diff --git a/src/main/graphql/graphql-client.ts b/src/main/graphql/graphql-client.ts index 0dba4b5..cdc15aa 100644 --- a/src/main/graphql/graphql-client.ts +++ b/src/main/graphql/graphql-client.ts @@ -1,4 +1,4 @@ -import { BrowserWindow, ipcMain } from "electron"; +import { ipcMain } from "electron"; import log from "electron-log/main"; import { GraphQLClient, RequestMiddleware } from "graphql-request"; import errorTypeCheck from "../../util/errorTypeCheck.js"; diff --git a/src/main/index.test.ts b/src/main/index.test.ts index f80e836..b359bcf 100644 --- a/src/main/index.test.ts +++ b/src/main/index.test.ts @@ -13,7 +13,7 @@ test("Basic Electron app compilation.", async () => { // Wait for the first BrowserWindow to open // and return its Page object - const window = await electronApp.firstWindow(); + await electronApp.firstWindow(); // close app await electronApp.close(); }); diff --git a/src/main/index.ts b/src/main/index.ts index 548f0c8..eea7aba 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,5 +1,5 @@ import { is, optimizer, platform } from "@electron-toolkit/utils"; -import Sentry from "@sentry/electron/main"; +import * as Sentry from "@sentry/electron/main"; import { app, BrowserWindow, @@ -105,7 +105,7 @@ function createWindow(): void { }, }); - const template: Electron.MenuItemConstructorOptions[] = [ + const template = [ // { role: 'appMenu' } // @ts-ignore ...(isMac @@ -387,7 +387,7 @@ function createWindow(): void { : [{ role: "close" }]), ], }, - ]; + ] as Electron.MenuItemConstructorOptions[]; const menu: Electron.Menu = Menu.buildFromTemplate(template); Menu.setApplicationMenu(menu); diff --git a/src/main/ipc/ipcMainConfig.ts b/src/main/ipc/ipcMainConfig.ts index 62a618a..1084fbe 100644 --- a/src/main/ipc/ipcMainConfig.ts +++ b/src/main/ipc/ipcMainConfig.ts @@ -27,10 +27,15 @@ import newWindow from "../../util/newWindow"; const logIpcMessages = (): void => { Object.keys(ipcTypes.toMain).forEach((key) => { const messageType = ipcTypes.toMain[key]; - const originalHandler = ipcMain.listeners(messageType)?.[0]; - if (originalHandler) { + if (typeof messageType !== "string") { + return; + } + + const originalHandlers = ipcMain.listeners(messageType); + if (originalHandlers.length > 0) { ipcMain.removeAllListeners(messageType); } + ipcMain.on(messageType, (event, payload) => { log.info( `%c[IPC Main]%c${messageType}`, @@ -38,9 +43,7 @@ const logIpcMessages = (): void => { "color: green", payload, ); - if (originalHandler) { - originalHandler(event, payload); - } + originalHandlers.forEach((handler) => handler(event, payload)); }); }); }; @@ -102,7 +105,7 @@ ipcMain.on(ipcTypes.toMain.updates.download, () => { }); }); -ipcMain.on(ipcTypes.toMain.openExternal, async (event, url: string) => { +ipcMain.on(ipcTypes.toMain.openExternal, async (_event, url: string) => { newWindow(url); }); diff --git a/src/main/util/notification.ts b/src/main/util/notification.ts new file mode 100644 index 0000000..d5dbda8 --- /dev/null +++ b/src/main/util/notification.ts @@ -0,0 +1,26 @@ +import { Notification, type NotificationConstructorOptions } from "electron"; +import log from "electron-log/main"; + +function createNotification( + options: NotificationConstructorOptions, + context = options.title, +): Notification { + const notification = new Notification(options); + + notification.on("failed", (_event, error) => { + log.warn(`Notification failed${context ? ` (${context})` : ""}:`, error); + }); + + return notification; +} + +function showNotification( + options: NotificationConstructorOptions, + context?: string, +): Notification { + const notification = createNotification(options, context); + notification.show(); + return notification; +} + +export { createNotification, showNotification }; diff --git a/src/main/watcher/watcher.ts b/src/main/watcher/watcher.ts index 6f2e1e0..ff46a63 100644 --- a/src/main/watcher/watcher.ts +++ b/src/main/watcher/watcher.ts @@ -1,5 +1,4 @@ import chokidar, { FSWatcher } from "chokidar"; -import { Notification } from "electron"; import log from "electron-log/main"; import fs from "fs"; import path from "path"; @@ -8,6 +7,7 @@ import ipcTypes from "../../util/ipcTypes.json"; import ImportJob from "../decoder/decoder"; import store from "../store/store"; import getMainWindow from "../../util/getMainWindow"; +import { showNotification } from "../util/notification"; import { setWatcherTrayStatus } from "../util/trayStatus"; let watcher: FSWatcher | null; let watcherReady = false; @@ -36,11 +36,11 @@ async function StartWatcher( if (filePaths.length === 0) { if (notifyOnNoPaths) { - new Notification({ + showNotification({ //TODO: Add Translations title: "Watcher cannot start", body: "Please set the appropriate file paths and try again.", - }).show(); + }); } log.warn("Cannot start watcher. No valid file paths set.", { configuredFilePaths, @@ -139,10 +139,10 @@ function onWatcherReady(): void { if (watcher) { const mainWindow = getMainWindow(); watcherReady = true; - new Notification({ + showNotification({ title: "Watcher Started", body: "Newly exported estimates will be automatically uploaded.", - }).show(); + }); log.info("Confirmed watched paths:", watcher.getWatched()); setWatcherTrayStatus(true); mainWindow?.webContents.send(ipcTypes.toRenderer.watcher.started); @@ -160,10 +160,10 @@ async function StopWatcher(): Promise { setWatcherTrayStatus(false); mainWindow?.webContents.send(ipcTypes.toRenderer.watcher.stopped); - new Notification({ + showNotification({ title: "Watcher Stopped", body: "Estimates will not be automatically uploaded.", - }).show(); + }); return true; } return false; diff --git a/src/renderer/src/redux/app.slice.ts b/src/renderer/src/redux/app.slice.ts index 806c8e8..4578856 100644 --- a/src/renderer/src/redux/app.slice.ts +++ b/src/renderer/src/redux/app.slice.ts @@ -2,7 +2,7 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import log from "electron-log/renderer"; import type { RootState } from "./redux-store"; -interface AppState { +export interface AppState { value: number; watcher: { started: boolean; diff --git a/src/renderer/src/redux/reduxHooks.ts b/src/renderer/src/redux/reduxHooks.ts index 6834500..1c741af 100644 --- a/src/renderer/src/redux/reduxHooks.ts +++ b/src/renderer/src/redux/reduxHooks.ts @@ -1,10 +1,8 @@ import type { TypedUseSelectorHook } from "react-redux"; import { useDispatch, useSelector, useStore } from "react-redux"; import type { AppDispatch, AppStore, RootState } from "./redux-store"; -import store from "./redux-store"; //Use these custom hooks to access the Redux store from your component with type safety. -export type AppDispatch = typeof store.dispatch; export const useAppDispatch = useDispatch.withTypes(); // Ex export const useAppSelector: TypedUseSelectorHook = useSelector; export const useAppStore: () => AppStore = useStore; diff --git a/src/renderer/src/util/countdownHook.ts b/src/renderer/src/util/countdownHook.ts index 61b2d28..9bd7aec 100644 --- a/src/renderer/src/util/countdownHook.ts +++ b/src/renderer/src/util/countdownHook.ts @@ -39,7 +39,10 @@ const useCountDown = ( interval, timer.current.timeLeft || Infinity, ); - if (timer.current.lastInterval && ts - timer.current.lastInterval >= localInterval) { + if ( + timer.current.lastInterval && + ts - timer.current.lastInterval >= localInterval + ) { timer.current.lastInterval += localInterval; setTimeLeft((timeLeft) => { timer.current.timeLeft = timeLeft - localInterval; diff --git a/src/renderer/src/util/graphql.client.ts b/src/renderer/src/util/graphql.client.ts index 939baa0..b04c928 100644 --- a/src/renderer/src/util/graphql.client.ts +++ b/src/renderer/src/util/graphql.client.ts @@ -9,9 +9,9 @@ import { // uri: import.meta.env.VITE_GRAPHQL_URL, // }); -const middlewares = []; +const middlewares: ApolloLink[] = []; -const client: ApolloClient = new ApolloClient({ +const client: ApolloClient = new ApolloClient({ link: ApolloLink.from(middlewares), cache: new InMemoryCache(), defaultOptions: { @@ -21,9 +21,6 @@ const client: ApolloClient = new ApolloClient({ query: { fetchPolicy: "network-only", }, - mutate: { - errorPolicy: "none", - }, }, });