feat: Move to Biome for linting and formatting (#8997)

* init biome

* lint

* format

* unused vars

* more unused vars

* error fixes

* import ordering

* test precommit hook

* add precommit hook

* [autofix.ci] apply automated fixes

* remove prettier and eslint and update gh actions

* pre-commit update

* ✨ (Makefile): add new targets 'biome' and 'biome_check' to run biome check and format on frontend code.

* 🔧 (Makefile): rename 'biome' target to 'format_frontend' for clarity and consistency
🔧 (Makefile): rename 'biome_check' target to 'format_frontend_check' for clarity and consistency

* 📝 (biome.json): Update a11y rule in biome.json to turn off 'noStaticElementInteractions' warning
🔧 (apiModal/code-tabs.tsx): Remove unused 'autologin' variable in APITabsComponent
♻️ (global-variable-modal.tsx): Simplify GeneralGlobalVariableModal component by removing unused props definition

* 📝 (biome.json): Remove 'debug' from allowed console methods to improve code quality
🔧 (index.tsx): Replace console.debug with console.log for better logging consistency
♻️ (index.tsx): Refactor UpdateAllComponents function signature to remove unnecessary empty object parameter

* fix console rules

* 📝 (biome.json): update a11y rule to warn for noStaticElementInteractions to improve accessibility compliance.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
This commit is contained in:
Mike Fortman 2025-07-15 13:46:51 -05:00 • committed by GitHub
commit 0f89e39da1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
680 changed files with 2245 additions and 2684 deletions

View file

@ -37,7 +37,7 @@ jobs:
cd src/frontend
npm ci
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Run Prettier
- name: Run Biome
run: |
cd src/frontend
npm run format

View file

@ -15,7 +15,7 @@ env:
jobs:
run-linters:
name: Run Prettier
name: Run Biome
runs-on: ubuntu-latest
permissions:
contents: write
@ -47,7 +47,7 @@ jobs:
npm install
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Run Prettier
- name: Run Biome
run: |
cd src/frontend
npm run check-format
npx @biomejs/biome check --changed

View file

@ -25,3 +25,11 @@ repos:
language: system
types_or: [python, pyi]
args: [--config, pyproject.toml]
- repo: local
hooks:
- id: local-biome-check
name: biome check
entry: bash -c 'cd src/frontend && npx @biomejs/biome check --write --files-ignore-unknown=true --no-errors-on-unmatched'
language: system
types: [text]
files: "\\.(jsx?|tsx?|c(js|ts)|m(js|ts)|d\\.(ts|cts|mts)|jsonc?)$"

View file

@ -177,6 +177,14 @@ format_backend: ## backend code formatters
format: format_backend format_frontend ## run code formatters
format_frontend: ## run biome check and format on frontend code
@echo 'Running Biome check and format on frontend...'
@cd src/frontend && npx @biomejs/biome check --write
format_frontend_check: ## run biome check without formatting
@echo 'Running Biome check on frontend...'
@cd src/frontend && npx @biomejs/biome check
unsafe_fix:
@uv run ruff check . --fix --unsafe-fixes

View file

13
src/frontend/.biomeignore Normal file
View file

@ -0,0 +1,13 @@
# Build outputs
build/
dist/
# Dependencies
node_modules/
# Test outputs
coverage/
test-results/
playwright-report/
blob-report/
playwright/.cache/

View file

@ -1,47 +0,0 @@
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended"
],
"plugins": ["react", "import-helpers", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.node.json", "./tsconfig.json"],
"extraFileExtensions:": [".mdx"],
"extensions:": [".mdx"]
},
"env": {
"browser": true,
"es2021": true
},
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"no-console": "warn",
"no-self-assign": "warn",
"no-self-compare": "warn",
"complexity": ["error", { "max": 15 }],
"indent": ["error", 2, { "SwitchCase": 1 }],
"no-dupe-keys": "error",
"no-invalid-regexp": "error",
"no-undef": "error",
"no-return-assign": "error",
"no-redeclare": "error",
"no-empty": "error",
"no-await-in-loop": "error",
"react/react-in-jsx-scope": 0,
"node/exports-style": ["error", "module.exports"],
"node/file-extension-in-import": ["error", "always"],
"node/prefer-global/buffer": ["error", "always"],
"node/prefer-global/console": ["error", "always"],
"node/prefer-global/process": ["error", "always"],
"node/prefer-global/url-search-params": ["error", "always"],
"node/prefer-global/url": ["error", "always"],
"node/prefer-promises/dns": "error",
"node/prefer-promises/fs": "error"
}
}

