diff --git a/.github/workflows/dashboard-test.yml b/.github/workflows/dashboard-test.yml new file mode 100644 index 0000000000..67b5a81d73 --- /dev/null +++ b/.github/workflows/dashboard-test.yml @@ -0,0 +1,85 @@ +name: Dashboard Test + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - main + push: + branches: + - main + workflow_dispatch: # Allow manual triggering + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # Use changes filter to detect dashboard changes + changes: + uses: ./.github/workflows/ci-changes.yml + + dashboard-test: + needs: changes + if: >- + ${{ !github.event.pull_request.draft + && needs.changes.outputs.dashboard == 'true' }} + runs-on: ubuntu-latest + name: Dashboard Lint and Type Check + + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v5 + with: + node-version: "23" + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "1.24" + + - name: Cache Node.js dependencies + uses: actions/cache@v4 + with: + path: | + ~/.npm + dashboard/frontend/node_modules + key: ${{ runner.os }}-node-dashboard-${{ hashFiles('dashboard/frontend/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-dashboard- + + - name: Cache Go dependencies + uses: actions/cache@v4 + with: + path: | + ~/go/pkg/mod + key: ${{ runner.os }}-go-dashboard-${{ hashFiles('dashboard/backend/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-dashboard- + + - name: Set up golangci-lint + uses: golangci/golangci-lint-action@v7 + with: + version: v2.5.0 + install-mode: binary + args: --help + + - name: Run dashboard checks + run: make dashboard-check + + - name: Build dashboard + run: make dashboard-build + + - name: Show results on failure + if: failure() + run: | + echo "::error::Dashboard checks failed. Please fix the issues and commit again." + echo "" + echo "To run checks locally:" + echo " make dashboard-check" + echo "" + echo "To auto-fix lint issues:" + echo " make dashboard-lint-fix" diff --git a/Makefile b/Makefile index 75b14be4c2..4a7172ebd5 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ _run: -f tools/make/rust.mk \ -f tools/make/build-run-test.mk \ -f tools/make/docs.mk \ + -f tools/make/dashboard.mk \ -f tools/make/linter.mk \ -f tools/make/milvus.mk \ -f tools/make/redis.mk \ diff --git a/dashboard/backend/handlers/config.go b/dashboard/backend/handlers/config.go index 03abae9339..ee886b4a7e 100644 --- a/dashboard/backend/handlers/config.go +++ b/dashboard/backend/handlers/config.go @@ -71,7 +71,7 @@ func UpdateConfigHandler(configPath string) http.HandlerFunc { } // Write to file - if err := os.WriteFile(configPath, yamlData, 0644); err != nil { + if err := os.WriteFile(configPath, yamlData, 0o644); err != nil { log.Printf("Error writing config file: %v", err) http.Error(w, fmt.Sprintf("Failed to write config file: %v", err), http.StatusInternalServerError) return @@ -80,6 +80,8 @@ func UpdateConfigHandler(configPath string) http.HandlerFunc { log.Printf("Configuration updated successfully") w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "Configuration updated successfully"}) + if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "Configuration updated successfully"}); err != nil { + log.Printf("Error encoding response: %v", err) + } } } diff --git a/dashboard/backend/handlers/health.go b/dashboard/backend/handlers/health.go index 2e8d349823..13c633d844 100644 --- a/dashboard/backend/handlers/health.go +++ b/dashboard/backend/handlers/health.go @@ -8,5 +8,5 @@ import ( func HealthCheck(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - w.Write([]byte(`{"status":"healthy","service":"semantic-router-dashboard"}`)) + _, _ = w.Write([]byte(`{"status":"healthy","service":"semantic-router-dashboard"}`)) } diff --git a/dashboard/backend/router/router.go b/dashboard/backend/router/router.go index 03422226f0..06c935bfe6 100644 --- a/dashboard/backend/router/router.go +++ b/dashboard/backend/router/router.go @@ -75,7 +75,7 @@ func Setup(cfg *config.Config) *http.ServeMux { mux.HandleFunc("/embedded/grafana/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusServiceUnavailable) - w.Write([]byte(`{"error":"Grafana not configured","message":"TARGET_GRAFANA_URL environment variable is not set"}`)) + _, _ = w.Write([]byte(`{"error":"Grafana not configured","message":"TARGET_GRAFANA_URL environment variable is not set"}`)) }) log.Printf("Warning: Grafana URL not configured") } @@ -253,7 +253,7 @@ func Setup(cfg *config.Config) *http.ServeMux { mux.HandleFunc("/embedded/chatui/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusServiceUnavailable) - w.Write([]byte(`{"error":"HuggingChat not configured","message":"TARGET_CHATUI_URL environment variable is not set"}`)) + _, _ = w.Write([]byte(`{"error":"HuggingChat not configured","message":"TARGET_CHATUI_URL environment variable is not set"}`)) }) log.Printf("Info: HuggingChat not configured (optional)") } @@ -328,7 +328,7 @@ func Setup(cfg *config.Config) *http.ServeMux { mux.HandleFunc("/embedded/prometheus/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusServiceUnavailable) - w.Write([]byte(`{"error":"Prometheus not configured","message":"TARGET_PROMETHEUS_URL environment variable is not set"}`)) + _, _ = w.Write([]byte(`{"error":"Prometheus not configured","message":"TARGET_PROMETHEUS_URL environment variable is not set"}`)) }) log.Printf("Warning: Prometheus URL not configured") } @@ -372,7 +372,7 @@ func Setup(cfg *config.Config) *http.ServeMux { mux.HandleFunc("/embedded/jaeger/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusServiceUnavailable) - w.Write([]byte(`{"error":"Jaeger not configured","message":"TARGET_JAEGER_URL environment variable is not set"}`)) + _, _ = w.Write([]byte(`{"error":"Jaeger not configured","message":"TARGET_JAEGER_URL environment variable is not set"}`)) }) log.Printf("Info: Jaeger URL not configured (optional)") } @@ -400,7 +400,7 @@ func Setup(cfg *config.Config) *http.ServeMux { mux.HandleFunc("/embedded/openwebui/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusServiceUnavailable) - w.Write([]byte(`{"error":"Open WebUI not configured","message":"TARGET_OPENWEBUI_URL environment variable is not set or empty"}`)) + _, _ = w.Write([]byte(`{"error":"Open WebUI not configured","message":"TARGET_OPENWEBUI_URL environment variable is not set or empty"}`)) }) log.Printf("Info: Open WebUI not configured (optional)") } diff --git a/dashboard/frontend/eslint.config.js b/dashboard/frontend/eslint.config.js new file mode 100644 index 0000000000..231b64129c --- /dev/null +++ b/dashboard/frontend/eslint.config.js @@ -0,0 +1,36 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist", "node_modules"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + "@typescript-eslint/no-unused-vars": [ + "error", + { argsIgnorePattern: "^_" }, + ], + // Temporarily relaxed rules for existing code - can be tightened later + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/ban-ts-comment": "warn", + "no-useless-escape": "warn", + }, + } +); diff --git a/dashboard/frontend/package-lock.json b/dashboard/frontend/package-lock.json index 29170bfc49..7e124e60fe 100644 --- a/dashboard/frontend/package-lock.json +++ b/dashboard/frontend/package-lock.json @@ -14,6 +14,7 @@ "reactflow": "^11.11.4" }, "devDependencies": { + "@eslint/js": "^9.18.0", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@typescript-eslint/eslint-plugin": "^8.45.0", @@ -22,7 +23,9 @@ "eslint": "^9.18.0", "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^16.1.0", "typescript": "^5.9.3", + "typescript-eslint": "^8.45.0", "vite": "^5.4.11" } }, @@ -848,6 +851,19 @@ "concat-map": "0.0.1" } }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -1129,9 +1145,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.4.tgz", - "integrity": "sha512-PWU3Y92H4DD0bOqorEPp1Y0tbzwAurFmIYpjcObv5axGVOtcTlB0b2UKMd2echo08MgN7jO8WQZSSysvfisFSQ==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz", + "integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==", "cpu": [ "arm" ], @@ -1143,9 +1159,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.4.tgz", - "integrity": "sha512-Gw0/DuVm3rGsqhMGYkSOXXIx20cC3kTlivZeuaGt4gEgILivykNyBWxeUV5Cf2tDA2nPLah26vq3emlRrWVbng==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz", + "integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==", "cpu": [ "arm64" ], @@ -1157,9 +1173,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.4.tgz", - "integrity": "sha512-+w06QvXsgzKwdVg5qRLZpTHh1bigHZIqoIUPtiqh05ZiJVUQ6ymOxaPkXTvRPRLH88575ZCRSRM3PwIoNma01Q==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz", + "integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==", "cpu": [ "arm64" ], @@ -1171,9 +1187,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.4.tgz", - "integrity": "sha512-EB4Na9G2GsrRNRNFPuxfwvDRDUwQEzJPpiK1vo2zMVhEeufZ1k7J1bKnT0JYDfnPC7RNZ2H5YNQhW6/p2QKATw==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz", + "integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==", "cpu": [ "x64" ], @@ -1185,9 +1201,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.4.tgz", - "integrity": "sha512-bldA8XEqPcs6OYdknoTMaGhjytnwQ0NClSPpWpmufOuGPN5dDmvIa32FygC2gneKK4A1oSx86V1l55hyUWUYFQ==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz", + "integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==", "cpu": [ "arm64" ], @@ -1199,9 +1215,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.4.tgz", - "integrity": "sha512-3T8GPjH6mixCd0YPn0bXtcuSXi1Lj+15Ujw2CEb7dd24j9thcKscCf88IV7n76WaAdorOzAgSSbuVRg4C8V8Qw==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz", + "integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==", "cpu": [ "x64" ], @@ -1213,9 +1229,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.4.tgz", - "integrity": "sha512-UPMMNeC4LXW7ZSHxeP3Edv09aLsFUMaD1TSVW6n1CWMECnUIJMFFB7+XC2lZTdPtvB36tYC0cJWc86mzSsaviw==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz", + "integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==", "cpu": [ "arm" ], @@ -1227,9 +1243,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.4.tgz", - "integrity": "sha512-H8uwlV0otHs5Q7WAMSoyvjV9DJPiy5nJ/xnHolY0QptLPjaSsuX7tw+SPIfiYH6cnVx3fe4EWFafo6gH6ekZKA==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz", + "integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==", "cpu": [ "arm" ], @@ -1241,9 +1257,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.4.tgz", - "integrity": "sha512-BLRwSRwICXz0TXkbIbqJ1ibK+/dSBpTJqDClF61GWIrxTXZWQE78ROeIhgl5MjVs4B4gSLPCFeD4xML9vbzvCQ==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz", + "integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==", "cpu": [ "arm64" ], @@ -1255,9 +1271,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.4.tgz", - "integrity": "sha512-6bySEjOTbmVcPJAywjpGLckK793A0TJWSbIa0sVwtVGfe/Nz6gOWHOwkshUIAp9j7wg2WKcA4Snu7Y1nUZyQew==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz", + "integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==", "cpu": [ "arm64" ], @@ -1269,9 +1285,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.4.tgz", - "integrity": "sha512-U0ow3bXYJZ5MIbchVusxEycBw7bO6C2u5UvD31i5IMTrnt2p4Fh4ZbHSdc/31TScIJQYHwxbj05BpevB3201ug==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz", + "integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==", "cpu": [ "loong64" ], @@ -1283,9 +1299,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.4.tgz", - "integrity": "sha512-iujDk07ZNwGLVn0YIWM80SFN039bHZHCdCCuX9nyx3Jsa2d9V/0Y32F+YadzwbvDxhSeVo9zefkoPnXEImnM5w==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz", + "integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==", "cpu": [ "ppc64" ], @@ -1297,9 +1313,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.4.tgz", - "integrity": "sha512-MUtAktiOUSu+AXBpx1fkuG/Bi5rhlorGs3lw5QeJ2X3ziEGAq7vFNdWVde6XGaVqi0LGSvugwjoxSNJfHFTC0g==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz", + "integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==", "cpu": [ "riscv64" ], @@ -1311,9 +1327,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.4.tgz", - "integrity": "sha512-btm35eAbDfPtcFEgaXCI5l3c2WXyzwiE8pArhd66SDtoLWmgK5/M7CUxmUglkwtniPzwvWioBKKl6IXLbPf2sQ==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz", + "integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==", "cpu": [ "riscv64" ], @@ -1325,9 +1341,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.4.tgz", - "integrity": "sha512-uJlhKE9ccUTCUlK+HUz/80cVtx2RayadC5ldDrrDUFaJK0SNb8/cCmC9RhBhIWuZ71Nqj4Uoa9+xljKWRogdhA==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz", + "integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==", "cpu": [ "s390x" ], @@ -1339,9 +1355,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.4.tgz", - "integrity": "sha512-jjEMkzvASQBbzzlzf4os7nzSBd/cvPrpqXCUOqoeCh1dQ4BP3RZCJk8XBeik4MUln3m+8LeTJcY54C/u8wb3DQ==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz", + "integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==", "cpu": [ "x64" ], @@ -1353,9 +1369,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.4.tgz", - "integrity": "sha512-lu90KG06NNH19shC5rBPkrh6mrTpq5kviFylPBXQVpdEu0yzb0mDgyxLr6XdcGdBIQTH/UAhDJnL+APZTBu1aQ==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz", + "integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==", "cpu": [ "x64" ], @@ -1367,9 +1383,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.4.tgz", - "integrity": "sha512-dFDcmLwsUzhAm/dn0+dMOQZoONVYBtgik0VuY/d5IJUUb787L3Ko/ibvTvddqhb3RaB7vFEozYevHN4ox22R/w==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz", + "integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==", "cpu": [ "arm64" ], @@ -1381,9 +1397,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.4.tgz", - "integrity": "sha512-WvUpUAWmUxZKtRnQWpRKnLW2DEO8HB/l8z6oFFMNuHndMzFTJEXzaYJ5ZAmzNw0L21QQJZsUQFt2oPf3ykAD/w==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz", + "integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==", "cpu": [ "arm64" ], @@ -1395,9 +1411,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.4.tgz", - "integrity": "sha512-JGbeF2/FDU0x2OLySw/jgvkwWUo05BSiJK0dtuI4LyuXbz3wKiC1xHhLB1Tqm5VU6ZZDmAorj45r/IgWNWku5g==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz", + "integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==", "cpu": [ "ia32" ], @@ -1409,9 +1425,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.4.tgz", - "integrity": "sha512-zuuC7AyxLWLubP+mlUwEyR8M1ixW1ERNPHJfXm8x7eQNP4Pzkd7hS3qBuKBR70VRiQ04Kw8FNfRMF5TNxuZq2g==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz", + "integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==", "cpu": [ "x64" ], @@ -1423,9 +1439,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.4.tgz", - "integrity": "sha512-Sbx45u/Lbb5RyptSbX7/3deP+/lzEmZ0BTSHxwxN/IMOZDZf8S0AGo0hJD5n/LQssxb5Z3B4og4P2X6Dd8acCA==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz", + "integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==", "cpu": [ "x64" ], @@ -2107,9 +2123,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", - "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "version": "2.9.9", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.9.tgz", + "integrity": "sha512-V8fbOCSeOFvlDj7LLChUcqbZrdKD9RU/VR260piF1790vT0mfLSwGc/Qzxv3IqiTukOpNtItePa0HBpMAj7MDg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2543,9 +2559,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.25", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.25.tgz", - "integrity": "sha512-dRUD2LOdEqI4zXHqbQ442blQAzdSuShAaiSq5Vtyy6LT08YUf0oOjBDo4VPx0dCPgiPWh1WB4dtbLOd0kOlDPQ==", + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", + "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2835,9 +2851,9 @@ } }, "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", "dev": true, "license": "MIT", "engines": { @@ -3363,9 +3379,9 @@ } }, "node_modules/rollup": { - "version": "4.53.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.4.tgz", - "integrity": "sha512-YpXaaArg0MvrnJpvduEDYIp7uGOqKXbH9NsHGQ6SxKCOsNAjZF018MmxefFUulVP2KLtiGw1UvZbr+/ekjvlDg==", + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.5.tgz", + "integrity": "sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3379,28 +3395,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.4", - "@rollup/rollup-android-arm64": "4.53.4", - "@rollup/rollup-darwin-arm64": "4.53.4", - "@rollup/rollup-darwin-x64": "4.53.4", - "@rollup/rollup-freebsd-arm64": "4.53.4", - "@rollup/rollup-freebsd-x64": "4.53.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.4", - "@rollup/rollup-linux-arm-musleabihf": "4.53.4", - "@rollup/rollup-linux-arm64-gnu": "4.53.4", - "@rollup/rollup-linux-arm64-musl": "4.53.4", - "@rollup/rollup-linux-loong64-gnu": "4.53.4", - "@rollup/rollup-linux-ppc64-gnu": "4.53.4", - "@rollup/rollup-linux-riscv64-gnu": "4.53.4", - "@rollup/rollup-linux-riscv64-musl": "4.53.4", - "@rollup/rollup-linux-s390x-gnu": "4.53.4", - "@rollup/rollup-linux-x64-gnu": "4.53.4", - "@rollup/rollup-linux-x64-musl": "4.53.4", - "@rollup/rollup-openharmony-arm64": "4.53.4", - "@rollup/rollup-win32-arm64-msvc": "4.53.4", - "@rollup/rollup-win32-ia32-msvc": "4.53.4", - "@rollup/rollup-win32-x64-gnu": "4.53.4", - "@rollup/rollup-win32-x64-msvc": "4.53.4", + "@rollup/rollup-android-arm-eabi": "4.53.5", + "@rollup/rollup-android-arm64": "4.53.5", + "@rollup/rollup-darwin-arm64": "4.53.5", + "@rollup/rollup-darwin-x64": "4.53.5", + "@rollup/rollup-freebsd-arm64": "4.53.5", + "@rollup/rollup-freebsd-x64": "4.53.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.5", + "@rollup/rollup-linux-arm-musleabihf": "4.53.5", + "@rollup/rollup-linux-arm64-gnu": "4.53.5", + "@rollup/rollup-linux-arm64-musl": "4.53.5", + "@rollup/rollup-linux-loong64-gnu": "4.53.5", + "@rollup/rollup-linux-ppc64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-musl": "4.53.5", + "@rollup/rollup-linux-s390x-gnu": "4.53.5", + "@rollup/rollup-linux-x64-gnu": "4.53.5", + "@rollup/rollup-linux-x64-musl": "4.53.5", + "@rollup/rollup-openharmony-arm64": "4.53.5", + "@rollup/rollup-win32-arm64-msvc": "4.53.5", + "@rollup/rollup-win32-ia32-msvc": "4.53.5", + "@rollup/rollup-win32-x64-gnu": "4.53.5", + "@rollup/rollup-win32-x64-msvc": "4.53.5", "fsevents": "~2.3.2" } }, @@ -3542,10 +3558,34 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.0.tgz", + "integrity": "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.50.0", + "@typescript-eslint/parser": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/utils": "8.50.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/update-browserslist-db": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", - "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { diff --git a/dashboard/frontend/package.json b/dashboard/frontend/package.json index 030688c2b8..520274e738 100644 --- a/dashboard/frontend/package.json +++ b/dashboard/frontend/package.json @@ -6,7 +6,7 @@ "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint": "eslint .", "type-check": "tsc --noEmit" }, "dependencies": { @@ -16,6 +16,7 @@ "reactflow": "^11.11.4" }, "devDependencies": { + "@eslint/js": "^9.18.0", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@typescript-eslint/eslint-plugin": "^8.45.0", @@ -24,7 +25,9 @@ "eslint": "^9.18.0", "eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^16.1.0", "typescript": "^5.9.3", + "typescript-eslint": "^8.45.0", "vite": "^5.4.11" } } diff --git a/tools/make/dashboard.mk b/tools/make/dashboard.mk new file mode 100644 index 0000000000..b5671de9a2 --- /dev/null +++ b/tools/make/dashboard.mk @@ -0,0 +1,106 @@ +# ========================== dashboard.mk ========================== +# = Everything For Dashboard, include Frontend and Backend = +# ========================== dashboard.mk ========================== + +DASHBOARD_DIR := dashboard +DASHBOARD_FRONTEND_DIR := $(DASHBOARD_DIR)/frontend +DASHBOARD_BACKEND_DIR := $(DASHBOARD_DIR)/backend + +##@ Dashboard + +## Install and Development + +dashboard-install: ## Install dashboard dependencies (frontend npm + backend go mod) + @$(LOG_TARGET) + @echo "Installing frontend dependencies..." + cd $(DASHBOARD_FRONTEND_DIR) && npm install + @echo "Tidying backend dependencies..." + cd $(DASHBOARD_BACKEND_DIR) && go mod tidy + @echo "✅ dashboard dependencies installed" + +dashboard-dev-frontend: dashboard-install ## Start dashboard frontend in dev mode + @$(LOG_TARGET) + cd $(DASHBOARD_FRONTEND_DIR) && npm run dev + +dashboard-dev-backend: ## Start dashboard backend in dev mode + @$(LOG_TARGET) + cd $(DASHBOARD_BACKEND_DIR) && go run main.go + + +## Build + +dashboard-build-frontend: dashboard-install ## Build dashboard frontend for production + @$(LOG_TARGET) + cd $(DASHBOARD_FRONTEND_DIR) && npm run build + @echo "✅ dashboard/frontend build completed" + +dashboard-build-backend: ## Build dashboard backend binary + @$(LOG_TARGET) + @echo "Building dashboard backend..." + cd $(DASHBOARD_BACKEND_DIR) && go build -o bin/dashboard-server ./main.go + @echo "✅ dashboard/backend build completed" + +dashboard-build: dashboard-build-frontend dashboard-build-backend ## Build dashboard (frontend + backend) + @$(LOG_TARGET) + @echo "✅ dashboard build completed (frontend + backend)" + +## Lint and Type Check + +dashboard-lint: ## Lint dashboard frontend and backend + @$(LOG_TARGET) + @echo "Running ESLint for dashboard frontend..." + cd $(DASHBOARD_FRONTEND_DIR) && npm install 2>/dev/null && npm run lint + @echo "✅ dashboard/frontend lint passed" + @echo "Running golangci-lint for dashboard backend..." + @cd $(DASHBOARD_BACKEND_DIR) && \ + export GOROOT=$$(dirname $$(dirname $$(readlink -f $$(which go)))) && \ + export GOPATH=$${GOPATH:-$$HOME/go} && \ + golangci-lint run ./... --config ../../tools/linter/go/.golangci.yml + @echo "✅ dashboard/backend lint passed" + +dashboard-lint-fix: ## Auto-fix lint issues in dashboard (frontend + backend) + @$(LOG_TARGET) + @echo "Running ESLint fix for dashboard frontend..." + cd $(DASHBOARD_FRONTEND_DIR) && npm install 2>/dev/null && npm run lint -- --fix || true + @echo "✅ dashboard/frontend lint fix applied" + @echo "Running golangci-lint fix for dashboard backend..." + @cd $(DASHBOARD_BACKEND_DIR) && \ + export GOROOT=$$(dirname $$(dirname $$(readlink -f $$(which go)))) && \ + export GOPATH=$${GOPATH:-$$HOME/go} && \ + golangci-lint run ./... --fix --config ../../tools/linter/go/.golangci.yml + @echo "✅ dashboard/backend lint fix applied" + +dashboard-type-check: ## Run TypeScript type checking for dashboard frontend + @$(LOG_TARGET) + cd $(DASHBOARD_FRONTEND_DIR) && npm install 2>/dev/null && npm run type-check + @echo "✅ dashboard/frontend type-check passed" + +dashboard-go-mod-tidy: ## Check go mod tidy for dashboard backend + @$(LOG_TARGET) + @echo "Checking dashboard/backend..." + @cd $(DASHBOARD_BACKEND_DIR) && go mod tidy && \ + if ! git diff --exit-code go.mod go.sum 2>/dev/null; then \ + echo "ERROR: go.mod or go.sum files are not tidy in dashboard/backend. Please run 'go mod tidy' in dashboard/backend directory and commit the changes."; \ + git diff go.mod go.sum; \ + exit 1; \ + fi + @echo "✅ dashboard/backend go mod tidy check passed" + +dashboard-check: dashboard-lint dashboard-type-check dashboard-go-mod-tidy ## Run all dashboard checks (lint, type-check, go mod tidy) + @$(LOG_TARGET) + @echo "✅ All dashboard checks passed" + +## Clean + +dashboard-clean: ## Clean dashboard build artifacts (frontend dist + backend bin) + @$(LOG_TARGET) + rm -rf $(DASHBOARD_FRONTEND_DIR)/dist + rm -rf $(DASHBOARD_FRONTEND_DIR)/node_modules + rm -rf $(DASHBOARD_BACKEND_DIR)/bin + @echo "✅ dashboard cleaned" + +.PHONY: dashboard-install dashboard-dev-frontend dashboard-dev-backend \ + dashboard-build dashboard-build-frontend dashboard-build-backend \ + dashboard-lint dashboard-lint-fix dashboard-type-check dashboard-go-mod-tidy \ + dashboard-check dashboard-clean +