diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 00000000..750f9ecc --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,34 @@ +name: ESLint + +on: + pull_request: + paths: + - '**/*.js' + - '**/*.jsx' + - '**/*.ts' + - '**/*.tsx' + - '.eslintrc*' + - 'package.json' + - 'yarn.lock' + - 'pnpm-lock.yaml' + - 'package-lock.json' + +jobs: + Linter: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: | + npm ci + + - name: Run ESLint + run: | + npx eslint . --ext .js,.jsx,.ts,.tsx \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index 71dc862c..dfc194bc 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,9 +1,19 @@ -// eslint.config.js -export default [ - { - rules: { - semi: "error", - "prefer-const": "error" - } +import tseslint from 'typescript-eslint'; + +export default tseslint.config({ + files: ["**/*.{ts,tsx,js,jsx}"], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + ecmaFeatures: { + jsx: true + } } -]; + }, + rules: { + "semi": "error", + "prefer-const": "warn" + } +}); \ No newline at end of file diff --git a/install/config/docker-compose.yml b/install/config/docker-compose.yml index ca2890b5..90349b7a 100644 --- a/install/config/docker-compose.yml +++ b/install/config/docker-compose.yml @@ -35,7 +35,7 @@ services: - 80:80 # Port for traefik because of the network_mode {{end}} traefik: - image: traefik:v3.4.0 + image: traefik:v3.4.1 container_name: traefik restart: unless-stopped {{if .InstallGerbil}} @@ -58,4 +58,4 @@ services: networks: default: driver: bridge - name: pangolin \ No newline at end of file + name: pangolin diff --git a/package-lock.json b/package-lock.json index f8326188..2a20d115 100644 --- a/package-lock.json +++ b/package-lock.json @@ -105,7 +105,7 @@ "@types/jsonwebtoken": "^9.0.9", "@types/node": "^22", "@types/nodemailer": "6.4.17", - "@types/react": "19.1.6", + "@types/react": "19.1.7", "@types/react-dom": "19.1.6", "@types/semver": "7.7.0", "@types/swagger-ui-express": "^4.1.8", @@ -120,6 +120,7 @@ "tsc-alias": "1.8.16", "tsx": "4.19.4", "typescript": "^5", + "typescript-eslint": "^8.34.0", "yargs": "18.0.0" } }, @@ -3006,9 +3007,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz", - "integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==", + "version": "19.1.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.7.tgz", + "integrity": "sha512-BnsPLV43ddr05N71gaGzyZ5hzkCmGwhMvYc8zmvI8Ci1bRkkDSzDDVfAXfN2tk748OwI7ediiPX6PfT9p0QGVg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3100,16 +3101,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", - "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.0.tgz", + "integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==", "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/type-utils": "8.33.1", - "@typescript-eslint/utils": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.34.0", + "@typescript-eslint/type-utils": "8.34.0", + "@typescript-eslint/utils": "8.34.0", + "@typescript-eslint/visitor-keys": "8.34.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -3123,7 +3124,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.33.1", + "@typescript-eslint/parser": "^8.34.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -3138,15 +3139,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", - "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.0.tgz", + "integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==", "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/scope-manager": "8.34.0", + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/typescript-estree": "8.34.0", + "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4" }, "engines": { @@ -3162,13 +3163,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", - "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.0.tgz", + "integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==", "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.33.1", - "@typescript-eslint/types": "^8.33.1", + "@typescript-eslint/tsconfig-utils": "^8.34.0", + "@typescript-eslint/types": "^8.34.0", "debug": "^4.3.4" }, "engines": { @@ -3183,13 +3184,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.0.tgz", + "integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/visitor-keys": "8.34.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3200,9 +3201,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", - "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz", + "integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3216,13 +3217,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", - "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.0.tgz", + "integrity": "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==", "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.33.1", - "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/typescript-estree": "8.34.0", + "@typescript-eslint/utils": "8.34.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -3239,9 +3240,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.0.tgz", + "integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3252,15 +3253,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.0.tgz", + "integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==", "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", + "@typescript-eslint/project-service": "8.34.0", + "@typescript-eslint/tsconfig-utils": "8.34.0", + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3332,15 +3333,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", - "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.0.tgz", + "integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/typescript-estree": "8.33.1" + "@typescript-eslint/scope-manager": "8.34.0", + "@typescript-eslint/types": "8.34.0", + "@typescript-eslint/typescript-estree": "8.34.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3355,12 +3356,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.0.tgz", + "integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/types": "8.34.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -13517,6 +13518,29 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.34.0.tgz", + "integrity": "sha512-MRpfN7uYjTrTGigFCt8sRyNqJFhjN0WwZecldaqhWm+wy0gaRt8Edb/3cuUy0zdq2opJWT6iXINKAtewnDOltQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.34.0", + "@typescript-eslint/parser": "8.34.0", + "@typescript-eslint/utils": "8.34.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 <5.9.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", diff --git a/package.json b/package.json index 714984e4..040a5453 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "@types/jsonwebtoken": "^9.0.9", "@types/node": "^22", "@types/nodemailer": "6.4.17", - "@types/react": "19.1.6", + "@types/react": "19.1.7", "@types/react-dom": "19.1.6", "@types/semver": "7.7.0", "@types/swagger-ui-express": "^4.1.8", @@ -137,6 +137,7 @@ "tsc-alias": "1.8.16", "tsx": "4.19.4", "typescript": "^5", + "typescript-eslint": "^8.34.0", "yargs": "18.0.0" }, "overrides": { diff --git a/server/lib/stoi.ts b/server/lib/stoi.ts index 8fa42b54..ebc789e6 100644 --- a/server/lib/stoi.ts +++ b/server/lib/stoi.ts @@ -1,6 +1,6 @@ export default function stoi(val: any) { if (typeof val === "string") { - return parseInt(val) + return parseInt(val); } else { return val; diff --git a/server/routers/auth/logout.ts b/server/routers/auth/logout.ts index db95c2e6..b9a1431a 100644 --- a/server/routers/auth/logout.ts +++ b/server/routers/auth/logout.ts @@ -34,7 +34,7 @@ export async function logout( try { await invalidateSession(session.sessionId); } catch (error) { - logger.error("Failed to invalidate session", error) + logger.error("Failed to invalidate session", error); } const isSecure = req.protocol === "https"; diff --git a/server/setup/scriptsSqlite/1.0.0-beta6.ts b/server/setup/scriptsSqlite/1.0.0-beta6.ts index 4fcfb114..8fbb1387 100644 --- a/server/setup/scriptsSqlite/1.0.0-beta6.ts +++ b/server/setup/scriptsSqlite/1.0.0-beta6.ts @@ -44,8 +44,8 @@ export default async function migration() { const updatedYaml = yaml.dump(rawConfig); fs.writeFileSync(filePath, updatedYaml, "utf8"); } catch (error) { - console.log("We were unable to add CORS to your config file. Please add it manually.") - console.error(error) + console.log("We were unable to add CORS to your config file. Please add it manually."); + console.error(error); } console.log("Done."); diff --git a/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx b/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx index 5619911b..e951971e 100644 --- a/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx +++ b/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx @@ -160,7 +160,7 @@ export default function GeneralPage() { href="https://docs.fossorial.io/Newt/overview#docker-socket-integration" target="_blank" rel="noopener noreferrer" - className="underline" + className="text-primary hover:underline inline-flex items-center" > {" "} diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx index ef6e4355..44c1b5b5 100644 --- a/src/components/ui/avatar.tsx +++ b/src/components/ui/avatar.tsx @@ -1,9 +1,9 @@ -"use client" +"use client"; -import * as React from "react" -import * as AvatarPrimitive from "@radix-ui/react-avatar" +import * as React from "react"; +import * as AvatarPrimitive from "@radix-ui/react-avatar"; -import { cn } from "@app/lib/cn" +import { cn } from "@app/lib/cn"; const Avatar = React.forwardRef< React.ElementRef, @@ -17,8 +17,8 @@ const Avatar = React.forwardRef< )} {...props} /> -)) -Avatar.displayName = AvatarPrimitive.Root.displayName +)); +Avatar.displayName = AvatarPrimitive.Root.displayName; const AvatarImage = React.forwardRef< React.ElementRef, @@ -29,8 +29,8 @@ const AvatarImage = React.forwardRef< className={cn("aspect-square h-full w-full", className)} {...props} /> -)) -AvatarImage.displayName = AvatarPrimitive.Image.displayName +)); +AvatarImage.displayName = AvatarPrimitive.Image.displayName; const AvatarFallback = React.forwardRef< React.ElementRef, @@ -44,7 +44,7 @@ const AvatarFallback = React.forwardRef< )} {...props} /> -)) -AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName +)); +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; -export { Avatar, AvatarImage, AvatarFallback } +export { Avatar, AvatarImage, AvatarFallback }; diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx index dd40aa55..98c13818 100644 --- a/src/components/ui/breadcrumb.tsx +++ b/src/components/ui/breadcrumb.tsx @@ -1,16 +1,16 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { ChevronRight, MoreHorizontal } from "lucide-react" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; -import { cn } from "@app/lib/cn" +import { cn } from "@app/lib/cn"; const Breadcrumb = React.forwardRef< HTMLElement, React.ComponentPropsWithoutRef<"nav"> & { separator?: React.ReactNode } ->(({ ...props }, ref) =>