View file

@ -0,0 +1 @@
npm test

View file

@ -1 +0,0 @@
build/*

View file

@ -1,7 +0,0 @@
const config = {
plugins: ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"],
tailwindConfig: "./tailwind.config.mjs",
organizeImportsSkipDestructiveCodeActions: true,
};
export default config;

90
src/frontend/biome.json Normal file
View file

@ -0,0 +1,90 @@
{
"$schema": "https://biomejs.dev/schemas/2.1.1/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true,
"defaultBranch": "main"
},
"files": { "ignoreUnknown": false },
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
"linter": {
"domains": {
"test": "recommended"
},
"enabled": true,
"rules": {
"recommended": false,
"a11y": { "noStaticElementInteractions": "warn" },
"complexity": {
"noAdjacentSpacesInRegex": "error",
"noExtraBooleanCast": "error",
"noUselessEscapeInRegex": "error"
},
"correctness": {
"noConstAssign": "error",
"noConstantCondition": "error",
"noEmptyCharacterClassInRegex": "error",
"noEmptyPattern": "warn",
"noGlobalObjectCalls": "error",
"noInvalidBuiltinInstantiation": "error",
"noInvalidConstructorSuper": "error",
"noNonoctalDecimalEscape": "error",
"noPrecisionLoss": "error",
"noSelfAssign": "warn",
"noSetterReturn": "error",
"noSwitchDeclarations": "error",
"noUnreachable": "error",
"noUnreachableSuper": "error",
"noUnsafeFinally": "error",
"noUnusedLabels": "error",
"noUnusedPrivateClassMembers": "error",
"noUnusedVariables": "warn",
"useExhaustiveDependencies": "off",
"useIsNan": "error",
"useValidForDirection": "error",
"useValidTypeof": "error",
"useYield": "error"
},
"suspicious": {
"noAssignInExpressions": "error",
"noAsyncPromiseExecutor": "warn",
"noCatchAssign": "error",
"noClassAssign": "error",
"noCompareNegZero": "error",
"noConsole": {
"level": "warn",
"options": {
"allow": ["error", "warn"]
}
},
"noControlCharactersInRegex": "error",
"noDebugger": "error",
"noDuplicateCase": "error",
"noDuplicateClassMembers": "error",
"noDuplicateElseIf": "error",
"noDuplicateObjectKeys": "error",
"noDuplicateParameters": "error",
"noFallthroughSwitchClause": "error",
"noFunctionAssign": "error",
"noGlobalAssign": "error",
"noImportAssign": "error",
"noIrregularWhitespace": "error",
"noMisleadingCharacterClass": "error",
"noPrototypeBuiltins": "error",
"noRedeclare": "error",
"noSelfCompare": "warn",
"noShadowRestrictedNames": "error",
"noSparseArray": "error",
"noUnsafeNegation": "error",
"noWith": "error",
"useGetterReturn": "error"
}
}
},
"javascript": { "formatter": { "quoteStyle": "double" } },
"assist": {
"enabled": true,
"actions": { "source": { "organizeImports": "on" } }
}
}

File diff suppressed because it is too large Load diff

View file

@ -96,16 +96,10 @@
"test": "jest",
"test:watch": "jest --watch",
"serve": "vite preview",
"format": "npx prettier --write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore",
"check-format": "npx prettier --check \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore",
"format": "npx @biomejs/biome check --write",
"check-format": "npx @biomejs/biome check",
"type-check": "tsc --noEmit --pretty --project tsconfig.json && vite"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
@ -120,6 +114,7 @@
},
"proxy": "http://localhost:7860",
"devDependencies": {
"@biomejs/biome": "2.1.1",
"@jest/types": "^30.0.1",
"@playwright/test": "^1.52.0",
"@swc/cli": "^0.5.2",
@ -137,15 +132,10 @@
"@types/uuid": "^9.0.8",
"@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19",
"eslint": "^9.5.0",
"jest": "^30.0.3",
"jest-environment-jsdom": "^30.0.2",
"jest-junit": "^16.0.0",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^3.2.4",
"prettier-plugin-tailwindcss": "^0.6.5",
"simple-git-hooks": "^2.11.1",
"tailwindcss": "^3.4.4",
"tailwindcss-dotted-background": "^1.1.0",
"ts-jest": "^29.4.0",

View file

@ -2,6 +2,7 @@ import { defineConfig, devices } from "@playwright/test";
import * as dotenv from "dotenv";
import path from "path";
import { PORT } from "./src/customization/config-constants";
dotenv.config();
dotenv.config({ path: path.resolve(__dirname, "../../.env") });

View file

@ -112,12 +112,7 @@ body {
}
.custom-hover:hover {
background-color: rgba(
99,
102,
241,
0.1
); /* Medium indigo color with 20% opacity */
background-color: rgba(99, 102, 241, 0.1); /* Medium indigo color with 20% opacity */
}
/* This CSS is to not apply the border for the column having 'no-border' class */

