diff --git a/.gitignore b/.gitignore
index 997dff9c5..74015c392 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
.idea
.vscode
-.VSCodeCounter
\ No newline at end of file
+.VSCodeCounter
+*.sh
+mongo
diff --git a/client/.gitignore b/client/.gitignore
index 83f6fe9ed..23b6e49af 100644
--- a/client/.gitignore
+++ b/client/.gitignore
@@ -28,4 +28,5 @@ dist-ssr
# Scripts
*.sh
-!env.sh
\ No newline at end of file
+!env.sh
+.env.development
\ No newline at end of file
diff --git a/client/package-lock.json b/client/package-lock.json
index 7cf0e8631..e917619ae 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -97,6 +97,7 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz",
"integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1",
@@ -408,6 +409,7 @@
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -451,6 +453,7 @@
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz",
"integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -496,6 +499,262 @@
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
+ "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
+ "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
+ "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
+ "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
+ "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
+ "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
+ "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
+ "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
+ "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
+ "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
+ "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
+ "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
+ "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
+ "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
+ "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@esbuild/linux-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
@@ -512,6 +771,134 @@
"node": ">=18"
}
},
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
+ "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
+ "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
+ "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
+ "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
+ "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
+ "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
@@ -989,6 +1376,7 @@
"resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.11.tgz",
"integrity": "sha512-k2D3FLJS+/qD0qnd6ZlAjGFvaaxe1Dl10NyvpeDzIebMuYdn8VqYe6XBgGueEAtnzSJM4V03VD9kb5Fi24dnTA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.26.0",
"@mui/core-downloads-tracker": "^6.4.11",
@@ -1153,7 +1541,6 @@
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.1.0.tgz",
"integrity": "sha512-4Kck4jxhqF6YxNwJdSae1WgDfXVg0lIH6JVJ7gtuFfuKcQCgomJxPvUEOySTFRPz1IZzwz5OAcToskRdffElDA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1",
"@mui/utils": "^7.1.0",
@@ -1181,7 +1568,6 @@
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.0.tgz",
"integrity": "sha512-/OM3S8kSHHmWNOP+NH9xEtpYSG10upXeQ0wLZnfDgmgadTAk5F4MQfFLyZ5FCRJENB3eRzltMmaNl6UtDnPovw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1",
"@mui/types": "^7.4.2",
@@ -1212,7 +1598,6 @@
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.1.0.tgz",
"integrity": "sha512-m0mJ0c6iRC+f9hMeRe0W7zZX1wme3oUX0+XTVHjPG7DJz6OdQ6K/ggEOq7ZdwilcpdsDUwwMfOmvO71qDkYd2w==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1",
"@emotion/cache": "^11.13.5",
@@ -1288,7 +1673,6 @@
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.1.0.tgz",
"integrity": "sha512-/OM3S8kSHHmWNOP+NH9xEtpYSG10upXeQ0wLZnfDgmgadTAk5F4MQfFLyZ5FCRJENB3eRzltMmaNl6UtDnPovw==",
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.1",
"@mui/types": "^7.4.2",
@@ -1696,6 +2080,123 @@
}
}
},
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.0.tgz",
+ "integrity": "sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.0.tgz",
+ "integrity": "sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.0.tgz",
+ "integrity": "sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.0.tgz",
+ "integrity": "sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.0.tgz",
+ "integrity": "sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.0.tgz",
+ "integrity": "sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.0.tgz",
+ "integrity": "sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.0.tgz",
+ "integrity": "sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.0.tgz",
+ "integrity": "sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.41.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.0.tgz",
@@ -1709,6 +2210,71 @@
"linux"
]
},
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.0.tgz",
+ "integrity": "sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.0.tgz",
+ "integrity": "sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.0.tgz",
+ "integrity": "sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.0.tgz",
+ "integrity": "sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.0.tgz",
+ "integrity": "sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.41.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.0.tgz",
@@ -1735,6 +2301,45 @@
"linux"
]
},
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.0.tgz",
+ "integrity": "sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.0.tgz",
+ "integrity": "sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.0.tgz",
+ "integrity": "sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
@@ -2133,6 +2738,7 @@
"integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~7.12.0"
}
@@ -2154,6 +2760,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.22.tgz",
"integrity": "sha512-vUhG0YmQZ7kL/tmKLrD3g5zXbXXreZXB3pmROW8bg3CnLnpjkRVwUlLne7Ufa2r9yJ8+/6B73RzhAek5TBKh2Q==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
@@ -2217,6 +2824,7 @@
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2523,6 +3131,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001716",
"electron-to-chromium": "^1.5.149",
@@ -2935,7 +3544,8 @@
"version": "1.11.13",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/debug": {
"version": "4.4.1",
@@ -3342,6 +3952,7 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -4149,6 +4760,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.27.6"
},
@@ -5416,6 +6028,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -5429,6 +6042,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.63.0.tgz",
"integrity": "sha512-ZwueDMvUeucovM2VjkCf7zIHcs1aAlDimZu2Hvel5C5907gUzMpm4xCrQXtRzCvsBqFjonB4m3x4LzCFI1ZKWA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -5632,7 +6246,8 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/redux-persist": {
"version": "6.0.0",
@@ -5770,6 +6385,7 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.0.tgz",
"integrity": "sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/estree": "1.0.7"
},
@@ -6405,6 +7021,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -6524,6 +7141,7 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz",
"integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
@@ -6744,20 +7362,6 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"license": "ISC"
},
- "node_modules/yaml": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
- "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
- "license": "ISC",
- "optional": true,
- "peer": true,
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- }
- },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/client/src/Components/v1/ActionsMenu/index.jsx b/client/src/Components/v1/ActionsMenu/index.jsx
index 229c7c875..5cd0dfa5b 100644
--- a/client/src/Components/v1/ActionsMenu/index.jsx
+++ b/client/src/Components/v1/ActionsMenu/index.jsx
@@ -12,7 +12,7 @@ import { useNavigate } from "react-router-dom";
import { createToast } from "../../../Utils/toastUtils.jsx";
import PropTypes from "prop-types";
-import { usePauseMonitor, useDeleteMonitor } from "../../../Hooks/v1/monitorHooks.js";
+import { usePauseMonitor, useDeleteMonitor } from "../../../Hooks/monitorHooks.js";
const ActionsMenu = ({
monitor,
@@ -31,7 +31,8 @@ const ActionsMenu = ({
const handleRemove = async (event) => {
event.preventDefault();
event.stopPropagation();
- let monitor = { _id: actions.id };
+ let monitor = { id: actions.id };
+ console.log(monitor);
await deleteMonitor({ monitor });
updateRowCallback();
};
@@ -39,7 +40,7 @@ const ActionsMenu = ({
const handlePause = async () => {
try {
setIsLoading(true);
- await pauseMonitor({ monitorId: monitor._id });
+ await pauseMonitor({ monitorId: monitor.id });
pauseCallback();
} catch (error) {
createToast({ body: "Failed to pause monitor." });
@@ -72,7 +73,7 @@ const ActionsMenu = ({
aria-label="monitor actions"
onClick={(event) => {
event.stopPropagation();
- openMenu(event, monitor._id, monitor.type === "ping" ? null : monitor.url);
+ openMenu(event, monitor.id, monitor.type === "ping" ? null : monitor.url);
}}
sx={{
"&:focus": {
@@ -197,6 +198,7 @@ const ActionsMenu = ({
confirmationButtonLabel="Delete"
/* Do we need stop propagation? */
onConfirm={(e) => {
+ console.log(e);
e.stopPropagation();
handleRemove(e);
}}
@@ -210,7 +212,7 @@ const ActionsMenu = ({
ActionsMenu.propTypes = {
monitor: PropTypes.shape({
- _id: PropTypes.string,
+ id: PropTypes.string,
url: PropTypes.string,
type: PropTypes.string,
isActive: PropTypes.bool,
diff --git a/client/src/Components/v1/Charts/BarChart/index.jsx b/client/src/Components/v1/Charts/BarChart/index.jsx
index 2bf8e1798..9f0ed8aa6 100644
--- a/client/src/Components/v1/Charts/BarChart/index.jsx
+++ b/client/src/Components/v1/Charts/BarChart/index.jsx
@@ -103,7 +103,7 @@ const BarChart = ({ checks = [] }) => {
>
}
placement="top"
- key={`check-${check?._id}`}
+ key={`check-${check?.id}`}
slotProps={{
popper: {
className: "bar-tooltip",
@@ -145,7 +145,7 @@ const BarChart = ({ checks = [] }) => {
position="relative"
width="9px"
height="100%"
- backgroundColor={theme.palette.primary.lowContrast} // CAIO_REVIEW
+ backgroundColor={theme.palette.primary.lowContrast}
sx={{
borderRadius: theme.spacing(1.5),
/*
diff --git a/client/src/Components/v1/Inputs/Search/index.jsx b/client/src/Components/v1/Inputs/Search/index.jsx
index 7a3771d47..8138ee6f4 100644
--- a/client/src/Components/v1/Inputs/Search/index.jsx
+++ b/client/src/Components/v1/Inputs/Search/index.jsx
@@ -85,7 +85,12 @@ const Search = ({
const enhancedOptions = React.useMemo(() => {
return multiple && isAdorned
? [
- { [filteredBy]: t("selectAll"), isSelectAll: true, _id: "select_all" },
+ {
+ [filteredBy]: t("selectAll"),
+ isSelectAll: true,
+ _id: "select_all",
+ id: "select_all",
+ },
...options,
]
: options;
@@ -93,7 +98,7 @@ const Search = ({
const isOptionSelected = (option) => {
if (!multiple && !isAdorned) return false;
if (Array.isArray(value)) {
- return value.some((item) => item._id === option._id);
+ return value.some((item) => (item._id ?? item.id) === (option._id ?? option.id));
}
return false;
};
@@ -145,7 +150,9 @@ const Search = ({
disableClearable
options={enhancedOptions}
getOptionLabel={(option) => option[filteredBy]}
- isOptionEqualToValue={(option, value) => option._id === value._id} // Compare by unique identifier
+ isOptionEqualToValue={(option, value) =>
+ (option._id ?? option.id) === (value?._id ?? value?.id)
+ } // Compare by unique identifier
renderInput={(params) => (
{
- return option._id;
+ return option._id ?? option.id;
}}
renderOption={(props, option) => {
const { key, ...optionProps } = props;
diff --git a/client/src/Components/v1/Inputs/Select/index.jsx b/client/src/Components/v1/Inputs/Select/index.jsx
index 37ce30dc1..f952b6818 100644
--- a/client/src/Components/v1/Inputs/Select/index.jsx
+++ b/client/src/Components/v1/Inputs/Select/index.jsx
@@ -62,6 +62,7 @@ const Select = ({
fieldWrapperSx = {},
}) => {
const theme = useTheme();
+ const getItemValue = (item) => item?._id ?? item?.id;
const itemStyles = {
fontSize: "var(--env-var-font-size-medium)",
color: theme.palette.primary.contrastTextTertiary,
@@ -123,7 +124,7 @@ const Select = ({
...sx,
}}
renderValue={(selected) => {
- const selectedItem = items.find((item) => item._id === selected);
+ const selectedItem = items.find((item) => getItemValue(item) === selected);
const displayName = selectedItem ? selectedItem.name : placeholder;
return (
)}
- {items.map((item) => (
-
- ))}
+ {items
+ .map((item) => {
+ const itemValue = getItemValue(item);
+ if (itemValue === undefined || itemValue === null) {
+ return null;
+ }
+ return (
+
+ );
+ })
+ .filter(Boolean)}
);
@@ -179,8 +188,8 @@ Select.propTypes = {
.isRequired,
items: PropTypes.arrayOf(
PropTypes.shape({
- _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool])
- .isRequired,
+ _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
+ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
name: PropTypes.string.isRequired,
})
diff --git a/client/src/Components/v1/MonitorActions/index.jsx b/client/src/Components/v1/MonitorActions/index.jsx
index 23cebc972..624d34b9a 100644
--- a/client/src/Components/v1/MonitorActions/index.jsx
+++ b/client/src/Components/v1/MonitorActions/index.jsx
@@ -11,7 +11,7 @@ import MenuList from "@mui/material/MenuList";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { createToast } from "../../../Utils/toastUtils.jsx";
-import { useExportMonitors } from "../../../Hooks/v1/monitorHooks.js";
+import { useExportMonitors } from "../../../Hooks/monitorHooks.js";
const MonitorActions = ({ isLoading }) => {
const [open, setOpen] = React.useState(false);
diff --git a/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx b/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx
index ae565f3bb..bb4399b85 100644
--- a/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx
+++ b/client/src/Components/v1/MonitorDetailsControlHeader/index.jsx
@@ -12,10 +12,10 @@ import EmailIcon from "@mui/icons-material/Email";
import PropTypes from "prop-types";
import { useNavigate } from "react-router-dom";
import { useTheme } from "@mui/material/styles";
-import { usePauseMonitor } from "../../../Hooks/v1/monitorHooks.js";
-import { useSendTestEmail } from "../../../Hooks/v1/useSendTestEmail.js";
+import { usePauseMonitor } from "../../../Hooks/monitorHooks.js";
+import { useSendTestEmail } from "../../../Hooks/useSendTestEmail.js";
import { useTranslation } from "react-i18next";
-import { useTestAllNotifications } from "../../../Hooks/v1/useNotifications.js";
+import { useTestAllNotifications } from "../../../Hooks/useNotifications.js";
/**
* MonitorDetailsControlHeader component displays the control header for monitor details.
* It includes status display, pause/resume button, and a configure button for admins.
diff --git a/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx b/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx
index d9b7afc40..febf449d4 100644
--- a/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx
+++ b/client/src/Components/v1/MonitorDetailsControlHeader/status.jsx
@@ -7,7 +7,7 @@ import Dot from "../Dot/index.jsx";
import { formatDurationRounded } from "../../../Utils/timeUtils.js";
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
-import { useMonitorUtils } from "../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../Hooks/useMonitorUtils.js";
import { formatMonitorUrl } from "../../../Utils/utils.js";
/**
* Status component displays the status information of a monitor.
diff --git a/client/src/Components/v1/PageStateWrapper/index.jsx b/client/src/Components/v1/PageStateWrapper/index.jsx
index ac97704df..08adbe514 100644
--- a/client/src/Components/v1/PageStateWrapper/index.jsx
+++ b/client/src/Components/v1/PageStateWrapper/index.jsx
@@ -3,7 +3,7 @@ import Fallback from "../Fallback/index.jsx";
import { Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
-import { useIsAdmin } from "../../../Hooks/v1/useIsAdmin.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
import PropTypes from "prop-types";
const PageStateWrapper = ({
networkError,
diff --git a/client/src/Components/v1/StatBox/index.jsx b/client/src/Components/v1/StatBox/index.jsx
index 1b5f1cf6f..e72f947b3 100644
--- a/client/src/Components/v1/StatBox/index.jsx
+++ b/client/src/Components/v1/StatBox/index.jsx
@@ -2,7 +2,7 @@ import { Stack, Typography } from "@mui/material";
import Image from "../Image/index.jsx";
import { useTheme } from "@mui/material/styles";
import PropTypes from "prop-types";
-import { useMonitorUtils } from "../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../Hooks/useMonitorUtils.js";
/**
* StatBox Component
diff --git a/client/src/Hooks/v1/checkHooks.js b/client/src/Hooks/checkHooks.js
similarity index 97%
rename from client/src/Hooks/v1/checkHooks.js
rename to client/src/Hooks/checkHooks.js
index 96fd1fe1c..b8af32073 100644
--- a/client/src/Hooks/v1/checkHooks.js
+++ b/client/src/Hooks/checkHooks.js
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
-import { networkService } from "../../main.jsx";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { networkService } from "../main.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
const useFetchChecksTeam = ({
diff --git a/client/src/Hooks/v1/inviteHooks.js b/client/src/Hooks/inviteHooks.js
similarity index 97%
rename from client/src/Hooks/v1/inviteHooks.js
rename to client/src/Hooks/inviteHooks.js
index b6a0851af..c862eec31 100644
--- a/client/src/Hooks/v1/inviteHooks.js
+++ b/client/src/Hooks/inviteHooks.js
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { networkService } from "../../main.jsx";
+import { networkService } from "../main.jsx";
import { useTranslation } from "react-i18next";
const CLIENT_HOST = import.meta.env.VITE_APP_CLIENT_HOST;
diff --git a/client/src/Hooks/v1/logHooks.js b/client/src/Hooks/logHooks.js
similarity index 96%
rename from client/src/Hooks/v1/logHooks.js
rename to client/src/Hooks/logHooks.js
index ff4d13872..d5162de5a 100644
--- a/client/src/Hooks/v1/logHooks.js
+++ b/client/src/Hooks/logHooks.js
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
-import { networkService } from "../../main.jsx";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { networkService } from "../main.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
const useFetchLogs = () => {
diff --git a/client/src/Hooks/v1/monitorHooks.js b/client/src/Hooks/monitorHooks.js
similarity index 85%
rename from client/src/Hooks/v1/monitorHooks.js
rename to client/src/Hooks/monitorHooks.js
index 8acbea608..bc391ebf6 100644
--- a/client/src/Hooks/v1/monitorHooks.js
+++ b/client/src/Hooks/monitorHooks.js
@@ -1,12 +1,12 @@
import { useEffect, useState } from "react";
-import { networkService } from "../../main.jsx";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { networkService } from "../main.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
import { useTheme } from "@emotion/react";
import { useMonitorUtils } from "./useMonitorUtils.js";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
-const useFetchMonitorsWithSummary = ({ types, monitorUpdateTrigger }) => {
+export const useFetchMonitorsWithSummary = ({ types, monitorUpdateTrigger }) => {
const [isLoading, setIsLoading] = useState(false);
const [monitors, setMonitors] = useState(undefined);
const [monitorsSummary, setMonitorsSummary] = useState(undefined);
@@ -37,7 +37,7 @@ const useFetchMonitorsWithSummary = ({ types, monitorUpdateTrigger }) => {
return [monitors, monitorsSummary, isLoading, networkError];
};
-const useFetchMonitorsWithChecks = ({
+export const useFetchMonitorsWithChecks = ({
types,
limit,
page,
@@ -67,12 +67,13 @@ const useFetchMonitorsWithChecks = ({
field,
order,
});
+
const { count, monitors } = res?.data?.data ?? {};
const mappedMonitors = monitors.map((monitor) =>
getMonitorWithPercentage(monitor, theme)
);
setMonitors(mappedMonitors);
- setCount(count?.monitorsCount ?? 0);
+ setCount(count || 0);
} catch (error) {
console.error(error);
setNetworkError(true);
@@ -99,22 +100,9 @@ const useFetchMonitorsWithChecks = ({
return [monitors, count, isLoading, networkError];
};
-const useFetchMonitorsByTeamId = ({
- types,
- limit,
- page,
- rowsPerPage,
- filter,
- field,
- order,
- checkOrder,
- normalize,
- status,
- updateTrigger,
-}) => {
+export const useFetchMonitorsByTeamId = ({ types, filter, updateTrigger }) => {
const [isLoading, setIsLoading] = useState(false);
const [monitors, setMonitors] = useState(undefined);
- const [summary, setSummary] = useState(undefined);
const [networkError, setNetworkError] = useState(false);
useEffect(() => {
@@ -122,20 +110,11 @@ const useFetchMonitorsByTeamId = ({
try {
setIsLoading(true);
const res = await networkService.getMonitorsByTeamId({
- limit,
types,
- page,
- rowsPerPage,
filter,
- field,
- order,
- checkOrder,
- status,
- normalize,
});
- if (res?.data?.data?.filteredMonitors) {
- setMonitors(res.data.data.filteredMonitors);
- setSummary(res.data.data.summary);
+ if (res?.data?.data) {
+ setMonitors(res.data.data);
}
} catch (error) {
setNetworkError(true);
@@ -147,23 +126,11 @@ const useFetchMonitorsByTeamId = ({
}
};
fetchMonitors();
- }, [
- types,
- limit,
- page,
- rowsPerPage,
- filter,
- field,
- order,
- updateTrigger,
- checkOrder,
- normalize,
- status,
- ]);
- return [monitors, summary, isLoading, networkError];
+ }, [types, filter, updateTrigger]);
+ return [monitors, isLoading, networkError];
};
-const useFetchStatsByMonitorId = ({
+export const useFetchStatsByMonitorId = ({
monitorId,
sortOrder,
limit,
@@ -202,7 +169,7 @@ const useFetchStatsByMonitorId = ({
return [monitor, audits, isLoading, networkError];
};
-const useFetchMonitorGames = ({ setGames, updateTrigger }) => {
+export const useFetchMonitorGames = ({ setGames, updateTrigger }) => {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchGames = async () => {
@@ -221,7 +188,7 @@ const useFetchMonitorGames = ({ setGames, updateTrigger }) => {
return [isLoading];
};
-const useFetchMonitorById = ({ monitorId, setMonitor, updateTrigger }) => {
+export const useFetchMonitorById = ({ monitorId, setMonitor, updateTrigger }) => {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
if (typeof monitorId === "undefined") {
@@ -244,7 +211,7 @@ const useFetchMonitorById = ({ monitorId, setMonitor, updateTrigger }) => {
return [isLoading];
};
-const useFetchHardwareMonitorById = ({ monitorId, dateRange, updateTrigger }) => {
+export const useFetchHardwareMonitorById = ({ monitorId, dateRange, updateTrigger }) => {
const [isLoading, setIsLoading] = useState(true);
const [networkError, setNetworkError] = useState(false);
const [monitor, setMonitor] = useState(undefined);
@@ -270,8 +237,34 @@ const useFetchHardwareMonitorById = ({ monitorId, dateRange, updateTrigger }) =>
}, [monitorId, dateRange, updateTrigger]);
return [monitor, isLoading, networkError];
};
+export const useFetchPageSpeedMonitorById = ({ monitorId, dateRange, updateTrigger }) => {
+ const [isLoading, setIsLoading] = useState(true);
+ const [networkError, setNetworkError] = useState(false);
+ const [monitor, setMonitor] = useState(undefined);
-const useFetchUptimeMonitorById = ({ monitorId, dateRange, trigger }) => {
+ useEffect(() => {
+ const fetchMonitor = async () => {
+ try {
+ if (!monitorId) {
+ return { monitor: undefined, isLoading: false, networkError: undefined };
+ }
+ const response = await networkService.getPageSpeedDetailsByMonitorId({
+ monitorId: monitorId,
+ dateRange: dateRange,
+ });
+ setMonitor(response.data.data);
+ } catch (error) {
+ setNetworkError(true);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+ fetchMonitor();
+ }, [monitorId, dateRange, updateTrigger]);
+ return [monitor, isLoading, networkError];
+};
+
+export const useFetchUptimeMonitorById = ({ monitorId, dateRange, trigger }) => {
const [networkError, setNetworkError] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [monitor, setMonitor] = useState(undefined);
@@ -299,7 +292,7 @@ const useFetchUptimeMonitorById = ({ monitorId, dateRange, trigger }) => {
return [monitor, monitorStats, isLoading, networkError];
};
-const useCreateMonitor = () => {
+export const useCreateMonitor = () => {
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const createMonitor = async ({ monitor, redirect }) => {
@@ -319,7 +312,7 @@ const useCreateMonitor = () => {
return [createMonitor, isLoading];
};
-const useFetchGlobalSettings = () => {
+export const useFetchGlobalSettings = () => {
const [isLoading, setIsLoading] = useState(true);
const [globalSettings, setGlobalSettings] = useState(undefined);
useEffect(() => {
@@ -341,13 +334,14 @@ const useFetchGlobalSettings = () => {
return [globalSettings, isLoading];
};
-const useDeleteMonitor = () => {
+export const useDeleteMonitor = () => {
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const deleteMonitor = async ({ monitor, redirect }) => {
try {
setIsLoading(true);
- await networkService.deleteMonitorById({ monitorId: monitor._id });
+ console.log(monitor);
+ await networkService.deleteMonitorById({ monitorId: monitor.id });
createToast({ body: "Monitor deleted successfully!" });
if (redirect) {
navigate(redirect);
@@ -361,7 +355,7 @@ const useDeleteMonitor = () => {
return [deleteMonitor, isLoading];
};
-const useUpdateMonitor = () => {
+export const useUpdateMonitor = () => {
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const updateMonitor = async ({ monitor, redirect }) => {
@@ -408,7 +402,7 @@ const useUpdateMonitor = () => {
return [updateMonitor, isLoading];
};
-const usePauseMonitor = () => {
+export const usePauseMonitor = () => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(undefined);
const pauseMonitor = async ({ monitorId, triggerUpdate }) => {
@@ -431,7 +425,7 @@ const usePauseMonitor = () => {
return [pauseMonitor, isLoading, error];
};
-const useAddDemoMonitors = () => {
+export const useAddDemoMonitors = () => {
const [isLoading, setIsLoading] = useState(false);
const { t } = useTranslation();
const addDemoMonitors = async () => {
@@ -448,7 +442,7 @@ const useAddDemoMonitors = () => {
return [addDemoMonitors, isLoading];
};
-const useDeleteAllMonitors = () => {
+export const useDeleteAllMonitors = () => {
const [isLoading, setIsLoading] = useState(false);
const { t } = useTranslation();
const deleteAllMonitors = async () => {
@@ -465,7 +459,7 @@ const useDeleteAllMonitors = () => {
return [deleteAllMonitors, isLoading];
};
-const useDeleteMonitorStats = () => {
+export const useDeleteMonitorStats = () => {
const { t } = useTranslation();
const [isLoading, setIsLoading] = useState(false);
const deleteMonitorStats = async () => {
@@ -483,7 +477,7 @@ const useDeleteMonitorStats = () => {
return [deleteMonitorStats, isLoading];
};
-const useCreateBulkMonitors = () => {
+export const useCreateBulkMonitors = () => {
const [isLoading, setIsLoading] = useState(false);
const createBulkMonitors = async (file, user) => {
@@ -506,7 +500,7 @@ const useCreateBulkMonitors = () => {
return [createBulkMonitors, isLoading];
};
-const useExportMonitors = () => {
+export const useExportMonitors = () => {
const [isLoading, setIsLoading] = useState(false);
const { t } = useTranslation();
@@ -539,7 +533,7 @@ const useExportMonitors = () => {
return [exportMonitors, isLoading];
};
-const useFetchJson = () => {
+export const useFetchJson = () => {
const [isLoading, setIsLoading] = useState(false);
const fetchJson = async () => {
try {
@@ -555,25 +549,3 @@ const useFetchJson = () => {
};
return [fetchJson, isLoading];
};
-
-export {
- useFetchMonitorsWithSummary,
- useFetchMonitorsWithChecks,
- useFetchMonitorsByTeamId,
- useFetchStatsByMonitorId,
- useFetchMonitorById,
- useFetchUptimeMonitorById,
- useFetchHardwareMonitorById,
- useCreateMonitor,
- useFetchGlobalSettings,
- useDeleteMonitor,
- useUpdateMonitor,
- usePauseMonitor,
- useAddDemoMonitors,
- useDeleteAllMonitors,
- useDeleteMonitorStats,
- useCreateBulkMonitors,
- useExportMonitors,
- useFetchMonitorGames,
- useFetchJson,
-};
diff --git a/client/src/Hooks/v1/settingsHooks.js b/client/src/Hooks/settingsHooks.js
similarity index 89%
rename from client/src/Hooks/v1/settingsHooks.js
rename to client/src/Hooks/settingsHooks.js
index 787e46ff9..8c4bef385 100644
--- a/client/src/Hooks/v1/settingsHooks.js
+++ b/client/src/Hooks/settingsHooks.js
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
-import { networkService } from "../../main.jsx";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { networkService } from "../main.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
const useFetchSettings = ({ setSettingsData, setIsApiKeySet, setIsEmailPasswordSet }) => {
@@ -42,11 +42,11 @@ const useSaveSettings = ({
setIsLoading(true);
try {
const settingsResponse = await networkService.updateAppSettings({ settings });
- if (settings.checkTTL) {
- await networkService.updateChecksTTL({
- ttl: settings.checkTTL,
- });
- }
+ // if (settings.checkTTL) {
+ // await networkService.updateChecksTTL({
+ // ttl: settings.checkTTL,
+ // });
+ // }
setIsApiKeySet(settingsResponse.data.data.pagespeedKeySet);
setIsEmailPasswordSet(settingsResponse.data.data.emailPasswordSet);
if (settingsResponse.data.data.pagespeedKeySet === true) {
diff --git a/client/src/Hooks/v1/useIsAdmin.js b/client/src/Hooks/useIsAdmin.js
similarity index 100%
rename from client/src/Hooks/v1/useIsAdmin.js
rename to client/src/Hooks/useIsAdmin.js
diff --git a/client/src/Hooks/v1/useMonitorUtils.js b/client/src/Hooks/useMonitorUtils.js
similarity index 100%
rename from client/src/Hooks/v1/useMonitorUtils.js
rename to client/src/Hooks/useMonitorUtils.js
diff --git a/client/src/Hooks/v1/useNotifications.js b/client/src/Hooks/useNotifications.js
similarity index 96%
rename from client/src/Hooks/v1/useNotifications.js
rename to client/src/Hooks/useNotifications.js
index d1b4a6652..5f2058b6a 100644
--- a/client/src/Hooks/v1/useNotifications.js
+++ b/client/src/Hooks/useNotifications.js
@@ -1,9 +1,9 @@
import { useState, useEffect, useCallback } from "react";
-import { createToast } from "../../Utils/toastUtils.jsx";
-import { networkService } from "../../main.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
+import { networkService } from "../main.jsx";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
-import { NOTIFICATION_TYPES } from "../../Pages/v1/Notifications/utils.js";
+import { NOTIFICATION_TYPES } from "../Pages/Notifications/utils.js";
const useCreateNotification = () => {
const navigate = useNavigate();
diff --git a/client/src/Hooks/v1/useSendTestEmail.js b/client/src/Hooks/useSendTestEmail.js
similarity index 93%
rename from client/src/Hooks/v1/useSendTestEmail.js
rename to client/src/Hooks/useSendTestEmail.js
index 0be77954a..7223a489a 100644
--- a/client/src/Hooks/v1/useSendTestEmail.js
+++ b/client/src/Hooks/useSendTestEmail.js
@@ -1,7 +1,7 @@
import { useState } from "react";
-import { networkService } from "../../main.jsx";
+import { networkService } from "../main.jsx";
import { useSelector } from "react-redux";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
const useSendTestEmail = () => {
diff --git a/client/src/Hooks/v1/userHooks.js b/client/src/Hooks/userHooks.js
similarity index 94%
rename from client/src/Hooks/v1/userHooks.js
rename to client/src/Hooks/userHooks.js
index f9c454450..3d822f979 100644
--- a/client/src/Hooks/v1/userHooks.js
+++ b/client/src/Hooks/userHooks.js
@@ -1,6 +1,6 @@
import { useEffect, useState, useCallback } from "react";
-import { networkService } from "../../main.jsx";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { networkService } from "../main.jsx";
+import { createToast } from "../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
export const useGetUser = (userId) => {
diff --git a/client/src/Pages/v1/About/index.jsx b/client/src/Pages/About/index.jsx
similarity index 100%
rename from client/src/Pages/v1/About/index.jsx
rename to client/src/Pages/About/index.jsx
diff --git a/client/src/Pages/v1/Account/EditUser/hooks/editUser.js b/client/src/Pages/Account/EditUser/hooks/editUser.js
similarity index 91%
rename from client/src/Pages/v1/Account/EditUser/hooks/editUser.js
rename to client/src/Pages/Account/EditUser/hooks/editUser.js
index 00660aead..aeb50ffff 100644
--- a/client/src/Pages/v1/Account/EditUser/hooks/editUser.js
+++ b/client/src/Pages/Account/EditUser/hooks/editUser.js
@@ -1,8 +1,8 @@
import { useState, useEffect } from "react";
-import { ROLES } from "../../../../../Utils/roleUtils.js";
-import { editUserValidation } from "../../../../../Validation/validation.js";
+import { ROLES } from "../../../../Utils/roleUtils.js";
+import { editUserValidation } from "../../../../Validation/validation.js";
import Joi from "joi";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
export const useEditUserForm = (user) => {
const [searchInput, setSearchInput] = useState("");
diff --git a/client/src/Pages/v1/Account/EditUser/index.jsx b/client/src/Pages/Account/EditUser/index.jsx
similarity index 96%
rename from client/src/Pages/v1/Account/EditUser/index.jsx
rename to client/src/Pages/Account/EditUser/index.jsx
index 674a522b8..2b2ac5128 100644
--- a/client/src/Pages/v1/Account/EditUser/index.jsx
+++ b/client/src/Pages/Account/EditUser/index.jsx
@@ -11,8 +11,8 @@ import ChangePasswordModal from "@/Pages/Account/components/ChangePasswordModal/
import { useParams } from "react-router-dom";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
-import { useGetUser, useEditUser } from "../../../../Hooks/v1/userHooks.js";
-import { EDITABLE_ROLES, ROLES } from "../../../../Utils/roleUtils.js";
+import { useGetUser, useEditUser } from "../../../Hooks/userHooks.js";
+import { EDITABLE_ROLES, ROLES } from "../../../Utils/roleUtils.js";
import { useEditUserForm, useValidateEditUserForm } from "./hooks/editUser.js";
import { useSelector } from "react-redux";
diff --git a/client/src/Pages/v1/Account/components/AddMemberMenu/index.jsx b/client/src/Pages/Account/components/AddMemberMenu/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Account/components/AddMemberMenu/index.jsx
rename to client/src/Pages/Account/components/AddMemberMenu/index.jsx
diff --git a/client/src/Pages/v1/Account/components/AddTeamMember/hooks/useAddTeamMember.jsx b/client/src/Pages/Account/components/AddTeamMember/hooks/useAddTeamMember.jsx
similarity index 93%
rename from client/src/Pages/v1/Account/components/AddTeamMember/hooks/useAddTeamMember.jsx
rename to client/src/Pages/Account/components/AddTeamMember/hooks/useAddTeamMember.jsx
index 58db019a3..1237777ff 100644
--- a/client/src/Pages/v1/Account/components/AddTeamMember/hooks/useAddTeamMember.jsx
+++ b/client/src/Pages/Account/components/AddTeamMember/hooks/useAddTeamMember.jsx
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { newOrChangedCredentials } from "../../../../../../Validation/validation.js";
+import { newOrChangedCredentials } from "../../../../../Validation/validation.js";
import { useTranslation } from "react-i18next";
const useAddTeamMember = () => {
const { t } = useTranslation();
diff --git a/client/src/Pages/v1/Account/components/AddTeamMember/index.jsx b/client/src/Pages/Account/components/AddTeamMember/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Account/components/AddTeamMember/index.jsx
rename to client/src/Pages/Account/components/AddTeamMember/index.jsx
index 219658b63..e5280af16 100644
--- a/client/src/Pages/v1/Account/components/AddTeamMember/index.jsx
+++ b/client/src/Pages/Account/components/AddTeamMember/index.jsx
@@ -2,10 +2,10 @@ import { Button, Stack } from "@mui/material";
import { GenericDialog } from "@/Components/v1/Dialog/genericDialog.jsx";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
import Select from "@/Components/v1/Inputs/Select/index.jsx";
-import { useGetInviteToken } from "../../../../../Hooks/v1/inviteHooks.js";
+import { useGetInviteToken } from "../../../../Hooks/inviteHooks.js";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
import { useState } from "react";
import PasswordTooltip from "../../../Auth/components/PasswordTooltip.jsx";
import useAddTeamMember from "./hooks/useAddTeamMember.jsx";
diff --git a/client/src/Pages/Account/components/ChangePasswordModal/index.jsx b/client/src/Pages/Account/components/ChangePasswordModal/index.jsx
index cc284a675..725a9b00e 100644
--- a/client/src/Pages/Account/components/ChangePasswordModal/index.jsx
+++ b/client/src/Pages/Account/components/ChangePasswordModal/index.jsx
@@ -2,12 +2,12 @@ import { useState } from "react";
import { Button, Stack } from "@mui/material";
import { GenericDialog } from "@/Components/v1/Dialog/genericDialog";
import TextInput from "@/Components/v1/Inputs/TextInput";
-import PasswordTooltip from "@/Pages/v1/Auth/components/PasswordTooltip";
+import PasswordTooltip from "@/Pages/Auth/components/PasswordTooltip";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
import { createToast } from "../../../../Utils/toastUtils";
import { PasswordEndAdornment } from "@/Components/v1/Inputs/TextInput/Adornments";
-import usePasswordFeedback from "@/Pages/v1/Auth/hooks/usePasswordFeedback";
+import usePasswordFeedback from "@/Pages/Auth/hooks/usePasswordFeedback";
import PropTypes from "prop-types";
const ChangePasswordModal = ({ isSaving, isLoading, changePassword }) => {
diff --git a/client/src/Pages/v1/Account/components/PasswordPanel.jsx b/client/src/Pages/Account/components/PasswordPanel.jsx
similarity index 95%
rename from client/src/Pages/v1/Account/components/PasswordPanel.jsx
rename to client/src/Pages/Account/components/PasswordPanel.jsx
index ca2af9205..f54c61a16 100644
--- a/client/src/Pages/v1/Account/components/PasswordPanel.jsx
+++ b/client/src/Pages/Account/components/PasswordPanel.jsx
@@ -4,12 +4,12 @@ import { useTheme } from "@emotion/react";
import { Box, Stack, Typography, Button } from "@mui/material";
import { PasswordEndAdornment } from "@/Components/v1/Inputs/TextInput/Adornments/index.jsx";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
-import { newOrChangedCredentials } from "../../../../Validation/validation.js";
+import { newOrChangedCredentials } from "../../../Validation/validation.js";
import Alert from "@/Components/v1/Alert/index.jsx";
-import { update } from "../../../../Features/Auth/authSlice.js";
+import { update } from "../../../Features/Auth/authSlice.js";
import { useDispatch, useSelector } from "react-redux";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
-import { getTouchedFieldErrors } from "../../../../Validation/error.js";
+import { createToast } from "../../../Utils/toastUtils.jsx";
+import { getTouchedFieldErrors } from "../../../Validation/error.js";
import { useTranslation } from "react-i18next";
const defaultPasswordsState = {
diff --git a/client/src/Pages/v1/Account/components/ProfilePanel.jsx b/client/src/Pages/Account/components/ProfilePanel.jsx
similarity index 97%
rename from client/src/Pages/v1/Account/components/ProfilePanel.jsx
rename to client/src/Pages/Account/components/ProfilePanel.jsx
index 2035861a2..d59923ae4 100644
--- a/client/src/Pages/v1/Account/components/ProfilePanel.jsx
+++ b/client/src/Pages/Account/components/ProfilePanel.jsx
@@ -5,15 +5,11 @@ import { Box, Button, Divider, Stack, Typography } from "@mui/material";
import Avatar from "@/Components/v1/Avatar/index.jsx";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
import ImageUpload from "@/Components/v1/Inputs/ImageUpload/index.jsx";
-import { newOrChangedCredentials } from "../../../../Validation/validation.js";
+import { newOrChangedCredentials } from "../../../Validation/validation.js";
import { useDispatch, useSelector } from "react-redux";
-import {
- clearAuthState,
- deleteUser,
- update,
-} from "../../../../Features/Auth/authSlice.js";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
-import { logger } from "../../../../Utils/Logger.js";
+import { clearAuthState, deleteUser, update } from "../../../Features/Auth/authSlice.js";
+import { createToast } from "../../../Utils/toastUtils.jsx";
+import { logger } from "../../../Utils/Logger.js";
import { GenericDialog } from "@/Components/v1/Dialog/genericDialog.jsx";
import Dialog from "@/Components/v1/Dialog/index.jsx";
import { useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/Account/components/RoleTable/index.jsx b/client/src/Pages/Account/components/RoleTable/index.jsx
similarity index 93%
rename from client/src/Pages/v1/Account/components/RoleTable/index.jsx
rename to client/src/Pages/Account/components/RoleTable/index.jsx
index 02dcaaf0d..5eea33685 100644
--- a/client/src/Pages/v1/Account/components/RoleTable/index.jsx
+++ b/client/src/Pages/Account/components/RoleTable/index.jsx
@@ -3,7 +3,7 @@ import DataTable from "@/Components/v1/Table/index.jsx";
import DeleteOutlineRoundedIcon from "@mui/icons-material/DeleteOutlineRounded";
import { useTranslation } from "react-i18next";
-import { ROLES } from "../../../../../Utils/roleUtils.js";
+import { ROLES } from "../../../../Utils/roleUtils.js";
const RoleTable = ({ roles, handleDeleteRole }) => {
const { t } = useTranslation();
diff --git a/client/src/Pages/v1/Account/components/TeamPanel.jsx b/client/src/Pages/Account/components/TeamPanel.jsx
similarity index 96%
rename from client/src/Pages/v1/Account/components/TeamPanel.jsx
rename to client/src/Pages/Account/components/TeamPanel.jsx
index 02918eb30..03a6145a5 100644
--- a/client/src/Pages/v1/Account/components/TeamPanel.jsx
+++ b/client/src/Pages/Account/components/TeamPanel.jsx
@@ -4,16 +4,16 @@ import { Button, ButtonGroup, Stack, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
-import { newOrChangedCredentials } from "../../../../Validation/validation.js";
-import { networkService } from "../../../../main.jsx";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { newOrChangedCredentials } from "../../../Validation/validation.js";
+import { networkService } from "../../../main.jsx";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import Select from "@/Components/v1/Inputs/Select/index.jsx";
import { GenericDialog } from "@/Components/v1/Dialog/genericDialog.jsx";
import AddTeamMember from "./AddTeamMember/index.jsx";
import DataTable from "@/Components/v1/Table/index.jsx";
-import { useGetInviteToken } from "../../../../Hooks/v1/inviteHooks.js";
+import { useGetInviteToken } from "../../../Hooks/inviteHooks.js";
import { useNavigate } from "react-router-dom";
-import { useIsSuperAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
+import { useIsSuperAdmin } from "@/Hooks/useIsAdmin.js";
import AddMemberMenu from "./AddMemberMenu/index.jsx";
/**
* TeamPanel component manages the organization and team members,
diff --git a/client/src/Pages/v1/Account/index.jsx b/client/src/Pages/Account/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Account/index.jsx
rename to client/src/Pages/Account/index.jsx
diff --git a/client/src/Pages/v1/Auth/CheckEmail.jsx b/client/src/Pages/Auth/CheckEmail.jsx
similarity index 94%
rename from client/src/Pages/v1/Auth/CheckEmail.jsx
rename to client/src/Pages/Auth/CheckEmail.jsx
index c12a84804..6aee7a470 100644
--- a/client/src/Pages/v1/Auth/CheckEmail.jsx
+++ b/client/src/Pages/Auth/CheckEmail.jsx
@@ -3,12 +3,12 @@ import { useEffect, useState } from "react";
import { useTheme } from "@emotion/react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
-import { createToast } from "../../../Utils/toastUtils.jsx";
-import { forgotPassword } from "../../../Features/Auth/authSlice.js";
+import { createToast } from "../../Utils/toastUtils.jsx";
+import { forgotPassword } from "../../Features/Auth/authSlice.js";
import { Trans, useTranslation } from "react-i18next";
-import Background from "../../../assets/Images/background-grid.svg?react";
-import EmailIcon from "../../../assets/icons/email.svg?react";
-import Logo from "../../../assets/icons/checkmate-icon.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
+import EmailIcon from "@/assets/icons/email.svg?react";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
import IconBox from "@/Components/v1/IconBox/index.jsx";
import "./index.css";
diff --git a/client/src/Pages/v1/Auth/ForgotPassword.jsx b/client/src/Pages/Auth/ForgotPassword.jsx
similarity index 93%
rename from client/src/Pages/v1/Auth/ForgotPassword.jsx
rename to client/src/Pages/Auth/ForgotPassword.jsx
index 8cbd85d8a..0a89b2987 100644
--- a/client/src/Pages/v1/Auth/ForgotPassword.jsx
+++ b/client/src/Pages/Auth/ForgotPassword.jsx
@@ -1,15 +1,15 @@
import { Box, Stack, Typography, Button } from "@mui/material";
import { useTheme } from "@emotion/react";
-import { createToast } from "../../../Utils/toastUtils.jsx";
+import { createToast } from "../../Utils/toastUtils.jsx";
import { useDispatch, useSelector } from "react-redux";
-import { forgotPassword } from "../../../Features/Auth/authSlice.js";
+import { forgotPassword } from "../../Features/Auth/authSlice.js";
import { useEffect, useState } from "react";
-import { newOrChangedCredentials } from "../../../Validation/validation.js";
+import { newOrChangedCredentials } from "../../Validation/validation.js";
import { useNavigate } from "react-router-dom";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
-import Logo from "../../../assets/icons/checkmate-icon.svg?react";
-import Key from "../../../assets/icons/key.svg?react";
-import Background from "../../../assets/Images/background-grid.svg?react";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
+import Key from "@/assets/icons/key.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
import IconBox from "@/Components/v1/IconBox/index.jsx";
import { Trans, useTranslation } from "react-i18next";
import "./index.css";
diff --git a/client/src/Pages/v1/Auth/Login/hooks/useLoadingSubmit.jsx b/client/src/Pages/Auth/Login/hooks/useLoadingSubmit.jsx
similarity index 100%
rename from client/src/Pages/v1/Auth/Login/hooks/useLoadingSubmit.jsx
rename to client/src/Pages/Auth/Login/hooks/useLoadingSubmit.jsx
diff --git a/client/src/Pages/v1/Auth/Login/hooks/useLoginForm.jsx b/client/src/Pages/Auth/Login/hooks/useLoginForm.jsx
similarity index 100%
rename from client/src/Pages/v1/Auth/Login/hooks/useLoginForm.jsx
rename to client/src/Pages/Auth/Login/hooks/useLoginForm.jsx
diff --git a/client/src/Pages/v1/Auth/Login/hooks/useLoginSubmit.jsx b/client/src/Pages/Auth/Login/hooks/useLoginSubmit.jsx
similarity index 87%
rename from client/src/Pages/v1/Auth/Login/hooks/useLoginSubmit.jsx
rename to client/src/Pages/Auth/Login/hooks/useLoginSubmit.jsx
index 0eed9bd07..b009793d5 100644
--- a/client/src/Pages/v1/Auth/Login/hooks/useLoginSubmit.jsx
+++ b/client/src/Pages/Auth/Login/hooks/useLoginSubmit.jsx
@@ -1,7 +1,7 @@
import { useDispatch } from "react-redux";
-import { login } from "../../../../../Features/Auth/authSlice.js";
+import { login } from "../../../../Features/Auth/authSlice.js";
import { useNavigate } from "react-router-dom";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
const useLoginSubmit = () => {
diff --git a/client/src/Pages/v1/Auth/Login/hooks/useValidateLoginForm.jsx b/client/src/Pages/Auth/Login/hooks/useValidateLoginForm.jsx
similarity index 90%
rename from client/src/Pages/v1/Auth/Login/hooks/useValidateLoginForm.jsx
rename to client/src/Pages/Auth/Login/hooks/useValidateLoginForm.jsx
index ca9bef879..0872213ad 100644
--- a/client/src/Pages/v1/Auth/Login/hooks/useValidateLoginForm.jsx
+++ b/client/src/Pages/Auth/Login/hooks/useValidateLoginForm.jsx
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { loginCredentials } from "../../../../../Validation/validation.js";
+import { loginCredentials } from "../../../../Validation/validation.js";
const useValidateLoginForm = () => {
const [errors, setErrors] = useState({
diff --git a/client/src/Pages/v1/Auth/Login/index.jsx b/client/src/Pages/Auth/Login/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Auth/Login/index.jsx
rename to client/src/Pages/Auth/Login/index.jsx
diff --git a/client/src/Pages/v1/Auth/NewPasswordConfirmed.jsx b/client/src/Pages/Auth/NewPasswordConfirmed.jsx
similarity index 92%
rename from client/src/Pages/v1/Auth/NewPasswordConfirmed.jsx
rename to client/src/Pages/Auth/NewPasswordConfirmed.jsx
index 629494098..53b352853 100644
--- a/client/src/Pages/v1/Auth/NewPasswordConfirmed.jsx
+++ b/client/src/Pages/Auth/NewPasswordConfirmed.jsx
@@ -2,10 +2,10 @@ import { Box, Button, Stack, Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
-import { clearAuthState } from "../../../Features/Auth/authSlice.js";
-import Background from "../../../assets/Images/background-grid.svg?react";
-import ConfirmIcon from "../../../assets/icons/check-outlined.svg?react";
-import Logo from "../../../assets/icons/checkmate-icon.svg?react";
+import { clearAuthState } from "../../Features/Auth/authSlice.js";
+import Background from "@/assets/Images/background-grid.svg?react";
+import ConfirmIcon from "@/assets/icons/check-outlined.svg?react";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
import IconBox from "@/Components/v1/IconBox/index.jsx";
import { Trans, useTranslation } from "react-i18next";
import "./index.css";
diff --git a/client/src/Pages/v1/Auth/Register/index.jsx b/client/src/Pages/Auth/Register/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Auth/Register/index.jsx
rename to client/src/Pages/Auth/Register/index.jsx
index d6515b85c..3345d8aa0 100644
--- a/client/src/Pages/v1/Auth/Register/index.jsx
+++ b/client/src/Pages/Auth/Register/index.jsx
@@ -13,11 +13,11 @@ import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { useParams } from "react-router-dom";
-import { networkService } from "../../../../main.jsx";
-import { newOrChangedCredentials } from "../../../../Validation/validation.js";
-import { register } from "../../../../Features/Auth/authSlice.js";
+import { networkService } from "../../../main.jsx";
+import { newOrChangedCredentials } from "../../../Validation/validation.js";
+import { register } from "../../../Features/Auth/authSlice.js";
import AuthPageWrapper from "../components/AuthPageWrapper.jsx";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import PropTypes from "prop-types";
const getFeedbackStatus = (form, errors, field, criteria) => {
diff --git a/client/src/Pages/v1/Auth/SetNewPassword.jsx b/client/src/Pages/Auth/SetNewPassword.jsx
similarity index 95%
rename from client/src/Pages/v1/Auth/SetNewPassword.jsx
rename to client/src/Pages/Auth/SetNewPassword.jsx
index 45f3351f3..6525c3f27 100644
--- a/client/src/Pages/v1/Auth/SetNewPassword.jsx
+++ b/client/src/Pages/Auth/SetNewPassword.jsx
@@ -4,16 +4,16 @@ import { useNavigate } from "react-router-dom";
import { useParams } from "react-router-dom";
import { useTheme } from "@emotion/react";
import { Box, Stack, Typography, Button } from "@mui/material";
-import { setNewPassword } from "../../../Features/Auth/authSlice.js";
-import { createToast } from "../../../Utils/toastUtils.jsx";
-import { newOrChangedCredentials } from "../../../Validation/validation.js";
+import { setNewPassword } from "../../Features/Auth/authSlice.js";
+import { createToast } from "../../Utils/toastUtils.jsx";
+import { newOrChangedCredentials } from "../../Validation/validation.js";
import Check from "@/Components/v1/Check/Check.jsx";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
import { PasswordEndAdornment } from "@/Components/v1/Inputs/TextInput/Adornments/index.jsx";
import IconBox from "@/Components/v1/IconBox/index.jsx";
-import LockIcon from "../../../assets/icons/lock.svg?react";
-import Logo from "../../../assets/icons/checkmate-icon.svg?react";
-import Background from "../../../assets/Images/background-grid.svg?react";
+import LockIcon from "@/assets/icons/lock.svg?react";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
import "./index.css";
import { useValidatePassword } from "./hooks/useValidatePassword.jsx";
import { Trans, useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/Auth/components/AuthHeader.jsx b/client/src/Pages/Auth/components/AuthHeader.jsx
similarity index 87%
rename from client/src/Pages/v1/Auth/components/AuthHeader.jsx
rename to client/src/Pages/Auth/components/AuthHeader.jsx
index a34e83d6a..56b69ef14 100644
--- a/client/src/Pages/v1/Auth/components/AuthHeader.jsx
+++ b/client/src/Pages/Auth/components/AuthHeader.jsx
@@ -1,8 +1,8 @@
// Components
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
-import Logo from "../../../../assets/icons/checkmate-icon.svg?react";
-import LanguageSelector from "../../../../Components/LanguageSelector.jsx";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
+import LanguageSelector from "@/Components/LanguageSelector.jsx";
import ThemeSwitch from "@/Components/v1/ThemeSwitch/index.jsx";
// Utils
diff --git a/client/src/Pages/v1/Auth/components/AuthPageWrapper.jsx b/client/src/Pages/Auth/components/AuthPageWrapper.jsx
similarity index 93%
rename from client/src/Pages/v1/Auth/components/AuthPageWrapper.jsx
rename to client/src/Pages/Auth/components/AuthPageWrapper.jsx
index 7e358e6ab..a5fbe311b 100644
--- a/client/src/Pages/v1/Auth/components/AuthPageWrapper.jsx
+++ b/client/src/Pages/Auth/components/AuthPageWrapper.jsx
@@ -1,10 +1,10 @@
-import Background from "../../../../assets/Images/background-grid.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import AuthHeader from "./AuthHeader.jsx";
import { useTheme } from "@mui/material/styles";
-import Logo from "../../../../assets/icons/checkmate-icon.svg?react";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
import PropTypes from "prop-types";
const AuthPageWrapper = ({ children, heading, welcome }) => {
diff --git a/client/src/Pages/v1/Auth/components/PasswordTooltip.jsx b/client/src/Pages/Auth/components/PasswordTooltip.jsx
similarity index 100%
rename from client/src/Pages/v1/Auth/components/PasswordTooltip.jsx
rename to client/src/Pages/Auth/components/PasswordTooltip.jsx
diff --git a/client/src/Pages/v1/Auth/hooks/usePasswordFeedback.jsx b/client/src/Pages/Auth/hooks/usePasswordFeedback.jsx
similarity index 96%
rename from client/src/Pages/v1/Auth/hooks/usePasswordFeedback.jsx
rename to client/src/Pages/Auth/hooks/usePasswordFeedback.jsx
index 3c199e25f..73e8fb738 100644
--- a/client/src/Pages/v1/Auth/hooks/usePasswordFeedback.jsx
+++ b/client/src/Pages/Auth/hooks/usePasswordFeedback.jsx
@@ -1,5 +1,5 @@
import { useState } from "react";
-import { newOrChangedCredentials } from "../../../../Validation/validation.js";
+import { newOrChangedCredentials } from "../../../Validation/validation.js";
const usePasswordFeedback = () => {
const [feedback, setFeedback] = useState({});
diff --git a/client/src/Pages/v1/Auth/hooks/useValidatePassword.jsx b/client/src/Pages/Auth/hooks/useValidatePassword.jsx
similarity index 96%
rename from client/src/Pages/v1/Auth/hooks/useValidatePassword.jsx
rename to client/src/Pages/Auth/hooks/useValidatePassword.jsx
index 231b8eeb8..014804d35 100644
--- a/client/src/Pages/v1/Auth/hooks/useValidatePassword.jsx
+++ b/client/src/Pages/Auth/hooks/useValidatePassword.jsx
@@ -1,5 +1,5 @@
import { useMemo, useState } from "react";
-import { newOrChangedCredentials } from "../../../../Validation/validation.js";
+import { newOrChangedCredentials } from "../../../Validation/validation.js";
const getFeedbackStatus = (form, errors, field, criteria) => {
const fieldErrors = errors[field];
diff --git a/client/src/Pages/v1/Auth/index.css b/client/src/Pages/Auth/index.css
similarity index 100%
rename from client/src/Pages/v1/Auth/index.css
rename to client/src/Pages/Auth/index.css
diff --git a/client/src/Pages/v1/Incidents/Components/IncidentTable/index.jsx b/client/src/Pages/Incidents/Components/IncidentTable/index.jsx
similarity index 95%
rename from client/src/Pages/v1/Incidents/Components/IncidentTable/index.jsx
rename to client/src/Pages/Incidents/Components/IncidentTable/index.jsx
index df457c0e2..e066049e6 100644
--- a/client/src/Pages/v1/Incidents/Components/IncidentTable/index.jsx
+++ b/client/src/Pages/Incidents/Components/IncidentTable/index.jsx
@@ -13,14 +13,16 @@ import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
import NetworkError from "@/Components/v1/GenericFallback/NetworkError.jsx";
//Utils
-import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
+import { formatDateWithTz } from "@/Utils/timeUtils.js";
import { useSelector } from "react-redux";
import { useState } from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
-import { useFetchChecksTeam } from "../../../../../Hooks/v1/checkHooks.js";
-import { useFetchChecksByMonitor } from "../../../../../Hooks/v1/checkHooks.js";
-import { useResolveIncident } from "../../../../../Hooks/v1/checkHooks.js";
+import {
+ useFetchChecksTeam,
+ useFetchChecksByMonitor,
+ useResolveIncident,
+} from "@/Hooks/checkHooks.js";
import { Button, Typography, useTheme } from "@mui/material";
import { lighten } from "@mui/material/styles";
diff --git a/client/src/Pages/v1/Incidents/Components/OptionsHeader/index.jsx b/client/src/Pages/Incidents/Components/OptionsHeader/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents/Components/OptionsHeader/index.jsx
rename to client/src/Pages/Incidents/Components/OptionsHeader/index.jsx
diff --git a/client/src/Pages/v1/Incidents/Components/OptionsHeader/skeleton.jsx b/client/src/Pages/Incidents/Components/OptionsHeader/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents/Components/OptionsHeader/skeleton.jsx
rename to client/src/Pages/Incidents/Components/OptionsHeader/skeleton.jsx
diff --git a/client/src/Pages/v1/Incidents/Components/StatusBoxes/StatusBox.jsx b/client/src/Pages/Incidents/Components/StatusBoxes/StatusBox.jsx
similarity index 87%
rename from client/src/Pages/v1/Incidents/Components/StatusBoxes/StatusBox.jsx
rename to client/src/Pages/Incidents/Components/StatusBoxes/StatusBox.jsx
index cd7078e6c..c27c5948c 100644
--- a/client/src/Pages/v1/Incidents/Components/StatusBoxes/StatusBox.jsx
+++ b/client/src/Pages/Incidents/Components/StatusBoxes/StatusBox.jsx
@@ -1,11 +1,11 @@
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { Box, Stack, Typography } from "@mui/material";
-import Background from "../../../../../assets/Images/background-grid.svg?react";
-import AlertIcon from "../../../../../assets/icons/alert-icon.svg?react";
-import CheckIcon from "../../../../../assets/icons/check-icon.svg?react";
-import CloseIcon from "../../../../../assets/icons/close-icon.svg?react";
-import WarningIcon from "../../../../../assets/icons/warning-icon.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
+import AlertIcon from "@/assets/icons/alert-icon.svg?react";
+import CheckIcon from "@/assets/icons/check-icon.svg?react";
+import CloseIcon from "@/assets/icons/close-icon.svg?react";
+import WarningIcon from "@/assets/icons/warning-icon.svg?react";
const StatusBox = ({ title, value, status }) => {
const theme = useTheme();
diff --git a/client/src/Pages/v1/Incidents/Components/StatusBoxes/index.jsx b/client/src/Pages/Incidents/Components/StatusBoxes/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents/Components/StatusBoxes/index.jsx
rename to client/src/Pages/Incidents/Components/StatusBoxes/index.jsx
diff --git a/client/src/Pages/v1/Incidents/Components/StatusBoxes/skeleton.jsx b/client/src/Pages/Incidents/Components/StatusBoxes/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents/Components/StatusBoxes/skeleton.jsx
rename to client/src/Pages/Incidents/Components/StatusBoxes/skeleton.jsx
diff --git a/client/src/Pages/v1/Incidents/index.jsx b/client/src/Pages/Incidents/index.jsx
similarity index 93%
rename from client/src/Pages/v1/Incidents/index.jsx
rename to client/src/Pages/Incidents/index.jsx
index 91cab2a40..698fc4a2f 100644
--- a/client/src/Pages/v1/Incidents/index.jsx
+++ b/client/src/Pages/Incidents/index.jsx
@@ -9,9 +9,11 @@ import { Box, Button } from "@mui/material";
//Utils
import { useTheme } from "@emotion/react";
-import { useFetchMonitorsByTeamId } from "../../../Hooks/v1/monitorHooks.js";
-import { useFetchChecksSummaryByTeamId } from "../../../Hooks/v1/checkHooks.js";
-import { useAcknowledgeChecks } from "../../../Hooks/v1/checkHooks.js";
+import { useFetchMonitorsByTeamId } from "@/Hooks/monitorHooks.js";
+import {
+ useFetchChecksSummaryByTeamId,
+ useAcknowledgeChecks,
+} from "@/Hooks/checkHooks.js";
import { useState, useEffect } from "react";
import NetworkError from "@/Components/v1/GenericFallback/NetworkError.jsx";
import { useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/Incidents2/Components/ActiveIncidentsPanel/index.jsx b/client/src/Pages/Incidents2/Components/ActiveIncidentsPanel/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/ActiveIncidentsPanel/index.jsx
rename to client/src/Pages/Incidents2/Components/ActiveIncidentsPanel/index.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/IncidentTable/index.jsx b/client/src/Pages/Incidents2/Components/IncidentTable/index.jsx
similarity index 98%
rename from client/src/Pages/v1/Incidents2/Components/IncidentTable/index.jsx
rename to client/src/Pages/Incidents2/Components/IncidentTable/index.jsx
index 8cac4e07b..d613e15c7 100644
--- a/client/src/Pages/v1/Incidents2/Components/IncidentTable/index.jsx
+++ b/client/src/Pages/Incidents2/Components/IncidentTable/index.jsx
@@ -8,7 +8,7 @@ import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
import NetworkError from "@/Components/v1/GenericFallback/NetworkError.jsx";
//Utils
-import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
+import { formatDateWithTz } from "../../../../Utils/timeUtils.js";
import { useSelector } from "react-redux";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/Incidents2/Components/IncidentsSummaryPanel/index.jsx b/client/src/Pages/Incidents2/Components/IncidentsSummaryPanel/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/IncidentsSummaryPanel/index.jsx
rename to client/src/Pages/Incidents2/Components/IncidentsSummaryPanel/index.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/IncidentsSummaryPanel/skeleton.jsx b/client/src/Pages/Incidents2/Components/IncidentsSummaryPanel/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/IncidentsSummaryPanel/skeleton.jsx
rename to client/src/Pages/Incidents2/Components/IncidentsSummaryPanel/skeleton.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/LatestIncidentsPanel/IncidentItem.jsx b/client/src/Pages/Incidents2/Components/LatestIncidentsPanel/IncidentItem.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/LatestIncidentsPanel/IncidentItem.jsx
rename to client/src/Pages/Incidents2/Components/LatestIncidentsPanel/IncidentItem.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/LatestIncidentsPanel/index.jsx b/client/src/Pages/Incidents2/Components/LatestIncidentsPanel/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/LatestIncidentsPanel/index.jsx
rename to client/src/Pages/Incidents2/Components/LatestIncidentsPanel/index.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/OptionsHeader/index.jsx b/client/src/Pages/Incidents2/Components/OptionsHeader/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/OptionsHeader/index.jsx
rename to client/src/Pages/Incidents2/Components/OptionsHeader/index.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/StatisticsPanel/index.jsx b/client/src/Pages/Incidents2/Components/StatisticsPanel/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/StatisticsPanel/index.jsx
rename to client/src/Pages/Incidents2/Components/StatisticsPanel/index.jsx
diff --git a/client/src/Pages/v1/Incidents2/Components/SummaryCard/index.jsx b/client/src/Pages/Incidents2/Components/SummaryCard/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Incidents2/Components/SummaryCard/index.jsx
rename to client/src/Pages/Incidents2/Components/SummaryCard/index.jsx
diff --git a/client/src/Pages/v1/Incidents2/hooks/useFetchIncidents.js b/client/src/Pages/Incidents2/hooks/useFetchIncidents.js
similarity index 97%
rename from client/src/Pages/v1/Incidents2/hooks/useFetchIncidents.js
rename to client/src/Pages/Incidents2/hooks/useFetchIncidents.js
index a67f6b7ee..ab22c42e0 100644
--- a/client/src/Pages/v1/Incidents2/hooks/useFetchIncidents.js
+++ b/client/src/Pages/Incidents2/hooks/useFetchIncidents.js
@@ -1,6 +1,6 @@
import { useState, useCallback } from "react";
-import { networkService } from "../../../../main.jsx";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { networkService } from "../../../main.jsx";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
/**
* Hook to fetch and manage incidents
diff --git a/client/src/Pages/v1/Incidents2/index.jsx b/client/src/Pages/Incidents2/index.jsx
similarity index 95%
rename from client/src/Pages/v1/Incidents2/index.jsx
rename to client/src/Pages/Incidents2/index.jsx
index 2983a38e8..966388b51 100644
--- a/client/src/Pages/v1/Incidents2/index.jsx
+++ b/client/src/Pages/Incidents2/index.jsx
@@ -14,7 +14,7 @@ import { useTranslation } from "react-i18next";
// Hooks
import useFetchIncidents from "./hooks/useFetchIncidents.js";
-import { useFetchMonitorsByTeamId } from "../../../Hooks/v1/monitorHooks.js";
+import { useFetchMonitorsByTeamId } from "../../Hooks/monitorHooks.js";
const Incidents2 = () => {
const { t } = useTranslation();
@@ -34,7 +34,7 @@ const Incidents2 = () => {
setUpdateTrigger((prev) => !prev);
};
- const [monitors, , isLoadingMonitors, monitorsNetworkError] = useFetchMonitorsByTeamId(
+ const [monitors, isLoadingMonitors, monitorsNetworkError] = useFetchMonitorsByTeamId(
{}
);
diff --git a/client/src/Pages/v1/Infrastructure/Create/Components/CustomAlertsSection.jsx b/client/src/Pages/Infrastructure/Create/Components/CustomAlertsSection.jsx
similarity index 96%
rename from client/src/Pages/v1/Infrastructure/Create/Components/CustomAlertsSection.jsx
rename to client/src/Pages/Infrastructure/Create/Components/CustomAlertsSection.jsx
index 5fe1d8984..64f82cec2 100644
--- a/client/src/Pages/v1/Infrastructure/Create/Components/CustomAlertsSection.jsx
+++ b/client/src/Pages/Infrastructure/Create/Components/CustomAlertsSection.jsx
@@ -1,7 +1,7 @@
import ConfigBox from "@/Components/v1/ConfigBox/index.jsx";
import { Box, Stack, Typography } from "@mui/material";
import { CustomThreshold } from "./CustomThreshold/index.jsx";
-import { capitalizeFirstLetter } from "../../../../../Utils/stringUtils.js";
+import { capitalizeFirstLetter } from "../../../../Utils/stringUtils.js";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
diff --git a/client/src/Pages/v1/Infrastructure/Create/Components/CustomThreshold/index.jsx b/client/src/Pages/Infrastructure/Create/Components/CustomThreshold/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Create/Components/CustomThreshold/index.jsx
rename to client/src/Pages/Infrastructure/Create/Components/CustomThreshold/index.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Create/Components/DiskSelection.jsx b/client/src/Pages/Infrastructure/Create/Components/DiskSelection.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Create/Components/DiskSelection.jsx
rename to client/src/Pages/Infrastructure/Create/Components/DiskSelection.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Create/Components/MonitorActionButtons.jsx b/client/src/Pages/Infrastructure/Create/Components/MonitorActionButtons.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Create/Components/MonitorActionButtons.jsx
rename to client/src/Pages/Infrastructure/Create/Components/MonitorActionButtons.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Create/Components/MonitorStatusHeader.jsx b/client/src/Pages/Infrastructure/Create/Components/MonitorStatusHeader.jsx
similarity index 95%
rename from client/src/Pages/v1/Infrastructure/Create/Components/MonitorStatusHeader.jsx
rename to client/src/Pages/Infrastructure/Create/Components/MonitorStatusHeader.jsx
index 570f38a7e..8fa6f4ff1 100644
--- a/client/src/Pages/v1/Infrastructure/Create/Components/MonitorStatusHeader.jsx
+++ b/client/src/Pages/Infrastructure/Create/Components/MonitorStatusHeader.jsx
@@ -1,5 +1,5 @@
import { Box, Stack, Tooltip, Typography } from "@mui/material";
-import { useMonitorUtils } from "../../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../../Hooks/useMonitorUtils.js";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
import PulseDot from "@/Components/v1/Animated/PulseDot.jsx";
diff --git a/client/src/Pages/v1/Infrastructure/Create/hooks/useInfrastructureMonitorForm.jsx b/client/src/Pages/Infrastructure/Create/hooks/useInfrastructureMonitorForm.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Create/hooks/useInfrastructureMonitorForm.jsx
rename to client/src/Pages/Infrastructure/Create/hooks/useInfrastructureMonitorForm.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Create/hooks/useInfrastructureSubmit.jsx b/client/src/Pages/Infrastructure/Create/hooks/useInfrastructureSubmit.jsx
similarity index 96%
rename from client/src/Pages/v1/Infrastructure/Create/hooks/useInfrastructureSubmit.jsx
rename to client/src/Pages/Infrastructure/Create/hooks/useInfrastructureSubmit.jsx
index 15a5f3c5d..c5c7aacf2 100644
--- a/client/src/Pages/v1/Infrastructure/Create/hooks/useInfrastructureSubmit.jsx
+++ b/client/src/Pages/Infrastructure/Create/hooks/useInfrastructureSubmit.jsx
@@ -1,7 +1,4 @@
-import {
- useCreateMonitor,
- useUpdateMonitor,
-} from "../../../../../Hooks/v1/monitorHooks.js";
+import { useCreateMonitor, useUpdateMonitor } from "../../../../Hooks/monitorHooks.js";
const useInfrastructureSubmit = () => {
const [createMonitor, isCreating] = useCreateMonitor();
const [updateMonitor, isUpdating] = useUpdateMonitor();
diff --git a/client/src/Pages/v1/Infrastructure/Create/hooks/useValidateInfrastructureForm.jsx b/client/src/Pages/Infrastructure/Create/hooks/useValidateInfrastructureForm.jsx
similarity index 85%
rename from client/src/Pages/v1/Infrastructure/Create/hooks/useValidateInfrastructureForm.jsx
rename to client/src/Pages/Infrastructure/Create/hooks/useValidateInfrastructureForm.jsx
index 73097d0d8..f7665e65f 100644
--- a/client/src/Pages/v1/Infrastructure/Create/hooks/useValidateInfrastructureForm.jsx
+++ b/client/src/Pages/Infrastructure/Create/hooks/useValidateInfrastructureForm.jsx
@@ -1,6 +1,6 @@
import { useState } from "react";
-import { infrastructureMonitorValidation } from "../../../../../Validation/validation.js";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { infrastructureMonitorValidation } from "../../../../Validation/validation.js";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
const useValidateInfrastructureForm = () => {
const [errors, setErrors] = useState({});
diff --git a/client/src/Pages/v1/Infrastructure/Create/index.jsx b/client/src/Pages/Infrastructure/Create/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Infrastructure/Create/index.jsx
rename to client/src/Pages/Infrastructure/Create/index.jsx
index c74d49816..b27c11cd4 100644
--- a/client/src/Pages/v1/Infrastructure/Create/index.jsx
+++ b/client/src/Pages/Infrastructure/Create/index.jsx
@@ -13,8 +13,8 @@ import CustomAlertsSection from "./Components/CustomAlertsSection.jsx";
import DiskSelection from "./Components/DiskSelection.jsx";
// Utils
import NotificationsConfig from "@/Components/v1/NotificationConfig/index.jsx";
-import { useGetNotificationsByTeamId } from "../../../../Hooks/v1/useNotifications.js";
-import { networkService } from "../../../../Utils/NetworkService";
+import { useGetNotificationsByTeamId } from "../../../Hooks/useNotifications.js";
+import { networkService } from "../../../Utils/NetworkService.js";
import { useParams } from "react-router-dom";
import { useState, useEffect } from "react";
import { useTheme } from "@emotion/react";
@@ -24,7 +24,7 @@ import {
useFetchGlobalSettings,
useFetchHardwareMonitorById,
usePauseMonitor,
-} from "../../../../Hooks/v1/monitorHooks.js";
+} from "../../../Hooks/monitorHooks.js";
import useInfrastructureMonitorForm from "./hooks/useInfrastructureMonitorForm.jsx";
import useValidateInfrastructureForm from "./hooks/useValidateInfrastructureForm.jsx";
import useInfrastructureSubmit from "./hooks/useInfrastructureSubmit.jsx";
@@ -150,7 +150,8 @@ const CreateInfrastructureMonitor = () => {
const handleRemove = async (event) => {
event.preventDefault();
- await deleteMonitor({ monitor, redirect: "/infrastructure" });
+ const TEMP_MONITOR = { id: monitor._id };
+ await deleteMonitor({ monitor: TEMP_MONITOR, redirect: "/infrastructure" });
};
const isBusy =
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/AreaChartBoxes/InfraAreaChart.jsx b/client/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/InfraAreaChart.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/AreaChartBoxes/InfraAreaChart.jsx
rename to client/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/InfraAreaChart.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/AreaChartBoxes/index.jsx b/client/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/AreaChartBoxes/index.jsx
rename to client/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/index.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/AreaChartBoxes/skeleton.jsx b/client/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/AreaChartBoxes/skeleton.jsx
rename to client/src/Pages/Infrastructure/Details/Components/AreaChartBoxes/skeleton.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/BaseContainer/index.jsx b/client/src/Pages/Infrastructure/Details/Components/BaseContainer/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/BaseContainer/index.jsx
rename to client/src/Pages/Infrastructure/Details/Components/BaseContainer/index.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx b/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx
rename to client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/Gauge.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/GaugeBoxes/index.jsx b/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/GaugeBoxes/index.jsx
rename to client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/index.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/GaugeBoxes/skeleton.jsx b/client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/GaugeBoxes/skeleton.jsx
rename to client/src/Pages/Infrastructure/Details/Components/GaugeBoxes/skeleton.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
rename to client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkCharts.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx
rename to client/src/Pages/Infrastructure/Details/Components/NetworkStats/NetworkStatBoxes.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/index.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/index.jsx
rename to client/src/Pages/Infrastructure/Details/Components/NetworkStats/index.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/skeleton.jsx b/client/src/Pages/Infrastructure/Details/Components/NetworkStats/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Components/NetworkStats/skeleton.jsx
rename to client/src/Pages/Infrastructure/Details/Components/NetworkStats/skeleton.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/Components/StatusBoxes/index.jsx b/client/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Infrastructure/Details/Components/StatusBoxes/index.jsx
rename to client/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx
index 7f09e82d5..ef91709cf 100644
--- a/client/src/Pages/v1/Infrastructure/Details/Components/StatusBoxes/index.jsx
+++ b/client/src/Pages/Infrastructure/Details/Components/StatusBoxes/index.jsx
@@ -4,7 +4,7 @@ import StatusBoxes from "@/Components/v1/StatusBoxes/index.jsx";
import StatBox from "@/Components/v1/StatBox/index.jsx";
//Utils
-import { useMonitorUtils } from "../../../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../../../Hooks/useMonitorUtils.js";
import { useHardwareUtils } from "../../Hooks/useHardwareUtils.jsx";
import { useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/Infrastructure/Details/Hooks/useHardwareUtils.jsx b/client/src/Pages/Infrastructure/Details/Hooks/useHardwareUtils.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Details/Hooks/useHardwareUtils.jsx
rename to client/src/Pages/Infrastructure/Details/Hooks/useHardwareUtils.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Details/index.jsx b/client/src/Pages/Infrastructure/Details/index.jsx
similarity index 96%
rename from client/src/Pages/v1/Infrastructure/Details/index.jsx
rename to client/src/Pages/Infrastructure/Details/index.jsx
index f9c51c27d..62a5c2642 100644
--- a/client/src/Pages/v1/Infrastructure/Details/index.jsx
+++ b/client/src/Pages/Infrastructure/Details/index.jsx
@@ -13,8 +13,8 @@ import TabContext from "@mui/lab/TabContext";
// Utils
import { useTheme } from "@emotion/react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
-import { useFetchHardwareMonitorById } from "../../../../Hooks/v1/monitorHooks.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
+import { useFetchHardwareMonitorById } from "../../../Hooks/monitorHooks.js";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
diff --git a/client/src/Pages/v1/Infrastructure/Monitors/Components/Filters/index.jsx b/client/src/Pages/Infrastructure/Monitors/Components/Filters/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Infrastructure/Monitors/Components/Filters/index.jsx
rename to client/src/Pages/Infrastructure/Monitors/Components/Filters/index.jsx
diff --git a/client/src/Pages/v1/Infrastructure/Monitors/Components/MonitorsTable/index.jsx b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
similarity index 95%
rename from client/src/Pages/v1/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
rename to client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
index cc2cd5f98..5f0360312 100644
--- a/client/src/Pages/v1/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
+++ b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTable/index.jsx
@@ -7,12 +7,12 @@ import { Stack } from "@mui/material";
import { InfrastructureMenu } from "../MonitorsTableMenu/index.jsx";
import LoadingSpinner from "../../../../Uptime/Monitors/Components/LoadingSpinner/index.jsx";
// Assets
-import CPUChipIcon from "../../../../../../assets/icons/cpu-chip.svg?react";
+import CPUChipIcon from "@/assets/icons/cpu-chip.svg?react";
import CustomGauge from "@/Components/v1/Charts/CustomGauge/index.jsx";
// Utils
import { useTheme } from "@emotion/react";
-import { useMonitorUtils } from "../../../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../../../Hooks/useMonitorUtils.js";
import { useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
@@ -115,7 +115,7 @@ const MonitorsTable = ({
: theme.palette.success.main;
return {
- id: monitor._id,
+ id: monitor.id,
name: monitor.name,
url: monitor.url,
processor,
diff --git a/client/src/Pages/v1/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx
similarity index 94%
rename from client/src/Pages/v1/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx
rename to client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx
index d3af34d00..39aa84e90 100644
--- a/client/src/Pages/v1/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx
+++ b/client/src/Pages/Infrastructure/Monitors/Components/MonitorsTableMenu/index.jsx
@@ -3,13 +3,13 @@
import { useRef, useState } from "react";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
-import { createToast } from "../../../../../../Utils/toastUtils.jsx";
+import { createToast } from "@/Utils/toastUtils.jsx";
import { IconButton, Menu, MenuItem } from "@mui/material";
-import Settings from "../../../../../../assets/icons/settings-bold.svg?react";
+import Settings from "@/assets/icons/settings-bold.svg?react";
import PropTypes from "prop-types";
import Dialog from "@/Components/v1/Dialog/index.jsx";
-import { networkService } from "../../../../../../Utils/NetworkService.js";
-import { usePauseMonitor } from "../../../../../../Hooks/v1/monitorHooks.js";
+import { networkService } from "@/Utils/NetworkService.js";
+import { usePauseMonitor } from "@/Hooks/monitorHooks.js";
import { useTranslation } from "react-i18next";
/**
diff --git a/client/src/Pages/v1/Infrastructure/Monitors/index.jsx b/client/src/Pages/Infrastructure/Monitors/index.jsx
similarity index 89%
rename from client/src/Pages/v1/Infrastructure/Monitors/index.jsx
rename to client/src/Pages/Infrastructure/Monitors/index.jsx
index 6c3a657ab..b25636fa9 100644
--- a/client/src/Pages/v1/Infrastructure/Monitors/index.jsx
+++ b/client/src/Pages/Infrastructure/Monitors/index.jsx
@@ -11,11 +11,12 @@ import SearchComponent from "../../Uptime/Monitors/Components/SearchComponent/in
// Utils
import { useTheme } from "@emotion/react";
import { useEffect, useState } from "react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
import { useTranslation } from "react-i18next";
-import { useFetchMonitorsByTeamId } from "../../../../Hooks/v1/monitorHooks.js";
+import { useFetchMonitorsWithChecks } from "@/Hooks/monitorHooks.js";
+
import { useDispatch, useSelector } from "react-redux";
-import { setRowsPerPage } from "../../../../Features/UI/uiSlice.js";
+import { setRowsPerPage } from "../../../Features/UI/uiSlice.js";
// Constants
const TYPES = ["hardware"];
const BREADCRUMBS = [{ name: `infrastructure`, path: "/infrastructure" }];
@@ -70,14 +71,14 @@ const InfrastructureMonitors = () => {
const field = toFilterStatus !== undefined ? "status" : undefined;
- const [monitors, summary, isLoading, networkError] = useFetchMonitorsByTeamId({
- limit: 1,
+ const [monitors, count, isLoading, networkError] = useFetchMonitorsWithChecks({
types: TYPES,
- page,
+ limit: 1,
+ page: page,
field: field,
filter: toFilterStatus ?? search,
- rowsPerPage,
- updateTrigger,
+ rowsPerPage: rowsPerPage,
+ monitorUpdateTrigger: updateTrigger,
});
return (
@@ -99,7 +100,7 @@ const InfrastructureMonitors = () => {
{
isSearching={isSearching}
/>
{
@@ -26,12 +26,12 @@ const Diagnostics = () => {
status="up"
heading={t("status")}
subHeading={
- error
+ error
? t("logsPage.logLevelSelect.values.error")
- : isLoading
+ : isLoading
? t("commonSaving")
- : diagnostics
- ? t("diagnosticsPage.diagnosticDescription")
+ : diagnostics
+ ? t("diagnosticsPage.diagnosticDescription")
: t("general.noOptionsFound", { unit: "data" })
}
/>
diff --git a/client/src/Pages/v1/Logs/Diagnostics/utils/utils.js b/client/src/Pages/Logs/Diagnostics/utils/utils.js
similarity index 100%
rename from client/src/Pages/v1/Logs/Diagnostics/utils/utils.js
rename to client/src/Pages/Logs/Diagnostics/utils/utils.js
diff --git a/client/src/Pages/v1/Logs/Logs/index.jsx b/client/src/Pages/Logs/Logs/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Logs/Logs/index.jsx
rename to client/src/Pages/Logs/Logs/index.jsx
index 64c4cb97a..c44a83ed9 100644
--- a/client/src/Pages/v1/Logs/Logs/index.jsx
+++ b/client/src/Pages/Logs/Logs/index.jsx
@@ -4,7 +4,7 @@ import Select from "@/Components/v1/Inputs/Select/index.jsx";
import Typography from "@mui/material/Typography";
import Divider from "@mui/material/Divider";
-import { useFetchLogs } from "../../../../Hooks/v1/logHooks.js";
+import { useFetchLogs } from "../../../Hooks/logHooks.js";
import { useTheme } from "@emotion/react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
@@ -51,7 +51,6 @@ const Logs = () => {
];
return (
-
{
MonitorListItem.propTypes = {
monitor: PropTypes.shape({
- _id: PropTypes.string.isRequired,
+ id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}).isRequired,
onDelete: PropTypes.func.isRequired,
@@ -33,7 +33,7 @@ MonitorListItem.propTypes = {
const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => {
const onDelete = (monitorToDelete) => {
const newMonitors = selectedMonitors.filter(
- (monitor) => monitor._id !== monitorToDelete._id
+ (monitor) => monitor.id !== monitorToDelete.id
);
setSelectedMonitors(newMonitors);
};
@@ -47,7 +47,7 @@ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => {
>
{selectedMonitors?.map((monitor) => (
@@ -59,7 +59,7 @@ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => {
MonitorList.propTypes = {
selectedMonitors: PropTypes.arrayOf(
PropTypes.shape({
- _id: PropTypes.string.isRequired,
+ id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
})
).isRequired,
diff --git a/client/src/Pages/v1/Maintenance/CreateMaintenance/Components/MonitorsConfig/index.jsx b/client/src/Pages/Maintenance/CreateMaintenance/Components/MonitorsConfig/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Maintenance/CreateMaintenance/Components/MonitorsConfig/index.jsx
rename to client/src/Pages/Maintenance/CreateMaintenance/Components/MonitorsConfig/index.jsx
diff --git a/client/src/Pages/v1/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx
similarity index 81%
rename from client/src/Pages/v1/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx
rename to client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx
index a75cbe206..22a61084d 100644
--- a/client/src/Pages/v1/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx
+++ b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceActions.jsx
@@ -1,4 +1,4 @@
-import { networkService } from "../../../../../main.jsx";
+import { networkService } from "../../../../main.jsx";
import dayjs from "dayjs";
import {
MS_PER_SECOND,
@@ -6,7 +6,7 @@ import {
MS_PER_HOUR,
MS_PER_DAY,
MS_PER_WEEK,
-} from "../../../../../Utils/timeUtils.js";
+} from "../../../../Utils/timeUtils.js";
const useMaintenanceActions = () => {
const MS_LOOKUP = {
@@ -22,6 +22,12 @@ const useMaintenanceActions = () => {
weekly: MS_PER_DAY * 7,
};
const handleSubmitForm = async (maintenanceWindowId, form) => {
+ const toStringId = (monitor) => {
+ if (!monitor) {
+ return "";
+ }
+ return monitor._id ?? monitor.id ?? "";
+ };
const start = dayjs(form.startDate)
.set("hour", form.startTime.hour())
.set("minute", form.startTime.minute());
@@ -33,7 +39,7 @@ const useMaintenanceActions = () => {
const repeat = REPEAT_LOOKUP[form.repeat];
const submit = {
- monitors: form.monitors.map((monitor) => monitor._id),
+ monitors: form.monitors.map((monitor) => toStringId(monitor)).filter(Boolean),
name: form.name,
start: start.toISOString(),
end: end.toISOString(),
diff --git a/client/src/Pages/v1/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx
similarity index 88%
rename from client/src/Pages/v1/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx
rename to client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx
index d21906e41..3414334a7 100644
--- a/client/src/Pages/v1/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx
+++ b/client/src/Pages/Maintenance/CreateMaintenance/hooks/useMaintenanceData.jsx
@@ -1,4 +1,4 @@
-import { networkService } from "../../../../../main.jsx";
+import { networkService } from "../../../../main.jsx";
import dayjs from "dayjs";
import {
MS_PER_SECOND,
@@ -6,7 +6,7 @@ import {
MS_PER_HOUR,
MS_PER_DAY,
MS_PER_WEEK,
-} from "../../../../../Utils/timeUtils.js";
+} from "../../../../Utils/timeUtils.js";
const useMaintenanceData = () => {
const REVERSE_REPEAT_LOOKUP = {
0: "none",
@@ -41,7 +41,7 @@ const useMaintenanceData = () => {
limit: null,
types: ["http", "ping", "pagespeed", "port"],
});
- const fetchedMonitors = response.data.data.monitors;
+ const fetchedMonitors = response.data.data;
return fetchedMonitors;
};
@@ -55,7 +55,9 @@ const useMaintenanceData = () => {
const endTime = dayjs(end);
const durationInMs = endTime.diff(startTime, "milliseconds").toString();
const { duration, durationUnit } = getDurationAndUnit(durationInMs);
- const monitor = monitorList.find((monitor) => monitor._id === monitorId);
+ const monitor = monitorList.find(
+ (monitor) => (monitor._id ?? monitor.id) === monitorId
+ );
const maintenanceWindowInformation = {
name,
repeat: REVERSE_REPEAT_LOOKUP[repeat],
diff --git a/client/src/Pages/v1/Maintenance/CreateMaintenance/index.css b/client/src/Pages/Maintenance/CreateMaintenance/index.css
similarity index 100%
rename from client/src/Pages/v1/Maintenance/CreateMaintenance/index.css
rename to client/src/Pages/Maintenance/CreateMaintenance/index.css
diff --git a/client/src/Pages/v1/Maintenance/CreateMaintenance/index.jsx b/client/src/Pages/Maintenance/CreateMaintenance/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Maintenance/CreateMaintenance/index.jsx
rename to client/src/Pages/Maintenance/CreateMaintenance/index.jsx
index d0e7b03cd..759679a2d 100644
--- a/client/src/Pages/v1/Maintenance/CreateMaintenance/index.jsx
+++ b/client/src/Pages/Maintenance/CreateMaintenance/index.jsx
@@ -7,8 +7,8 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider } from "@mui/x-date-pickers";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { MobileTimePicker } from "@mui/x-date-pickers/MobileTimePicker";
-import { maintenanceWindowValidation } from "../../../../Validation/validation.js";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { maintenanceWindowValidation } from "@/Validation/validation.js";
+import { createToast } from "@/Utils/toastUtils.jsx";
import MonitorList from "./Components/MonitorList/index.jsx";
import ConfigSelect from "./Components/ConfigSelect/index.jsx";
import useMaintenanceData from "./hooks/useMaintenanceData.jsx";
@@ -16,13 +16,13 @@ import useMaintenanceActions from "./hooks/useMaintenanceActions.jsx";
import TextInput from "@/Components/v1/Inputs/TextInput/index.jsx";
import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
-import CalendarIcon from "../../../../assets/icons/calendar.svg?react";
+import CalendarIcon from "@/assets/icons/calendar.svg?react";
import "./index.css";
import Search from "@/Components/v1/Inputs/Search/index.jsx";
-import { logger } from "../../../../Utils/Logger.js";
+import { logger } from "@/Utils/Logger.js";
import { useNavigate, useParams } from "react-router-dom";
-import { buildErrors, hasValidationErrors } from "../../../../Validation/error.js";
+import { buildErrors, hasValidationErrors } from "@/Validation/error.js";
import { useTranslation } from "react-i18next";
import dayjs from "dayjs";
@@ -108,6 +108,7 @@ const CreateMaintenance = () => {
const handleSubmit = async () => {
if (hasValidationErrors(form, maintenanceWindowValidation, setErrors)) return;
+
const request = handleSubmitForm(maintenanceWindowId, form);
try {
setIsLoading(true);
diff --git a/client/src/Pages/v1/Maintenance/MaintenanceTable/ActionsMenu/index.jsx b/client/src/Pages/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
similarity index 93%
rename from client/src/Pages/v1/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
rename to client/src/Pages/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
index b2654da49..38a3d8e64 100644
--- a/client/src/Pages/v1/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
+++ b/client/src/Pages/Maintenance/MaintenanceTable/ActionsMenu/index.jsx
@@ -3,11 +3,11 @@ import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";
import { IconButton, Menu, MenuItem } from "@mui/material";
-import { logger } from "../../../../../Utils/Logger.js";
-import Settings from "../../../../../assets/icons/settings-bold.svg?react";
+import { logger } from "@/Utils/Logger.js";
+import Settings from "@/assets/icons/settings-bold.svg?react";
import PropTypes from "prop-types";
-import { networkService } from "../../../../../main.jsx";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { networkService } from "../../../../main.jsx";
+import { createToast } from "@/Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
import Dialog from "@/Components/v1/Dialog/index.jsx";
diff --git a/client/src/Pages/v1/Maintenance/MaintenanceTable/index.jsx b/client/src/Pages/Maintenance/MaintenanceTable/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Maintenance/MaintenanceTable/index.jsx
rename to client/src/Pages/Maintenance/MaintenanceTable/index.jsx
index f1d44f944..faeb2072c 100644
--- a/client/src/Pages/v1/Maintenance/MaintenanceTable/index.jsx
+++ b/client/src/Pages/Maintenance/MaintenanceTable/index.jsx
@@ -7,9 +7,9 @@ import ArrowUpwardRoundedIcon from "@mui/icons-material/ArrowUpwardRounded";
import ActionsMenu from "./ActionsMenu/index.jsx";
import { memo } from "react";
import { useDispatch, useSelector } from "react-redux";
-import { formatDurationRounded } from "../../../../Utils/timeUtils.js";
+import { formatDurationRounded } from "../../../Utils/timeUtils.js";
import { StatusLabel } from "@/Components/v1/Label/index.jsx";
-import { setRowsPerPage } from "../../../../Features/UI/uiSlice.js";
+import { setRowsPerPage } from "../../../Features/UI/uiSlice.js";
import { useTranslation } from "react-i18next";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
diff --git a/client/src/Pages/v1/Maintenance/index.css b/client/src/Pages/Maintenance/index.css
similarity index 100%
rename from client/src/Pages/v1/Maintenance/index.css
rename to client/src/Pages/Maintenance/index.css
diff --git a/client/src/Pages/v1/Maintenance/index.jsx b/client/src/Pages/Maintenance/index.jsx
similarity index 98%
rename from client/src/Pages/v1/Maintenance/index.jsx
rename to client/src/Pages/Maintenance/index.jsx
index cba0e9f18..b49cd9f6e 100644
--- a/client/src/Pages/v1/Maintenance/index.jsx
+++ b/client/src/Pages/Maintenance/index.jsx
@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
import "./index.css";
import MaintenanceTable from "./MaintenanceTable/index.jsx";
import { useSelector } from "react-redux";
-import { networkService } from "../../../main.jsx";
+import { networkService } from "../../main.jsx";
import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/NotFound/index.jsx b/client/src/Pages/NotFound/index.jsx
similarity index 96%
rename from client/src/Pages/v1/NotFound/index.jsx
rename to client/src/Pages/NotFound/index.jsx
index 48825c9f6..27e3173b0 100644
--- a/client/src/Pages/v1/NotFound/index.jsx
+++ b/client/src/Pages/NotFound/index.jsx
@@ -1,5 +1,5 @@
import PropTypes from "prop-types";
-import NotFoundSvg from "../../../assets/Images/sushi_404.svg";
+import NotFoundSvg from "@/assets/Images/sushi_404.svg";
import { Button, Stack, Typography } from "@mui/material";
import { useNavigate } from "react-router-dom";
import { useTheme } from "@emotion/react";
diff --git a/client/src/Pages/v1/Notifications/components/ActionMenu.jsx b/client/src/Pages/Notifications/components/ActionMenu.jsx
similarity index 100%
rename from client/src/Pages/v1/Notifications/components/ActionMenu.jsx
rename to client/src/Pages/Notifications/components/ActionMenu.jsx
diff --git a/client/src/Pages/v1/Notifications/create/index.jsx b/client/src/Pages/Notifications/create/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Notifications/create/index.jsx
rename to client/src/Pages/Notifications/create/index.jsx
index b1c50493c..11bf2a95d 100644
--- a/client/src/Pages/v1/Notifications/create/index.jsx
+++ b/client/src/Pages/Notifications/create/index.jsx
@@ -18,9 +18,9 @@ import {
useEditNotification,
useTestNotification,
useDeleteNotification,
-} from "../../../../Hooks/v1/useNotifications.js";
-import { notificationValidation } from "../../../../Validation/validation.js";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+} from "../../../Hooks/useNotifications.js";
+import { notificationValidation } from "../../../Validation/validation.js";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
import { useParams, useNavigate } from "react-router-dom";
import {
diff --git a/client/src/Pages/v1/Notifications/index.jsx b/client/src/Pages/Notifications/index.jsx
similarity index 98%
rename from client/src/Pages/v1/Notifications/index.jsx
rename to client/src/Pages/Notifications/index.jsx
index 78ec6e9bb..8ebdb22ec 100644
--- a/client/src/Pages/v1/Notifications/index.jsx
+++ b/client/src/Pages/Notifications/index.jsx
@@ -14,7 +14,7 @@ import { useNavigate } from "react-router-dom";
import {
useGetNotificationsByTeamId,
useDeleteNotification,
-} from "../../../Hooks/v1/useNotifications.js";
+} from "../../Hooks/useNotifications.js";
import { useTranslation } from "react-i18next";
const Notifications = () => {
diff --git a/client/src/Pages/v1/Notifications/utils.js b/client/src/Pages/Notifications/utils.js
similarity index 100%
rename from client/src/Pages/v1/Notifications/utils.js
rename to client/src/Pages/Notifications/utils.js
diff --git a/client/src/Pages/v1/PageSpeed/Create/index.css b/client/src/Pages/PageSpeed/Create/index.css
similarity index 100%
rename from client/src/Pages/v1/PageSpeed/Create/index.css
rename to client/src/Pages/PageSpeed/Create/index.css
diff --git a/client/src/Pages/v1/PageSpeed/Create/index.jsx b/client/src/Pages/PageSpeed/Create/index.jsx
similarity index 96%
rename from client/src/Pages/v1/PageSpeed/Create/index.jsx
rename to client/src/Pages/PageSpeed/Create/index.jsx
index cb856bd37..2cce26159 100644
--- a/client/src/Pages/v1/PageSpeed/Create/index.jsx
+++ b/client/src/Pages/PageSpeed/Create/index.jsx
@@ -16,22 +16,22 @@ import Radio from "@/Components/v1/Inputs/Radio/index.jsx";
// Utils
import { useState, useEffect } from "react";
import { useSelector } from "react-redux";
-import { monitorValidation } from "../../../../Validation/validation.js";
-import { parseDomainName } from "../../../../Utils/monitorUtils.js";
+import { monitorValidation } from "../../../Validation/validation.js";
+import { parseDomainName } from "../../../Utils/monitorUtils.js";
import { useTranslation } from "react-i18next";
-import { useGetNotificationsByTeamId } from "../../../../Hooks/v1/useNotifications.js";
+import { useGetNotificationsByTeamId } from "../../../Hooks/useNotifications.js";
import { useTheme } from "@emotion/react";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import { useParams } from "react-router";
-import { useMonitorUtils } from "../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../Hooks/useMonitorUtils.js";
import {
useCreateMonitor,
useFetchMonitorById,
useDeleteMonitor,
useUpdateMonitor,
usePauseMonitor,
-} from "../../../../Hooks/v1/monitorHooks.js";
+} from "../../../Hooks/monitorHooks.js";
const PageSpeedSetup = () => {
const { monitorId } = useParams();
@@ -178,7 +178,8 @@ const PageSpeedSetup = () => {
const handleRemove = async (event) => {
event.preventDefault();
- await deleteMonitor({ monitor, redirect: "/pagespeed" });
+ const TEMP_MONITOR = { id: monitor._id };
+ await deleteMonitor({ monitor: TEMP_MONITOR, redirect: "/pagespeed" });
};
const isBusy = isLoading || isCreating || isDeleting || isUpdating || isPausing;
diff --git a/client/src/Pages/v1/PageSpeed/Create/skeleton.jsx b/client/src/Pages/PageSpeed/Create/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/PageSpeed/Create/skeleton.jsx
rename to client/src/Pages/PageSpeed/Create/skeleton.jsx
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/AreaChart.jsx b/client/src/Pages/PageSpeed/Details/Components/Charts/AreaChart.jsx
similarity index 99%
rename from client/src/Pages/v1/PageSpeed/Details/Components/Charts/AreaChart.jsx
rename to client/src/Pages/PageSpeed/Details/Components/Charts/AreaChart.jsx
index 5c79cc06c..06b92c933 100644
--- a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/AreaChart.jsx
+++ b/client/src/Pages/PageSpeed/Details/Components/Charts/AreaChart.jsx
@@ -11,7 +11,7 @@ import {
import { useTheme } from "@emotion/react";
import { useMemo, useState } from "react";
import { Box, Stack, Typography } from "@mui/material";
-import { formatDateWithTz } from "../../../../../../Utils/timeUtils.js";
+import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
import { useSelector } from "react-redux";
const config = {
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx b/client/src/Pages/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx
similarity index 94%
rename from client/src/Pages/v1/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx
rename to client/src/Pages/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx
index c0da1600f..113e4d618 100644
--- a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx
+++ b/client/src/Pages/PageSpeed/Details/Components/Charts/AreaChartLegend.jsx
@@ -1,6 +1,6 @@
import { Box, Typography, Divider } from "@mui/material";
import Checkbox from "@/Components/v1/Inputs/Checkbox/index.jsx";
-import MetricsIcon from "../../../../../../assets/icons/ruler-icon.svg?react";
+import MetricsIcon from "@/assets/icons/ruler-icon.svg?react";
import LegendBox from "@/Components/v1/Charts/LegendBox/index.jsx";
import { useTranslation } from "react-i18next";
import { useTheme } from "@emotion/react";
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/PieChart.jsx b/client/src/Pages/PageSpeed/Details/Components/Charts/PieChart.jsx
similarity index 100%
rename from client/src/Pages/v1/PageSpeed/Details/Components/Charts/PieChart.jsx
rename to client/src/Pages/PageSpeed/Details/Components/Charts/PieChart.jsx
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/PieChartLegend.jsx b/client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx
similarity index 96%
rename from client/src/Pages/v1/PageSpeed/Details/Components/Charts/PieChartLegend.jsx
rename to client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx
index 1297bd699..43e2371b4 100644
--- a/client/src/Pages/v1/PageSpeed/Details/Components/Charts/PieChartLegend.jsx
+++ b/client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx
@@ -1,7 +1,7 @@
import { Stack, Box, Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
import LegendBox from "@/Components/v1/Charts/LegendBox/index.jsx";
-import SpeedometerIcon from "../../../../../../assets/icons/speedometer-icon.svg?react";
+import SpeedometerIcon from "@/assets/icons/speedometer-icon.svg?react";
import PropTypes from "prop-types";
const PieChartLegend = ({ audits }) => {
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx b/client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx
similarity index 93%
rename from client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx
rename to client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx
index 1281a396e..aa88d57e5 100644
--- a/client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx
+++ b/client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx
@@ -2,7 +2,7 @@ import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
import AreaChart from "../Charts/AreaChart.jsx";
import AreaChartLegend from "../Charts/AreaChartLegend.jsx";
import SkeletonLayout from "./skeleton.jsx";
-import ScoreIcon from "../../../../../../assets/icons/monitor-graph-line.svg?react";
+import ScoreIcon from "@/assets/icons/monitor-graph-line.svg?react";
import { Stack } from "@mui/material";
import PropTypes from "prop-types";
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedAreaChart/skeleton.jsx b/client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedAreaChart/skeleton.jsx
rename to client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/skeleton.jsx
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx b/client/src/Pages/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx
similarity index 91%
rename from client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx
rename to client/src/Pages/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx
index ff265317c..493d1ece6 100644
--- a/client/src/Pages/v1/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx
+++ b/client/src/Pages/PageSpeed/Details/Components/PageSpeedStatusBoxes/index.jsx
@@ -1,7 +1,7 @@
import StatusBoxes from "@/Components/v1/StatusBoxes/index.jsx";
import StatBox from "@/Components/v1/StatBox/index.jsx";
import { Typography } from "@mui/material";
-import { getHumanReadableDuration } from "../../../../../../Utils/timeUtils.js";
+import { getHumanReadableDuration } from "../../../../../Utils/timeUtils.js";
import { useTranslation } from "react-i18next";
const PageSpeedStatusBoxes = ({ shouldRender, monitor }) => {
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/PerformanceReport/index.jsx b/client/src/Pages/PageSpeed/Details/Components/PerformanceReport/index.jsx
similarity index 93%
rename from client/src/Pages/v1/PageSpeed/Details/Components/PerformanceReport/index.jsx
rename to client/src/Pages/PageSpeed/Details/Components/PerformanceReport/index.jsx
index 27f9e885b..c2eecaa6a 100644
--- a/client/src/Pages/v1/PageSpeed/Details/Components/PerformanceReport/index.jsx
+++ b/client/src/Pages/PageSpeed/Details/Components/PerformanceReport/index.jsx
@@ -1,5 +1,5 @@
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
-import PerformanceIcon from "../../../../../../assets/icons/performance-report.svg?react";
+import PerformanceIcon from "@/assets/icons/performance-report.svg?react";
import PieChart from "../Charts/PieChart.jsx";
import { Typography } from "@mui/material";
import { useTheme } from "@emotion/react";
diff --git a/client/src/Pages/v1/PageSpeed/Details/Components/PerformanceReport/skeleton.jsx b/client/src/Pages/PageSpeed/Details/Components/PerformanceReport/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/PageSpeed/Details/Components/PerformanceReport/skeleton.jsx
rename to client/src/Pages/PageSpeed/Details/Components/PerformanceReport/skeleton.jsx
diff --git a/client/src/Pages/v1/PageSpeed/Details/index.jsx b/client/src/Pages/PageSpeed/Details/index.jsx
similarity index 88%
rename from client/src/Pages/v1/PageSpeed/Details/index.jsx
rename to client/src/Pages/PageSpeed/Details/index.jsx
index 836f0ca37..df411048a 100644
--- a/client/src/Pages/v1/PageSpeed/Details/index.jsx
+++ b/client/src/Pages/PageSpeed/Details/index.jsx
@@ -9,16 +9,15 @@ import PerformanceReport from "./Components/PerformanceReport/index.jsx";
import GenericFallback from "@/Components/v1/GenericFallback/index.jsx";
// Utils
import { useTheme } from "@emotion/react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
import { useParams } from "react-router-dom";
-import { useFetchStatsByMonitorId } from "../../../../Hooks/v1/monitorHooks.js";
+import { useFetchPageSpeedMonitorById } from "../../../Hooks/monitorHooks.js";
import { useState } from "react";
import { useTranslation } from "react-i18next";
// Constants
const BREADCRUMBS = [
{ name: "pagespeed", path: "/pagespeed" },
{ name: "details", path: `` },
- // { name: "details", path: `/pagespeed/${monitorId}` }, // Not needed?
];
const PageSpeedDetails = () => {
@@ -36,13 +35,9 @@ const PageSpeedDetails = () => {
});
const [trigger, setTrigger] = useState(false);
// Network
- const [monitor, audits, isLoading, networkError] = useFetchStatsByMonitorId({
+ const [monitor, isLoading, networkError] = useFetchPageSpeedMonitorById({
monitorId,
- sortOrder: "desc",
- limit: 50,
dateRange: "day",
- numToDisplay: null,
- normalize: null,
updateTrigger: trigger,
});
@@ -116,7 +111,7 @@ const PageSpeedDetails = () => {
/>
);
diff --git a/client/src/Pages/v1/PageSpeed/Monitors/Components/Card/index.jsx b/client/src/Pages/PageSpeed/Monitors/Components/Card/index.jsx
similarity index 96%
rename from client/src/Pages/v1/PageSpeed/Monitors/Components/Card/index.jsx
rename to client/src/Pages/PageSpeed/Monitors/Components/Card/index.jsx
index 4e551526b..8a6444d1b 100644
--- a/client/src/Pages/v1/PageSpeed/Monitors/Components/Card/index.jsx
+++ b/client/src/Pages/PageSpeed/Monitors/Components/Card/index.jsx
@@ -1,17 +1,14 @@
import PropTypes from "prop-types";
// import PageSpeedIcon from "../../../../assets/icons/page-speed.svg?react";
-import PageSpeedIcon from "../../../../../../assets/icons/page-speed.svg?react";
+import PageSpeedIcon from "@/assets/icons/page-speed.svg?react";
import { StatusLabel } from "@/Components/v1/Label/index.jsx";
import { Box, Grid, Stack, Typography } from "@mui/material";
import { useNavigate } from "react-router-dom";
import { useTheme } from "@emotion/react";
import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip } from "recharts";
import { useSelector } from "react-redux";
-import {
- formatDateWithTz,
- formatDurationSplit,
-} from "../../../../../../Utils/timeUtils.js";
-import { useMonitorUtils } from "../../../../../../Hooks/v1/useMonitorUtils.js";
+import { formatDateWithTz, formatDurationSplit } from "@/Utils/timeUtils.js";
+import { useMonitorUtils } from "@/Hooks/useMonitorUtils.js";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import IconBox from "@/Components/v1/IconBox/index.jsx";
@@ -224,7 +221,7 @@ const Card = ({ monitor }) => {
navigate(`/pagespeed/${monitor._id}`)}
+ onClick={() => navigate(`/pagespeed/${monitor.id}`)}
border={1}
borderColor={theme.palette.primary.lowContrast}
borderRadius={theme.shape.borderRadius}
diff --git a/client/src/Pages/v1/PageSpeed/Monitors/Components/MonitorGrid/index.jsx b/client/src/Pages/PageSpeed/Monitors/Components/MonitorGrid/index.jsx
similarity index 100%
rename from client/src/Pages/v1/PageSpeed/Monitors/Components/MonitorGrid/index.jsx
rename to client/src/Pages/PageSpeed/Monitors/Components/MonitorGrid/index.jsx
diff --git a/client/src/Pages/v1/PageSpeed/Monitors/index.jsx b/client/src/Pages/PageSpeed/Monitors/index.jsx
similarity index 70%
rename from client/src/Pages/v1/PageSpeed/Monitors/index.jsx
rename to client/src/Pages/PageSpeed/Monitors/index.jsx
index 7485a72c9..4530a41e9 100644
--- a/client/src/Pages/v1/PageSpeed/Monitors/index.jsx
+++ b/client/src/Pages/PageSpeed/Monitors/index.jsx
@@ -10,9 +10,9 @@ import FallbackPageSpeedWarning from "@/Components/v1/Fallback/FallbackPageSpeed
// Utils
import { useTheme } from "@emotion/react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
-import { useFetchMonitorsByTeamId } from "../../../../Hooks/v1/monitorHooks.js";
-import { useFetchSettings } from "../../../../Hooks/v1/settingsHooks.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
+import { useFetchMonitorsWithChecks } from "@/Hooks/monitorHooks.js";
+import { useFetchSettings } from "@/Hooks/settingsHooks.js";
// Constants
const BREADCRUMBS = [{ name: `pagespeed`, path: "/pagespeed" }];
const TYPES = ["pagespeed"];
@@ -20,14 +20,20 @@ const PageSpeed = () => {
const theme = useTheme();
const isAdmin = useIsAdmin();
- const [monitors, monitorsSummary, isLoading, networkError] = useFetchMonitorsByTeamId({
- limit: 10,
+ const [
+ monitorsWithChecks,
+ monitorsWithChecksCount,
+ monitorsWithChecksIsLoading,
+ monitorsWithChecksNetworkError,
+ ] = useFetchMonitorsWithChecks({
types: TYPES,
+ limit: 10,
page: null,
rowsPerPage: null,
filter: null,
field: null,
order: null,
+ monitorUpdateTrigger: null,
});
const [settingsData, setSettingsData] = useState(undefined);
@@ -40,9 +46,9 @@ const PageSpeed = () => {
return (
<>
{
diff --git a/client/src/Pages/v1/ServerUnreachable.jsx b/client/src/Pages/ServerUnreachable.jsx
similarity index 92%
rename from client/src/Pages/v1/ServerUnreachable.jsx
rename to client/src/Pages/ServerUnreachable.jsx
index 8230f473b..bfbbfa90a 100644
--- a/client/src/Pages/v1/ServerUnreachable.jsx
+++ b/client/src/Pages/ServerUnreachable.jsx
@@ -2,14 +2,14 @@ import React, { useState } from "react";
import { Box, Typography, Button, Stack } from "@mui/material";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
-import { networkService } from "../../Utils/NetworkService.js";
+import { networkService } from "@/Utils/NetworkService.js";
import Alert from "@/Components/v1/Alert/index.jsx";
-import { createToast } from "../../Utils/toastUtils.jsx";
+import { createToast } from "@/Utils/toastUtils.jsx";
import { useTranslation } from "react-i18next";
-import Background from "../../assets/Images/background-grid.svg?react";
-import Logo from "../../assets/icons/checkmate-icon.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
+import Logo from "@/assets/icons/checkmate-icon.svg?react";
import ThemeSwitch from "@/Components/v1/ThemeSwitch/index.jsx";
-import LanguageSelector from "../../Components/LanguageSelector.jsx";
+import LanguageSelector from "@/Components/LanguageSelector.jsx";
const ServerUnreachable = () => {
const theme = useTheme();
diff --git a/client/src/Pages/v1/Settings/SettingsAbout.jsx b/client/src/Pages/Settings/SettingsAbout.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsAbout.jsx
rename to client/src/Pages/Settings/SettingsAbout.jsx
diff --git a/client/src/Pages/v1/Settings/SettingsDemoMonitors.jsx b/client/src/Pages/Settings/SettingsDemoMonitors.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsDemoMonitors.jsx
rename to client/src/Pages/Settings/SettingsDemoMonitors.jsx
diff --git a/client/src/Pages/v1/Settings/SettingsEmail.jsx b/client/src/Pages/Settings/SettingsEmail.jsx
similarity index 98%
rename from client/src/Pages/v1/Settings/SettingsEmail.jsx
rename to client/src/Pages/Settings/SettingsEmail.jsx
index 7b5ad175e..6f0b02137 100644
--- a/client/src/Pages/v1/Settings/SettingsEmail.jsx
+++ b/client/src/Pages/Settings/SettingsEmail.jsx
@@ -12,8 +12,8 @@ import { PropTypes } from "prop-types";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { PasswordEndAdornment } from "@/Components/v1/Inputs/TextInput/Adornments/index.jsx";
-import { useSendTestEmail } from "../../../Hooks/v1/useSendTestEmail.js";
-import { createToast } from "../../../Utils/toastUtils.jsx";
+import { useSendTestEmail } from "@/Hooks/useSendTestEmail.js";
+import { createToast } from "@/Utils/toastUtils.jsx";
const SettingsEmail = ({
isAdmin,
diff --git a/client/src/Pages/v1/Settings/SettingsExport.jsx b/client/src/Pages/Settings/SettingsExport.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsExport.jsx
rename to client/src/Pages/Settings/SettingsExport.jsx
diff --git a/client/src/Pages/v1/Settings/SettingsGlobalThresholds.jsx b/client/src/Pages/Settings/SettingsGlobalThresholds.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsGlobalThresholds.jsx
rename to client/src/Pages/Settings/SettingsGlobalThresholds.jsx
diff --git a/client/src/Pages/v1/Settings/SettingsPagespeed.jsx b/client/src/Pages/Settings/SettingsPagespeed.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsPagespeed.jsx
rename to client/src/Pages/Settings/SettingsPagespeed.jsx
diff --git a/client/src/Pages/v1/Settings/SettingsStats.jsx b/client/src/Pages/Settings/SettingsStats.jsx
similarity index 86%
rename from client/src/Pages/v1/Settings/SettingsStats.jsx
rename to client/src/Pages/Settings/SettingsStats.jsx
index b68006ab2..690b306be 100644
--- a/client/src/Pages/v1/Settings/SettingsStats.jsx
+++ b/client/src/Pages/Settings/SettingsStats.jsx
@@ -36,16 +36,6 @@ const SettingsStats = ({ isAdmin, HEADING_SX, handleChange, settingsData, errors
-
{t("settingsPage.statsSettings.clearAllStatsDescription")}
diff --git a/client/src/Pages/v1/Settings/SettingsTimeZone.jsx b/client/src/Pages/Settings/SettingsTimeZone.jsx
similarity index 97%
rename from client/src/Pages/v1/Settings/SettingsTimeZone.jsx
rename to client/src/Pages/Settings/SettingsTimeZone.jsx
index f684c871d..8ed7e5b3b 100644
--- a/client/src/Pages/v1/Settings/SettingsTimeZone.jsx
+++ b/client/src/Pages/Settings/SettingsTimeZone.jsx
@@ -3,7 +3,7 @@ import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import ConfigBox from "@/Components/v1/ConfigBox/index.jsx";
import Search from "@/Components/v1/Inputs/Search/index.jsx";
-import timezones from "../../../Utils/timezones.json";
+import timezones from "@/Utils/timezones.json";
// Utils
import { useTheme } from "@emotion/react";
diff --git a/client/src/Pages/v1/Settings/SettingsUI.jsx b/client/src/Pages/Settings/SettingsUI.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsUI.jsx
rename to client/src/Pages/Settings/SettingsUI.jsx
diff --git a/client/src/Pages/v1/Settings/SettingsURL.jsx b/client/src/Pages/Settings/SettingsURL.jsx
similarity index 100%
rename from client/src/Pages/v1/Settings/SettingsURL.jsx
rename to client/src/Pages/Settings/SettingsURL.jsx
diff --git a/client/src/Pages/v1/Settings/index.jsx b/client/src/Pages/Settings/index.jsx
similarity index 95%
rename from client/src/Pages/v1/Settings/index.jsx
rename to client/src/Pages/Settings/index.jsx
index b6137121b..27cc6bb21 100644
--- a/client/src/Pages/v1/Settings/index.jsx
+++ b/client/src/Pages/Settings/index.jsx
@@ -12,27 +12,22 @@ import SettingsGlobalThresholds from "./SettingsGlobalThresholds.jsx";
import SettingsExport from "./SettingsExport.jsx";
import Button from "@mui/material/Button";
// Utils
-import { settingsValidation } from "../../../Validation/validation.js";
+import { settingsValidation } from "@/Validation/validation.js";
import { useState } from "react";
import { useTheme } from "@emotion/react";
import { useTranslation } from "react-i18next";
import { useSelector, useDispatch } from "react-redux";
-import {
- setTimezone,
- setMode,
- setLanguage,
- setShowURL,
-} from "../../../Features/UI/uiSlice.js";
+import { setTimezone, setMode, setLanguage, setShowURL } from "@/Features/UI/uiSlice.js";
import SettingsStats from "./SettingsStats.jsx";
-import { useFetchSettings, useSaveSettings } from "../../../Hooks/v1/settingsHooks.js";
-import { useIsAdmin } from "../../../Hooks/v1/useIsAdmin.js";
+import { useFetchSettings, useSaveSettings } from "@/Hooks/settingsHooks.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
import {
useAddDemoMonitors,
useDeleteAllMonitors,
useDeleteMonitorStats,
useFetchJson,
-} from "../../../Hooks/v1/monitorHooks.js";
+} from "@/Hooks/monitorHooks.js";
// Constants
const BREADCRUMBS = [{ name: `Settings`, path: "/settings" }];
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/MonitorList/index.jsx b/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx
similarity index 95%
rename from client/src/Pages/v1/StatusPage/Create/Components/MonitorList/index.jsx
rename to client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx
index 5484202d5..d2a13b2eb 100644
--- a/client/src/Pages/v1/StatusPage/Create/Components/MonitorList/index.jsx
+++ b/client/src/Pages/StatusPage/Create/Components/MonitorList/index.jsx
@@ -43,7 +43,7 @@ const MonitorListItem = ({
const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => {
const onDelete = (monitorToDelete) => {
const newMonitors = selectedMonitors.filter(
- (monitor) => monitor._id !== monitorToDelete._id
+ (monitor) => monitor.id !== monitorToDelete.id
);
setSelectedMonitors(newMonitors);
};
@@ -80,8 +80,8 @@ const MonitorList = ({ selectedMonitors, setSelectedMonitors }) => {
>
{selectedMonitors?.map((monitor, index) => (
{(provided, snapshot) => (
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/Progress/index.jsx b/client/src/Pages/StatusPage/Create/Components/Progress/index.jsx
similarity index 92%
rename from client/src/Pages/v1/StatusPage/Create/Components/Progress/index.jsx
rename to client/src/Pages/StatusPage/Create/Components/Progress/index.jsx
index 232a12f1d..2d9731ea0 100644
--- a/client/src/Pages/v1/StatusPage/Create/Components/Progress/index.jsx
+++ b/client/src/Pages/StatusPage/Create/Components/Progress/index.jsx
@@ -2,7 +2,7 @@ import { Button, Box } from "@mui/material";
import ProgressUpload from "@/Components/v1/ProgressBars/index.jsx";
import ImageIcon from "@mui/icons-material/Image";
import { useTranslation } from "react-i18next";
-import { formatBytes } from "../../../../../../Utils/fileUtils.js";
+import { formatBytes } from "../../../../../Utils/fileUtils.js";
const Progress = ({ isLoading, progressValue, logo, logoType, removeLogo, errors }) => {
const { t } = useTranslation();
if (isLoading) {
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/Skeleton/index.jsx b/client/src/Pages/StatusPage/Create/Components/Skeleton/index.jsx
similarity index 100%
rename from client/src/Pages/v1/StatusPage/Create/Components/Skeleton/index.jsx
rename to client/src/Pages/StatusPage/Create/Components/Skeleton/index.jsx
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/Tabs/ConfigStack.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx
similarity index 100%
rename from client/src/Pages/v1/StatusPage/Create/Components/Tabs/ConfigStack.jsx
rename to client/src/Pages/StatusPage/Create/Components/Tabs/ConfigStack.jsx
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/Tabs/Content.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx
similarity index 99%
rename from client/src/Pages/v1/StatusPage/Create/Components/Tabs/Content.jsx
rename to client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx
index d11825e69..e84de16dc 100644
--- a/client/src/Pages/v1/StatusPage/Create/Components/Tabs/Content.jsx
+++ b/client/src/Pages/StatusPage/Create/Components/Tabs/Content.jsx
@@ -24,7 +24,7 @@ const Content = ({
// Handlers
const handleMonitorsChange = (selectedMonitors) => {
handleFormChange({
- target: { name: "monitors", value: selectedMonitors.map((monitor) => monitor._id) },
+ target: { name: "monitors", value: selectedMonitors.map((monitor) => monitor.id) },
});
setSelectedMonitors(selectedMonitors);
};
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/Tabs/Settings.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
similarity index 98%
rename from client/src/Pages/v1/StatusPage/Create/Components/Tabs/Settings.jsx
rename to client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
index a668a9db8..d4c583d3a 100644
--- a/client/src/Pages/v1/StatusPage/Create/Components/Tabs/Settings.jsx
+++ b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
@@ -11,7 +11,7 @@ import Progress from "../Progress/index.jsx";
// Utils
import { useTheme } from "@emotion/react";
-import timezones from "../../../../../../Utils/timezones.json";
+import timezones from "../../../../../Utils/timezones.json";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import { useMemo, useState, useCallback } from "react";
diff --git a/client/src/Pages/v1/StatusPage/Create/Components/Tabs/index.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx
similarity index 100%
rename from client/src/Pages/v1/StatusPage/Create/Components/Tabs/index.jsx
rename to client/src/Pages/StatusPage/Create/Components/Tabs/index.jsx
diff --git a/client/src/Pages/v1/StatusPage/Create/Hooks/useCreateStatusPage.jsx b/client/src/Pages/StatusPage/Create/Hooks/useCreateStatusPage.jsx
similarity index 83%
rename from client/src/Pages/v1/StatusPage/Create/Hooks/useCreateStatusPage.jsx
rename to client/src/Pages/StatusPage/Create/Hooks/useCreateStatusPage.jsx
index 808598052..dac5997f9 100644
--- a/client/src/Pages/v1/StatusPage/Create/Hooks/useCreateStatusPage.jsx
+++ b/client/src/Pages/StatusPage/Create/Hooks/useCreateStatusPage.jsx
@@ -1,6 +1,6 @@
import { useState } from "react";
-import { networkService } from "../../../../../main.jsx";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { networkService } from "../../../../main.jsx";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
const useCreateStatusPage = (isCreate, url) => {
const [isLoading, setIsLoading] = useState(false);
diff --git a/client/src/Pages/v1/StatusPage/Create/Hooks/useMonitorsFetch.jsx b/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx
similarity index 83%
rename from client/src/Pages/v1/StatusPage/Create/Hooks/useMonitorsFetch.jsx
rename to client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx
index 81fefd65c..03ebb07bf 100644
--- a/client/src/Pages/v1/StatusPage/Create/Hooks/useMonitorsFetch.jsx
+++ b/client/src/Pages/StatusPage/Create/Hooks/useMonitorsFetch.jsx
@@ -1,7 +1,7 @@
import { useEffect, useState } from "react";
-import { networkService } from "../../../../../main.jsx";
+import { networkService } from "../../../../main.jsx";
import { useSelector } from "react-redux";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
const useMonitorsFetch = () => {
const { user } = useSelector((state) => state.auth);
@@ -16,7 +16,7 @@ const useMonitorsFetch = () => {
limit: null, // donot return any checks for the monitors
types: ["http", "ping", "port", "game"], // include game servers in status page monitor selection
});
- setMonitors(response.data.data.monitors);
+ setMonitors(response.data.data);
} catch (error) {
setNetworkError(true);
createToast({ body: error.message });
diff --git a/client/src/Pages/v1/StatusPage/Create/index.jsx b/client/src/Pages/StatusPage/Create/index.jsx
similarity index 96%
rename from client/src/Pages/v1/StatusPage/Create/index.jsx
rename to client/src/Pages/StatusPage/Create/index.jsx
index d9fafed70..f8fcf0e91 100644
--- a/client/src/Pages/v1/StatusPage/Create/index.jsx
+++ b/client/src/Pages/StatusPage/Create/index.jsx
@@ -8,11 +8,11 @@ import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
//Utils
import { useTheme } from "@emotion/react";
import { useState, useEffect, useRef, useCallback } from "react";
-import { statusPageValidation } from "../../../../Validation/validation.js";
-import { buildErrors } from "../../../../Validation/error.js";
+import { statusPageValidation } from "../../../Validation/validation.js";
+import { buildErrors } from "../../../Validation/error.js";
import { useMonitorsFetch } from "./Hooks/useMonitorsFetch.jsx";
import { useCreateStatusPage } from "./Hooks/useCreateStatusPage.jsx";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import { useNavigate } from "react-router-dom";
import { useStatusPageFetch } from "../Status/Hooks/useStatusPageFetch.jsx";
import { useParams } from "react-router-dom";
@@ -62,7 +62,6 @@ const CreateStatusPage = () => {
useStatusPageFetch(isCreate, url);
const [deleteStatusPage, isDeleting] = useStatusPageDelete(fetchStatusPage, url);
- console.log(JSON.stringify(form, null, 2));
// Handlers
const handleFormChange = (e) => {
let { type, name, value, checked } = e.target;
@@ -144,6 +143,8 @@ const CreateStatusPage = () => {
...form,
logo: { type: form.logo?.type ?? null, size: form.logo?.size ?? null },
};
+
+ console.log(toSubmit);
const { error } = statusPageValidation.validate(toSubmit, {
abortEarly: false,
});
@@ -205,7 +206,7 @@ const CreateStatusPage = () => {
companyName: statusPage?.companyName,
isPublished: statusPage?.isPublished,
timezone: statusPage?.timezone,
- monitors: statusPageMonitors.map((monitor) => monitor._id),
+ monitors: statusPageMonitors.map((monitor) => monitor.id),
color: statusPage?.color,
logo: newLogo,
showCharts: statusPage?.showCharts ?? true,
diff --git a/client/src/Pages/v1/StatusPage/Status/Components/AdminLink/index.jsx b/client/src/Pages/StatusPage/Status/Components/AdminLink/index.jsx
similarity index 100%
rename from client/src/Pages/v1/StatusPage/Status/Components/AdminLink/index.jsx
rename to client/src/Pages/StatusPage/Status/Components/AdminLink/index.jsx
diff --git a/client/src/Pages/v1/StatusPage/Status/Components/ControlsHeader/index.jsx b/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx
similarity index 97%
rename from client/src/Pages/v1/StatusPage/Status/Components/ControlsHeader/index.jsx
rename to client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx
index c56aa40cc..60a4882f5 100644
--- a/client/src/Pages/v1/StatusPage/Status/Components/ControlsHeader/index.jsx
+++ b/client/src/Pages/StatusPage/Status/Components/ControlsHeader/index.jsx
@@ -1,7 +1,7 @@
// Components
import { Box, Stack, Typography, Button } from "@mui/material";
import Image from "@/Components/v1/Image/index.jsx";
-import SettingsIcon from "../../../../../../assets/icons/settings-bold.svg?react";
+import SettingsIcon from "@/assets/icons/settings-bold.svg?react";
import ThemeSwitch from "@/Components/v1/ThemeSwitch/index.jsx";
import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
//Utils
diff --git a/client/src/Pages/v1/StatusPage/Status/Components/MonitorsList/index.jsx b/client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx
similarity index 92%
rename from client/src/Pages/v1/StatusPage/Status/Components/MonitorsList/index.jsx
rename to client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx
index 1628b3d44..33f771233 100644
--- a/client/src/Pages/v1/StatusPage/Status/Components/MonitorsList/index.jsx
+++ b/client/src/Pages/StatusPage/Status/Components/MonitorsList/index.jsx
@@ -6,7 +6,7 @@ import { StatusLabel } from "@/Components/v1/Label/index.jsx";
//Utils
import { useTheme } from "@mui/material/styles";
-import { useMonitorUtils } from "../../../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../../../Hooks/useMonitorUtils.js";
import PropTypes from "prop-types";
import { useSelector } from "react-redux";
@@ -28,14 +28,14 @@ const MonitorsList = ({
const status = determineState(monitor);
return (
{
const [isLoading, setIsLoading] = useState(true);
diff --git a/client/src/Pages/v1/StatusPage/Status/index.jsx b/client/src/Pages/StatusPage/Status/index.jsx
similarity index 98%
rename from client/src/Pages/v1/StatusPage/Status/index.jsx
rename to client/src/Pages/StatusPage/Status/index.jsx
index e700bbbd9..adcd9c2c7 100644
--- a/client/src/Pages/v1/StatusPage/Status/index.jsx
+++ b/client/src/Pages/StatusPage/Status/index.jsx
@@ -12,7 +12,7 @@ import TextLink from "@/Components/v1/TextLink/index.jsx";
// Utils
import { useStatusPageFetch } from "./Hooks/useStatusPageFetch.jsx";
import { useTheme } from "@emotion/react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
import { useLocation } from "react-router-dom";
import { useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
diff --git a/client/src/Pages/v1/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx b/client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx
similarity index 100%
rename from client/src/Pages/v1/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx
rename to client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable/index.jsx
diff --git a/client/src/Pages/v1/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx b/client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
similarity index 86%
rename from client/src/Pages/v1/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
rename to client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
index 89df1b84d..839ff4cdf 100644
--- a/client/src/Pages/v1/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
+++ b/client/src/Pages/StatusPage/StatusPages/Hooks/useStatusPagesFetch.jsx
@@ -1,7 +1,7 @@
import { useState, useEffect } from "react";
-import { networkService } from "../../../../../main.jsx";
+import { networkService } from "../../../../main.jsx";
import { useSelector } from "react-redux";
-import { createToast } from "../../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../../Utils/toastUtils.jsx";
const useStatusPagesFetch = () => {
const { user } = useSelector((state) => state.auth);
diff --git a/client/src/Pages/v1/StatusPage/StatusPages/index.jsx b/client/src/Pages/StatusPage/StatusPages/index.jsx
similarity index 95%
rename from client/src/Pages/v1/StatusPage/StatusPages/index.jsx
rename to client/src/Pages/StatusPage/StatusPages/index.jsx
index 3c60fe950..7137d01ad 100644
--- a/client/src/Pages/v1/StatusPage/StatusPages/index.jsx
+++ b/client/src/Pages/StatusPage/StatusPages/index.jsx
@@ -7,7 +7,7 @@ import PageStateWrapper from "@/Components/v1/PageStateWrapper/index.jsx";
// Utils
import { useTheme } from "@emotion/react";
import { useStatusPagesFetch } from "./Hooks/useStatusPagesFetch.jsx";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
const BREADCRUMBS = [{ name: `Status Pages`, path: "" }];
const StatusPages = () => {
diff --git a/client/src/Pages/v1/Uptime/BulkImport/Upload.jsx b/client/src/Pages/Uptime/BulkImport/Upload.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/BulkImport/Upload.jsx
rename to client/src/Pages/Uptime/BulkImport/Upload.jsx
diff --git a/client/src/Pages/v1/Uptime/BulkImport/index.jsx b/client/src/Pages/Uptime/BulkImport/index.jsx
similarity index 95%
rename from client/src/Pages/v1/Uptime/BulkImport/index.jsx
rename to client/src/Pages/Uptime/BulkImport/index.jsx
index 9f3efcd67..6f2f7bcb5 100644
--- a/client/src/Pages/v1/Uptime/BulkImport/index.jsx
+++ b/client/src/Pages/Uptime/BulkImport/index.jsx
@@ -5,14 +5,14 @@ import { useState } from "react";
import { Box, Stack, Typography, Button, Link } from "@mui/material";
//Components
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
import ConfigBox from "@/Components/v1/ConfigBox/index.jsx";
import UploadFile from "./Upload.jsx";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next";
-import { useCreateBulkMonitors } from "../../../../Hooks/v1/monitorHooks.js";
+import { useCreateBulkMonitors } from "../../../Hooks/monitorHooks.js";
const BulkImport = () => {
const theme = useTheme();
diff --git a/client/src/Pages/v1/Uptime/Create/index.css b/client/src/Pages/Uptime/Create/index.css
similarity index 100%
rename from client/src/Pages/v1/Uptime/Create/index.css
rename to client/src/Pages/Uptime/Create/index.css
diff --git a/client/src/Pages/v1/Uptime/Create/index.jsx b/client/src/Pages/Uptime/Create/index.jsx
similarity index 98%
rename from client/src/Pages/v1/Uptime/Create/index.jsx
rename to client/src/Pages/Uptime/Create/index.jsx
index 003869b10..4f847db4e 100644
--- a/client/src/Pages/v1/Uptime/Create/index.jsx
+++ b/client/src/Pages/Uptime/Create/index.jsx
@@ -26,14 +26,14 @@ import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
-import { monitorValidation } from "../../../../Validation/validation.js";
-import { createToast } from "../../../../Utils/toastUtils.jsx";
+import { monitorValidation } from "../../../Validation/validation.js";
+import { createToast } from "../../../Utils/toastUtils.jsx";
import {
PauseOutlined as PauseOutlinedIcon,
PlayArrowOutlined as PlayArrowOutlinedIcon,
} from "@mui/icons-material";
-import { useMonitorUtils } from "../../../../Hooks/v1/useMonitorUtils.js";
-import { useGetNotificationsByTeamId } from "../../../../Hooks/v1/useNotifications.js";
+import { useMonitorUtils } from "../../../Hooks/useMonitorUtils.js";
+import { useGetNotificationsByTeamId } from "../../../Hooks/useNotifications.js";
import { useParams } from "react-router-dom";
import {
useCreateMonitor,
@@ -42,7 +42,7 @@ import {
usePauseMonitor,
useFetchMonitorById,
useFetchMonitorGames,
-} from "../../../../Hooks/v1/monitorHooks.js";
+} from "../../../Hooks/monitorHooks.js";
/**
* Create page renders monitor creation or configuration views.
@@ -292,7 +292,8 @@ const UptimeCreate = ({ isClone = false }) => {
const handleRemove = async (event) => {
event.preventDefault();
- await deleteMonitor({ monitor, redirect: "/uptime" });
+ const TEMP_MONITOR = { id: monitor._id };
+ await deleteMonitor({ monitor: TEMP_MONITOR, redirect: "/uptime" });
};
const isBusy = isLoading || isCreating || isDeleting || isUpdating || isPausing;
diff --git a/client/src/Pages/v1/Uptime/Create/skeleton.jsx b/client/src/Pages/Uptime/Create/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Create/skeleton.jsx
rename to client/src/Pages/Uptime/Create/skeleton.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/ChartBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx
similarity index 92%
rename from client/src/Pages/v1/Uptime/Details/Components/ChartBoxes/index.jsx
rename to client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx
index 45f35a42e..582c7891f 100644
--- a/client/src/Pages/v1/Uptime/Details/Components/ChartBoxes/index.jsx
+++ b/client/src/Pages/Uptime/Details/Components/ChartBoxes/index.jsx
@@ -1,15 +1,15 @@
// Components
import { Stack, Typography, Box } from "@mui/material";
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
-import UptimeIcon from "../../../../../../assets/icons/uptime-icon.svg?react";
-import IncidentsIcon from "../../../../../../assets/icons/incidents.svg?react";
-import AverageResponseIcon from "../../../../../../assets/icons/average-response-icon.svg?react";
+import UptimeIcon from "@/assets/icons/uptime-icon.svg?react";
+import IncidentsIcon from "@/assets/icons/incidents.svg?react";
+import AverageResponseIcon from "@/assets/icons/average-response-icon.svg?react";
import UpBarChart from "../Charts/UpBarChart.jsx";
import DownBarChart from "../Charts/DownBarChart.jsx";
import ResponseGaugeChart from "../Charts/ResponseGaugeChart.jsx";
import SkeletonLayout from "./skeleton.jsx";
// Utils
-import { formatDateWithTz } from "../../../../../../Utils/timeUtils.js";
+import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { useState } from "react";
diff --git a/client/src/Pages/v1/Uptime/Details/Components/ChartBoxes/skeleton.jsx b/client/src/Pages/Uptime/Details/Components/ChartBoxes/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Details/Components/ChartBoxes/skeleton.jsx
rename to client/src/Pages/Uptime/Details/Components/ChartBoxes/skeleton.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/Charts/CustomLabels.jsx b/client/src/Pages/Uptime/Details/Components/Charts/CustomLabels.jsx
similarity index 93%
rename from client/src/Pages/v1/Uptime/Details/Components/Charts/CustomLabels.jsx
rename to client/src/Pages/Uptime/Details/Components/Charts/CustomLabels.jsx
index c9c1ff58d..472c8d058 100644
--- a/client/src/Pages/v1/Uptime/Details/Components/Charts/CustomLabels.jsx
+++ b/client/src/Pages/Uptime/Details/Components/Charts/CustomLabels.jsx
@@ -1,6 +1,6 @@
import PropTypes from "prop-types";
import { useSelector } from "react-redux";
-import { formatDateWithTz } from "../../../../../../Utils/timeUtils.js";
+import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
const CustomLabels = ({ x, width, height, firstDataPoint, lastDataPoint, type }) => {
const uiTimezone = useSelector((state) => state.ui.timezone);
diff --git a/client/src/Pages/v1/Uptime/Details/Components/Charts/DownBarChart.jsx b/client/src/Pages/Uptime/Details/Components/Charts/DownBarChart.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Details/Components/Charts/DownBarChart.jsx
rename to client/src/Pages/Uptime/Details/Components/Charts/DownBarChart.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseGaugeChart.jsx b/client/src/Pages/Uptime/Details/Components/Charts/ResponseGaugeChart.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseGaugeChart.jsx
rename to client/src/Pages/Uptime/Details/Components/Charts/ResponseGaugeChart.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseTimeChart.jsx b/client/src/Pages/Uptime/Details/Components/Charts/ResponseTimeChart.jsx
similarity index 89%
rename from client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseTimeChart.jsx
rename to client/src/Pages/Uptime/Details/Components/Charts/ResponseTimeChart.jsx
index daa7b4f53..861b600d4 100644
--- a/client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseTimeChart.jsx
+++ b/client/src/Pages/Uptime/Details/Components/Charts/ResponseTimeChart.jsx
@@ -1,6 +1,6 @@
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
import MonitorDetailsAreaChart from "@/Components/v1/Charts/MonitorDetailsAreaChart/index.jsx";
-import ResponseTimeIcon from "../../../../../../assets/icons/response-time-icon.svg?react";
+import ResponseTimeIcon from "@/assets/icons/response-time-icon.svg?react";
import SkeletonLayout from "./ResponseTimeChartSkeleton.jsx";
import PropTypes from "prop-types";
diff --git a/client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseTimeChartSkeleton.jsx b/client/src/Pages/Uptime/Details/Components/Charts/ResponseTimeChartSkeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Details/Components/Charts/ResponseTimeChartSkeleton.jsx
rename to client/src/Pages/Uptime/Details/Components/Charts/ResponseTimeChartSkeleton.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/Charts/UpBarChart.jsx b/client/src/Pages/Uptime/Details/Components/Charts/UpBarChart.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Details/Components/Charts/UpBarChart.jsx
rename to client/src/Pages/Uptime/Details/Components/Charts/UpBarChart.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/ResponseTable/index.jsx b/client/src/Pages/Uptime/Details/Components/ResponseTable/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Uptime/Details/Components/ResponseTable/index.jsx
rename to client/src/Pages/Uptime/Details/Components/ResponseTable/index.jsx
index 0d0defc3b..0715561d4 100644
--- a/client/src/Pages/v1/Uptime/Details/Components/ResponseTable/index.jsx
+++ b/client/src/Pages/Uptime/Details/Components/ResponseTable/index.jsx
@@ -1,11 +1,11 @@
import ChartBox from "@/Components/v1/Charts/ChartBox/index.jsx";
import PropTypes from "prop-types";
-import HistoryIcon from "../../../../../../assets/icons/history-icon.svg?react";
+import HistoryIcon from "@/assets/icons/history-icon.svg?react";
import Table from "@/Components/v1/Table/index.jsx";
import TablePagination from "@/Components/v1/Table/TablePagination/index.jsx";
import { StatusLabel } from "@/Components/v1/Label/index.jsx";
import { useTranslation } from "react-i18next";
-import { formatDateWithTz } from "../../../../../../Utils/timeUtils.js";
+import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
import SkeletonLayout from "./skeleton.jsx";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
diff --git a/client/src/Pages/v1/Uptime/Details/Components/ResponseTable/skeleton.jsx b/client/src/Pages/Uptime/Details/Components/ResponseTable/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Details/Components/ResponseTable/skeleton.jsx
rename to client/src/Pages/Uptime/Details/Components/ResponseTable/skeleton.jsx
diff --git a/client/src/Pages/v1/Uptime/Details/Components/UptimeStatusBoxes/index.jsx b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx
similarity index 92%
rename from client/src/Pages/v1/Uptime/Details/Components/UptimeStatusBoxes/index.jsx
rename to client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx
index a7b971839..0bfdc1096 100644
--- a/client/src/Pages/v1/Uptime/Details/Components/UptimeStatusBoxes/index.jsx
+++ b/client/src/Pages/Uptime/Details/Components/UptimeStatusBoxes/index.jsx
@@ -2,10 +2,10 @@ import StatusBoxes from "@/Components/v1/StatusBoxes/index.jsx";
import StatBox from "@/Components/v1/StatBox/index.jsx";
import PropTypes from "prop-types";
-import { getHumanReadableDuration } from "../../../../../../Utils/timeUtils.js";
+import { getHumanReadableDuration } from "../../../../../Utils/timeUtils.js";
import { useTheme } from "@mui/material/styles";
import { Typography } from "@mui/material";
-import { useMonitorUtils } from "../../../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../../../Hooks/useMonitorUtils.js";
const UptimeStatusBoxes = ({
isLoading = false,
diff --git a/client/src/Pages/v1/Uptime/Details/Hooks/useCertificateFetch.jsx b/client/src/Pages/Uptime/Details/Hooks/useCertificateFetch.jsx
similarity index 84%
rename from client/src/Pages/v1/Uptime/Details/Hooks/useCertificateFetch.jsx
rename to client/src/Pages/Uptime/Details/Hooks/useCertificateFetch.jsx
index f85111f97..e74a99d82 100644
--- a/client/src/Pages/v1/Uptime/Details/Hooks/useCertificateFetch.jsx
+++ b/client/src/Pages/Uptime/Details/Hooks/useCertificateFetch.jsx
@@ -1,7 +1,7 @@
-import { logger } from "../../../../../Utils/Logger.js";
+import { logger } from "../../../../Utils/Logger.js";
import { useEffect, useState } from "react";
-import { networkService } from "../../../../../main.jsx";
-import { formatDateWithTz } from "../../../../../Utils/timeUtils.js";
+import { networkService } from "../../../../main.jsx";
+import { formatDateWithTz } from "../../../../Utils/timeUtils.js";
const useCertificateFetch = ({
monitor,
diff --git a/client/src/Pages/v1/Uptime/Details/index.jsx b/client/src/Pages/Uptime/Details/index.jsx
similarity index 95%
rename from client/src/Pages/v1/Uptime/Details/index.jsx
rename to client/src/Pages/Uptime/Details/index.jsx
index f5e283495..144ceb4dc 100644
--- a/client/src/Pages/v1/Uptime/Details/index.jsx
+++ b/client/src/Pages/Uptime/Details/index.jsx
@@ -15,10 +15,10 @@ import { useState } from "react";
import { useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import { useTheme } from "@emotion/react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
-import { useFetchUptimeMonitorById } from "../../../../Hooks/v1/monitorHooks.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
+import { useFetchUptimeMonitorById } from "../../../Hooks/monitorHooks.js";
import useCertificateFetch from "./Hooks/useCertificateFetch.jsx";
-import { useFetchChecksByMonitor } from "../../../../Hooks/v1/checkHooks.js";
+import { useFetchChecksByMonitor } from "../../../Hooks/checkHooks.js";
import { useTranslation } from "react-i18next";
// Constants
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/Filter/index.jsx b/client/src/Pages/Uptime/Monitors/Components/Filter/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Components/Filter/index.jsx
rename to client/src/Pages/Uptime/Monitors/Components/Filter/index.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/LoadingSpinner/index.jsx b/client/src/Pages/Uptime/Monitors/Components/LoadingSpinner/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Components/LoadingSpinner/index.jsx
rename to client/src/Pages/Uptime/Monitors/Components/LoadingSpinner/index.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/SearchComponent/index.jsx b/client/src/Pages/Uptime/Monitors/Components/SearchComponent/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Components/SearchComponent/index.jsx
rename to client/src/Pages/Uptime/Monitors/Components/SearchComponent/index.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/Skeleton/index.jsx b/client/src/Pages/Uptime/Monitors/Components/Skeleton/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Components/Skeleton/index.jsx
rename to client/src/Pages/Uptime/Monitors/Components/Skeleton/index.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/index.jsx b/client/src/Pages/Uptime/Monitors/Components/StatusBoxes/index.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/index.jsx
rename to client/src/Pages/Uptime/Monitors/Components/StatusBoxes/index.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/skeleton.jsx b/client/src/Pages/Uptime/Monitors/Components/StatusBoxes/skeleton.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/skeleton.jsx
rename to client/src/Pages/Uptime/Monitors/Components/StatusBoxes/skeleton.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/statusBox.jsx b/client/src/Pages/Uptime/Monitors/Components/StatusBoxes/statusBox.jsx
similarity index 90%
rename from client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/statusBox.jsx
rename to client/src/Pages/Uptime/Monitors/Components/StatusBoxes/statusBox.jsx
index c745e7935..c9015816a 100644
--- a/client/src/Pages/v1/Uptime/Monitors/Components/StatusBoxes/statusBox.jsx
+++ b/client/src/Pages/Uptime/Monitors/Components/StatusBoxes/statusBox.jsx
@@ -1,9 +1,9 @@
import PropTypes from "prop-types";
import { useTheme } from "@emotion/react";
import { Box, Stack, Typography } from "@mui/material";
-import Arrow from "../../../../../../assets/icons/top-right-arrow.svg?react";
-import Background from "../../../../../../assets/Images/background-grid.svg?react";
-import ClockSnooze from "../../../../../../assets/icons/clock-snooze.svg?react";
+import Arrow from "@/assets/icons/top-right-arrow.svg?react";
+import Background from "@/assets/Images/background-grid.svg?react";
+import ClockSnooze from "@/assets/icons/clock-snooze.svg?react";
const StatusBox = ({ title, value, status }) => {
const theme = useTheme();
diff --git a/client/src/Pages/v1/Uptime/Monitors/Components/UptimeDataTable/index.jsx b/client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx
similarity index 97%
rename from client/src/Pages/v1/Uptime/Monitors/Components/UptimeDataTable/index.jsx
rename to client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx
index 9cf2d247d..fe220251d 100644
--- a/client/src/Pages/v1/Uptime/Monitors/Components/UptimeDataTable/index.jsx
+++ b/client/src/Pages/Uptime/Monitors/Components/UptimeDataTable/index.jsx
@@ -13,7 +13,7 @@ import TableSkeleton from "@/Components/v1/Table/skeleton.jsx";
// Utils
import { useTheme } from "@emotion/react";
-import { useMonitorUtils } from "../../../../../../Hooks/v1/useMonitorUtils.js";
+import { useMonitorUtils } from "../../../../../Hooks/useMonitorUtils.js";
import { useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
@@ -24,13 +24,13 @@ import { useTranslation } from "react-i18next";
* @param {boolean} props.isAdmin - Whether the current user has admin privileges
* @param {boolean} props.isLoading - Loading state of the table
* @param {Array<{
- * _id: string,
+ * id: string,
* url: string,
* title: string,
* percentage: number,
* percentageColor: string,
* monitor: {
- * _id: string,
+ * id: string,
* type: string,
* checks: Array
* }
@@ -101,7 +101,7 @@ const UptimeDataTable = ({
),
render: (row) => (
{
- navigate(`/uptime/${row._id}`);
+ navigate(`/uptime/${row.id}`);
},
emptyView: "No monitors found",
}}
diff --git a/client/src/Pages/v1/Uptime/Monitors/Hooks/useDebounce.jsx b/client/src/Pages/Uptime/Monitors/Hooks/useDebounce.jsx
similarity index 100%
rename from client/src/Pages/v1/Uptime/Monitors/Hooks/useDebounce.jsx
rename to client/src/Pages/Uptime/Monitors/Hooks/useDebounce.jsx
diff --git a/client/src/Pages/v1/Uptime/Monitors/index.jsx b/client/src/Pages/Uptime/Monitors/index.jsx
similarity index 96%
rename from client/src/Pages/v1/Uptime/Monitors/index.jsx
rename to client/src/Pages/Uptime/Monitors/index.jsx
index cacfc23b4..fb8d6246b 100644
--- a/client/src/Pages/v1/Uptime/Monitors/index.jsx
+++ b/client/src/Pages/Uptime/Monitors/index.jsx
@@ -5,7 +5,7 @@
// Components
import Breadcrumbs from "@/Components/v1/Breadcrumbs/index.jsx";
-import Greeting from "../../../../Utils/greeting.jsx";
+import Greeting from "../../../Utils/greeting.jsx";
import StatusBoxes from "./Components/StatusBoxes/index.jsx";
import UptimeDataTable from "./Components/UptimeDataTable/index.jsx";
import Pagination from "@/Components/v1/Table/TablePagination/index.jsx";
@@ -20,16 +20,16 @@ import MonitorCountHeader from "@/Components/v1/MonitorCountHeader/index.jsx";
import { Stack, Box, Button } from "@mui/material";
// Utils
import { useState, useCallback, useEffect } from "react";
-import { useIsAdmin } from "../../../../Hooks/v1/useIsAdmin.js";
+import { useIsAdmin } from "@/Hooks/useIsAdmin.js";
import { useTheme } from "@emotion/react";
import { useNavigate } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
-import { setRowsPerPage } from "../../../../Features/UI/uiSlice.js";
+import { setRowsPerPage } from "../../../Features/UI/uiSlice.js";
import PropTypes from "prop-types";
import {
useFetchMonitorsWithSummary,
useFetchMonitorsWithChecks,
-} from "../../../../Hooks/v1/monitorHooks.js";
+} from "@/Hooks/monitorHooks.js";
import { useTranslation } from "react-i18next";
const TYPES = ["http", "ping", "docker", "port", "game"];
diff --git a/client/src/Routes/index.jsx b/client/src/Routes/index.jsx
index 255d913c1..d9f6d58cb 100644
--- a/client/src/Routes/index.jsx
+++ b/client/src/Routes/index.jsx
@@ -1,58 +1,58 @@
import { useSelector } from "react-redux";
import { Navigate, Route, Routes as LibRoutes } from "react-router";
import HomeLayout from "@/Components/v1/Layouts/HomeLayout";
-import NotFound from "../Pages/v1/NotFound";
+import NotFound from "../Pages/NotFound/index.jsx";
// Auth
-import AuthLogin from "../Pages/v1/Auth/Login";
-import AuthRegister from "../Pages/v1/Auth/Register/";
-import AuthForgotPassword from "../Pages/v1/Auth/ForgotPassword";
-import AuthCheckEmail from "../Pages/v1/Auth/CheckEmail";
-import AuthSetNewPassword from "../Pages/v1/Auth/SetNewPassword";
-import AuthNewPasswordConfirmed from "../Pages/v1/Auth/NewPasswordConfirmed";
+import AuthLogin from "../Pages/Auth/Login/index.jsx";
+import AuthRegister from "../Pages/Auth/Register/index.jsx";
+import AuthForgotPassword from "../Pages/Auth/ForgotPassword.jsx";
+import AuthCheckEmail from "../Pages/Auth/CheckEmail.jsx";
+import AuthSetNewPassword from "../Pages/Auth/SetNewPassword.jsx";
+import AuthNewPasswordConfirmed from "../Pages/Auth/NewPasswordConfirmed.jsx";
// Uptime
-import Uptime from "../Pages/v1/Uptime/Monitors";
-import UptimeDetails from "../Pages/v1/Uptime/Details";
-import UptimeCreate from "../Pages/v1/Uptime/Create";
+import Uptime from "../Pages/Uptime/Monitors/index.jsx";
+import UptimeDetails from "../Pages/Uptime/Details/index.jsx";
+import UptimeCreate from "../Pages/Uptime/Create/index.jsx";
// PageSpeed
-import PageSpeed from "../Pages/v1/PageSpeed/Monitors";
-import PageSpeedDetails from "../Pages/v1/PageSpeed/Details";
-import PageSpeedCreate from "../Pages/v1/PageSpeed/Create";
+import PageSpeed from "../Pages/PageSpeed/Monitors/index.jsx";
+import PageSpeedDetails from "../Pages/PageSpeed/Details/index.jsx";
+import PageSpeedCreate from "../Pages/PageSpeed/Create/index.jsx";
// Infrastructure
-import Infrastructure from "../Pages/v1/Infrastructure/Monitors";
-import InfrastructureCreate from "../Pages/v1/Infrastructure/Create";
-import InfrastructureDetails from "../Pages/v1/Infrastructure/Details";
+import Infrastructure from "../Pages/Infrastructure/Monitors/index.jsx";
+import InfrastructureCreate from "../Pages/Infrastructure/Create/index.jsx";
+import InfrastructureDetails from "../Pages/Infrastructure/Details/index.jsx";
// Server Status
-import ServerUnreachable from "../Pages/v1/ServerUnreachable.jsx";
+import ServerUnreachable from "../Pages/ServerUnreachable.jsx";
// Incidents
-import Checks from "../Pages/v1/Incidents";
-import Incidents2 from "../Pages/v1/Incidents2";
+import Checks from "../Pages/Incidents";
+import Incidents2 from "../Pages/Incidents2/index.jsx";
// Status pages
-import CreateStatus from "../Pages/v1/StatusPage/Create";
-import StatusPages from "../Pages/v1/StatusPage/StatusPages";
-import Status from "../Pages/v1/StatusPage/Status";
+import CreateStatus from "../Pages/StatusPage/Create/index.jsx";
+import StatusPages from "../Pages/StatusPage/StatusPages/index.jsx";
+import Status from "../Pages/StatusPage/Status/index.jsx";
-import Notifications from "../Pages/v1/Notifications";
-import CreateNotifications from "../Pages/v1/Notifications/create";
+import Notifications from "../Pages/Notifications/index.jsx";
+import CreateNotifications from "../Pages/Notifications/create/index.jsx";
// Settings
-import Account from "../Pages/v1/Account";
-import EditUser from "../Pages/v1/Account/EditUser";
-import Settings from "../Pages/v1/Settings";
+import Account from "../Pages/Account/index.jsx";
+import EditUser from "../Pages/Account/EditUser/index.jsx";
+import Settings from "../Pages/Settings";
-import Maintenance from "../Pages/v1/Maintenance";
+import Maintenance from "../Pages/Maintenance/index.jsx";
import ProtectedRoute from "../Components/v1/ProtectedRoute";
import RoleProtectedRoute from "../Components/v1/RoleProtectedRoute";
-import CreateNewMaintenanceWindow from "../Pages/v1/Maintenance/CreateMaintenance";
+import CreateNewMaintenanceWindow from "../Pages/Maintenance/CreateMaintenance/index.jsx";
import withAdminCheck from "@/Components/v1/HOC/withAdminCheck";
-import BulkImport from "../Pages/v1/Uptime/BulkImport";
-import Logs from "../Pages/v1/Logs";
+import BulkImport from "../Pages/Uptime/BulkImport/index.jsx";
+import Logs from "../Pages/Logs/index.jsx";
const Routes = () => {
const mode = useSelector((state) => state.ui.mode);
diff --git a/client/src/Utils/NetworkService.js b/client/src/Utils/NetworkService.js
index fe4eb7e14..bd0e37b30 100644
--- a/client/src/Utils/NetworkService.js
+++ b/client/src/Utils/NetworkService.js
@@ -144,20 +144,16 @@ class NetworkService {
*/
async getMonitorsByTeamId(config) {
- const { limit, types, page, rowsPerPage, filter, field, order } = config;
+ const { types, filter } = config ?? {};
const params = new URLSearchParams();
- if (limit) params.append("limit", limit);
if (types) {
types.forEach((type) => {
params.append("type", type);
});
}
- if (page) params.append("page", page);
- if (rowsPerPage) params.append("rowsPerPage", rowsPerPage);
- if (filter) params.append("filter", filter);
- if (field) params.append("field", field);
- if (order) params.append("order", order);
+ if (filter !== undefined && filter !== null && filter !== "")
+ params.append("filter", filter);
return this.axiosInstance.get(`/monitors/team?${params.toString()}`, {
headers: {
@@ -202,6 +198,14 @@ class NetworkService {
`/monitors/hardware/details/${config.monitorId}?${params.toString()}`
);
}
+ async getPageSpeedDetailsByMonitorId(config) {
+ const params = new URLSearchParams();
+ if (config.dateRange) params.append("dateRange", config.dateRange);
+
+ return this.axiosInstance.get(
+ `/monitors/pagespeed/details/${config.monitorId}?${params.toString()}`
+ );
+ }
async getUptimeDetailsById(config) {
const params = new URLSearchParams();
if (config.dateRange) params.append("dateRange", config.dateRange);
diff --git a/docker/dist-arm/docker-compose.yaml b/docker/dist-arm/docker-compose.yaml
index 0a5825b3e..9a87aa59b 100644
--- a/docker/dist-arm/docker-compose.yaml
+++ b/docker/dist-arm/docker-compose.yaml
@@ -15,7 +15,7 @@ services:
depends_on:
- mongodb
mongodb:
- image: mongo:4.4.18
+ image: mongo:4.4.30
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
ports:
diff --git a/server/jest.config.ts b/server/jest.config.ts
new file mode 100644
index 000000000..2bcfcbf21
--- /dev/null
+++ b/server/jest.config.ts
@@ -0,0 +1,20 @@
+import type { Config } from "jest";
+
+const config: Config = {
+ rootDir: ".",
+ testEnvironment: "node",
+ extensionsToTreatAsEsm: [".ts"],
+ transform: {
+ "^.+\\.(t|j)sx?$": ["ts-jest", { useESM: true, tsconfig: "./tsconfig.jest.json" }],
+ },
+ moduleNameMapper: {
+ "^@/(.*)$": "/src/$1",
+ },
+ testMatch: ["/test/**/*.test.ts"],
+ setupFilesAfterEnv: [],
+ collectCoverageFrom: ["src/**/*.ts"],
+ coveragePathIgnorePatterns: ["/node_modules/", "/test/"],
+ clearMocks: true,
+};
+
+export default config;
diff --git a/server/nodemon.json b/server/nodemon.json
index 389209fa7..3faf346d3 100755
--- a/server/nodemon.json
+++ b/server/nodemon.json
@@ -1,5 +1,5 @@
{
- "ignore": ["src/locales/*", "*.log", "node_modules/*"],
+ "ignore": ["node_modules/*"],
"watch": ["src/**/*.ts", "src/**/*.js", "*.json"],
"ext": "ts,js,json"
}
diff --git a/server/package-lock.json b/server/package-lock.json
index 8de5cfc0c..11e1829b4 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -13,6 +13,7 @@
"axios": "^1.7.2",
"bcryptjs": "3.0.2",
"bullmq": "5.41.2",
+ "cacheable-lookup": "7.0.0",
"compression": "1.8.1",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
@@ -39,25 +40,34 @@
"ping": "0.4.4",
"sharp": "0.33.5",
"ssl-checker": "2.0.10",
- "super-simple-scheduler": "1.4.4",
+ "super-simple-scheduler": "1.4.5",
"swagger-ui-express": "5.0.1",
"winston": "^3.13.0"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
+ "@types/dockerode": "^4.0.0",
"@types/express": "5.0.3",
+ "@types/gamedig": "^5.0.3",
+ "@types/jest": "^30.0.0",
+ "@types/jmespath": "^0.15.2",
"@types/jsonwebtoken": "9.0.10",
+ "@types/mjml": "^4.7.4",
+ "@types/multer": "^2.0.0",
"@types/nodemailer": "7.0.1",
+ "@types/papaparse": "^5.5.2",
"@types/ping": "0.4.4",
"c8": "10.1.3",
- "chai": "5.2.0",
"eslint": "^9.17.0",
"eslint-plugin-mocha": "^10.5.0",
"esm": "3.2.25",
"globals": "^15.14.0",
- "mocha": "11.1.0",
+ "jest": "^30.2.0",
+ "nodemon": "^3.1.11",
"prettier": "^3.3.3",
- "sinon": "19.0.2",
+ "ts-jest": "^29.4.6",
+ "ts-node": "^10.9.2",
+ "tsc-alias": "1.8.16",
"tsx": "4.20.5",
"typescript": "5.9.2"
},
@@ -830,12 +840,12 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
- "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz",
+ "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==",
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
},
@@ -843,6 +853,174 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz",
+ "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz",
+ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/generator": "^7.28.6",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz",
+ "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-validator-identifier": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
@@ -852,6 +1030,285 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
+ "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
+ "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.6"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz",
+ "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz",
+ "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
+ "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/runtime": {
"version": "7.28.4",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
@@ -861,6 +1318,54 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz",
+ "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/generator": "^7.28.6",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.6",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
+ "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@balena/dockerignore": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz",
@@ -886,6 +1391,30 @@
"node": ">=0.1.90"
}
},
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
"node_modules/@csstools/color-helpers": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz",
@@ -970,6 +1499,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -1014,6 +1544,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
}
@@ -1029,6 +1560,18 @@
"kuler": "^2.0.0"
}
},
+ "node_modules/@emnapi/core": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
+ "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@emnapi/runtime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz",
@@ -1039,6 +1582,17 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
+ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.11",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz",
@@ -2138,6 +2692,113 @@
"node": ">=12"
}
},
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": {
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@istanbuljs/schema": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@@ -2148,6 +2809,377 @@
"node": ">=8"
}
},
+ "node_modules/@jest/console": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz",
+ "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "jest-message-util": "30.2.0",
+ "jest-util": "30.2.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz",
+ "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.2.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/reporters": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-changed-files": "30.2.0",
+ "jest-config": "30.2.0",
+ "jest-haste-map": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-resolve-dependencies": "30.2.0",
+ "jest-runner": "30.2.0",
+ "jest-runtime": "30.2.0",
+ "jest-snapshot": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "jest-watcher": "30.2.0",
+ "micromatch": "^4.0.8",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/diff-sequences": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz",
+ "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz",
+ "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/fake-timers": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "jest-mock": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz",
+ "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "30.2.0",
+ "jest-snapshot": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz",
+ "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz",
+ "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@sinonjs/fake-timers": "^13.0.0",
+ "@types/node": "*",
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/get-type": {
+ "version": "30.1.0",
+ "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz",
+ "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz",
+ "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/expect": "30.2.0",
+ "@jest/types": "30.2.0",
+ "jest-mock": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/pattern": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz",
+ "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-regex-util": "30.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz",
+ "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "collect-v8-coverage": "^1.0.2",
+ "exit-x": "^0.2.2",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^5.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-worker": "30.2.0",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.2",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jest/schemas": {
+ "version": "30.0.5",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz",
+ "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/snapshot-utils": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz",
+ "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "natural-compare": "^1.4.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz",
+ "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "callsites": "^3.1.0",
+ "graceful-fs": "^4.2.11"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz",
+ "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "collect-v8-coverage": "^1.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz",
+ "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "30.2.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz",
+ "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@jest/types": "30.2.0",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "babel-plugin-istanbul": "^7.0.1",
+ "chalk": "^4.1.2",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-util": "30.2.0",
+ "micromatch": "^4.0.8",
+ "pirates": "^4.0.7",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^5.0.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz",
+ "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.0.1",
+ "@jest/schemas": "30.0.5",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
@@ -2273,6 +3305,57 @@
"win32"
]
},
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "0.2.12",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz",
+ "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.4.3",
+ "@emnapi/runtime": "^1.4.3",
+ "@tybys/wasm-util": "^0.10.0"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -2283,6 +3366,19 @@
"node": ">=14"
}
},
+ "node_modules/@pkgr/core": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
+ }
+ },
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -2395,6 +3491,13 @@
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
"license": "BSD-3-Clause"
},
+ "node_modules/@sinclair/typebox": {
+ "version": "0.34.47",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.47.tgz",
+ "integrity": "sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@sindresorhus/is": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.1.0.tgz",
@@ -2427,34 +3530,6 @@
"@sinonjs/commons": "^3.0.1"
}
},
- "node_modules/@sinonjs/samsam": {
- "version": "8.0.3",
- "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz",
- "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.1",
- "type-detect": "^4.1.0"
- }
- },
- "node_modules/@sinonjs/samsam/node_modules/type-detect": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
- "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@sinonjs/text-encoding": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz",
- "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==",
- "dev": true,
- "license": "(Unlicense OR Apache-2.0)"
- },
"node_modules/@smithy/abort-controller": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.3.tgz",
@@ -3143,6 +4218,100 @@
"node": ">=14.16"
}
},
+ "node_modules/@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "license": "ISC",
+ "optional": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz",
+ "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
"node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
@@ -3164,6 +4333,29 @@
"@types/node": "*"
}
},
+ "node_modules/@types/docker-modem": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz",
+ "integrity": "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/ssh2": "*"
+ }
+ },
+ "node_modules/@types/dockerode": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-4.0.0.tgz",
+ "integrity": "sha512-NBm/UIL1KYWivh9ihJELK4Jv0dzOQCleS0OT5JklErra8mZ/t0UQpHfTkMmPrAqtra7OyFius1EFLVs0DhiHQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/docker-modem": "*",
+ "@types/node": "*",
+ "@types/ssh2": "*"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -3196,6 +4388,13 @@
"@types/send": "*"
}
},
+ "node_modules/@types/gamedig": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@types/gamedig/-/gamedig-5.0.3.tgz",
+ "integrity": "sha512-VLrOVRf72wVE6P0DhFtRVodiONwL51uojn6dNpP/Ks/Vdm3CDH6dZTAw74WmCDLuyvpytNy8auKzlTKfBlO8jg==",
+ "dev": true,
+ "license": "MIT"
+ },
"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",
@@ -3216,6 +4415,44 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "30.0.0",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz",
+ "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^30.0.0",
+ "pretty-format": "^30.0.0"
+ }
+ },
+ "node_modules/@types/jmespath": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@types/jmespath/-/jmespath-0.15.2.tgz",
+ "integrity": "sha512-pegh49FtNsC389Flyo9y8AfkVIZn9MMPE9yJrO9svhq6Fks2MwymULWjZqySuxmctd3ZH4/n7Mr98D+1Qo5vGA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -3241,6 +4478,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/mjml": {
+ "version": "4.7.4",
+ "resolved": "https://registry.npmjs.org/@types/mjml/-/mjml-4.7.4.tgz",
+ "integrity": "sha512-vyi1vzWgMzFMwZY7GSZYX0GU0dmtC8vLHwpgk+NWmwbwRSrlieVyJ9sn5elodwUfklJM7yGl0zQeet1brKTWaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mjml-core": "*"
+ }
+ },
+ "node_modules/@types/mjml-core": {
+ "version": "4.15.2",
+ "resolved": "https://registry.npmjs.org/@types/mjml-core/-/mjml-core-4.15.2.tgz",
+ "integrity": "sha512-Q7SxFXgoX979HP57DEVsRI50TV8x1V4lfCA4Up9AvfINDM5oD/X9ARgfoyX1qS987JCnDLv85JjkqAjt3hZSiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
@@ -3248,11 +4502,22 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/multer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/multer/-/multer-2.0.0.tgz",
+ "integrity": "sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
"node_modules/@types/node": {
"version": "24.9.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
"integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -3268,6 +4533,16 @@
"@types/node": "*"
}
},
+ "node_modules/@types/papaparse": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.5.2.tgz",
+ "integrity": "sha512-gFnFp/JMzLHCwRf7tQHrNnfhN4eYBVYYI897CGX4MY1tzY9l2aLkVyx2IlKZ/SAqDbB3I1AOZW5gTMGGsqWliA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/ping": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/@types/ping/-/ping-0.4.4.tgz",
@@ -3328,6 +4603,40 @@
"@types/node": "*"
}
},
+ "node_modules/@types/ssh2": {
+ "version": "1.15.5",
+ "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.5.tgz",
+ "integrity": "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "^18.11.18"
+ }
+ },
+ "node_modules/@types/ssh2/node_modules/@types/node": {
+ "version": "18.19.130",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
+ "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@types/ssh2/node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/triple-beam": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
@@ -3356,6 +4665,299 @@
"@types/webidl-conversions": "*"
}
},
+ "node_modules/@types/yargs": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@unrs/resolver-binding-android-arm-eabi": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz",
+ "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-android-arm64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz",
+ "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-arm64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz",
+ "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-darwin-x64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz",
+ "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-freebsd-x64": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz",
+ "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz",
+ "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz",
+ "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz",
+ "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz",
+ "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz",
+ "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz",
+ "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz",
+ "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz",
+ "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz",
+ "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-linux-x64-musl": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz",
+ "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-wasm32-wasi": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz",
+ "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^0.2.11"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz",
+ "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz",
+ "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz",
+ "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -3384,6 +4986,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3401,6 +5004,19 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/agent-base": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
@@ -3436,6 +5052,35 @@
"node": ">=6"
}
},
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-escapes/node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
@@ -3488,6 +5133,13 @@
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
"license": "MIT"
},
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -3500,6 +5152,16 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
},
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
@@ -3509,16 +5171,6 @@
"safer-buffer": "~2.1.0"
}
},
- "node_modules/assertion-error": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
- "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
@@ -3542,6 +5194,142 @@
"proxy-from-env": "^1.1.0"
}
},
+ "node_modules/babel-jest": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz",
+ "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/transform": "30.2.0",
+ "@types/babel__core": "^7.20.5",
+ "babel-plugin-istanbul": "^7.0.1",
+ "babel-preset-jest": "30.2.0",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.11.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz",
+ "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "workspaces": [
+ "test/babel-8"
+ ],
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-instrument": "^6.0.2",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/babel-plugin-istanbul/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/babel-plugin-istanbul/node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz",
+ "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/babel__core": "^7.20.5"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz",
+ "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz",
+ "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-jest-hoist": "30.2.0",
+ "babel-preset-current-node-syntax": "^1.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.11.0 || ^8.0.0-beta.1"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -3655,23 +5443,23 @@
}
},
"node_modules/body-parser": {
- "version": "1.20.3",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
- "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "version": "1.20.4",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz",
+ "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==",
"license": "MIT",
"dependencies": {
- "bytes": "3.1.2",
+ "bytes": "~3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.13.0",
- "raw-body": "2.5.2",
+ "destroy": "~1.2.0",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "on-finished": "~2.4.1",
+ "qs": "~6.14.0",
+ "raw-body": "~2.5.3",
"type-is": "~1.6.18",
- "unpipe": "1.0.0"
+ "unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8",
@@ -3687,12 +5475,41 @@
"ms": "2.0.0"
}
},
+ "node_modules/body-parser/node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/body-parser/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
+ "node_modules/body-parser/node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -3729,13 +5546,6 @@
"node": ">=8"
}
},
- "node_modules/browser-stdout": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
- "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/browserslist": {
"version": "4.27.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz",
@@ -3755,6 +5565,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.19",
"caniuse-lite": "^1.0.30001751",
@@ -3769,6 +5580,29 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
"node_modules/bson": {
"version": "6.10.4",
"resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz",
@@ -3958,16 +5792,13 @@
}
},
"node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=6"
}
},
"node_modules/caniuse-api": {
@@ -4002,23 +5833,6 @@
],
"license": "CC-BY-4.0"
},
- "node_modules/chai": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
- "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "assertion-error": "^2.0.1",
- "check-error": "^2.1.1",
- "deep-eql": "^5.0.1",
- "loupe": "^3.1.0",
- "pathval": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -4036,14 +5850,14 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/check-error": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
- "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 16"
+ "node": ">=10"
}
},
"node_modules/cheerio": {
@@ -4126,6 +5940,29 @@
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
"license": "ISC"
},
+ "node_modules/ci-info": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz",
+ "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz",
+ "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -4207,6 +6044,24 @@
"node": ">=0.10.0"
}
},
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz",
+ "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/color": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
@@ -4493,6 +6348,13 @@
"node": ">=10.0.0"
}
},
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cron-parser": {
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz",
@@ -4589,6 +6451,7 @@
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.1.tgz",
"integrity": "sha512-fm4D8ti0dQmFPeF8DXSAA//btEmqCOgAc/9Oa3C1LW94h5usNrJEfrON7b4FkPZgnDEn6OUs5NdxiJZmAtGOpQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssnano-preset-default": "^7.0.9",
"lilconfig": "^3.1.3"
@@ -4769,19 +6632,6 @@
}
}
},
- "node_modules/decamelize": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
- "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/decimal.js": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
@@ -4815,14 +6665,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/deep-eql": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
- "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "node_modules/dedent": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz",
+ "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=6"
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
}
},
"node_modules/deep-is": {
@@ -4832,6 +6687,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
@@ -4887,6 +6752,16 @@
"node": ">=8"
}
},
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
@@ -4894,15 +6769,28 @@
"license": "MIT"
},
"node_modules/diff": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
- "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
},
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/docker-modem": {
"version": "5.0.6",
"resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.6.tgz",
@@ -5074,6 +6962,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@@ -5292,6 +7193,7 @@
"integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -5480,6 +7382,20 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/esquery": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
@@ -5542,40 +7458,126 @@
"deprecated": "Use promise-toolbox/fromEvent instead",
"license": "MIT"
},
- "node_modules/express": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
- "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/execa/node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/execa/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/execa/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/exit-x": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz",
+ "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz",
+ "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/expect-utils": "30.2.0",
+ "@jest/get-type": "30.1.0",
+ "jest-matcher-utils": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
+ "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
+ "license": "MIT",
+ "peer": true,
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.3",
- "content-disposition": "0.5.4",
+ "body-parser": "~1.20.3",
+ "content-disposition": "~0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.7.1",
- "cookie-signature": "1.0.6",
+ "cookie": "~0.7.1",
+ "cookie-signature": "~1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
- "finalhandler": "1.3.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
+ "finalhandler": "~1.3.1",
+ "fresh": "~0.5.2",
+ "http-errors": "~2.0.0",
"merge-descriptors": "1.0.3",
"methods": "~1.1.2",
- "on-finished": "2.4.1",
+ "on-finished": "~2.4.1",
"parseurl": "~1.3.3",
- "path-to-regexp": "0.1.12",
+ "path-to-regexp": "~0.1.12",
"proxy-addr": "~2.0.7",
- "qs": "6.13.0",
+ "qs": "~6.14.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
- "send": "0.19.0",
- "serve-static": "1.16.2",
+ "send": "~0.19.0",
+ "serve-static": "~1.16.2",
"setprototypeof": "1.2.0",
- "statuses": "2.0.1",
+ "statuses": "~2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
@@ -5606,15 +7608,6 @@
"express": ">= 4.11"
}
},
- "node_modules/express/node_modules/cookie": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
- "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -5643,6 +7636,36 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/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/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -5675,6 +7698,26 @@
"fxparser": "src/cli/cli.js"
}
},
+ "node_modules/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
"node_modules/fecha": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
@@ -5779,16 +7822,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/flat": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
- "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
- "dev": true,
- "license": "BSD-3-Clause",
- "bin": {
- "flat": "cli.js"
- }
- },
"node_modules/flat-cache": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
@@ -5913,6 +7946,13 @@
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"license": "MIT"
},
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -6103,6 +8143,16 @@
"node": ">=0.10"
}
},
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -6136,6 +8186,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
@@ -6179,9 +8239,9 @@
}
},
"node_modules/glob": {
- "version": "10.4.5",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
- "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@@ -6248,6 +8308,27 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -6285,6 +8366,13 @@
"url": "https://github.com/sindresorhus/got?sponsor=1"
}
},
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/handlebars": {
"version": "4.7.8",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
@@ -6355,16 +8443,6 @@
"node": ">= 0.4"
}
},
- "node_modules/he": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
- "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "he": "bin/he"
- }
- },
"node_modules/helmet": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz",
@@ -6529,6 +8607,16 @@
"numbered": "^1.1.0"
}
},
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -6571,6 +8659,13 @@
"node": ">= 4"
}
},
+ "node_modules/ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -6587,6 +8682,26 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -6597,6 +8712,18 @@
"node": ">=0.8.19"
}
},
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -6681,6 +8808,16 @@
"node": ">=8"
}
},
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -6708,16 +8845,6 @@
"node": ">=0.12.0"
}
},
- "node_modules/is-plain-obj": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
- "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-potential-custom-element-name": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
@@ -6736,19 +8863,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-unicode-supported": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
- "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -6988,6 +9102,23 @@
"node": ">=8"
}
},
+ "node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
@@ -7003,6 +9134,21 @@
"node": ">=10"
}
},
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/istanbul-reports": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
@@ -7032,6 +9178,600 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/jest": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz",
+ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@jest/core": "30.2.0",
+ "@jest/types": "30.2.0",
+ "import-local": "^3.2.0",
+ "jest-cli": "30.2.0"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz",
+ "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^5.1.1",
+ "jest-util": "30.2.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz",
+ "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/expect": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "co": "^4.6.0",
+ "dedent": "^1.6.0",
+ "is-generator-fn": "^2.1.0",
+ "jest-each": "30.2.0",
+ "jest-matcher-utils": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-runtime": "30.2.0",
+ "jest-snapshot": "30.2.0",
+ "jest-util": "30.2.0",
+ "p-limit": "^3.1.0",
+ "pretty-format": "30.2.0",
+ "pure-rand": "^7.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-cli": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz",
+ "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/types": "30.2.0",
+ "chalk": "^4.1.2",
+ "exit-x": "^0.2.2",
+ "import-local": "^3.2.0",
+ "jest-config": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz",
+ "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@jest/get-type": "30.1.0",
+ "@jest/pattern": "30.0.1",
+ "@jest/test-sequencer": "30.2.0",
+ "@jest/types": "30.2.0",
+ "babel-jest": "30.2.0",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "deepmerge": "^4.3.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "jest-circus": "30.2.0",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-runner": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "micromatch": "^4.0.8",
+ "parse-json": "^5.2.0",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "esbuild-register": ">=3.4.0",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "esbuild-register": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-diff": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz",
+ "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/diff-sequences": "30.0.1",
+ "@jest/get-type": "30.1.0",
+ "chalk": "^4.1.2",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz",
+ "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-newline": "^3.1.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz",
+ "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "@jest/types": "30.2.0",
+ "chalk": "^4.1.2",
+ "jest-util": "30.2.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-environment-node": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz",
+ "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/fake-timers": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "jest-mock": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz",
+ "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "anymatch": "^3.1.3",
+ "fb-watchman": "^2.0.2",
+ "graceful-fs": "^4.2.11",
+ "jest-regex-util": "30.0.1",
+ "jest-util": "30.2.0",
+ "jest-worker": "30.2.0",
+ "micromatch": "^4.0.8",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.3"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz",
+ "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz",
+ "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "chalk": "^4.1.2",
+ "jest-diff": "30.2.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-message-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz",
+ "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@jest/types": "30.2.0",
+ "@types/stack-utils": "^2.0.3",
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "micromatch": "^4.0.8",
+ "pretty-format": "30.2.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.6"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-mock": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz",
+ "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "jest-util": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "30.0.1",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz",
+ "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz",
+ "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.2",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "jest-pnp-resolver": "^1.2.3",
+ "jest-util": "30.2.0",
+ "jest-validate": "30.2.0",
+ "slash": "^3.0.0",
+ "unrs-resolver": "^1.7.11"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz",
+ "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-regex-util": "30.0.1",
+ "jest-snapshot": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz",
+ "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "30.2.0",
+ "@jest/environment": "30.2.0",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "emittery": "^0.13.1",
+ "exit-x": "^0.2.2",
+ "graceful-fs": "^4.2.11",
+ "jest-docblock": "30.2.0",
+ "jest-environment-node": "30.2.0",
+ "jest-haste-map": "30.2.0",
+ "jest-leak-detector": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-resolve": "30.2.0",
+ "jest-runtime": "30.2.0",
+ "jest-util": "30.2.0",
+ "jest-watcher": "30.2.0",
+ "jest-worker": "30.2.0",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz",
+ "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "30.2.0",
+ "@jest/fake-timers": "30.2.0",
+ "@jest/globals": "30.2.0",
+ "@jest/source-map": "30.0.1",
+ "@jest/test-result": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "cjs-module-lexer": "^2.1.0",
+ "collect-v8-coverage": "^1.0.2",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "jest-haste-map": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-mock": "30.2.0",
+ "jest-regex-util": "30.0.1",
+ "jest-resolve": "30.2.0",
+ "jest-snapshot": "30.2.0",
+ "jest-util": "30.2.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz",
+ "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.27.4",
+ "@babel/generator": "^7.27.5",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.27.1",
+ "@babel/types": "^7.27.3",
+ "@jest/expect-utils": "30.2.0",
+ "@jest/get-type": "30.1.0",
+ "@jest/snapshot-utils": "30.2.0",
+ "@jest/transform": "30.2.0",
+ "@jest/types": "30.2.0",
+ "babel-preset-current-node-syntax": "^1.2.0",
+ "chalk": "^4.1.2",
+ "expect": "30.2.0",
+ "graceful-fs": "^4.2.11",
+ "jest-diff": "30.2.0",
+ "jest-matcher-utils": "30.2.0",
+ "jest-message-util": "30.2.0",
+ "jest-util": "30.2.0",
+ "pretty-format": "30.2.0",
+ "semver": "^7.7.2",
+ "synckit": "^0.11.8"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz",
+ "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz",
+ "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/get-type": "30.1.0",
+ "@jest/types": "30.2.0",
+ "camelcase": "^6.3.0",
+ "chalk": "^4.1.2",
+ "leven": "^3.1.0",
+ "pretty-format": "30.2.0"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-watcher": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz",
+ "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "30.2.0",
+ "@jest/types": "30.2.0",
+ "@types/node": "*",
+ "ansi-escapes": "^4.3.2",
+ "chalk": "^4.1.2",
+ "emittery": "^0.13.1",
+ "jest-util": "30.2.0",
+ "string-length": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz",
+ "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@ungap/structured-clone": "^1.3.0",
+ "jest-util": "30.2.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.1.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/jmespath": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
@@ -7061,9 +9801,9 @@
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -7111,6 +9851,19 @@
}
}
},
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
@@ -7137,6 +9890,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
@@ -7247,13 +10013,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/just-extend": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
- "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/jwa": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
@@ -7266,12 +10025,12 @@
}
},
"node_modules/jws": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
- "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz",
+ "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==",
"license": "MIT",
"dependencies": {
- "jwa": "^1.4.1",
+ "jwa": "^1.4.2",
"safe-buffer": "^5.0.1"
}
},
@@ -7299,6 +10058,16 @@
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==",
"license": "MIT"
},
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -7432,23 +10201,6 @@
"integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
"license": "MIT"
},
- "node_modules/log-symbols": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
- "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.1.0",
- "is-unicode-supported": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/logform": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
@@ -7472,13 +10224,6 @@
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"license": "Apache-2.0"
},
- "node_modules/loupe": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
- "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/lowercase-keys": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
@@ -7533,6 +10278,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -7578,6 +10340,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -7587,6 +10366,20 @@
"node": ">= 0.6"
}
},
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -7629,6 +10422,16 @@
"node": ">= 0.6"
}
},
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/mimic-response": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
@@ -8119,81 +10922,6 @@
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"license": "MIT"
},
- "node_modules/mocha": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
- "integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-colors": "^4.1.3",
- "browser-stdout": "^1.3.1",
- "chokidar": "^3.5.3",
- "debug": "^4.3.5",
- "diff": "^5.2.0",
- "escape-string-regexp": "^4.0.0",
- "find-up": "^5.0.0",
- "glob": "^10.4.5",
- "he": "^1.2.0",
- "js-yaml": "^4.1.0",
- "log-symbols": "^4.1.0",
- "minimatch": "^5.1.6",
- "ms": "^2.1.3",
- "serialize-javascript": "^6.0.2",
- "strip-json-comments": "^3.1.1",
- "supports-color": "^8.1.1",
- "workerpool": "^6.5.1",
- "yargs": "^17.7.2",
- "yargs-parser": "^21.1.1",
- "yargs-unparser": "^2.0.0"
- },
- "bin": {
- "_mocha": "bin/_mocha",
- "mocha": "bin/mocha.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/mocha/node_modules/brace-expansion": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
- "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/mocha/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/mocha/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
@@ -8370,6 +11098,20 @@
"node": ">= 6.0.0"
}
},
+ "node_modules/mylas": {
+ "version": "2.1.14",
+ "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.14.tgz",
+ "integrity": "sha512-BzQguy9W9NJgoVn2mRWzbFrFWWztGCcng2QI9+41frfk+Athwgx3qhqhvStz7ExeUUu7Kzw427sNzHpEZNINog==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/raouldeheer"
+ }
+ },
"node_modules/nan": {
"version": "2.23.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
@@ -8395,6 +11137,22 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
+ "node_modules/napi-postinstall": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
+ "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "napi-postinstall": "lib/cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/napi-postinstall"
+ }
+ },
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -8423,31 +11181,6 @@
"integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==",
"license": "MIT"
},
- "node_modules/nise": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz",
- "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@sinonjs/commons": "^3.0.1",
- "@sinonjs/fake-timers": "^13.0.1",
- "@sinonjs/text-encoding": "^0.7.3",
- "just-extend": "^6.2.0",
- "path-to-regexp": "^8.1.0"
- }
- },
- "node_modules/nise/node_modules/path-to-regexp": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
- "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
"node_modules/node-abort-controller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
@@ -8531,6 +11264,13 @@
"node-gyp-build-optional-packages-test": "build-test.js"
}
},
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/node-releases": {
"version": "2.0.26",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz",
@@ -8546,6 +11286,58 @@
"node": ">=6.0.0"
}
},
+ "node_modules/nodemon": {
+ "version": "3.1.11",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.11.tgz",
+ "integrity": "sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^4",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.1.2",
+ "pstree.remy": "^1.1.8",
+ "semver": "^7.5.3",
+ "simple-update-notifier": "^2.0.0",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nodemon"
+ }
+ },
+ "node_modules/nodemon/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/nodemon/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -8567,6 +11359,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -8651,6 +11456,22 @@
"fn.name": "1.x.x"
}
},
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -8710,6 +11531,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
@@ -8820,6 +11651,16 @@
"node": ">=8"
}
},
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -8851,14 +11692,14 @@
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT"
},
- "node_modules/pathval": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
- "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 14.16"
+ "node": ">=8"
}
},
"node_modules/picocolors": {
@@ -8888,6 +11729,98 @@
"node": ">=4.0.0"
}
},
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/plimit-lit": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.6.1.tgz",
+ "integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "queue-lit": "^1.5.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@@ -8907,6 +11840,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -9325,6 +12259,40 @@
"postcss": "^8.4.32"
}
},
+ "node_modules/postcss-svgo/node_modules/commander": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/postcss-svgo/node_modules/svgo": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz",
+ "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==",
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^11.1.0",
+ "css-select": "^5.1.0",
+ "css-tree": "^3.0.1",
+ "css-what": "^6.1.0",
+ "csso": "^5.0.5",
+ "picocolors": "^1.1.1",
+ "sax": "^1.4.1"
+ },
+ "bin": {
+ "svgo": "bin/svgo.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/svgo"
+ }
+ },
"node_modules/postcss-unique-selectors": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.4.tgz",
@@ -9491,6 +12459,34 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
+ "node_modules/pretty-format": {
+ "version": "30.2.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
+ "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "30.0.5",
+ "ansi-styles": "^5.2.0",
+ "react-is": "^18.3.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -9540,6 +12536,13 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/pump": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
@@ -9559,13 +12562,30 @@
"node": ">=6"
}
},
+ "node_modules/pure-rand": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz",
+ "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/qs": {
- "version": "6.13.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
- "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "version": "6.14.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
+ "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
"license": "BSD-3-Clause",
"dependencies": {
- "side-channel": "^1.0.6"
+ "side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
@@ -9574,6 +12594,37 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/queue-lit": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz",
+ "integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "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/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
@@ -9593,16 +12644,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/randombytes": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
- "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "^5.1.0"
- }
- },
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -9613,20 +12654,56 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
- "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz",
+ "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==",
"license": "MIT",
"dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.4.24",
+ "unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
+ "node_modules/raw-body/node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/raw-body/node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -9698,6 +12775,29 @@
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
"license": "MIT"
},
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-cwd/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -9732,12 +12832,47 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/rrweb-cssom": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz",
"integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==",
"license": "MIT"
},
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "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": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -9774,10 +12909,13 @@
"license": "MIT"
},
"node_modules/sax": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
- "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
- "license": "ISC"
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz",
+ "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
},
"node_modules/saxes": {
"version": "6.0.0",
@@ -9873,16 +13011,6 @@
"node": ">= 0.8"
}
},
- "node_modules/serialize-javascript": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
- "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "randombytes": "^2.1.0"
- }
- },
"node_modules/serve-static": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
@@ -10069,33 +13197,27 @@
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
"license": "MIT"
},
- "node_modules/sinon": {
- "version": "19.0.2",
- "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz",
- "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==",
+ "node_modules/simple-update-notifier": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
+ "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
"dev": true,
- "license": "BSD-3-Clause",
+ "license": "MIT",
"dependencies": {
- "@sinonjs/commons": "^3.0.1",
- "@sinonjs/fake-timers": "^13.0.2",
- "@sinonjs/samsam": "^8.0.1",
- "diff": "^7.0.0",
- "nise": "^6.1.1",
- "supports-color": "^7.2.0"
+ "semver": "^7.5.3"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/sinon"
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/sinon/node_modules/diff": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
- "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true,
- "license": "BSD-3-Clause",
+ "license": "MIT",
"engines": {
- "node": ">=0.3.1"
+ "node": ">=8"
}
},
"node_modules/slick": {
@@ -10125,6 +13247,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
"node_modules/sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -10140,6 +13273,13 @@
"integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==",
"license": "ISC"
},
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
"node_modules/ssh2": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.17.0.tgz",
@@ -10172,6 +13312,29 @@
"node": "*"
}
},
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/stack-utils/node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/standard-as-callback": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
@@ -10213,6 +13376,43 @@
"safe-buffer": "~5.2.0"
}
},
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-length/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-length/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/string-to-stream": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string-to-stream/-/string-to-stream-1.1.1.tgz",
@@ -10355,6 +13555,26 @@
"node": ">=8"
}
},
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -10397,9 +13617,9 @@
}
},
"node_modules/super-simple-scheduler": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/super-simple-scheduler/-/super-simple-scheduler-1.4.4.tgz",
- "integrity": "sha512-o99zHFrrFECwj1FFE+ns4su5hKSYif+SUNB3fUJbaRWGkwLLoj19TRuRJYp72TYt9eDiCii68UBuKiLF4tlkMg==",
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/super-simple-scheduler/-/super-simple-scheduler-1.4.5.tgz",
+ "integrity": "sha512-xHR3a+pLywY7HtwjWj/+OaANdEwAieQhckC/i0s6OoHtVJQ4+VLO1VfkKUbxp+oSROGXcaZet8PTGONVdKNUUw==",
"license": "MIT",
"dependencies": {
"uuid": "11.1.0",
@@ -10467,24 +13687,25 @@
}
},
"node_modules/svgo": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz",
- "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz",
+ "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==",
"license": "MIT",
+ "optional": true,
"dependencies": {
- "commander": "^11.1.0",
+ "@trysound/sax": "0.2.0",
+ "commander": "^7.2.0",
"css-select": "^5.1.0",
- "css-tree": "^3.0.1",
+ "css-tree": "^2.3.1",
"css-what": "^6.1.0",
"csso": "^5.0.5",
- "picocolors": "^1.1.1",
- "sax": "^1.4.1"
+ "picocolors": "^1.0.0"
},
"bin": {
- "svgo": "bin/svgo.js"
+ "svgo": "bin/svgo"
},
"engines": {
- "node": ">=16"
+ "node": ">=14.0.0"
},
"funding": {
"type": "opencollective",
@@ -10492,14 +13713,36 @@
}
},
"node_modules/svgo/node_modules/commander": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
- "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"license": "MIT",
+ "optional": true,
"engines": {
- "node": ">=16"
+ "node": ">= 10"
}
},
+ "node_modules/svgo/node_modules/css-tree": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+ "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "mdn-data": "2.0.30",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/svgo/node_modules/mdn-data": {
+ "version": "2.0.30",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+ "license": "CC0-1.0",
+ "optional": true
+ },
"node_modules/swagger-ui-dist": {
"version": "5.30.0",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.30.0.tgz",
@@ -10530,6 +13773,22 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"license": "MIT"
},
+ "node_modules/synckit": {
+ "version": "0.11.12",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz",
+ "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@pkgr/core": "^0.2.9"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/synckit"
+ }
+ },
"node_modules/tar-fs": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
@@ -10637,6 +13896,13 @@
"integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
"license": "MIT"
},
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -10658,6 +13924,16 @@
"node": ">=0.6"
}
},
+ "node_modules/touch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
+ "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
+ }
+ },
"node_modules/tough-cookie": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
@@ -10691,6 +13967,136 @@
"node": ">= 14.0.0"
}
},
+ "node_modules/ts-jest": {
+ "version": "29.4.6",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz",
+ "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bs-logger": "^0.2.6",
+ "fast-json-stable-stringify": "^2.1.0",
+ "handlebars": "^4.7.8",
+ "json5": "^2.2.3",
+ "lodash.memoize": "^4.1.2",
+ "make-error": "^1.3.6",
+ "semver": "^7.7.3",
+ "type-fest": "^4.41.0",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/transform": "^29.0.0 || ^30.0.0",
+ "@jest/types": "^29.0.0 || ^30.0.0",
+ "babel-jest": "^29.0.0 || ^30.0.0",
+ "jest": "^29.0.0 || ^30.0.0",
+ "jest-util": "^29.0.0 || ^30.0.0",
+ "typescript": ">=4.3 <6"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/transform": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jest-util": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsc-alias": {
+ "version": "1.8.16",
+ "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.16.tgz",
+ "integrity": "sha512-QjCyu55NFyRSBAl6+MTFwplpFcnm2Pq01rR/uxfqJoLMm6X3O14KEGtaSDZpJYaE1bJBGDjD0eSuiIWPe2T58g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.3",
+ "commander": "^9.0.0",
+ "get-tsconfig": "^4.10.0",
+ "globby": "^11.0.4",
+ "mylas": "^2.1.9",
+ "normalize-path": "^3.0.0",
+ "plimit-lit": "^1.2.6"
+ },
+ "bin": {
+ "tsc-alias": "dist/bin/index.js"
+ },
+ "engines": {
+ "node": ">=16.20.2"
+ }
+ },
+ "node_modules/tsc-alias/node_modules/commander": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -10783,6 +14189,7 @@
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"devOptional": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -10804,6 +14211,13 @@
"node": ">=0.8.0"
}
},
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/undici": {
"version": "6.22.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz",
@@ -10837,6 +14251,41 @@
"node": ">= 0.8"
}
},
+ "node_modules/unrs-resolver": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz",
+ "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "napi-postinstall": "^0.3.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unrs-resolver"
+ },
+ "optionalDependencies": {
+ "@unrs/resolver-binding-android-arm-eabi": "1.11.1",
+ "@unrs/resolver-binding-android-arm64": "1.11.1",
+ "@unrs/resolver-binding-darwin-arm64": "1.11.1",
+ "@unrs/resolver-binding-darwin-x64": "1.11.1",
+ "@unrs/resolver-binding-freebsd-x64": "1.11.1",
+ "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1",
+ "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1",
+ "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-arm64-musl": "1.11.1",
+ "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1",
+ "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-x64-gnu": "1.11.1",
+ "@unrs/resolver-binding-linux-x64-musl": "1.11.1",
+ "@unrs/resolver-binding-wasm32-wasi": "1.11.1",
+ "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1",
+ "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1",
+ "@unrs/resolver-binding-win32-x64-msvc": "1.11.1"
+ }
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz",
@@ -10905,6 +14354,13 @@
"uuid": "dist/bin/uuid"
}
},
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/v8-to-istanbul": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
@@ -10956,6 +14412,16 @@
"node": ">=18"
}
},
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
"node_modules/web-resource-inliner": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-7.0.0.tgz",
@@ -11224,13 +14690,6 @@
"integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
"license": "MIT"
},
- "node_modules/workerpool": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
- "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
- "dev": true,
- "license": "Apache-2.0"
- },
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
@@ -11325,6 +14784,20 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
+ "node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
+ "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
@@ -11408,6 +14881,13 @@
"node": ">=10"
}
},
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@@ -11435,22 +14915,6 @@
"node": ">=12"
}
},
- "node_modules/yargs-unparser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
- "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "camelcase": "^6.0.0",
- "decamelize": "^4.0.0",
- "flat": "^5.0.2",
- "is-plain-obj": "^2.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/yargs/node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -11492,6 +14956,16 @@
"node": ">=8"
}
},
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/server/package.json b/server/package.json
index 7486e81a2..91ba82988 100755
--- a/server/package.json
+++ b/server/package.json
@@ -5,10 +5,10 @@
"main": "index.js",
"type": "module",
"scripts": {
- "test": "c8 mocha",
- "dev": "tsx watch src/index.js",
+ "test": "NODE_OPTIONS=--experimental-vm-modules c8 jest --runInBand",
+ "dev": "nodemon --exec tsx src/index.js",
"start": "node --watch ./dist/index.js",
- "build": "tsc",
+ "build": "tsc && tsc-alias",
"lint": "eslint .",
"lint-fix": "eslint --fix .",
"format": "prettier --write .",
@@ -58,19 +58,28 @@
},
"devDependencies": {
"@eslint/js": "^9.17.0",
+ "@types/dockerode": "^4.0.0",
"@types/express": "5.0.3",
+ "@types/gamedig": "^5.0.3",
+ "@types/jest": "^30.0.0",
+ "@types/jmespath": "^0.15.2",
"@types/jsonwebtoken": "9.0.10",
+ "@types/mjml": "^4.7.4",
+ "@types/multer": "^2.0.0",
"@types/nodemailer": "7.0.1",
+ "@types/papaparse": "^5.5.2",
"@types/ping": "0.4.4",
"c8": "10.1.3",
- "chai": "5.2.0",
"eslint": "^9.17.0",
"eslint-plugin-mocha": "^10.5.0",
"esm": "3.2.25",
"globals": "^15.14.0",
- "mocha": "11.1.0",
+ "jest": "^30.2.0",
+ "nodemon": "^3.1.11",
"prettier": "^3.3.3",
- "sinon": "19.0.2",
+ "ts-jest": "^29.4.6",
+ "ts-node": "^10.9.2",
+ "tsc-alias": "1.8.16",
"tsx": "4.20.5",
"typescript": "5.9.2"
}
diff --git a/server/scripts/generate-checks.js b/server/scripts/generate-checks.js
new file mode 100644
index 000000000..d3a33b033
--- /dev/null
+++ b/server/scripts/generate-checks.js
@@ -0,0 +1,176 @@
+import mongoose from "mongoose";
+import { MonitorModel } from "../dist/db/models/Monitor.js";
+import { CheckModel } from "../dist/db/models/Check.js";
+
+const DEFAULT_MONITOR_ID = "000000000000000000000001";
+const DEFAULT_TEAM_ID = "0000000000000000000000aa";
+const DEFAULT_USER_ID = "0000000000000000000000bb";
+const DEFAULT_MONITOR_TYPE = "http";
+const DEFAULT_TOTAL = 1_000_000;
+const DEFAULT_BATCH_SIZE = 5_000;
+
+const parseObjectId = (value, fallback) => {
+ try {
+ return new mongoose.Types.ObjectId(value || fallback);
+ } catch (error) {
+ console.warn(`Invalid ObjectId '${value}', falling back to '${fallback}'.`);
+ return new mongoose.Types.ObjectId(fallback);
+ }
+};
+
+async function ensureMonitor({ monitorId, teamId, userId, type }) {
+ const existing = await MonitorModel.findById(monitorId);
+ if (existing) {
+ return existing;
+ }
+
+ console.log(`Monitor ${monitorId.toString()} not found, creating it.`);
+ const monitor = new MonitorModel({
+ _id: monitorId,
+ userId,
+ teamId,
+ name: `Seed Monitor ${monitorId.toString()}`,
+ description: "Synthetic monitor for performance testing",
+ statusWindow: [],
+ statusWindowSize: 5,
+ statusWindowThreshold: 60,
+ type,
+ ignoreTlsErrors: false,
+ url: "https://example.com",
+ isActive: true,
+ interval: 60000,
+ alertThreshold: 5,
+ cpuAlertThreshold: 5,
+ memoryAlertThreshold: 5,
+ diskAlertThreshold: 5,
+ tempAlertThreshold: 5,
+ selectedDisks: [],
+ });
+
+ await monitor.save();
+ return monitor;
+}
+
+async function run() {
+ const mongoUri = process.env.MONGO_URI ?? "mongodb://localhost:27017/uptime_db";
+ const monitorId = parseObjectId(process.env.MONITOR_ID ?? DEFAULT_MONITOR_ID, DEFAULT_MONITOR_ID);
+ const teamId = parseObjectId("69648b0578209af45f9ffe30");
+ const userId = parseObjectId("69648b0678209af45f9ffe32");
+ const monitorType = process.env.MONITOR_TYPE ?? DEFAULT_MONITOR_TYPE;
+ const total = Number(process.env.CHECK_TOTAL ?? DEFAULT_TOTAL);
+ const batchSize = Number(process.env.CHECK_BATCH_SIZE ?? DEFAULT_BATCH_SIZE);
+
+ console.log(`Connecting to MongoDB at ${mongoUri}`);
+ await mongoose.connect(mongoUri);
+
+ await ensureMonitor({ monitorId, teamId, userId, type: monitorType });
+
+ console.log(`Seeding ${total} checks for monitor ${monitorId.toString()} (team ${teamId.toString()}) in batches of ${batchSize}.`);
+
+ const docs = [];
+ const startTime = Date.now();
+
+ for (let i = 0; i < total; i += 1) {
+ const baseTime = Date.now() - (total - i) * 1000;
+ const createdAt = new Date(baseTime);
+ docs.push({
+ metadata: {
+ monitorId,
+ teamId,
+ type: monitorType,
+ },
+ status: i % 50 !== 0,
+ statusCode: i % 50 !== 0 ? 200 : 500,
+ responseTime: Math.floor(Math.random() * 1000),
+ message: i % 50 !== 0 ? "OK" : "Error",
+ expiry: createdAt,
+ createdAt,
+ updatedAt: createdAt,
+ timings: {
+ start: baseTime,
+ socket: baseTime,
+ lookup: baseTime,
+ connect: baseTime,
+ secureConnect: baseTime,
+ upload: baseTime,
+ response: baseTime + 40,
+ end: baseTime + 45,
+ phases: {
+ wait: 0,
+ dns: 1,
+ tcp: 2,
+ tls: 4,
+ request: 0,
+ firstByte: 30,
+ download: 5,
+ total: 45,
+ },
+ },
+ cpu: {
+ physical_core: 8,
+ logical_core: 16,
+ frequency: 3600,
+ temperature: [50 + Math.random() * 10],
+ free_percent: 40,
+ usage_percent: Math.random() * 100,
+ },
+ memory: {
+ total_bytes: 32 * 1024 ** 3,
+ available_bytes: 16 * 1024 ** 3,
+ used_bytes: 16 * 1024 ** 3,
+ usage_percent: Math.random() * 100,
+ },
+ disk: [
+ {
+ device: "/dev/sda1",
+ mountpoint: "/",
+ read_speed_bytes: Math.random() * 10_000_000,
+ write_speed_bytes: Math.random() * 10_000_000,
+ total_bytes: 512 * 1024 ** 3,
+ free_bytes: 128 * 1024 ** 3,
+ usage_percent: Math.random() * 100,
+ },
+ ],
+ host: {
+ os: "linux",
+ platform: "ubuntu",
+ kernel_version: "5.15.0",
+ },
+ net: [
+ {
+ name: "eth0",
+ bytes_sent: Math.random() * 10_000_000,
+ bytes_recv: Math.random() * 10_000_000,
+ packets_sent: Math.random() * 1_000_000,
+ packets_recv: Math.random() * 1_000_000,
+ err_in: 0,
+ err_out: 0,
+ drop_in: 0,
+ drop_out: 0,
+ fifo_in: 0,
+ fifo_out: 0,
+ },
+ ],
+ errors: i % 50 === 0 ? [{ metric: ["uptime"], err: "500" }] : [],
+ });
+
+ if (docs.length === batchSize) {
+ await CheckModel.insertMany(docs, { ordered: false });
+ console.log(`Inserted ${i + 1} / ${total}`);
+ docs.length = 0;
+ }
+ }
+
+ if (docs.length > 0) {
+ await CheckModel.insertMany(docs, { ordered: false });
+ }
+
+ await mongoose.disconnect();
+ const duration = ((Date.now() - startTime) / 1000).toFixed(2);
+ console.log(`Finished inserting ${total} checks in ${duration}s`);
+}
+
+run().catch((error) => {
+ console.error("Failed to seed checks", error);
+ process.exit(1);
+});
diff --git a/server/src/app.js b/server/src/app.js
index 4578de896..d782d07eb 100644
--- a/server/src/app.js
+++ b/server/src/app.js
@@ -14,7 +14,6 @@ import { sanitizeBody, sanitizeQuery } from "./middleware/v1/sanitization.js";
export const createApp = ({ services, controllers, envSettings, frontendPath, openApiSpec }) => {
const allowedOrigin = envSettings.clientHost;
-
const app = express();
app.use(generalApiLimiter);
// Static files
diff --git a/server/src/config/controllers.js b/server/src/config/controllers.js
deleted file mode 100644
index 5493a141b..000000000
--- a/server/src/config/controllers.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import { createCommonDependencies } from "../controllers/v1/baseController.js";
-
-// Services
-
-// V1 Controllers
-import MonitorController from "../controllers/v1/monitorController.js";
-import AuthController from "../controllers/v1/authController.js";
-import SettingsController from "../controllers/v1/settingsController.js";
-import CheckController from "../controllers/v1/checkController.js";
-import InviteController from "../controllers/v1/inviteController.js";
-import MaintenanceWindowController from "../controllers/v1/maintenanceWindowController.js";
-import QueueController from "../controllers/v1/queueController.js";
-import LogController from "../controllers/v1/logController.js";
-import StatusPageController from "../controllers/v1/statusPageController.js";
-import NotificationController from "../controllers/v1/notificationController.js";
-import DiagnosticController from "../controllers/v1/diagnosticController.js";
-import IncidentController from "../controllers/v1/incidentController.js";
-
-export const initializeControllers = (services) => {
- const controllers = {};
- const commonDependencies = createCommonDependencies(services.db, services.errorService, services.logger, services.stringService);
-
- // V1
- controllers.authController = new AuthController(commonDependencies, {
- settingsService: services.settingsService,
- emailService: services.emailService,
- jobQueue: services.jobQueue,
- userService: services.userService,
- });
-
- controllers.monitorController = new MonitorController(commonDependencies, {
- settingsService: services.settingsService,
- jobQueue: services.jobQueue,
- emailService: services.emailService,
- monitorService: services.monitorService,
- });
-
- controllers.settingsController = new SettingsController(commonDependencies, {
- settingsService: services.settingsService,
- emailService: services.emailService,
- });
- controllers.checkController = new CheckController(commonDependencies, {
- settingsService: services.settingsService,
- checkService: services.checkService,
- });
- controllers.inviteController = new InviteController(commonDependencies, {
- inviteService: services.inviteService,
- });
-
- controllers.maintenanceWindowController = new MaintenanceWindowController(commonDependencies, {
- settingsService: services.settingsService,
- maintenanceWindowService: services.maintenanceWindowService,
- });
- controllers.queueController = new QueueController(commonDependencies, {
- jobQueue: services.jobQueue,
- });
- controllers.logController = new LogController(commonDependencies);
- controllers.statusPageController = new StatusPageController(commonDependencies);
- controllers.notificationController = new NotificationController(commonDependencies, {
- notificationService: services.notificationService,
- statusService: services.statusService,
- });
- controllers.diagnosticController = new DiagnosticController(commonDependencies, {
- diagnosticService: services.diagnosticService,
- });
-
- controllers.incidentController = new IncidentController(commonDependencies, {
- incidentService: services.incidentService,
- });
-
- return controllers;
-};
diff --git a/server/src/config/controllers.ts b/server/src/config/controllers.ts
new file mode 100644
index 000000000..9fe834348
--- /dev/null
+++ b/server/src/config/controllers.ts
@@ -0,0 +1,35 @@
+import MonitorController from "../controllers/monitorController.js";
+import AuthController from "../controllers/authController.js";
+import SettingsController from "../controllers/settingsController.js";
+import CheckController from "../controllers/checkController.js";
+import InviteController from "../controllers/inviteController.js";
+import MaintenanceWindowController from "../controllers/maintenanceWindowController.js";
+import QueueController from "../controllers/queueController.js";
+import LogController from "../controllers/logController.js";
+import StatusPageController from "../controllers/statusPageController.js";
+import NotificationController from "../controllers/notificationController.js";
+import DiagnosticController from "../controllers/diagnosticController.js";
+import IncidentController from "../controllers/incidentController.js";
+
+export const initializeControllers = (services: any) => {
+ const controllers: Record = {};
+
+ controllers.authController = new AuthController(services.userService);
+
+ controllers.monitorController = new MonitorController(services.monitorService);
+
+ controllers.settingsController = new SettingsController(services.settingsService, services.emailService, services.db);
+ controllers.checkController = new CheckController(services.checkService);
+ controllers.inviteController = new InviteController(services.inviteService);
+
+ controllers.maintenanceWindowController = new MaintenanceWindowController(services.maintenanceWindowService);
+ controllers.queueController = new QueueController(services.jobQueue);
+ controllers.logController = new LogController(services.logger);
+ controllers.statusPageController = new StatusPageController(services.db);
+ controllers.notificationController = new NotificationController(services.notificationService, services.db);
+ controllers.diagnosticController = new DiagnosticController(services.diagnosticService);
+
+ controllers.incidentController = new IncidentController(services.incidentService);
+
+ return controllers;
+};
diff --git a/server/src/config/routes.js b/server/src/config/routes.ts
similarity index 92%
rename from server/src/config/routes.js
rename to server/src/config/routes.ts
index 97b2d6a1d..303dd4eb7 100644
--- a/server/src/config/routes.js
+++ b/server/src/config/routes.ts
@@ -2,7 +2,7 @@ import { verifyJWT } from "../middleware/v1/verifyJWT.js";
import { authApiLimiter } from "../middleware/v1/rateLimiter.js";
import AuthRoutes from "../routes/v1/authRoute.js";
-import InviteRoutes from "../routes/v1//inviteRoute.js";
+import InviteRoutes from "../routes/v1/inviteRoute.js";
import MonitorRoutes from "../routes/v1/monitorRoute.js";
import CheckRoutes from "../routes/v1/checkRoute.js";
import SettingsRoutes from "../routes/v1/settingsRoute.js";
@@ -10,12 +10,12 @@ import MaintenanceWindowRoutes from "../routes/v1/maintenanceWindowRoute.js";
import StatusPageRoutes from "../routes/v1/statusPageRoute.js";
import QueueRoutes from "../routes/v1/queueRoute.js";
import LogRoutes from "../routes/v1/logRoutes.js";
-import DiagnosticRoutes from "../routes/v1//diagnosticRoute.js";
+import DiagnosticRoutes from "../routes/v1/diagnosticRoute.js";
import NotificationRoutes from "../routes/v1/notificationRoute.js";
import IncidentRoutes from "../routes/v1/incidentRoute.js";
-export const setupRoutes = (app, controllers) => {
+export const setupRoutes = (app: any, controllers: Record) => {
// V1
const authRoutes = new AuthRoutes(controllers.authController);
const monitorRoutes = new MonitorRoutes(controllers.monitorController);
diff --git a/server/src/config/services.js b/server/src/config/services.ts
similarity index 57%
rename from server/src/config/services.js
rename to server/src/config/services.ts
index 9744c647d..74c68c86e 100644
--- a/server/src/config/services.js
+++ b/server/src/config/services.ts
@@ -1,23 +1,23 @@
-import ServiceRegistry from "../service/v1/system/serviceRegistry.js";
-import TranslationService from "../service/v1/system/translationService.js";
-import StringService from "../service/v1/system/stringService.js";
-import MongoDB from "../db/v1/MongoDB.js";
-import NetworkService from "../service/v1/infrastructure/networkService.js";
-import EmailService from "../service/v1/infrastructure/emailService.js";
-import BufferService from "../service/v1/infrastructure/bufferService.js";
-import StatusService from "../service/v1/infrastructure/statusService.js";
-import NotificationUtils from "../service/v1/infrastructure/notificationUtils.js";
-import NotificationService from "../service/v1/infrastructure/notificationService.js";
-import ErrorService from "../service/v1/infrastructure/errorService.js";
-import SuperSimpleQueueHelper from "../service/v1/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js";
-import SuperSimpleQueue from "../service/v1/infrastructure/SuperSimpleQueue/SuperSimpleQueue.js";
-import UserService from "../service/v1/business/userService.js";
-import CheckService from "../service/v1/business/checkService.js";
-import DiagnosticService from "../service/v1/business/diagnosticService.js";
-import InviteService from "../service/v1/business/inviteService.js";
-import MaintenanceWindowService from "../service/v1/business/maintenanceWindowService.js";
-import MonitorService from "../service/v1/business/monitorService.js";
-import IncidentService from "../service/v1/business/incidentService.js";
+import ServiceRegistry from "../service/system/serviceRegistry.js";
+import TranslationService from "../service/system/translationService.js";
+import StringService from "../service/system/stringService.js";
+import MongoDB from "../db/MongoDB.js";
+import NetworkService from "../service/infrastructure/networkService.js";
+import EmailService from "../service/infrastructure/emailService.js";
+import BufferService from "../service/infrastructure/bufferService.js";
+import StatusService from "../service/infrastructure/statusService.js";
+import NotificationUtils from "../service/infrastructure/notificationUtils.js";
+import NotificationService from "../service/infrastructure/notificationService.js";
+import ErrorService from "../service/infrastructure/errorService.js";
+import SuperSimpleQueueHelper from "../service/infrastructure/SuperSimpleQueue/SuperSimpleQueueHelper.js";
+import SuperSimpleQueue from "../service/infrastructure/SuperSimpleQueue/SuperSimpleQueue.js";
+import UserService from "../service/business/userService.js";
+import CheckService from "../service/business/checkService.js";
+import DiagnosticService from "../service/business/diagnosticService.js";
+import InviteService from "../service/business/inviteService.js";
+import MaintenanceWindowService from "../service/business/maintenanceWindowService.js";
+import { MonitorService } from "@/service/index.js";
+import IncidentService from "../service/business/incidentService.js";
import papaparse from "papaparse";
import axios from "axios";
import got from "got";
@@ -34,9 +34,8 @@ const { compile } = pkg;
import mjml2html from "mjml";
import jwt from "jsonwebtoken";
import crypto from "crypto";
-import { games } from "gamedig";
+import { games, GameDig } from "gamedig";
import jmespath from "jmespath";
-import { GameDig } from "gamedig";
import { fileURLToPath } from "url";
import { ObjectId } from "mongodb";
@@ -47,33 +46,35 @@ import { GenerateAvatarImage } from "../utils/imageProcessing.js";
import { ParseBoolean } from "../utils/utils.js";
// Models
-import Check from "../db/v1/models/Check.js";
-import Monitor from "../db/v1/models/Monitor.js";
-import User from "../db/v1/models/User.js";
-import InviteToken from "../db/v1/models/InviteToken.js";
-import StatusPage from "../db/v1/models/StatusPage.js";
-import Team from "../db/v1/models/Team.js";
-import MaintenanceWindow from "../db/v1/models/MaintenanceWindow.js";
-import MonitorStats from "../db/v1/models/MonitorStats.js";
-import Notification from "../db/v1/models/Notification.js";
-import RecoveryToken from "../db/v1/models/RecoveryToken.js";
-import AppSettings from "../db/v1/models/AppSettings.js";
-import Incident from "../db/v1/models/Incident.js";
+import Monitor from "../db/models/Monitor.js";
+import User from "../db/models/User.js";
+import InviteToken from "../db/models/InviteToken.js";
+import StatusPage from "../db/models/StatusPage.js";
+import Team from "../db/models/Team.js";
+import MaintenanceWindow from "../db/models/MaintenanceWindow.js";
+import MonitorStats from "../db/models/MonitorStats.js";
+import Notification from "../db/models/Notification.js";
+import RecoveryToken from "../db/models/RecoveryToken.js";
+import AppSettings from "../db/models/AppSettings.js";
+import Incident from "../db/models/Incident.js";
-import InviteModule from "../db/v1/modules/inviteModule.js";
-import CheckModule from "../db/v1/modules/checkModule.js";
-import StatusPageModule from "../db/v1/modules/statusPageModule.js";
-import UserModule from "../db/v1/modules/userModule.js";
-import MaintenanceWindowModule from "../db/v1/modules/maintenanceWindowModule.js";
-import MonitorModule from "../db/v1/modules/monitorModule.js";
-import NotificationModule from "../db/v1/modules/notificationModule.js";
-import RecoveryModule from "../db/v1/modules/recoveryModule.js";
-import SettingsModule from "../db/v1/modules/settingsModule.js";
-import IncidentModule from "../db/v1/modules/incidentModule.js";
+import InviteModule from "../db/modules/inviteModule.js";
+import CheckModule from "../db/modules/checkModule.js";
+import StatusPageModule from "../db/modules/statusPageModule.js";
+import UserModule from "../db/modules/userModule.js";
+import MaintenanceWindowModule from "../db/modules/maintenanceWindowModule.js";
+import MonitorModule from "../db/modules/monitorModule.js";
+import NotificationModule from "../db/modules/notificationModule.js";
+import RecoveryModule from "../db/modules/recoveryModule.js";
+import SettingsModule from "../db/modules/settingsModule.js";
+import IncidentModule from "../db/modules/incidentModule.js";
-export const initializeServices = async ({ logger, envSettings, settingsService }) => {
+// repositories
+import { MongoMonitorsRepository, MongoChecksRepository, MongoMonitorStatsRepository } from "@/repositories/index.js";
+
+export const initializeServices = async ({ logger, envSettings, settingsService }: { logger: any; envSettings: any; settingsService: any }) => {
const serviceRegistry = new ServiceRegistry({ logger });
- ServiceRegistry.instance = serviceRegistry;
+ (ServiceRegistry as any).instance = serviceRegistry;
const translationService = new TranslationService(logger);
await translationService.initialize();
@@ -81,7 +82,7 @@ export const initializeServices = async ({ logger, envSettings, settingsService
const stringService = new StringService(translationService);
// Create DB
- const checkModule = new CheckModule({ logger, Check, Monitor, User });
+ const checkModule = new CheckModule({ logger, Monitor, User });
const inviteModule = new InviteModule({ InviteToken, crypto, stringService });
const statusPageModule = new StatusPageModule({ StatusPage, NormalizeData, stringService });
const userModule = new UserModule({ User, Team, GenerateAvatarImage, ParseBoolean, stringService });
@@ -89,7 +90,6 @@ export const initializeServices = async ({ logger, envSettings, settingsService
const monitorModule = new MonitorModule({
Monitor,
MonitorStats,
- Check,
stringService,
fs,
path,
@@ -120,6 +120,11 @@ export const initializeServices = async ({ logger, envSettings, settingsService
await db.connect();
+ // Repositories
+ const monitorsRepository = new MongoMonitorsRepository();
+ const checksRepository = new MongoChecksRepository();
+ const monitorStatsRepository = new MongoMonitorStatsRepository();
+
const networkService = new NetworkService({
axios,
got,
@@ -146,7 +151,7 @@ export const initializeServices = async ({ logger, envSettings, settingsService
const bufferService = new BufferService({ db, logger, envSettings, incidentService });
- const statusService = new StatusService({ db, logger, buffer: bufferService, incidentService });
+ const statusService = new StatusService({ db, logger, buffer: bufferService, incidentService, monitorsRepository });
const notificationUtils = new NotificationUtils({
stringService,
@@ -176,6 +181,7 @@ export const initializeServices = async ({ logger, envSettings, settingsService
db,
logger,
helper: superSimpleQueueHelper,
+ monitorsRepository,
});
// Business services
@@ -212,7 +218,6 @@ export const initializeServices = async ({ logger, envSettings, settingsService
});
const monitorService = new MonitorService({
db,
- settingsService,
jobQueue: superSimpleQueue,
stringService,
emailService,
@@ -220,6 +225,9 @@ export const initializeServices = async ({ logger, envSettings, settingsService
logger,
errorService,
games,
+ monitorsRepository,
+ checksRepository,
+ monitorStatsRepository,
});
const services = {
diff --git a/server/src/controllers/authController.ts b/server/src/controllers/authController.ts
new file mode 100755
index 000000000..d033aa39d
--- /dev/null
+++ b/server/src/controllers/authController.ts
@@ -0,0 +1,233 @@
+import { Request, Response, NextFunction } from "express";
+import { AppError } from "@/utils/AppError.js";
+
+import {
+ registrationBodyValidation,
+ loginValidation,
+ editUserBodyValidation,
+ recoveryValidation,
+ recoveryTokenBodyValidation,
+ newPasswordValidation,
+ getUserByIdParamValidation,
+ editUserByIdParamValidation,
+ editUserByIdBodyValidation,
+ editSuperadminUserByIdBodyValidation,
+ editUserPasswordByIdBodyValidation,
+} from "@/validation/joi.js";
+
+const SERVICE_NAME = "authController";
+
+class AuthController {
+ static SERVICE_NAME = SERVICE_NAME;
+
+ private userService: any;
+
+ constructor(userService: any) {
+ this.userService = userService;
+ }
+
+ get serviceName() {
+ return AuthController.SERVICE_NAME;
+ }
+
+ registerUser = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ if (req.body?.email) {
+ req.body.email = req.body.email?.toLowerCase();
+ }
+ await registrationBodyValidation.validateAsync(req.body);
+ const { user, token } = await this.userService.registerUser(req.body, req.file);
+ res.status(200).json({
+ success: true,
+ msg: "User registered successfully",
+ data: { user, token },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ loginUser = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ if (req.body?.email) {
+ req.body.email = req.body.email?.toLowerCase();
+ }
+ await loginValidation.validateAsync(req.body);
+ const { user, token } = await this.userService.loginUser(req.body.email, req.body.password);
+
+ return res.status(200).json({
+ success: true,
+ msg: "User logged in successfully",
+ data: {
+ user,
+ token,
+ },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ editUser = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await editUserBodyValidation.validateAsync(req.body);
+
+ const updatedUser = await this.userService.editUser(req.body, req.file, req.user);
+
+ res.status(200).json({
+ success: true,
+ msg: "User updated successfully",
+ data: updatedUser,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ checkSuperadminExists = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const superAdminExists = await this.userService.checkSuperadminExists();
+ return res.status(200).json({
+ success: true,
+ msg: "Superadmin existence checked successfully",
+ data: superAdminExists,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ requestRecovery = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await recoveryValidation.validateAsync(req.body);
+ const email = req?.body?.email;
+ const msgId = await this.userService.requestRecovery(email);
+ return res.status(200).json({
+ success: true,
+ msg: "Password recovery email sent successfully",
+ data: msgId,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ validateRecovery = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await recoveryTokenBodyValidation.validateAsync(req.body);
+ await this.userService.validateRecovery(req.body.recoveryToken);
+ return res.status(200).json({
+ success: true,
+ msg: "Recovery token is valid",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ resetPassword = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await newPasswordValidation.validateAsync(req.body);
+ const { user, token } = await this.userService.resetPassword(req.body.password, req.body.recoveryToken);
+ return res.status(200).json({
+ success: true,
+ msg: "Password has been reset successfully",
+ data: { user, token },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ deleteUser = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await this.userService.deleteUser(req.user);
+ return res.status(200).json({
+ success: true,
+ msg: "User deleted successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getAllUsers = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const allUsers = await this.userService.getAllUsers();
+ return res.status(200).json({
+ success: true,
+ msg: "Users retrieved successfully",
+ data: allUsers,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getUserById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getUserByIdParamValidation.validateAsync(req.params);
+ const userId = req?.params?.userId;
+ const roles = req?.user?.role;
+
+ if (!userId) {
+ throw new Error("No user ID in request");
+ }
+
+ if (!roles || roles.length === 0) {
+ throw new Error("No roles in request");
+ }
+
+ const user = await this.userService.getUserById(roles, userId);
+
+ return res.status(200).json({ success: true, msg: "ok", data: user });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ editUserById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const roles = req?.user?.role;
+ if (!roles.includes("superadmin")) {
+ throw new AppError({ message: "Unauthorized", status: 403 });
+ }
+
+ const userId = req.params.userId;
+ const user = { ...req.body };
+
+ await editUserByIdParamValidation.validateAsync(req.params);
+ // If this is superadmin self edit, allow "superadmin" role
+ if (userId === req.user._id) {
+ await editSuperadminUserByIdBodyValidation.validateAsync(req.body);
+ } else {
+ await editUserByIdBodyValidation.validateAsync(req.body);
+ }
+
+ await this.userService.editUserById(userId, user);
+ return res.status(200).json({ success: true, msg: "ok" });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ editUserPasswordById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const roles = req?.user?.role;
+ if (!roles.includes("superadmin")) {
+ throw new AppError({ message: "Unauthorized", status: 403 });
+ }
+
+ const userId = req.params.userId;
+ await editUserByIdParamValidation.validateAsync(req.params);
+ await editUserPasswordByIdBodyValidation.validateAsync(req.body);
+ const updatedPassword = req.body.password;
+ await this.userService.setPasswordByUserId(userId, updatedPassword);
+ return res.status(200).json({ success: true, msg: "Password reset successfully" });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default AuthController;
diff --git a/server/src/controllers/checkController.ts b/server/src/controllers/checkController.ts
new file mode 100755
index 000000000..8ae6fd785
--- /dev/null
+++ b/server/src/controllers/checkController.ts
@@ -0,0 +1,181 @@
+import { Request, Response, NextFunction } from "express";
+
+import {
+ getChecksParamValidation,
+ getChecksQueryValidation,
+ getTeamChecksQueryValidation,
+ deleteChecksParamValidation,
+ deleteChecksByTeamIdParamValidation,
+ updateChecksTTLBodyValidation,
+ ackCheckBodyValidation,
+ ackAllChecksParamValidation,
+ ackAllChecksBodyValidation,
+} from "@/validation/joi.js";
+
+const SERVICE_NAME = "checkController";
+
+class CheckController {
+ static SERVICE_NAME = SERVICE_NAME;
+
+ private checkService: any;
+ constructor(checkService: any) {
+ this.checkService = checkService;
+ }
+
+ get serviceName() {
+ return CheckController.SERVICE_NAME;
+ }
+
+ getChecksByMonitor = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getChecksParamValidation.validateAsync(req.params);
+ await getChecksQueryValidation.validateAsync(req.query);
+
+ const result = await this.checkService.getChecksByMonitor({
+ monitorId: req?.params?.monitorId,
+ query: req?.query,
+ teamId: req?.user?.teamId,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Checks retrieved successfully",
+ data: result,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getChecksByTeam = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getTeamChecksQueryValidation.validateAsync(req.query);
+ const checkData = await this.checkService.getChecksByTeam({
+ teamId: req?.user?.teamId,
+ query: req?.query,
+ });
+ return res.status(200).json({
+ success: true,
+ msg: "Team checks retrieved successfully",
+ data: checkData,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getChecksSummaryByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const summary = await this.checkService.getChecksSummaryByTeamId({ teamId: req?.user?.teamId });
+ return res.status(200).json({
+ success: true,
+ msg: "Checks summary retrieved successfully",
+ data: summary,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ ackCheck = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await ackCheckBodyValidation.validateAsync(req.body);
+
+ const updatedCheck = await this.checkService.ackCheck({
+ checkId: req?.params?.checkId,
+ teamId: req?.user?.teamId,
+ ack: req?.body?.ack,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Check acknowledged successfully",
+ data: updatedCheck,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ ackAllChecks = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await ackAllChecksParamValidation.validateAsync(req.params);
+ await ackAllChecksBodyValidation.validateAsync(req.body);
+
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new Error("No team ID in request");
+ }
+
+ const updatedChecks = await this.checkService.ackAllChecks({
+ monitorId: req?.params?.monitorId,
+ path: req?.params?.path,
+ teamId: req?.user?.teamId,
+ ack: req?.body?.ack,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "All checks acknowledged successfully",
+ data: updatedChecks,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ deleteChecks = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await deleteChecksParamValidation.validateAsync(req.params);
+
+ const deletedCount = await this.checkService.deleteChecks({
+ monitorId: req.params.monitorId,
+ teamId: req?.user?.teamId,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Checks deleted successfully",
+ data: { deletedCount },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ deleteChecksByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await deleteChecksByTeamIdParamValidation.validateAsync(req.params);
+
+ const deletedCount = await this.checkService.deleteChecksByTeamId({ teamId: req?.user?.teamId });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Checks deleted successfully",
+ data: { deletedCount },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ updateChecksTTL = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await updateChecksTTLBodyValidation.validateAsync(req.body);
+
+ await this.checkService.updateChecksTTL({
+ teamId: req?.user?.teamId,
+ ttl: req?.body?.ttl,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Checks TTL updated successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default CheckController;
diff --git a/server/src/controllers/controllerUtils.ts b/server/src/controllers/controllerUtils.ts
new file mode 100755
index 000000000..af3eddd44
--- /dev/null
+++ b/server/src/controllers/controllerUtils.ts
@@ -0,0 +1,111 @@
+import { AppError } from "@/utils/AppError.js";
+import { type MonitorType, MonitorTypes } from "@/types/index.js";
+
+const fetchMonitorCertificate = async (sslChecker: any, monitor: any): Promise => {
+ const monitorUrl = new URL(monitor.url);
+ const hostname = monitorUrl.hostname;
+ const cert = await sslChecker(hostname);
+ // Throw an error if no cert or if cert.validTo is not present
+ if (cert?.validTo === null || cert?.validTo === undefined) {
+ throw new Error("Certificate not found");
+ }
+ return cert;
+};
+const requireString = (value: unknown, fieldName: string): string => {
+ if (typeof value === "string" && value.trim().length > 0) {
+ return value;
+ }
+ throw new AppError({ message: `${fieldName} is required`, status: 400 });
+};
+
+const optionalString = (value: unknown, fieldName: string): string | undefined => {
+ if (value === undefined) {
+ return undefined;
+ }
+ if (typeof value === "string") {
+ return value;
+ }
+ throw new AppError({ message: `${fieldName} must be a string`, status: 400 });
+};
+
+const optionalNumber = (value: unknown, fieldName: string): number | undefined => {
+ if (value === undefined) {
+ return undefined;
+ }
+ if (typeof value === "number" && Number.isFinite(value)) {
+ return value;
+ }
+ if (typeof value === "string" && value.trim() !== "") {
+ const parsed = Number(value);
+ if (!Number.isNaN(parsed)) {
+ return parsed;
+ }
+ }
+ throw new AppError({ message: `${fieldName} must be a number`, status: 400 });
+};
+
+const optionalBoolean = (value: unknown, fieldName: string): boolean | undefined => {
+ if (value === undefined) {
+ return undefined;
+ }
+ if (typeof value === "boolean") {
+ return value;
+ }
+ if (typeof value === "string") {
+ if (value === "true") {
+ return true;
+ }
+ if (value === "false") {
+ return false;
+ }
+ }
+ throw new AppError({ message: `${fieldName} must be a boolean`, status: 400 });
+};
+
+const parseMonitorTypeFilter = (value: unknown): MonitorType | MonitorType[] | undefined => {
+ const parseSingle = (input: unknown): MonitorType => {
+ if (typeof input !== "string") {
+ throw new AppError({ message: "Monitor type must be a string", status: 400 });
+ }
+ if (!MonitorTypes.includes(input as MonitorType)) {
+ throw new AppError({ message: `Invalid monitor type: ${input}`, status: 400 });
+ }
+ return input as MonitorType;
+ };
+
+ if (value === undefined) {
+ return undefined;
+ }
+ if (Array.isArray(value)) {
+ return value.map((entry) => parseSingle(entry));
+ }
+ return parseSingle(value);
+};
+
+const parseSortOrder = (value: unknown): "asc" | "desc" | undefined => {
+ if (value === undefined) {
+ return undefined;
+ }
+ if (value === "asc" || value === "desc") {
+ return value;
+ }
+ throw new AppError({ message: "order must be either 'asc' or 'desc'", status: 400 });
+};
+
+const requireTeamId = (teamId?: string): string => {
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+ return teamId;
+};
+
+export {
+ fetchMonitorCertificate,
+ requireString,
+ optionalString,
+ optionalNumber,
+ optionalBoolean,
+ parseMonitorTypeFilter,
+ parseSortOrder,
+ requireTeamId,
+};
diff --git a/server/src/controllers/diagnosticController.ts b/server/src/controllers/diagnosticController.ts
new file mode 100755
index 000000000..b4d59ceaf
--- /dev/null
+++ b/server/src/controllers/diagnosticController.ts
@@ -0,0 +1,31 @@
+import { Request, Response, NextFunction } from "express";
+
+const SERVICE_NAME = "diagnosticController";
+class DiagnosticController {
+ static SERVICE_NAME = SERVICE_NAME;
+
+ private diagnosticService: any;
+
+ constructor(diagnosticService: any) {
+ this.diagnosticService = diagnosticService;
+ }
+
+ get serviceName() {
+ return DiagnosticController.SERVICE_NAME;
+ }
+
+ getSystemStats = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const diagnostics = await this.diagnosticService.getSystemStats();
+ return res.status(200).json({
+ success: true,
+ msg: "OK",
+ data: diagnostics,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default DiagnosticController;
diff --git a/server/src/controllers/incidentController.ts b/server/src/controllers/incidentController.ts
new file mode 100644
index 000000000..8a56b5ef8
--- /dev/null
+++ b/server/src/controllers/incidentController.ts
@@ -0,0 +1,88 @@
+import { Request, Response, NextFunction } from "express";
+
+const SERVICE_NAME = "incidentController";
+
+class IncidentController {
+ static SERVICE_NAME = SERVICE_NAME;
+
+ private incidentService: any;
+ constructor(incidentService: any) {
+ this.incidentService = incidentService;
+ }
+
+ get serviceName() {
+ return IncidentController.SERVICE_NAME;
+ }
+
+ getIncidentsByTeam = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const result = await this.incidentService.getIncidentsByTeam({
+ teamId: req?.user?.teamId,
+ query: req?.query,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Incidents retrieved successfully",
+ data: result,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getIncidentSummary = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const summary = await this.incidentService.getIncidentSummary({
+ teamId: req?.user?.teamId,
+ query: req?.query,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Incident summary retrieved successfully",
+ data: summary,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getIncidentById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const incident = await this.incidentService.getIncidentById({
+ incidentId: req?.params?.incidentId,
+ teamId: req?.user?.teamId,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Incident retrieved successfully",
+ data: incident,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ resolveIncidentManually = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const resolvedIncident = await this.incidentService.resolveIncidentManually({
+ incidentId: req?.params?.incidentId,
+ userId: req?.user?._id,
+ teamId: req?.user?.teamId,
+ comment: req?.body?.comment,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Incident resolved successfully",
+ data: resolvedIncident,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default IncidentController;
diff --git a/server/src/controllers/inviteController.ts b/server/src/controllers/inviteController.ts
new file mode 100755
index 000000000..c3d63aa80
--- /dev/null
+++ b/server/src/controllers/inviteController.ts
@@ -0,0 +1,68 @@
+import { Request, Response, NextFunction } from "express";
+import { inviteBodyValidation, inviteVerificationBodyValidation } from "@/validation/joi.js";
+const SERVICE_NAME = "inviteController";
+
+class InviteController {
+ static SERVICE_NAME = SERVICE_NAME;
+ private inviteService: any;
+ constructor(inviteService: any) {
+ this.inviteService = inviteService;
+ }
+
+ get serviceName() {
+ return InviteController.SERVICE_NAME;
+ }
+
+ getInviteToken = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const invite = req.body;
+ const teamId = req?.user?.teamId;
+ invite.teamId = teamId;
+ await inviteBodyValidation.validateAsync(invite);
+ const inviteToken = await this.inviteService.getInviteToken({ invite, teamId });
+ return res.status(200).json({
+ success: true,
+ msg: "Invite token generated successfully",
+ data: inviteToken,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ sendInviteEmail = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const inviteRequest = req.body;
+ inviteRequest.teamId = req?.user?.teamId;
+ await inviteBodyValidation.validateAsync(inviteRequest);
+
+ const inviteToken = await this.inviteService.sendInviteEmail({
+ inviteRequest,
+ firstName: req?.user?.firstName,
+ });
+ return res.status(200).json({
+ success: true,
+ msg: "Invite issued successfully",
+ data: inviteToken,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ verifyInviteToken = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await inviteVerificationBodyValidation.validateAsync(req.body);
+ const invite = await this.inviteService.verifyInviteToken({ inviteToken: req?.body?.token });
+ return res.status(200).json({
+ success: true,
+ msg: "Invite verified successfully",
+ data: invite,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default InviteController;
diff --git a/server/src/controllers/logController.ts b/server/src/controllers/logController.ts
new file mode 100644
index 000000000..d99de1e9c
--- /dev/null
+++ b/server/src/controllers/logController.ts
@@ -0,0 +1,28 @@
+import { Request, Response, NextFunction } from "express";
+
+const SERVICE_NAME = "LogController";
+
+class LogController {
+ static SERVICE_NAME = SERVICE_NAME;
+ private logger: any;
+ constructor(logger: any) {
+ this.logger = logger;
+ }
+ get serviceName() {
+ return LogController.SERVICE_NAME;
+ }
+
+ getLogs = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const logs = await this.logger.getLogs();
+ res.status(200).json({
+ success: true,
+ msg: "Logs fetched successfully",
+ data: logs,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+export default LogController;
diff --git a/server/src/controllers/v1/maintenanceWindowController.js b/server/src/controllers/maintenanceWindowController.ts
similarity index 52%
rename from server/src/controllers/v1/maintenanceWindowController.js
rename to server/src/controllers/maintenanceWindowController.ts
index be373ace5..afeba9219 100644
--- a/server/src/controllers/v1/maintenanceWindowController.js
+++ b/server/src/controllers/maintenanceWindowController.ts
@@ -1,3 +1,5 @@
+import { Request, Response, NextFunction } from "express";
+import { AppError } from "@/utils/AppError.js";
import {
createMaintenanceWindowBodyValidation,
editMaintenanceWindowByIdParamValidation,
@@ -6,16 +8,14 @@ import {
getMaintenanceWindowsByMonitorIdParamValidation,
getMaintenanceWindowsByTeamIdQueryValidation,
deleteMaintenanceWindowByIdParamValidation,
-} from "../../validation/joi.js";
-import BaseController from "./baseController.js";
+} from "@/validation/joi.js";
const SERVICE_NAME = "maintenanceWindowController";
-class MaintenanceWindowController extends BaseController {
+class MaintenanceWindowController {
static SERVICE_NAME = SERVICE_NAME;
- constructor(commonDependencies, { settingsService, maintenanceWindowService }) {
- super(commonDependencies);
- this.settingsService = settingsService;
+ private maintenanceWindowService: any;
+ constructor(maintenanceWindowService: any) {
this.maintenanceWindowService = maintenanceWindowService;
}
@@ -23,124 +23,128 @@ class MaintenanceWindowController extends BaseController {
return MaintenanceWindowController.SERVICE_NAME;
}
- createMaintenanceWindows = this.asyncHandler(
- async (req, res) => {
+ createMaintenanceWindows = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await createMaintenanceWindowBodyValidation.validateAsync(req.body);
const teamId = req?.user?.teamId;
if (!teamId) {
- throw this.errorService.createBadRequestError("Team ID is required");
+ throw new AppError({ message: "Team ID is required", status: 400 });
}
await this.maintenanceWindowService.createMaintenanceWindow({ teamId, body: req.body });
- return res.success({
- msg: this.stringService.maintenanceWindowCreate,
+ return res.status(200).json({
+ success: true,
+ msg: "Maintenance window created successfully",
});
- },
- SERVICE_NAME,
- "createMaintenanceWindows"
- );
-
- getMaintenanceWindowById = this.asyncHandler(
- async (req, res) => {
+ } catch (error) {
+ next(error);
+ }
+ };
+ getMaintenanceWindowById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await getMaintenanceWindowByIdParamValidation.validateAsync(req.params);
const teamId = req.user.teamId;
if (!teamId) {
- throw this.errorService.createBadRequestError("Team ID is required");
+ throw new AppError({ message: "Team ID is required", status: 400 });
}
const maintenanceWindow = await this.maintenanceWindowService.getMaintenanceWindowById({ id: req.params.id, teamId });
- return res.success({
- msg: this.stringService.maintenanceWindowGetById,
+ return res.status(200).json({
+ success: true,
+ msg: "Maintenance window fetched successfully",
data: maintenanceWindow,
});
- },
- SERVICE_NAME,
- "getMaintenanceWindowById"
- );
+ } catch (error) {
+ next(error);
+ }
+ };
- getMaintenanceWindowsByTeamId = this.asyncHandler(
- async (req, res) => {
+ getMaintenanceWindowsByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await getMaintenanceWindowsByTeamIdQueryValidation.validateAsync(req.query);
const teamId = req?.user?.teamId;
if (!teamId) {
- throw this.errorService.createBadRequestError("Team ID is required");
+ throw new AppError({ message: "Team ID is required", status: 400 });
}
const maintenanceWindows = await this.maintenanceWindowService.getMaintenanceWindowsByTeamId({ teamId, query: req.query });
- return res.success({
- msg: this.stringService.maintenanceWindowGetByTeam,
+ return res.status(200).json({
+ success: true,
+ msg: "Maintenance windows fetched successfully",
data: maintenanceWindows,
});
- },
- SERVICE_NAME,
- "getMaintenanceWindowsByTeamId"
- );
+ } catch (error) {
+ next(error);
+ }
+ };
- getMaintenanceWindowsByMonitorId = this.asyncHandler(
- async (req, res) => {
+ getMaintenanceWindowsByMonitorId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await getMaintenanceWindowsByMonitorIdParamValidation.validateAsync(req.params);
const teamId = req?.user?.teamId;
if (!teamId) {
- throw this.errorService.createBadRequestError("Team ID is required");
+ throw new AppError({ message: "Team ID is required", status: 400 });
}
const maintenanceWindows = await this.maintenanceWindowService.getMaintenanceWindowsByMonitorId({ monitorId: req.params.monitorId, teamId });
- return res.success({
- msg: this.stringService.maintenanceWindowGetByUser,
+ return res.status(200).json({
+ success: true,
+ msg: "Maintenance windows fetched successfully",
data: maintenanceWindows,
});
- },
- SERVICE_NAME,
- "getMaintenanceWindowsByMonitorId"
- );
-
- deleteMaintenanceWindow = this.asyncHandler(
- async (req, res) => {
+ } catch (error) {
+ next(error);
+ }
+ };
+ deleteMaintenanceWindow = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await deleteMaintenanceWindowByIdParamValidation.validateAsync(req.params);
const teamId = req?.user?.teamId;
if (!teamId) {
- throw this.errorService.createBadRequestError("Team ID is required");
+ throw new AppError({ message: "Team ID is required", status: 400 });
}
await this.maintenanceWindowService.deleteMaintenanceWindow({ id: req.params.id, teamId });
- return res.success({
- msg: this.stringService.maintenanceWindowDelete,
+ return res.status(200).json({
+ success: true,
+ msg: "Maintenance window deleted successfully",
});
- },
- SERVICE_NAME,
- "deleteMaintenanceWindow"
- );
+ } catch (error) {
+ next(error);
+ }
+ };
- editMaintenanceWindow = this.asyncHandler(
- async (req, res) => {
+ editMaintenanceWindow = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await editMaintenanceWindowByIdParamValidation.validateAsync(req.params);
await editMaintenanceByIdWindowBodyValidation.validateAsync(req.body);
const teamId = req.user.teamId;
if (!teamId) {
- throw this.errorService.createBadRequestError("Team ID is required");
+ throw new AppError({ message: "Team ID is required", status: 400 });
}
const editedMaintenanceWindow = await this.maintenanceWindowService.editMaintenanceWindow({ id: req.params.id, body: req.body, teamId });
- return res.success({
- msg: this.stringService.maintenanceWindowEdit,
+ return res.status(200).json({
+ success: true,
+ msg: "Maintenance window edited successfully",
data: editedMaintenanceWindow,
});
- },
- SERVICE_NAME,
- "editMaintenanceWindow"
- );
+ } catch (error) {
+ next(error);
+ }
+ };
}
export default MaintenanceWindowController;
diff --git a/server/src/controllers/monitorController.ts b/server/src/controllers/monitorController.ts
new file mode 100644
index 000000000..90ab5e7a5
--- /dev/null
+++ b/server/src/controllers/monitorController.ts
@@ -0,0 +1,464 @@
+import { Request, Response, NextFunction } from "express";
+
+import {
+ getMonitorByIdParamValidation,
+ getMonitorByIdQueryValidation,
+ getMonitorsByTeamIdParamValidation,
+ getMonitorsByTeamIdQueryValidation,
+ getMonitorsWithChecksQueryValidation,
+ createMonitorBodyValidation,
+ editMonitorBodyValidation,
+ pauseMonitorParamValidation,
+ getCertificateParamValidation,
+ getHardwareDetailsByIdParamValidation,
+ getHardwareDetailsByIdQueryValidation,
+} from "@/validation/joi.js";
+import sslChecker from "ssl-checker";
+import {
+ fetchMonitorCertificate,
+ requireString,
+ optionalString,
+ optionalNumber,
+ optionalBoolean,
+ parseMonitorTypeFilter,
+ parseSortOrder,
+ requireTeamId,
+} from "./controllerUtils.js";
+import { AppError } from "@/utils/AppError.js";
+import { IMonitorService } from "@/service/index.js";
+
+const SERVICE_NAME = "monitorController";
+class MonitorController {
+ static SERVICE_NAME = SERVICE_NAME;
+
+ private monitorService: IMonitorService;
+
+ constructor(monitorService: IMonitorService) {
+ this.monitorService = monitorService;
+ }
+
+ get serviceName() {
+ return MonitorController.SERVICE_NAME;
+ }
+
+ async verifyTeamAccess(teamId: string, monitorId: string) {
+ const monitor = await this.monitorService.getMonitorById({ teamId, monitorId });
+ if (monitor.teamId !== teamId) {
+ throw new AppError({ message: "Access denied", status: 403 });
+ }
+ }
+
+ getMonitorCertificate = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getCertificateParamValidation.validateAsync(req.params);
+ const teamId = requireTeamId(req?.user?.teamId);
+ const monitorId = requireString(req.params?.monitorId, "Monitor ID");
+ const monitor = await this.monitorService.getMonitorById({ teamId, monitorId });
+ const certificate = await fetchMonitorCertificate(sslChecker, monitor);
+
+ return res.status(200).json({
+ success: true,
+ msg: "SSL certificate retrieved successfully",
+ data: {
+ certificateDate: new Date(certificate.validTo),
+ },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getUptimeDetailsById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+ const dateRange = requireString(req?.query?.dateRange, "dateRange");
+ const normalize = optionalBoolean(req?.query?.normalize, "normalize");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const data = await this.monitorService.getUptimeDetailsById({
+ teamId,
+ monitorId,
+ dateRange,
+ normalize,
+ });
+ return res.status(200).json({
+ success: true,
+ msg: "Uptime details retrieved successfully",
+ data: data,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getHardwareDetailsById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getHardwareDetailsByIdParamValidation.validateAsync(req.params);
+ await getHardwareDetailsByIdQueryValidation.validateAsync(req.query);
+
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+ const dateRange = requireString(req?.query?.dateRange, "dateRange");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const monitor = await this.monitorService.getHardwareDetailsById({
+ teamId,
+ monitorId,
+ dateRange,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Hardware details retrieved successfully",
+ data: monitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+ getPageSpeedDetailsById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getHardwareDetailsByIdParamValidation.validateAsync(req.params);
+ await getHardwareDetailsByIdQueryValidation.validateAsync(req.query);
+
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+ const dateRange = requireString(req?.query?.dateRange, "dateRange");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const monitor = await this.monitorService.getPageSpeedDetailsById({
+ teamId,
+ monitorId,
+ dateRange,
+ });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Page speed details retrieved successfully",
+ data: monitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getMonitorById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getMonitorByIdParamValidation.validateAsync(req.params);
+ await getMonitorByIdQueryValidation.validateAsync(req.query);
+
+ const teamId = requireTeamId(req?.user?.teamId);
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+
+ const monitor = await this.monitorService.getMonitorById({ teamId, monitorId });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Monitor retrieved successfully",
+ data: monitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ createMonitor = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await createMonitorBodyValidation.validateAsync(req.body);
+
+ const userId = requireString(req?.user?._id, "User ID");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const monitor = await this.monitorService.createMonitor(teamId, userId, req.body);
+
+ return res.status(200).json({
+ success: true,
+ msg: "Monitor created successfully",
+ data: monitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ createBulkMonitors = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ if (!req.file) {
+ throw new AppError({ message: "No file uploaded", status: 400 });
+ }
+
+ if (!req.file.mimetype.includes("csv")) {
+ throw new AppError({ message: "File is not a CSV", status: 400 });
+ }
+
+ if (req.file.size === 0) {
+ throw new AppError({ message: "File is empty", status: 400 });
+ }
+
+ const userId = requireString(req?.user?._id, "User ID");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const fileData = req?.file?.buffer?.toString("utf-8");
+ if (!fileData) {
+ throw new AppError({ message: "Cannot get file from buffer", status: 400 });
+ }
+
+ const monitors = await this.monitorService.createBulkMonitors(fileData, userId, teamId);
+
+ return res.status(200).json({
+ success: true,
+ msg: "Bulk monitors created successfully",
+ data: monitors,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ deleteMonitor = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getMonitorByIdParamValidation.validateAsync(req.params);
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const deletedMonitor = await this.monitorService.deleteMonitor({ teamId, monitorId });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Monitor deleted successfully",
+ data: deletedMonitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ deleteAllMonitors = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const deletedCount = await this.monitorService.deleteAllMonitors({ teamId });
+
+ return res.status(200).json({
+ success: true,
+ msg: `Deleted ${deletedCount} monitors`,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ editMonitor = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getMonitorByIdParamValidation.validateAsync(req.params);
+ await editMonitorBodyValidation.validateAsync(req.body);
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const editedMonitor = await this.monitorService.editMonitor({ teamId, monitorId, body: req.body });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Monitor edited successfully",
+ data: editedMonitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ pauseMonitor = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await pauseMonitorParamValidation.validateAsync(req.params);
+
+ const monitorId = requireString(req?.params?.monitorId, "Monitor ID");
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const monitor = await this.monitorService.pauseMonitor({ teamId, monitorId });
+
+ return res.status(200).json({
+ success: true,
+ msg: monitor.isActive ? "Monitor resumed successfully" : "Monitor paused successfully",
+ data: monitor,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ addDemoMonitors = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const _id = requireString(req?.user?._id, "User ID");
+ const teamId = requireTeamId(req?.user?.teamId);
+ const demoMonitors = await this.monitorService.addDemoMonitors({ userId: _id, teamId });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Demo monitors added successfully",
+ data: demoMonitors?.length ?? 0,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ sendTestEmail = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const { to } = req.body;
+ if (!to || typeof to !== "string") {
+ throw new AppError({ message: "Invalid 'to' email address", status: 400 });
+ }
+
+ const messageId = await this.monitorService.sendTestEmail({ to });
+ return res.status(200).json({
+ success: true,
+ msg: "Test email sent successfully",
+ data: { messageId },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getMonitorsByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
+ await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
+
+ const teamId = requireTeamId(req?.user?.teamId);
+ const type = parseMonitorTypeFilter(req.query?.type);
+ const filter = optionalString(req.query?.filter, "filter");
+
+ const monitors = await this.monitorService.getMonitorsByTeamId({ teamId, type, filter });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Monitors retrieved successfully",
+ data: monitors,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getMonitorsAndSummaryByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
+ await getMonitorsByTeamIdQueryValidation.validateAsync(req.query);
+
+ const explain = optionalBoolean(req?.query?.explain, "explain");
+ const type = parseMonitorTypeFilter(req?.query?.type);
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const result = await this.monitorService.getMonitorsAndSummaryByTeamId({ teamId, type, explain });
+
+ return res.status(200).json({
+ msg: "Monitors and summary retrieved successfully",
+ data: result,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getMonitorsWithChecksByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getMonitorsByTeamIdParamValidation.validateAsync(req.params);
+ await getMonitorsWithChecksQueryValidation.validateAsync(req.query);
+
+ const explain = optionalBoolean(req?.query?.explain, "explain");
+ const limit = optionalNumber(req?.query?.limit, "limit");
+ const page = optionalNumber(req?.query?.page, "page");
+ const rowsPerPage = optionalNumber(req?.query?.rowsPerPage, "rowsPerPage");
+ const filter = optionalString(req?.query?.filter, "filter");
+ const field = optionalString(req?.query?.field, "field");
+ const order = parseSortOrder(req?.query?.order);
+ const type = parseMonitorTypeFilter(req?.query?.type);
+ const teamId = requireTeamId(req?.user?.teamId);
+
+ const monitors = await this.monitorService.getMonitorsWithChecksByTeamId({
+ teamId,
+ limit,
+ type,
+ page,
+ rowsPerPage,
+ filter,
+ field,
+ order,
+ explain,
+ });
+
+ return res.status(200).json({
+ msg: "Monitors retrieved successfully",
+ data: monitors,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+ exportMonitorsToCSV = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const csv = await this.monitorService.exportMonitorsToCSV({ teamId });
+ res.setHeader("Content-Type", "text/csv");
+ res.setHeader("Content-Disposition", "attachment; filename=monitors.csv");
+ return res.send(csv);
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ exportMonitorsToJSON = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const json = await this.monitorService.exportMonitorsToJSON({ teamId });
+
+ return res.status(200).json({
+ success: true,
+ msg: "Monitors exported successfully",
+ data: json,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getAllGames = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const games = this.monitorService.getAllGames();
+ return res.status(200).json({
+ success: true,
+ msg: "Supported games retrieved successfully",
+ data: games,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getGroupsByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const groups = await this.monitorService.getGroupsByTeamId({ teamId });
+
+ return res.status(200).json({
+ msg: "Groups retrieved successfully",
+ data: groups,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default MonitorController;
diff --git a/server/src/controllers/notificationController.ts b/server/src/controllers/notificationController.ts
new file mode 100644
index 000000000..74849c6aa
--- /dev/null
+++ b/server/src/controllers/notificationController.ts
@@ -0,0 +1,197 @@
+import { Request, Response, NextFunction } from "express";
+
+import { createNotificationBodyValidation } from "@/validation/joi.js";
+import { AppError } from "@/utils/AppError.js";
+
+const SERVICE_NAME = "NotificationController";
+
+class NotificationController {
+ static SERVICE_NAME = SERVICE_NAME;
+ private db: any;
+ private notificationService: any;
+ constructor(notificationService: any, db: any) {
+ this.notificationService = notificationService;
+ this.db = db;
+ }
+
+ get serviceName() {
+ return NotificationController.SERVICE_NAME;
+ }
+
+ testNotification = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const notification = req.body;
+
+ const success = await this.notificationService.sendTestNotification(notification);
+
+ if (!success) {
+ throw new AppError({ message: "Sending notification failed", status: 500 });
+ }
+
+ return res.status(200).json({
+ success: true,
+ msg: "Notification sent successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ createNotification = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await createNotificationBodyValidation.validateAsync(req.body, {
+ abortEarly: false,
+ });
+
+ const body = req.body;
+
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const userId = req?.user?._id;
+ if (!userId) {
+ throw new AppError({ message: "User ID is required", status: 400 });
+ }
+ body.userId = userId;
+ body.teamId = teamId;
+
+ const notification = await this.db.notificationModule.createNotification(body);
+ return res.status(200).json({
+ success: true,
+ msg: "Notification created successfully",
+ data: notification,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getNotificationsByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const notifications = await this.db.notificationModule.getNotificationsByTeamId(teamId);
+
+ return res.status(200).json({
+ success: true,
+ msg: "Notifications fetched successfully",
+ data: notifications,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ deleteNotification = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const notification = await this.db.notificationModule.getNotificationById(req.params.id);
+ if (!notification.teamId.equals(teamId)) {
+ throw new AppError({ message: "Unauthorized", status: 403 });
+ }
+
+ await this.db.notificationModule.deleteNotificationById(req.params.id);
+ return res.status(200).json({
+ success: true,
+ msg: "Notification deleted successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getNotificationById = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const notification = await this.db.notificationModule.getNotificationById(req.params.id);
+
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ if (!notification.teamId.equals(teamId)) {
+ throw new AppError({ message: "Unauthorized", status: 403 });
+ }
+ return res.status(200).json({
+ success: true,
+ msg: "Notification fetched successfully",
+ data: notification,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ editNotification = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await createNotificationBodyValidation.validateAsync(req.body, {
+ abortEarly: false,
+ });
+
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const notification = await this.db.notificationModule.getNotificationById(req.params.id);
+
+ if (!notification.teamId.equals(teamId)) {
+ throw new AppError({ message: "Unauthorized", status: 403 });
+ }
+
+ const editedNotification = await this.db.notificationModule.editNotification(req.params.id, req.body);
+ return res.status(200).json({
+ success: true,
+ msg: "Notification updated successfully",
+ data: editedNotification,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ testAllNotifications = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const monitorId = req.body.monitorId;
+ const teamId = req?.user?.teamId;
+ if (!teamId) {
+ throw new AppError({ message: "Team ID is required", status: 400 });
+ }
+
+ const monitor = await this.db.monitorModule.getMonitorById(monitorId);
+
+ if (!monitor.teamId.equals(teamId)) {
+ throw new AppError({ message: "Unauthorized", status: 403 });
+ }
+
+ const notifications = monitor.notifications;
+ if (notifications.length === 0) {
+ throw new AppError({ message: "No notifications", status: 400 });
+ }
+
+ const result = await this.notificationService.testAllNotifications(notifications);
+
+ if (!result) {
+ throw new AppError({ message: "Failed to send all notifications", status: 500 });
+ }
+
+ return res.status(200).json({
+ success: true,
+ msg: "All notifications sent successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default NotificationController;
diff --git a/server/src/controllers/queueController.ts b/server/src/controllers/queueController.ts
new file mode 100755
index 000000000..9885bab87
--- /dev/null
+++ b/server/src/controllers/queueController.ts
@@ -0,0 +1,94 @@
+import { Request, Response, NextFunction } from "express";
+
+const SERVICE_NAME = "JobQueueController";
+
+class JobQueueController {
+ static SERVICE_NAME = SERVICE_NAME;
+ private jobQueue: any;
+ constructor(jobQueue: any) {
+ this.jobQueue = jobQueue;
+ }
+
+ get serviceName() {
+ return JobQueueController.SERVICE_NAME;
+ }
+
+ getMetrics = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const metrics = await this.jobQueue.getMetrics();
+ res.status(200).json({
+ success: true,
+ msg: "Queue metrics fetched successfully",
+ data: metrics,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getJobs = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const jobs = await this.jobQueue.getJobs();
+ return res.status(200).json({
+ success: true,
+ msg: "Queue jobs fetched successfully",
+ data: jobs,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getAllMetrics = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const jobs = await this.jobQueue.getJobs();
+ const metrics = await this.jobQueue.getMetrics();
+ return res.status(200).json({
+ success: true,
+ msg: "Queue metrics fetched successfully",
+ data: { jobs, metrics },
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ addJob = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await this.jobQueue.addJob(Math.random().toString(36).substring(7));
+ return res.status(200).json({
+ success: true,
+ msg: "Job added to queue successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ flushQueue = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const result = await this.jobQueue.flushQueues();
+ return res.status(200).json({
+ success: true,
+ msg: "Queue flushed successfully",
+ data: result,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ checkQueueHealth = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const stuckQueues = await this.jobQueue.checkQueueHealth();
+ return res.status(200).json({
+ success: true,
+ msg: "Queue health checked successfully",
+ data: stuckQueues,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+export default JobQueueController;
diff --git a/server/src/controllers/v1/settingsController.js b/server/src/controllers/settingsController.ts
similarity index 57%
rename from server/src/controllers/v1/settingsController.js
rename to server/src/controllers/settingsController.ts
index 3db73a05a..5d3f6ed0e 100644
--- a/server/src/controllers/v1/settingsController.js
+++ b/server/src/controllers/settingsController.ts
@@ -1,28 +1,32 @@
-import { updateAppSettingsBodyValidation } from "../../validation/joi.js";
-import { sendTestEmailBodyValidation } from "../../validation/joi.js";
-import BaseController from "./baseController.js";
+import { Request, Response, NextFunction } from "express";
+import { sendTestEmailBodyValidation, updateAppSettingsBodyValidation } from "@/validation/joi.js";
+import { AppError } from "@/utils/AppError.js";
const SERVICE_NAME = "SettingsController";
-class SettingsController extends BaseController {
+class SettingsController {
static SERVICE_NAME = SERVICE_NAME;
- constructor(commonDependencies, { settingsService, emailService }) {
- super(commonDependencies);
+ private settingsService: any;
+ private emailService: any;
+ private db: any;
+ constructor(settingsService: any, emailService: any, db: any) {
this.settingsService = settingsService;
this.emailService = emailService;
+ this.db = db;
}
get serviceName() {
return SettingsController.SERVICE_NAME;
}
- buildAppSettings = (dbSettings) => {
+ buildAppSettings = (dbSettings: any) => {
const sanitizedSettings = { ...dbSettings };
delete sanitizedSettings.version;
const returnSettings = {
pagespeedKeySet: false,
emailPasswordSet: false,
+ settings: null,
};
if (typeof sanitizedSettings.pagespeedApiKey !== "undefined") {
@@ -37,37 +41,35 @@ class SettingsController extends BaseController {
return returnSettings;
};
- getAppSettings = this.asyncHandler(
- async (req, res) => {
+ getAppSettings = async (req: Request, res: Response, next: NextFunction) => {
+ try {
const dbSettings = await this.settingsService.getDBSettings();
const returnSettings = this.buildAppSettings(dbSettings);
- return res.success({
- msg: this.stringService.getAppSettings,
+ return res.status(200).json({
+ success: true,
+ msg: "App settings fetched successfully",
data: returnSettings,
});
- },
- SERVICE_NAME,
- "getAppSettings"
- );
+ } catch (error) {
+ next(error);
+ }
+ };
- updateAppSettings = this.asyncHandler(
- async (req, res) => {
- await updateAppSettingsBodyValidation.validateAsync(req.body);
+ updateAppSettings = async (req: Request, res: Response, next: NextFunction) => {
+ await updateAppSettingsBodyValidation.validateAsync(req.body);
- const updatedSettings = await this.db.settingsModule.updateAppSettings(req.body);
- const returnSettings = this.buildAppSettings(updatedSettings);
- return res.success({
- msg: this.stringService.updateAppSettings,
- data: returnSettings,
- });
- },
- SERVICE_NAME,
- "updateAppSettings"
- );
+ const updatedSettings = await this.db.settingsModule.updateAppSettings(req.body);
+ const returnSettings = this.buildAppSettings(updatedSettings);
+ return res.status(200).json({
+ success: true,
+ msg: "App settings updated successfully",
+ data: returnSettings,
+ });
+ };
- sendTestEmail = this.asyncHandler(
- async (req, res) => {
+ sendTestEmail = async (req: Request, res: Response, next: NextFunction) => {
+ try {
await sendTestEmailBodyValidation.validateAsync(req.body);
const {
@@ -86,7 +88,7 @@ class SettingsController extends BaseController {
systemEmailTLSServername,
} = req.body;
- const subject = this.stringService.testEmailSubject;
+ const subject = "This is a test email from Checkmate";
const context = { testName: "Monitoring System" };
const html = await this.emailService.buildEmail("testEmailTemplate", context);
@@ -106,17 +108,18 @@ class SettingsController extends BaseController {
});
if (!messageId) {
- throw this.errorService.createServerError("Failed to send test email.");
+ throw new AppError({ message: "Failed to send test email.", status: 500 });
}
- return res.success({
- msg: this.stringService.sendTestEmail,
+ return res.status(200).json({
+ success: true,
+ msg: "Test email sent successfully",
data: { messageId },
});
- },
- SERVICE_NAME,
- "sendTestEmail"
- );
+ } catch (error) {
+ next(error);
+ }
+ };
}
export default SettingsController;
diff --git a/server/src/controllers/statusPageController.ts b/server/src/controllers/statusPageController.ts
new file mode 100644
index 000000000..105beb230
--- /dev/null
+++ b/server/src/controllers/statusPageController.ts
@@ -0,0 +1,115 @@
+import { Request, Response, NextFunction } from "express";
+
+import { createStatusPageBodyValidation, getStatusPageParamValidation, getStatusPageQueryValidation, imageValidation } from "@/validation/joi.js";
+import { AppError } from "@/utils/AppError.js";
+
+const SERVICE_NAME = "statusPageController";
+
+class StatusPageController {
+ static SERVICE_NAME = SERVICE_NAME;
+ private db: any;
+ constructor(db: any) {
+ this.db = db;
+ }
+
+ get serviceName() {
+ return StatusPageController.SERVICE_NAME;
+ }
+
+ createStatusPage = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await createStatusPageBodyValidation.validateAsync(req.body);
+ await imageValidation.validateAsync(req.file);
+
+ const { _id, teamId } = req.user;
+ const statusPage = await this.db.statusPageModule.createStatusPage({
+ statusPageData: req.body,
+ image: req.file,
+ userId: _id,
+ teamId,
+ });
+ return res.status(200).json({
+ success: true,
+ msg: "Status page created successfully",
+ data: statusPage,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ updateStatusPage = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await createStatusPageBodyValidation.validateAsync(req.body);
+ await imageValidation.validateAsync(req.file);
+
+ const statusPage = await this.db.statusPageModule.updateStatusPage(req.body, req.file);
+ if (statusPage === null) {
+ throw new AppError({ message: "Status page not found", status: 404 });
+ }
+ return res.status(200).json({
+ success: true,
+ msg: "Status page updated successfully",
+ data: statusPage,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getStatusPage = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const statusPage = await this.db.statusPageModule.getStatusPage();
+ return res.status(200).json({
+ success: true,
+ msg: "Status page retrieved successfully",
+ data: statusPage,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+
+ getStatusPageByUrl = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await getStatusPageParamValidation.validateAsync(req.params);
+ await getStatusPageQueryValidation.validateAsync(req.query);
+
+ const statusPage = await this.db.statusPageModule.getStatusPageByUrl(req.params.url);
+ return res.status(200).json({
+ success: true,
+ msg: "Status page retrieved successfully",
+ data: statusPage,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+ getStatusPagesByTeamId = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ const teamId = req.user.teamId;
+ const statusPages = await this.db.statusPageModule.getStatusPagesByTeamId(teamId);
+
+ return res.status(200).json({
+ success: true,
+ msg: "Status pages retrieved successfully",
+ data: statusPages,
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+ deleteStatusPage = async (req: Request, res: Response, next: NextFunction) => {
+ try {
+ await this.db.statusPageModule.deleteStatusPage(req.params.url);
+ return res.status(200).json({
+ success: true,
+ msg: "Status page deleted successfully",
+ });
+ } catch (error) {
+ next(error);
+ }
+ };
+}
+
+export default StatusPageController;
diff --git a/server/src/controllers/v1/announcementsController.js b/server/src/controllers/v1/announcementsController.js
deleted file mode 100755
index 0425b44aa..000000000
--- a/server/src/controllers/v1/announcementsController.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import { createAnnouncementValidation } from "../../validation/joi.js";
-import BaseController from "./baseController.js";
-
-const SERVICE_NAME = "announcementController";
-
-/**
- * Controller for managing announcements in the system.
- * This class handles the creation of new announcements.
- *
- * @class AnnouncementController
- */
-
-class AnnouncementController extends BaseController {
- static SERVICE_NAME = SERVICE_NAME;
- constructor(commonDependencies) {
- super(commonDependencies);
- this.createAnnouncement = this.createAnnouncement.bind(this);
- this.getAnnouncement = this.getAnnouncement.bind(this);
- }
-
- get serviceName() {
- return AnnouncementController.SERVICE_NAME;
- }
-
- /**
- * Handles the creation of a new announcement.
- *
- * @async
- * @param {Object} req - The request object, containing the announcement data in the body.
- * @param {Object} res - The response object used to send the result back to the client.
- * @param {Function} next - The next middleware function in the stack for error handling.
- *
- * @returns {Promise} A promise that resolves once the response is sent.
- */
- createAnnouncement = asyncHandler(
- async (req, res, next) => {
- await createAnnouncementValidation.validateAsync(req.body);
- const { title, message } = req.body;
- const announcementData = {
- title: title.trim(),
- message: message.trim(),
- userId: req.user._id,
- };
-
- const newAnnouncement = await this.db.createAnnouncement(announcementData);
- return res.success({
- msg: this.stringService.createAnnouncement,
- data: newAnnouncement,
- });
- },
- SERVICE_NAME,
- "createAnnouncement"
- );
-
- /**
- * Handles retrieving announcements with pagination.
- *
- * @async
- * @param {Object} res - The response object used to send the result back to the client.
- * - `data`: The list of announcements to be sent back to the client.
- * - `msg`: A message about the success of the request.
- * @param {Function} next - The next middleware function in the stack for error handling.
- */
- getAnnouncement = asyncHandler(
- async (req, res, next) => {
- const allAnnouncements = await this.db.getAnnouncements();
- return res.success({
- msg: this.stringService.getAnnouncement,
- data: allAnnouncements,
- });
- },
- SERVICE_NAME,
- "getAnnouncement"
- );
-}
-
-export default AnnouncementController;
diff --git a/server/src/controllers/v1/authController.js b/server/src/controllers/v1/authController.js
deleted file mode 100755
index e52de3849..000000000
--- a/server/src/controllers/v1/authController.js
+++ /dev/null
@@ -1,478 +0,0 @@
-import BaseController from "./baseController.js";
-import {
- registrationBodyValidation,
- loginValidation,
- editUserBodyValidation,
- recoveryValidation,
- recoveryTokenBodyValidation,
- newPasswordValidation,
- getUserByIdParamValidation,
- editUserByIdParamValidation,
- editUserByIdBodyValidation,
- editSuperadminUserByIdBodyValidation,
- editUserPasswordByIdBodyValidation,
-} from "../../validation/joi.js";
-
-const SERVICE_NAME = "authController";
-/**
- * Authentication Controller
- *
- * Handles all authentication-related HTTP requests including user registration,
- * login, password recovery, and user management operations.
- *
- * @class AuthController
- * @description Manages user authentication and authorization operations
- */
-class AuthController extends BaseController {
- static SERVICE_NAME = SERVICE_NAME;
- /**
- * Creates an instance of AuthController.
- *
- * @param {Object} commonDependencies - Common dependencies injected into the controller
- * @param {Object} dependencies - The dependencies required by the controller
- * @param {Object} dependencies.settingsService - Service for application settings
- * @param {Object} dependencies.emailService - Service for email operations
- * @param {Object} dependencies.jobQueue - Service for job queue operations
- * @param {Object} dependencies.userService - User business logic service
- */
- constructor(commonDependencies, { settingsService, emailService, jobQueue, userService }) {
- super(commonDependencies);
- this.settingsService = settingsService;
- this.emailService = emailService;
- this.jobQueue = jobQueue;
- this.userService = userService;
- }
-
- get serviceName() {
- return AuthController.SERVICE_NAME;
- }
-
- /**
- * Registers a new user in the system.
- *
- * @async
- * @function registerUser
- * @param {Object} req - Express request object
- * @param {Object} req.body - Request body containing user registration data
- * @param {string} req.body.firstName - User's first name
- * @param {string} req.body.lastName - User's last name
- * @param {string} req.body.email - User's email address (will be converted to lowercase)
- * @param {string} req.body.password - User's password
- * @param {string} [req.body.inviteToken] - Invite token for registration (required if superadmin exists)
- * @param {string} [req.body.teamId] - Team ID (auto-assigned if superadmin)
- * @param {Array} [req.body.role] - User roles (auto-assigned if superadmin)
- * @param {Object} [req.file] - Profile image file uploaded via multer
- * @param {Object} res - Express response object
- * @returns {Promise