diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index ebf28d8091..0000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,51 +0,0 @@ -module.exports = { - /** - * https://prettier.io/docs/en/options.html#semicolons - */ - semi: true, - - /** - * https://prettier.io/docs/en/options.html#trailing-commas - */ - trailingComma: 'all', - - /** - * https://prettier.io/docs/en/options.html#bracket-spacing - */ - bracketSpacing: true, - - /** - * https://prettier.io/docs/en/options.html#tabs - */ - useTabs: true, - - /** - * https://prettier.io/docs/en/options.html#tab-width - */ - tabWidth: 2, - - /** - * https://prettier.io/docs/en/options.html#arrow-function-parentheses - */ - arrowParens: 'always', - - /** - * https://prettier.io/docs/en/options.html#quotes - */ - singleQuote: true, - - /** - * https://prettier.io/docs/en/options.html#quote-props - */ - quoteProps: 'as-needed', - - /** - * https://prettier.io/docs/en/options.html#end-of-line - */ - endOfLine: 'lf', - - /** - * https://prettier.io/docs/en/options.html#print-width - */ - printWidth: 100, -}; diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0c5abcba47..0eb9d1cc05 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,7 +5,6 @@ "dangmai.workspace-default-settings", "dbaeumer.vscode-eslint", "EditorConfig.EditorConfig", - "esbenp.prettier-vscode", "mjmlio.vscode-mjml", "Vue.volar", "vitest.explorer" diff --git a/.vscode/settings.default.json b/.vscode/settings.default.json index 99c514f741..530d8e09ff 100644 --- a/.vscode/settings.default.json +++ b/.vscode/settings.default.json @@ -1,5 +1,5 @@ { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "biomejs.biome", "editor.formatOnSave": true, "[javascript]": { "editor.defaultFormatter": "biomejs.biome" @@ -25,7 +25,6 @@ "typescript.format.enable": false, "typescript.tsdk": "node_modules/typescript/lib", "workspace-default-settings.runOnActivation": true, - "prettier.prettierPath": "node_modules/prettier/index.cjs", "eslint.probe": ["javascript", "typescript", "vue"], "eslint.workingDirectories": [ { diff --git a/biome.jsonc b/biome.jsonc index d11acefc5a..e040f0ab4f 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -6,6 +6,16 @@ "useIgnoreFile": true }, "files": { + "include": [ + "**/*.js", + "**/*.ts", + "**/*.json", + "**/*.vue", + "**/*.yml", + "**/*.md", + "**/*.css", + "**/*.scss" + ], "ignore": [ "**/.turbo", "**/coverage", @@ -22,11 +32,7 @@ "indentWidth": 2, "lineEnding": "lf", "lineWidth": 100, - "attributePosition": "auto", - "ignore": [ - // Handled by prettier - "**/*.vue" - ] + "attributePosition": "auto" }, "organizeImports": { "enabled": false }, "linter": { diff --git a/lefthook.yml b/lefthook.yml index aa17417824..5f3487a7e0 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -1,16 +1,9 @@ pre-commit: commands: biome_check: - glob: 'packages/**/*.{js,ts,json}' + glob: 'packages/**/*.{js,ts,json,vue,yml,md,css,scss}' run: ./node_modules/.bin/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} stage_fixed: true skip: - merge - rebase - prettier_check: - glob: 'packages/**/*.{vue,yml,md,css,scss}' - run: ./node_modules/.bin/prettier --write --ignore-unknown --no-error-on-unmatched-pattern {staged_files} - stage_fixed: true - skip: - - merge - - rebase diff --git a/package.json b/package.json index 9002c8dd4e..fb83851e3a 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "worker": "./packages/cli/bin/n8n worker" }, "devDependencies": { - "@biomejs/biome": "^1.9.0", + "@biomejs/biome": "^1.9.4", "@n8n_io/eslint-config": "workspace:*", "@types/jest": "^29.5.3", "@types/node": "*", diff --git a/packages/@n8n/chat/package.json b/packages/@n8n/chat/package.json index 1db1c50f9a..e67e090fbe 100644 --- a/packages/@n8n/chat/package.json +++ b/packages/@n8n/chat/package.json @@ -12,8 +12,8 @@ "typecheck": "vue-tsc --noEmit", "lint": "eslint . --ext .js,.ts,.vue --quiet", "lintfix": "eslint . --ext .js,.ts,.vue --fix", - "format": "biome format --write src .storybook && prettier --write src/ --ignore-path ../../.prettierignore", - "format:check": "biome ci src .storybook && prettier --check src/ --ignore-path ../../.prettierignore", + "format": "biome format --write src .storybook", + "format:check": "biome ci src .storybook", "storybook": "storybook dev -p 6006 --no-open", "build:storybook": "storybook build" }, diff --git a/packages/@n8n_io/eslint-config/base.js b/packages/@n8n_io/eslint-config/base.js index 0864a20a7b..0e447f2aca 100644 --- a/packages/@n8n_io/eslint-config/base.js +++ b/packages/@n8n_io/eslint-config/base.js @@ -62,11 +62,11 @@ const config = (module.exports = { 'eslint-config-airbnb-typescript/base', /** - * Config to disable ESLint rules covered by Prettier + * Config to disable ESLint rules covered by Biome * - * https://github.com/prettier/eslint-config-prettier + * https://github.com/ftzi/eslint-config-biome */ - 'eslint-config-prettier', + 'eslint-config-biome', ], rules: { @@ -105,7 +105,7 @@ const config = (module.exports = { /** * https://eslint.org/docs/latest/rules/indent * - * Delegated to Prettier. + * Delegated to Biome. */ indent: 'off', diff --git a/packages/@n8n_io/eslint-config/package.json b/packages/@n8n_io/eslint-config/package.json index aac4ea2e32..91c2c54ad4 100644 --- a/packages/@n8n_io/eslint-config/package.json +++ b/packages/@n8n_io/eslint-config/package.json @@ -9,7 +9,7 @@ "@vue/eslint-config-typescript": "^13.0.0", "eslint": "^8.57.0", "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-config-prettier": "^9.1.0", + "eslint-config-biome": "^1.9.4", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-lodash": "^7.4.0", diff --git a/packages/design-system/package.json b/packages/design-system/package.json index d35d701825..4744845e03 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -13,8 +13,8 @@ "build:storybook": "storybook build", "storybook": "storybook dev -p 6006 --no-open", "chromatic": "chromatic", - "format": "biome format --write . && prettier --write . --ignore-path ../../.prettierignore", - "format:check": "biome ci . && prettier --check . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint src --ext .js,.ts,.vue --quiet", "lintfix": "eslint src --ext .js,.ts,.vue --fix" }, diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index 97a7660293..4fd919d775 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -11,8 +11,8 @@ "dev": "pnpm serve", "lint": "eslint src --ext .js,.ts,.vue --quiet", "lintfix": "eslint src --ext .js,.ts,.vue --fix", - "format": "biome format --write . && prettier --write . --ignore-path ../../.prettierignore", - "format:check": "biome ci . && prettier --check . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "serve": "cross-env VUE_APP_URL_BASE_API=http://localhost:5678/ vite --host 0.0.0.0 --port 8080 dev", "test": "vitest run", "test:dev": "vitest --silent=false" diff --git a/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts b/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts index e08f4f05c4..7b6d1587c6 100644 --- a/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts +++ b/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts @@ -158,11 +158,15 @@ describe('tmpl Expression Parser', () => { }); test('Multiple optional chains in an expression', () => { - expect(extendTransform('$json.test?.test2($json.test?.test2)')?.code).toBe(`window.chainCancelToken2 = ((window.chainValue2 = $json.test) ?? undefined) === undefined, window.chainCancelToken2 === true ? undefined : window.chainValue2.test2( + expect( + extendTransform('$json.test?.test2($json.test?.test2)')?.code, + ).toBe(`window.chainCancelToken2 = ((window.chainValue2 = $json.test) ?? undefined) === undefined, window.chainCancelToken2 === true ? undefined : window.chainValue2.test2( (window.chainCancelToken1 = ((window.chainValue1 = $json.test) ?? undefined) === undefined, window.chainCancelToken1 === true ? undefined : window.chainValue1.test2) );`); - expect(extendTransform('$json.test?.test2($json.test.sum?.())')?.code).toBe(`window.chainCancelToken2 = ((window.chainValue2 = $json.test) ?? undefined) === undefined, window.chainCancelToken2 === true ? undefined : window.chainValue2.test2( + expect( + extendTransform('$json.test?.test2($json.test.sum?.())')?.code, + ).toBe(`window.chainCancelToken2 = ((window.chainValue2 = $json.test) ?? undefined) === undefined, window.chainCancelToken2 === true ? undefined : window.chainValue2.test2( (window.chainCancelToken1 = ((window.chainValue1 = extendOptional($json.test, "sum")) ?? undefined) === undefined, window.chainCancelToken1 === true ? undefined : window.chainValue1()) );`); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 679b1155d2..38c416fec2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -145,8 +145,8 @@ importers: .: devDependencies: '@biomejs/biome': - specifier: ^1.9.0 - version: 1.9.0 + specifier: ^1.9.4 + version: 1.9.4 '@n8n_io/eslint-config': specifier: workspace:* version: link:packages/@n8n_io/eslint-config @@ -730,9 +730,9 @@ importers: eslint-config-airbnb-typescript: specifier: ^18.0.0 version: 18.0.0(@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.7.2))(eslint@8.57.0)(typescript@5.7.2))(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.7.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.0(eslint@8.57.0) + eslint-config-biome: + specifier: ^1.9.4 + version: 1.9.4 eslint-import-resolver-typescript: specifier: ^3.6.1 version: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.7.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0) @@ -3054,55 +3054,55 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@biomejs/biome@1.9.0': - resolution: {integrity: sha512-NlWh2F1wbxB3O/wE+aohGL0BziTS6e+6+dyFvpdeqLsbQZY7EsiklFb9W5Xs41U4vEmY7ANgdNp+oVDij6sQdA==} + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@1.9.0': - resolution: {integrity: sha512-2w9v/NRtYSmodx5QWQ49OGcyGKSECdWKbzc7n532Iq5sBhkKk996fd19icT6BuL54f01KFKRCRibAW+A2rg1Kw==} + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@1.9.0': - resolution: {integrity: sha512-fBVt8jJQi0zX0SJ1C+tdzUbRpuX/07sgtBXEhunWRkPjdi6W/2S1sYHQ1wKn4OKiRAKfHM2Cf2FNO7hQvY61dA==} + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@1.9.0': - resolution: {integrity: sha512-Jy84mZ4vcppdmWMgQWOCfd8qIVC/vHmlaS5gy7GXkdWlBKSQ56YxEXTU58MHTbZ16LwJQpK2IulqRCC/rqWLBA==} + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@1.9.0': - resolution: {integrity: sha512-l8U2lcqsl9yKPP5WUdIrKH//C1pWyM2cSUfcTBn6GSvXmsSjBNEdGSdM4Wfne777Oe/9ONaD1Ga53U2HksHHLw==} + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@1.9.0': - resolution: {integrity: sha512-N3enoFoIrkB6qJWyYfTiYmFdB1R/Mrij1dd1xBHqxxCKZY9GRkEswRX3F1Uqzo5T+9Iu8nAQobDqI/ygicYy/Q==} + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@1.9.0': - resolution: {integrity: sha512-8jAzjrrJTj510pwq4aVs7ZKkOvEy1D+nzl9DKvrPh4TOyUw5Ie+0EDwXGE2RAkCKHkGNOQBZ78WtIdsATgz5sA==} + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@1.9.0': - resolution: {integrity: sha512-AIjwJTGfdWGMRluSQ9pDB29nzce077dfHh0/HMqzztKzgD3spyuo2R9VoaFpbR0hLHPWEH6g6OxxDO7hfkXNkQ==} + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@1.9.0': - resolution: {integrity: sha512-4/4wTjNSoyNkm1SzcUaStDx46baX1VJRXtUoeEHjX9LfedR5N3qwZz5KfrRUnCd2fl5bmXK1CwMqKBkoF6zEiA==} + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -7947,11 +7947,8 @@ packages: '@typescript-eslint/parser': ^7.0.0 eslint: ^8.56.0 - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' + eslint-config-biome@1.9.4: + resolution: {integrity: sha512-4HX+rfUk1R2rPwN3hcxPxq5sLDLGb/xtu48AggTtxCVoRoD18kjwOwHA1c7gYsbRrEQso+9mlRSS9+G7OfDqFg==} eslint-config-riot@1.0.0: resolution: {integrity: sha512-NB/L/1Y30qyJcG5xZxCJKW/+bqyj+llbcCwo9DEz8bESIP0SLTOQ8T1DWCCFc+wJ61AMEstj4511PSScqMMfCw==} @@ -15394,39 +15391,39 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@biomejs/biome@1.9.0': + '@biomejs/biome@1.9.4': optionalDependencies: - '@biomejs/cli-darwin-arm64': 1.9.0 - '@biomejs/cli-darwin-x64': 1.9.0 - '@biomejs/cli-linux-arm64': 1.9.0 - '@biomejs/cli-linux-arm64-musl': 1.9.0 - '@biomejs/cli-linux-x64': 1.9.0 - '@biomejs/cli-linux-x64-musl': 1.9.0 - '@biomejs/cli-win32-arm64': 1.9.0 - '@biomejs/cli-win32-x64': 1.9.0 + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 - '@biomejs/cli-darwin-arm64@1.9.0': + '@biomejs/cli-darwin-arm64@1.9.4': optional: true - '@biomejs/cli-darwin-x64@1.9.0': + '@biomejs/cli-darwin-x64@1.9.4': optional: true - '@biomejs/cli-linux-arm64-musl@1.9.0': + '@biomejs/cli-linux-arm64-musl@1.9.4': optional: true - '@biomejs/cli-linux-arm64@1.9.0': + '@biomejs/cli-linux-arm64@1.9.4': optional: true - '@biomejs/cli-linux-x64-musl@1.9.0': + '@biomejs/cli-linux-x64-musl@1.9.4': optional: true - '@biomejs/cli-linux-x64@1.9.0': + '@biomejs/cli-linux-x64@1.9.4': optional: true - '@biomejs/cli-win32-arm64@1.9.0': + '@biomejs/cli-win32-arm64@1.9.4': optional: true - '@biomejs/cli-win32-x64@1.9.0': + '@biomejs/cli-win32-x64@1.9.4': optional: true '@cfaester/enzyme-adapter-react-18@0.8.0(enzyme@3.11.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': @@ -21276,9 +21273,7 @@ snapshots: transitivePeerDependencies: - eslint-plugin-import - eslint-config-prettier@9.1.0(eslint@8.57.0): - dependencies: - eslint: 8.57.0 + eslint-config-biome@1.9.4: {} eslint-config-riot@1.0.0: {} diff --git a/scripts/format.mjs b/scripts/format.mjs index 69bbfce015..9aea0a137e 100644 --- a/scripts/format.mjs +++ b/scripts/format.mjs @@ -4,10 +4,9 @@ import fs from 'fs'; import path from 'path'; import { execSync } from 'child_process'; -const prettier = path.resolve('node_modules', '.bin', 'prettier'); const biome = path.resolve('node_modules', '.bin', 'biome'); -[prettier, biome].forEach((bin) => { +[biome].forEach((bin) => { if (!fs.existsSync(bin)) { throw new Error( [`${path.basename(bin)} not found at path: ${bin}`, 'Please run `pnpm i` first'].join('\n'), @@ -15,28 +14,21 @@ const biome = path.resolve('node_modules', '.bin', 'biome'); } }); -const prettierConfig = path.resolve('.prettierrc.js'); const biomeConfig = path.resolve('biome.jsonc'); -const ignore = path.resolve('.prettierignore'); const ROOT_DIRS_TO_SKIP = ['.git', 'node_modules', 'packages', '.turbo', 'cypress']; -const EXTENSIONS_TO_FORMAT_WITH_PRETTIER = ['.yml']; -const EXTENSIONS_TO_FORMAT_WITH_BIOME = ['.js', '.json', '.ts']; +const EXTENSIONS_TO_FORMAT_WITH_BIOME = ['.js', '.json', '.ts', '.yml', '.vue', '.css', '.scss', '.md']; const isDir = (path) => fs.lstatSync(path).isDirectory(); -const isPrettierTarget = (path) => - EXTENSIONS_TO_FORMAT_WITH_PRETTIER.some((ext) => path.endsWith(ext)); const isBiomeTarget = (path) => EXTENSIONS_TO_FORMAT_WITH_BIOME.some((ext) => path.endsWith(ext)); const biomeTargets = []; -const prettierTargets = []; const walk = (dir) => { fs.readdirSync(dir).forEach((entry) => { const entryPath = path.resolve(dir, entry); if (isDir(entryPath)) walk(entryPath); - if (isPrettierTarget(entryPath)) prettierTargets.push(entryPath); if (isBiomeTarget(entryPath)) biomeTargets.push(entryPath); }); }; @@ -44,22 +36,9 @@ const walk = (dir) => { fs.readdirSync('.').forEach((cur) => { if (ROOT_DIRS_TO_SKIP.includes(cur)) return; if (isDir(cur)) walk(cur); - if (isPrettierTarget(cur)) prettierTargets.push(cur); if (isBiomeTarget(cur)) biomeTargets.push(cur); }); -execSync( - [ - prettier, - '--config', - prettierConfig, - '--ignore-path', - ignore, - '--write', - prettierTargets.join(' '), - ].join(' '), -); - execSync( [biome, 'format', '--write', `--config-path=${biomeConfig}`, biomeTargets.join(' ')].join(' '), );