View file

@ -1,6 +1,11 @@
import {
BaseEdge,
type EdgeProps,
getBezierPath,
Position,
} from "@xyflow/react";
import useFlowStore from "@/stores/flowStore";
import { scapeJSONParse } from "@/utils/reactflowUtils";
import { BaseEdge, EdgeProps, getBezierPath, Position } from "@xyflow/react";
export function DefaultEdge({
sourceHandleId,
@ -56,16 +61,7 @@ export function DefaultEdge({
targetY: targetYNew,
});
const {
animated,
selectable,
deletable,
sourcePosition,
targetPosition,
pathOptions,
selected,
...domSafeProps
} = props;
const { animated, selectable, deletable, selected, ...domSafeProps } = props;
return (
<BaseEdge

View file

@ -1,5 +1,5 @@
import { Button } from "@/components/ui/button";
import { useState } from "react";
import { Button } from "@/components/ui/button";
interface ComboBoxItemProps {
item: any;

View file

@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import { Button } from "@/components/ui/button";
import { cn } from "@/utils/utils";
import { useEffect, useRef, useState } from "react";
const ListItem = ({
item,

View file

@ -1,12 +1,12 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ForwardedIconComponent from "@/components/common/genericIconComponent";
import SearchBarComponent from "@/components/core/parameterRenderComponent/components/searchBarComponent";
import { InputProps } from "@/components/core/parameterRenderComponent/types";
import type { InputProps } from "@/components/core/parameterRenderComponent/types";
import { Button } from "@/components/ui/button";
import { DialogFooter, DialogHeader } from "@/components/ui/dialog";
import { Dialog, DialogContent } from "@/components/ui/dialog-with-no-close";
import { Input } from "@/components/ui/input";
import { cn, testIdCase } from "@/utils/utils";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ListItem from "./ListItem";
// Update interface with better types

View file

@ -1,10 +1,10 @@
import { Textarea } from "@/components/ui/textarea";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import useFlowStore from "@/stores/flowStore";
import { handleKeyDown } from "@/utils/reactflowUtils";
import { cn } from "@/utils/utils";
import { memo, useEffect, useMemo, useRef, useState } from "react";
import Markdown from "react-markdown";
import { Textarea } from "@/components/ui/textarea";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { handleKeyDown } from "@/utils/reactflowUtils";
import { cn } from "@/utils/utils";
export default function NodeDescription({
description,

Some files were not shown because too many files have changed in this diff Show more