From ce9cff4fb688e6dfe2c12992d2eba4334d4e4c28 Mon Sep 17 00:00:00 2001 From: Vitalij Ryndin Date: Tue, 6 Jan 2026 17:00:13 +0300 Subject: [PATCH 1/5] feat(dashboard): split chunks --- bun.lock | 45 +++++++++++-------- frontend/dashboard/package.json | 1 + frontend/dashboard/vite.config.ts | 75 ++++++++++++++++++++++++++++++- package.json | 2 +- 4 files changed, 102 insertions(+), 21 deletions(-) diff --git a/bun.lock b/bun.lock index 26b9823ad..5e0eda10c 100644 --- a/bun.lock +++ b/bun.lock @@ -92,6 +92,7 @@ "tinycolor2": "1.6.0", "vaul-vue": "0.4.1", "vee-validate": "4.15.1", + "vite-bundle-analyzer": "1.3.2", "vue": "catalog:", "vue-draggable-plus": "0.5.6", "vue-i18n": "11.2.2", @@ -358,7 +359,7 @@ "graphql": "16.12.0", "graphql-ws": "6.0.6", "typescript": "5.9.3", - "vite": "8.0.0-beta.0", + "vite": "8.0.0-beta.5", "vue": "3.5.25", "vue-router": "4.3.0", "vue-tsc": "3.1.8", @@ -966,7 +967,7 @@ "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.99.0", "", { "os": "win32", "cpu": "x64" }, "sha512-sJN1Q8h7ggFOyDn0zsHaXbP/MklAVUvhrbq0LA46Qum686P3SZQHjbATqJn9yaVEvaSKXCshgl0vQ1gWkGgpcQ=="], - "@oxc-project/runtime": ["@oxc-project/runtime@0.101.0", "", {}, "sha512-t3qpfVZIqSiLQ5Kqt/MC4Ge/WCOGrrcagAdzTcDaggupjiGxUx4nJF2v6wUCXWSzWHn5Ns7XLv13fCJEwCOERQ=="], + "@oxc-project/runtime": ["@oxc-project/runtime@0.103.0", "", {}, "sha512-sQKZo5lLS1/yzbsVlZ+zaQorOkLe3OkQjyyMN29tMvCax5e5Sa9uUYKChDDMR4D41n6ApEazMN2UcIwFdHgS7g=="], "@oxc-project/types": ["@oxc-project/types@0.99.0", "", {}, "sha512-LLDEhXB7g1m5J+woRSgfKsFPS3LhR9xRhTeIoEBm5WrkwMxn6eZ0Ld0c0K5eHB57ChZX6I3uSmmLjZ8pcjlRcw=="], @@ -1232,33 +1233,33 @@ "@resvg/resvg-wasm": ["@resvg/resvg-wasm@2.6.2", "", {}, "sha512-FqALmHI8D4o6lk/LRWDnhw95z5eO+eAa6ORjVg09YRR7BkcM6oPHU9uyC0gtQG5vpFLvgpeU4+zEAz2H8APHNw=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-beta.53", "", { "os": "android", "cpu": "arm64" }, "sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-beta.57", "", { "os": "android", "cpu": "arm64" }, "sha512-GoOVDy8bjw9z1K30Oo803nSzXJS/vWhFijFsW3kzvZCO8IZwFnNa6pGctmbbJstKl3Fv6UBwyjJQN6msejW0IQ=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-beta.53", "", { "os": "darwin", "cpu": "arm64" }, "sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-beta.57", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9c4FOhRGpl+PX7zBK5p17c5efpF9aSpTPgyigv57hXf5NjQUaJOOiejPLAtFiKNBIfm5Uu6yFkvLKzOafNvlTw=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-beta.53", "", { "os": "darwin", "cpu": "x64" }, "sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-beta.57", "", { "os": "darwin", "cpu": "x64" }, "sha512-6RsB8Qy4LnGqNGJJC/8uWeLWGOvbRL/KG5aJ8XXpSEupg/KQtlBEiFaYU/Ma5Usj1s+bt3ItkqZYAI50kSplBA=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-beta.53", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-beta.57", "", { "os": "freebsd", "cpu": "x64" }, "sha512-uA9kG7+MYkHTbqwv67Tx+5GV5YcKd33HCJIi0311iYBd25yuwyIqvJfBdt1VVB8tdOlyTb9cPAgfCki8nhwTQg=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53", "", { "os": "linux", "cpu": "arm" }, "sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.57", "", { "os": "linux", "cpu": "arm" }, "sha512-3KkS0cHsllT2T+Te+VZMKHNw6FPQihYsQh+8J4jkzwgvAQpbsbXmrqhkw3YU/QGRrD8qgcOvBr6z5y6Jid+rmw=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53", "", { "os": "linux", "cpu": "arm64" }, "sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-beta.57", "", { "os": "linux", "cpu": "arm64" }, "sha512-A3/wu1RgsHhqP3rVH2+sM81bpk+Qd2XaHTl8LtX5/1LNR7QVBFBCpAoiXwjTdGnI5cMdBVi7Z1pi52euW760Fw=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-beta.53", "", { "os": "linux", "cpu": "arm64" }, "sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-beta.57", "", { "os": "linux", "cpu": "arm64" }, "sha512-d0kIVezTQtazpyWjiJIn5to8JlwfKITDqwsFv0Xc6s31N16CD2PC/Pl2OtKgS7n8WLOJbfqgIp5ixYzTAxCqMg=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-beta.53", "", { "os": "linux", "cpu": "x64" }, "sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-beta.57", "", { "os": "linux", "cpu": "x64" }, "sha512-E199LPijo98yrLjPCmETx8EF43sZf9t3guSrLee/ej1rCCc3zDVTR4xFfN9BRAapGVl7/8hYqbbiQPTkv73kUg=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-beta.53", "", { "os": "linux", "cpu": "x64" }, "sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-beta.57", "", { "os": "linux", "cpu": "x64" }, "sha512-++EQDpk/UJ33kY/BNsh7A7/P1sr/jbMuQ8cE554ZIy+tCUWCivo9zfyjDUoiMdnxqX6HLJEqqGnbGQOvzm2OMQ=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-beta.53", "", { "os": "none", "cpu": "arm64" }, "sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-beta.57", "", { "os": "none", "cpu": "arm64" }, "sha512-voDEBcNqxbUv/GeXKFtxXVWA+H45P/8Dec4Ii/SbyJyGvCqV1j+nNHfnFUIiRQ2Q40DwPe/djvgYBs9PpETiMA=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-beta.53", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.0" }, "cpu": "none" }, "sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-beta.57", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.0" }, "cpu": "none" }, "sha512-bRhcF7NLlCnpkzLVlVhrDEd0KH22VbTPkPTbMjlYvqhSmarxNIq5vtlQS8qmV7LkPKHrNLWyJW/V/sOyFba26Q=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53", "", { "os": "win32", "cpu": "arm64" }, "sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-beta.57", "", { "os": "win32", "cpu": "arm64" }, "sha512-rnDVGRks2FQ2hgJ2g15pHtfxqkGFGjJQUDWzYznEkE8Ra2+Vag9OffxdbJMZqBWXHVM0iS4dv8qSiEn7bO+n1Q=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-beta.53", "", { "os": "win32", "cpu": "x64" }, "sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-beta.57", "", { "os": "win32", "cpu": "x64" }, "sha512-OqIUyNid1M4xTj6VRXp/Lht/qIP8fo25QyAZlCP+p6D2ATCEhyW4ZIFLnC9zAGN/HMbXoCzvwfa8Jjg/8J4YEg=="], - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="], + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.57", "", {}, "sha512-aQNelgx14tGA+n2tNSa9x6/jeoCL9fkDeCei7nOKnHx0fEFRRMu5ReiITo+zZD5TzWDGGRjbSYCs93IfRIyTuQ=="], "@rollup/plugin-alias": ["@rollup/plugin-alias@5.1.1", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ=="], @@ -3044,7 +3045,7 @@ "rimraf": ["rimraf@5.0.5", "", { "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A=="], - "rolldown": ["rolldown@1.0.0-beta.53", "", { "dependencies": { "@oxc-project/types": "=0.101.0", "@rolldown/pluginutils": "1.0.0-beta.53" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-beta.53", "@rolldown/binding-darwin-arm64": "1.0.0-beta.53", "@rolldown/binding-darwin-x64": "1.0.0-beta.53", "@rolldown/binding-freebsd-x64": "1.0.0-beta.53", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.53", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.53", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.53", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.53", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.53", "@rolldown/binding-openharmony-arm64": "1.0.0-beta.53", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.53", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.53", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.53" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw=="], + "rolldown": ["rolldown@1.0.0-beta.57", "", { "dependencies": { "@oxc-project/types": "=0.103.0", "@rolldown/pluginutils": "1.0.0-beta.57" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-beta.57", "@rolldown/binding-darwin-arm64": "1.0.0-beta.57", "@rolldown/binding-darwin-x64": "1.0.0-beta.57", "@rolldown/binding-freebsd-x64": "1.0.0-beta.57", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.57", "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.57", "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.57", "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.57", "@rolldown/binding-linux-x64-musl": "1.0.0-beta.57", "@rolldown/binding-openharmony-arm64": "1.0.0-beta.57", "@rolldown/binding-wasm32-wasi": "1.0.0-beta.57", "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.57", "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.57" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-lMMxcNN71GMsSko8RyeTaFoATHkCh4IWU7pYF73ziMYjhHZWfVesC6GQ+iaJCvZmVjvgSks9Ks1aaqEkBd8udg=="], "rollup": ["rollup@4.53.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.53.3", "@rollup/rollup-android-arm64": "4.53.3", "@rollup/rollup-darwin-arm64": "4.53.3", "@rollup/rollup-darwin-x64": "4.53.3", "@rollup/rollup-freebsd-arm64": "4.53.3", "@rollup/rollup-freebsd-x64": "4.53.3", "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", "@rollup/rollup-linux-arm-musleabihf": "4.53.3", "@rollup/rollup-linux-arm64-gnu": "4.53.3", "@rollup/rollup-linux-arm64-musl": "4.53.3", "@rollup/rollup-linux-loong64-gnu": "4.53.3", "@rollup/rollup-linux-ppc64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-musl": "4.53.3", "@rollup/rollup-linux-s390x-gnu": "4.53.3", "@rollup/rollup-linux-x64-gnu": "4.53.3", "@rollup/rollup-linux-x64-musl": "4.53.3", "@rollup/rollup-openharmony-arm64": "4.53.3", "@rollup/rollup-win32-arm64-msvc": "4.53.3", "@rollup/rollup-win32-ia32-msvc": "4.53.3", "@rollup/rollup-win32-x64-gnu": "4.53.3", "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA=="], @@ -3394,7 +3395,9 @@ "vee-validate": ["vee-validate@4.15.1", "", { "dependencies": { "@vue/devtools-api": "^7.5.2", "type-fest": "^4.8.3" }, "peerDependencies": { "vue": "^3.4.26" } }, "sha512-DkFsiTwEKau8VIxyZBGdO6tOudD+QoUBPuHj3e6QFqmbfCRj1ArmYWue9lEp6jLSWBIw4XPlDLjFIZNLdRAMSg=="], - "vite": ["vite@8.0.0-beta.0", "", { "dependencies": { "@oxc-project/runtime": "0.101.0", "fdir": "^6.5.0", "lightningcss": "^1.30.2", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rolldown": "1.0.0-beta.53", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "esbuild": "^0.25.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-bXHWmtg5hUxn/MB5zJ8qhBLphnsNmO1EYOFmBO/fVCBJekTdWDuqJ/GmUMLgrC0QUCCrxhw3JLgteWdiyqaVSQ=="], + "vite": ["vite@8.0.0-beta.5", "", { "dependencies": { "@oxc-project/runtime": "0.103.0", "fdir": "^6.5.0", "lightningcss": "^1.30.2", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rolldown": "1.0.0-beta.57", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "esbuild": "^0.25.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-wgvJ+rdGKggZ1m0KnSYF4mEdEEaAAUWKiHe9IDl8oagjUkyrD2CdgSoxiJdpLNNzCKIZdHsAi2xMRRwrCEd4AQ=="], + + "vite-bundle-analyzer": ["vite-bundle-analyzer@1.3.2", "", { "bin": { "analyze": "dist/bin.js" } }, "sha512-Od4ILUKRvBV3LuO/E+S+c1XULlxdkRZPSf6Vzzu+UAXG0D3hZYUu9imZIkSj/PU4e1FB14yB+av8g3KiljH8zQ=="], "vite-bundle-visualizer": ["vite-bundle-visualizer@1.1.0", "", { "dependencies": { "cac": "^6.7.14", "import-from-esm": "^1.3.3", "rollup-plugin-visualizer": "^5.11.0", "tmp": "^0.2.1" }, "bin": { "vite-bundle-visualizer": "bin.js" } }, "sha512-cmi5OuS7Eta5keTJmCTEbBBA7gOsUQ4K44W5dbsP+n/X0GIilIIFbJeXF120MQpTxdiZ/GIx4A9zkPEcKpPAog=="], @@ -3790,6 +3793,8 @@ "@vitejs/plugin-vue/vite": ["vite@7.2.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ=="], + "@vitejs/plugin-vue-jsx/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="], + "@vitejs/plugin-vue-jsx/vite": ["vite@7.2.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ=="], "@volar/language-server/@volar/typescript": ["@volar/typescript@2.4.23", "", { "dependencies": { "@volar/language-core": "2.4.23", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag=="], @@ -3986,7 +3991,7 @@ "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], - "rolldown/@oxc-project/types": ["@oxc-project/types@0.101.0", "", {}, "sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ=="], + "rolldown/@oxc-project/types": ["@oxc-project/types@0.103.0", "", {}, "sha512-bkiYX5kaXWwUessFRSoXFkGIQTmc6dLGdxuRTrC+h8PSnIdZyuXHHlLAeTmOue5Br/a0/a7dHH0Gca6eXn9MKg=="], "shadcn-nuxt/@nuxt/kit": ["@nuxt/kit@3.20.2", "", { "dependencies": { "c12": "^3.3.2", "consola": "^3.4.2", "defu": "^6.1.4", "destr": "^2.0.5", "errx": "^0.1.0", "exsolve": "^1.0.8", "ignore": "^7.0.5", "jiti": "^2.6.1", "klona": "^2.0.6", "knitwork": "^1.3.0", "mlly": "^1.8.0", "ohash": "^2.0.11", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "rc9": "^2.1.2", "scule": "^1.3.0", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ufo": "^1.6.1", "unctx": "^2.4.1", "untyped": "^2.0.0" } }, "sha512-laqfmMcWWNV1FsVmm1+RQUoGY8NIJvCRl0z0K8ikqPukoEry0LXMqlQ+xaf8xJRvoH2/78OhZmsEEsUBTXipcw=="], @@ -4202,6 +4207,8 @@ "@nuxt/fonts/@nuxt/devtools-kit/vite": ["vite@7.2.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ=="], + "@nuxt/vite-builder/@vitejs/plugin-vue/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="], + "@nuxt/vite-builder/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA=="], "@nuxt/vite-builder/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.1", "", { "os": "android", "cpu": "arm" }, "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg=="], diff --git a/frontend/dashboard/package.json b/frontend/dashboard/package.json index f26c7f5c3..a888e80a4 100644 --- a/frontend/dashboard/package.json +++ b/frontend/dashboard/package.json @@ -65,6 +65,7 @@ "tinycolor2": "1.6.0", "vaul-vue": "0.4.1", "vee-validate": "4.15.1", + "vite-bundle-analyzer": "1.3.2", "vue": "catalog:", "vue-draggable-plus": "0.5.6", "vue-i18n": "11.2.2", diff --git a/frontend/dashboard/vite.config.ts b/frontend/dashboard/vite.config.ts index ec2370c35..ee7110e87 100644 --- a/frontend/dashboard/vite.config.ts +++ b/frontend/dashboard/vite.config.ts @@ -1,6 +1,7 @@ import path from 'node:path' import process from 'node:process' import { fileURLToPath } from 'node:url' +// import { analyzer, unstableRolldownAdapter } from 'vite-bundle-analyzer' import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import { webUpdateNotice } from '@plugin-web-update-notification/vite' @@ -15,7 +16,6 @@ export default defineConfig(({ mode }) => { const env = loadEnv(mode, path.resolve(process.cwd(), '..', '..'), '') const plugins: PluginOption[] = [ - // @ts-ignore vue(), svgSprite(['./src/assets/*/*.svg', './src/assets/*.svg']), webUpdateNotice({ @@ -35,6 +35,8 @@ export default defineConfig(({ mode }) => { runtimeOnly: true, }), tailwindcss(), + // https://github.com/nonzzz/vite-bundle-analyzer + // unstableRolldownAdapter(analyzer()), ] if (mode === 'development') { @@ -67,6 +69,77 @@ export default defineConfig(({ mode }) => { build: { sourcemap: true, + rolldownOptions: { + output: { + chunkFileNames: 'assets/[name]-[hash].js', + entryFileNames: 'assets/[name]-[hash].js', + assetFileNames: 'assets/[name]-[hash].[ext]', + + manualChunks: (id) => { + if (id.includes('node_modules')) { + if (id.includes('node_modules/.bun/')) { + const match = id.match(/\.bun\/([^@/]+)@/) + if (match && match[1]) { + return `vendor-${match[1]}` + } + + const simpleMatch = id.match(/\.bun\/([^/]+)/) + if (simpleMatch && simpleMatch[1] && simpleMatch[1] !== '.bun') { + return `vendor-${simpleMatch[1]}` + } + + return 'vendor-common' + } + + const match = id.match(/node_modules\/(@[^/]+\/[^/]+|[^/@]+)/) + if (match && match[1]) { + const packageName = match[1].replace('@', '').replace('/', '-') + return `vendor-${packageName}` + } + + return 'vendor-common' + } + + if (id.includes('src/gql/')) { + return 'gql' + } + + if (id.includes('src/plugins/')) { + return 'plugins' + } + + if (id.includes('src/api/')) { + return 'api' + } + + if (id.includes('src/composables/')) { + return 'composables' + } + + if (id.includes('src/features/')) { + const match = id.match(/src\/features\/([^/]+)/) + if (match) { + return `feature-${match[1]}` + } + } + + if (id.includes('src/components/')) { + const match = id.match(/src\/components\/([^/]+)/) + if (match) { + return `components-${match[1]}` + } + return 'components-common' + } + + if (id.includes('src/pages/')) { + const match = id.match(/src\/pages\/([^/]+)/) + if (match) { + return `page-${match[1].replace('.vue', '').toLowerCase()}` + } + } + }, + }, + }, }, } }) diff --git a/package.json b/package.json index f6746f3c4..bc47a3981 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "vue": "3.5.25", "vue-router": "4.3.0", "vue-tsc": "3.1.8", - "vite": "8.0.0-beta.0", + "vite": "8.0.0-beta.5", "typescript": "5.9.3", "graphql": "16.12.0", "graphql-ws": "6.0.6", From 58377f922ec71a4107caefcc94936414c30da798 Mon Sep 17 00:00:00 2001 From: Vitalij Ryndin Date: Tue, 6 Jan 2026 17:21:44 +0300 Subject: [PATCH 2/5] chore: split api and components --- frontend/dashboard/vite.config.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/frontend/dashboard/vite.config.ts b/frontend/dashboard/vite.config.ts index ee7110e87..d65a76686 100644 --- a/frontend/dashboard/vite.config.ts +++ b/frontend/dashboard/vite.config.ts @@ -109,7 +109,12 @@ export default defineConfig(({ mode }) => { } if (id.includes('src/api/')) { - return 'api' + const match = id.match(/src\/api\/([^/]+)/) + if (match && match[1]) { + const fileName = match[1].replace(/\.ts$/, '') + return `api-${fileName}` + } + return 'api-common' } if (id.includes('src/composables/')) { @@ -124,9 +129,10 @@ export default defineConfig(({ mode }) => { } if (id.includes('src/components/')) { - const match = id.match(/src\/components\/([^/]+)/) - if (match) { - return `components-${match[1]}` + const match = id.match(/src\/components\/([^/]+(?:\/[^/]+)?)/) + if (match && match[1]) { + const path = match[1].replace(/\.(ts|vue)$/, '').replace(/\//g, '-') + return `components-${path}` } return 'components-common' } From 9d7ec9544db6f807ad5344d389cb2d2f92146464 Mon Sep 17 00:00:00 2001 From: Vitalij Ryndin Date: Tue, 6 Jan 2026 18:02:34 +0300 Subject: [PATCH 3/5] chore: add analyze env --- frontend/dashboard/vite.config.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frontend/dashboard/vite.config.ts b/frontend/dashboard/vite.config.ts index d65a76686..627b1d91b 100644 --- a/frontend/dashboard/vite.config.ts +++ b/frontend/dashboard/vite.config.ts @@ -1,7 +1,7 @@ import path from 'node:path' import process from 'node:process' import { fileURLToPath } from 'node:url' -// import { analyzer, unstableRolldownAdapter } from 'vite-bundle-analyzer' +import { analyzer, unstableRolldownAdapter } from 'vite-bundle-analyzer' import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import { webUpdateNotice } from '@plugin-web-update-notification/vite' @@ -13,6 +13,7 @@ import tailwindcss from '@tailwindcss/vite' // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { + const analyzeMode = process.env.ANALYZE const env = loadEnv(mode, path.resolve(process.cwd(), '..', '..'), '') const plugins: PluginOption[] = [ @@ -36,7 +37,10 @@ export default defineConfig(({ mode }) => { }), tailwindcss(), // https://github.com/nonzzz/vite-bundle-analyzer - // unstableRolldownAdapter(analyzer()), + // ANALYZE=server bun run build + analyzeMode && unstableRolldownAdapter(analyzer({ + analyzerMode: analyzeMode === 'json' ? 'json' : 'server', + })), ] if (mode === 'development') { From d7be7f139a1da6a4fd37bc58ad94f76a1cfce263 Mon Sep 17 00:00:00 2001 From: Satont Date: Tue, 6 Jan 2026 18:07:20 +0300 Subject: [PATCH 4/5] chore: update imports from api --- frontend/dashboard/codegen.ts | 13 +- frontend/dashboard/src/api/index.ts | 9 -- .../dashboard/src/api/overlays/kappagen.ts | 16 ++- .../src/components/dashboard/audit-logs.vue | 2 +- .../src/components/dashboard/chat.vue | 2 +- .../src/components/dashboard/events.vue | 2 +- .../src/components/dashboard/stream.vue | 2 +- .../dashboard/src/components/files/files.vue | 2 +- .../dashboard/src/components/games/8ball.vue | 2 +- .../dashboard/src/components/games/card.vue | 2 +- .../src/components/integrations/donatepay.vue | 2 +- .../components/integrations/streamlabs.vue | 2 +- .../integrations/variants/oauth.vue | 2 +- .../integrations/variants/withSettings.vue | 2 +- .../src/components/overlays/card.vue | 2 +- .../src/components/registry/overlays/edit.vue | 2 +- .../src/components/songRequests/hook.ts | 30 ++-- .../src/components/songRequests/player.vue | 2 +- ...twitch-category-search-shadcn-multiple.vue | 2 +- .../components/twitch-category-selector.vue | 2 +- .../twitchUsers/twitch-user-select.vue | 2 +- .../twitchUsers/twitch-users-select.vue | 2 +- .../composables/use-alerts-information.ts | 2 +- .../alerts/ui/alerts-create-button.vue | 2 +- .../alerts/ui/alerts-dialog-content.vue | 2 +- .../src/features/chat-alerts/ui/settings.vue | 2 +- .../src/features/commands/commands.vue | 2 +- .../commands/ui/form/form-responses.vue | 2 +- .../src/features/commands/ui/list-actions.vue | 2 +- .../community-rewards-history-query.ts | 15 +- .../community-roles/community-roles.vue | 2 +- .../src/features/community-roles/ui/modal.vue | 2 +- .../dashboard/widgets/composables/events.ts | 16 ++- .../events/ui/events-create-button.vue | 2 +- .../events/ui/events-table-actions.vue | 2 +- .../composables/giveaways-use-list-table.ts | 134 +++++++++--------- .../giveaways/ui/giveaways-create-dialog.vue | 2 +- .../ui/giveaways-current-giveaway.vue | 2 +- .../greetings/ui/greetings-create-button.vue | 2 +- .../features/integrations/ui/discord/card.vue | 2 +- .../ui/discord/guild-settings-form.vue | 2 +- .../keywords/ui/keywords-create-button.vue | 2 +- .../composables/use-moderation-form.ts | 71 ++++++---- .../src/features/moderation/moderation.vue | 2 +- .../src/features/moderation/ui/card.vue | 2 +- .../ui/form/moderation-form-language.vue | 2 +- .../modules/ui/module-chat-translations.vue | 2 +- .../src/features/overlays/brb/card.vue | 2 +- .../src/features/overlays/brb/page.vue | 3 +- .../overlays/tts/ui/general-settings.vue | 2 +- .../timers/ui/timers-create-button.vue | 2 +- .../variables/ui/variables-actions.vue | 2 +- .../variables/ui/variables-create-button.vue | 2 +- frontend/dashboard/src/global.d.ts | 82 +++++------ .../src/layout/header/header-bot-status.vue | 2 +- .../src/layout/header/header-profile.vue | 2 +- .../dashboard/src/layout/header/header.vue | 2 +- .../sidebar/sidebar-dashboard-selector.vue | 2 +- .../src/layout/sidebar/sidebar-navigation.vue | 2 +- .../src/layout/stream-info-editor.vue | 4 +- .../src/layout/use-public-page-href.ts | 7 +- .../src/pages/IntegrationsCallback.vue | 2 +- frontend/dashboard/src/pages/Overlays.vue | 8 +- frontend/dashboard/src/pages/chat-alerts.vue | 2 +- frontend/dashboard/src/pages/community.vue | 2 +- .../src/pages/overlays/chat/Chat.vue | 3 +- .../pages/overlays/chat/components/Form.vue | 3 +- .../overlays/dudes/dudes-settings-form.vue | 3 +- .../pages/overlays/dudes/dudes-settings.vue | 3 +- .../overlays/now-playing/now-playing-form.vue | 3 +- .../overlays/now-playing/now-playing.vue | 3 +- .../user-settings/user-account-settings.vue | 2 +- .../user-settings/user-public-settings.vue | 2 +- 73 files changed, 285 insertions(+), 249 deletions(-) delete mode 100644 frontend/dashboard/src/api/index.ts diff --git a/frontend/dashboard/codegen.ts b/frontend/dashboard/codegen.ts index 2f358a144..dfe005067 100644 --- a/frontend/dashboard/codegen.ts +++ b/frontend/dashboard/codegen.ts @@ -1,8 +1,8 @@ +import type { CodegenConfig } from '@graphql-codegen/cli' + import { join, resolve } from 'node:path' import * as process from 'node:process' -import type { CodegenConfig } from '@graphql-codegen/cli' - const schemaDir = resolve( join( process.cwd(), @@ -34,6 +34,15 @@ const config: CodegenConfig = { config: { useTypeImports: true, }, + presetConfig: { + // persistedDocuments: { + // hashAlgorithm: (operation: string) => { + // const h = new Bun.CryptoHasher('sha256') + // h.update(operation) + // return h.digest('hex') + // }, + // }, + }, // presetConfig: { // onExecutableDocumentNode: generatePersistHash, // }, diff --git a/frontend/dashboard/src/api/index.ts b/frontend/dashboard/src/api/index.ts deleted file mode 100644 index e7bd564a6..000000000 --- a/frontend/dashboard/src/api/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from './auth.js' -export * from './integrations/index.js' -export * from './crud.js' -export * from './twitch.js' -export * from './overlays/index.js' -export * from './overlays-be-right-back.js' -export * from './dashboard.js' -export * from './files.js' -export * from './moderation.js' diff --git a/frontend/dashboard/src/api/overlays/kappagen.ts b/frontend/dashboard/src/api/overlays/kappagen.ts index cdc2a26ee..f768b1a49 100644 --- a/frontend/dashboard/src/api/overlays/kappagen.ts +++ b/frontend/dashboard/src/api/overlays/kappagen.ts @@ -4,7 +4,7 @@ import { computed } from 'vue' import type { KappagenOverlaySettingsFragment } from '@/gql/graphql.ts' -import { useProfile } from '@/api' +import { useProfile } from '@/api/auth' import { graphql } from '@/gql' graphql(` @@ -137,12 +137,12 @@ export const useKappagenApi = createGlobalState(() => { }) const { executeMutation: updateKappagen, fetching: isUpdating } = useMutation( - KappagenOverlayUpdateMutation, + KappagenOverlayUpdateMutation ) const selectedDashboard = computed(() => { return profile.value?.availableDashboards.find( - (d) => d.id === profile.value?.selectedDashboardId, + (d) => d.id === profile.value?.selectedDashboardId ) }) @@ -161,12 +161,14 @@ export const useKappagenApi = createGlobalState(() => { }) const availableAnimations = computed(() => { - const data = subscriptionData.value?.overlaysKappagen as KappagenOverlaySettingsFragment | undefined + const data = subscriptionData.value?.overlaysKappagen as + | KappagenOverlaySettingsFragment + | undefined return ( - data?.animations?.map((a) => a.style) - || kappagenData.value?.overlaysKappagenAvailableAnimations - || [] + data?.animations?.map((a) => a.style) || + kappagenData.value?.overlaysKappagenAvailableAnimations || + [] ) }) diff --git a/frontend/dashboard/src/components/dashboard/audit-logs.vue b/frontend/dashboard/src/components/dashboard/audit-logs.vue index d14b28131..170677eb0 100644 --- a/frontend/dashboard/src/components/dashboard/audit-logs.vue +++ b/frontend/dashboard/src/components/dashboard/audit-logs.vue @@ -3,7 +3,7 @@ import { ExternalLinkIcon } from 'lucide-vue-next' import { UseTimeAgo } from '@vueuse/components' import { useI18n } from 'vue-i18n' -import { useProfile } from '@/api' +import { useProfile } from '@/api/auth' import { mapOperationTypeToTranslate, mapSystemToTranslate, useAuditLogs } from '@/api/audit-logs' import Card from '@/components/dashboard/card.vue' import { Badge, type BadgeVariants } from '@/components/ui/badge' diff --git a/frontend/dashboard/src/components/dashboard/chat.vue b/frontend/dashboard/src/components/dashboard/chat.vue index dfc2e97ee..af4d22313 100644 --- a/frontend/dashboard/src/components/dashboard/chat.vue +++ b/frontend/dashboard/src/components/dashboard/chat.vue @@ -4,7 +4,7 @@ import { computed, ref } from 'vue' import Card from './card.vue' -import { useProfile } from '@/api/index.js' +import { useProfile } from '@/api/auth' import { useTheme } from '@/composables/use-theme.js' import { Button } from '@/components/ui/button' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip' diff --git a/frontend/dashboard/src/components/dashboard/events.vue b/frontend/dashboard/src/components/dashboard/events.vue index e8b2a6223..7b2642020 100644 --- a/frontend/dashboard/src/components/dashboard/events.vue +++ b/frontend/dashboard/src/components/dashboard/events.vue @@ -22,7 +22,7 @@ import ReSubscribe from './events/resubscribe.vue' import SubGift from './events/subgift.vue' import Subscribe from './events/subscribe.vue' -import { useProfile } from '@/api/index.js' +import { useProfile } from '@/api/auth' import UnbanRequestCreated from '@/components/dashboard/events/unban-request-created.vue' import UnbanRequestResolved from '@/components/dashboard/events/unban-request-resolved.vue' import { useEvents } from '@/features/dashboard/widgets/composables/events' diff --git a/frontend/dashboard/src/components/dashboard/stream.vue b/frontend/dashboard/src/components/dashboard/stream.vue index 6276325c6..adf4f6bfb 100644 --- a/frontend/dashboard/src/components/dashboard/stream.vue +++ b/frontend/dashboard/src/components/dashboard/stream.vue @@ -3,7 +3,7 @@ import { computed } from 'vue' import Card from './card.vue' -import { useProfile } from '@/api/index.js' +import { useProfile } from '@/api/auth' const { data: profile } = useProfile() diff --git a/frontend/dashboard/src/components/files/files.vue b/frontend/dashboard/src/components/files/files.vue index 0e6d99508..859330d28 100644 --- a/frontend/dashboard/src/components/files/files.vue +++ b/frontend/dashboard/src/components/files/files.vue @@ -5,7 +5,7 @@ import { toast } from 'vue-sonner' import { computed, onMounted, ref } from 'vue' import { useI18n } from 'vue-i18n' -import { useFilesApi } from '@/api/index.js' +import { useFilesApi } from '@/api/files' import { Alert, AlertDescription } from '@/components/ui/alert' import { Button, FileButton } from '@/components/ui/button' import { Progress } from '@/components/ui/progress' diff --git a/frontend/dashboard/src/components/games/8ball.vue b/frontend/dashboard/src/components/games/8ball.vue index bab481776..5a61fc352 100644 --- a/frontend/dashboard/src/components/games/8ball.vue +++ b/frontend/dashboard/src/components/games/8ball.vue @@ -3,7 +3,7 @@ import { MessageCircle, Trash } from 'lucide-vue-next' import { computed, ref, toRaw, watch } from 'vue' import { useI18n } from 'vue-i18n' -import { useProfile } from '@/api' +import { useProfile } from '@/api/auth' import { useGamesApi } from '@/api/games/games.js' import Card from '@/components/games/card.vue' import { Button } from '@/components/ui/button' diff --git a/frontend/dashboard/src/components/games/card.vue b/frontend/dashboard/src/components/games/card.vue index 900041818..261fee4fd 100644 --- a/frontend/dashboard/src/components/games/card.vue +++ b/frontend/dashboard/src/components/games/card.vue @@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n' import type { FunctionalComponent } from 'vue' -import { useUserAccessFlagChecker } from '@/api' +import { useUserAccessFlagChecker } from '@/api/auth' import Card from '@/components/card/card.vue' import { Button } from '@/components/ui/button' import { ChannelRolePermissionEnum } from '@/gql/graphql' diff --git a/frontend/dashboard/src/components/integrations/donatepay.vue b/frontend/dashboard/src/components/integrations/donatepay.vue index 91298dc8d..176b2767f 100644 --- a/frontend/dashboard/src/components/integrations/donatepay.vue +++ b/frontend/dashboard/src/components/integrations/donatepay.vue @@ -2,7 +2,7 @@ import { ExternalLink, Eye, EyeOff } from 'lucide-vue-next' import { ref, watch } from 'vue' -import { useDonatepayIntegration } from '@/api/index.js' +import { useDonatepayIntegration } from '@/api/integrations/donatepay' import { useIntegrationsPageData } from '@/api/integrations/integrations-page.ts' import DonatePaySVG from '@/assets/integrations/donatepay.svg?use' import DonateDescription from '@/components/integrations/helpers/donateDescription.vue' diff --git a/frontend/dashboard/src/components/integrations/streamlabs.vue b/frontend/dashboard/src/components/integrations/streamlabs.vue index bd694f9fc..7b18c099d 100644 --- a/frontend/dashboard/src/components/integrations/streamlabs.vue +++ b/frontend/dashboard/src/components/integrations/streamlabs.vue @@ -1,6 +1,6 @@ diff --git a/frontend/dashboard/src/features/variables/ui/variables-create-button.vue b/frontend/dashboard/src/features/variables/ui/variables-create-button.vue index 26466df18..e3a76b9e1 100644 --- a/frontend/dashboard/src/features/variables/ui/variables-create-button.vue +++ b/frontend/dashboard/src/features/variables/ui/variables-create-button.vue @@ -18,7 +18,7 @@ const maxVariables = computed(() => { const selectedDashboard = profile.value?.availableDashboards.find( (d) => d.id === profile.value?.selectedDashboardId ) - return selectedDashboard?.plan.maxVariables ?? 50 + return selectedDashboard?.plan?.maxVariables ?? 50 }) const isCreateDisabled = computed(() => { diff --git a/frontend/dashboard/src/pages/Overlays.vue b/frontend/dashboard/src/pages/Overlays.vue index 3e07eba3b..18741d52f 100644 --- a/frontend/dashboard/src/pages/Overlays.vue +++ b/frontend/dashboard/src/pages/Overlays.vue @@ -71,7 +71,7 @@ const maxCustomOverlays = computed(() => { const selectedDashboard = profile.value?.availableDashboards.find( (d) => d.id === profile.value?.selectedDashboardId ) - return selectedDashboard?.plan.maxCustomOverlays ?? 10 + return selectedDashboard?.plan?.maxCustomOverlays ?? 10 }) const isCreateDisabled = computed(() => { diff --git a/frontend/dashboard/src/pages/chat-alerts.vue b/frontend/dashboard/src/pages/chat-alerts.vue index f8962ebe3..d3d235728 100644 --- a/frontend/dashboard/src/pages/chat-alerts.vue +++ b/frontend/dashboard/src/pages/chat-alerts.vue @@ -15,7 +15,7 @@ const maxChatAlertsMessages = computed(() => { const selectedDashboard = profile.value?.availableDashboards.find( (d) => d.id === profile.value?.selectedDashboardId ) - return selectedDashboard?.plan.maxChatAlertsMessages ?? 20 + return selectedDashboard?.plan?.maxChatAlertsMessages ?? 20 }) const pageTabs = computed(() => [ diff --git a/libs/gomodels/channels.go b/libs/gomodels/channels.go index f58ca5f77..1b32af4e2 100755 --- a/libs/gomodels/channels.go +++ b/libs/gomodels/channels.go @@ -21,6 +21,7 @@ type Channels struct { IsTwitchBanned bool `gorm:"column:isTwitchBanned;type:BOOL;" json:"isTwitchBanned"` IsBotMod bool `gorm:"column:isBotMod;type:BOOL;" json:"isBotMod"` BotID string `gorm:"column:botId;type:TEXT;" json:"botId"` + PlanID *string `gorm:"column:plan_id;type:UUID;" json:"planId"` CreatedAt time.Time `gorm:"column:created_at;type:TIMESTAMPTZ;default:now()" json:"createdAt"` Commands []ChannelsCommands `gorm:"foreignKey:ChannelID" json:"commands"` diff --git a/libs/repositories/plans/pgx/pgx.go b/libs/repositories/plans/pgx/pgx.go index 81d3cb042..2a62dfa3b 100644 --- a/libs/repositories/plans/pgx/pgx.go +++ b/libs/repositories/plans/pgx/pgx.go @@ -86,7 +86,7 @@ func (r *repository) GetByID(ctx context.Context, id string) (plan.Plan, error) return r.dbToEntity(dbPlan), nil } -func (r *repository) GetByNameID(ctx context.Context, nameID string) (plan.Plan, error) { +func (r *repository) GetByName(ctx context.Context, name string) (plan.Plan, error) { query, args, err := squirrel.Select( "id", "name", @@ -106,7 +106,7 @@ func (r *repository) GetByNameID(ctx context.Context, nameID string) (plan.Plan, "updated_at", ). From("plans"). - Where(squirrel.Eq{"name": nameID}). + Where(squirrel.Eq{"name": name}). PlaceholderFormat(squirrel.Dollar). ToSql() if err != nil { @@ -199,6 +199,87 @@ func (r *repository) GetByChannelID(ctx context.Context, channelID string) (plan return r.dbToEntity(dbPlan), nil } +func (r *repository) GetManyByIDs(ctx context.Context, ids []string) ([]plan.Plan, error) { + if len(ids) == 0 { + return []plan.Plan{}, nil + } + + query, args, err := squirrel.Select( + "id", + "name", + "max_commands", + "max_timers", + "max_variables", + "max_alerts", + "max_events", + "max_chat_alerts_messages", + "max_custom_overlays", + "max_eightball_answers", + "max_commands_responses", + "max_moderation_rules", + "max_keywords", + "max_greetings", + "created_at", + "updated_at", + ). + From("plans"). + Where(squirrel.Eq{"id": ids}). + PlaceholderFormat(squirrel.Dollar). + ToSql() + if err != nil { + return nil, fmt.Errorf("failed to build query: %w", err) + } + + rows, err := r.db.Query(ctx, query, args...) + if err != nil { + return nil, fmt.Errorf("failed to query plans: %w", err) + } + defer rows.Close() + + plansMap := make(map[string]plan.Plan) + for rows.Next() { + var dbPlan model.Plan + err = rows.Scan( + &dbPlan.ID, + &dbPlan.Name, + &dbPlan.MaxCommands, + &dbPlan.MaxTimers, + &dbPlan.MaxVariables, + &dbPlan.MaxAlerts, + &dbPlan.MaxEvents, + &dbPlan.MaxChatAlertsMessages, + &dbPlan.MaxCustomOverlays, + &dbPlan.MaxEightballAnswers, + &dbPlan.MaxCommandsResponses, + &dbPlan.MaxModerationRules, + &dbPlan.MaxKeywords, + &dbPlan.MaxGreetings, + &dbPlan.CreatedAt, + &dbPlan.UpdatedAt, + ) + if err != nil { + return nil, fmt.Errorf("failed to scan plan: %w", err) + } + plansMap[dbPlan.ID] = r.dbToEntity(dbPlan) + } + + if err = rows.Err(); err != nil { + return nil, fmt.Errorf("rows error: %w", err) + } + + // Return plans in the same order as requested IDs + result := make([]plan.Plan, len(ids)) + for i, id := range ids { + if p, ok := plansMap[id]; ok { + result[i] = p + } else { + result[i] = plan.Nil + } + } + + return result, nil +} + func (r *repository) dbToEntity(m model.Plan) plan.Plan { return plan.Plan{ ID: m.ID, diff --git a/libs/repositories/plans/plans.go b/libs/repositories/plans/plans.go index cebbd3d29..5e7e0ca77 100644 --- a/libs/repositories/plans/plans.go +++ b/libs/repositories/plans/plans.go @@ -8,6 +8,7 @@ import ( type Repository interface { GetByID(ctx context.Context, id string) (plan.Plan, error) - GetByNameID(ctx context.Context, nameID string) (plan.Plan, error) + GetByName(ctx context.Context, name string) (plan.Plan, error) GetByChannelID(ctx context.Context, channelID string) (plan.Plan, error) + GetManyByIDs(ctx context.Context, ids []string) ([]plan.Plan, error) }