From 6a35812f9288c13d0a1887fcb7df5d2a16db88e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Tue, 17 Sep 2024 14:10:22 +0200 Subject: [PATCH] ci: Setup biome and pre-commit hooks for formatting (no-changelog) (#10795) Co-authored-by: Tomi Turtiainen <10324676+tomi@users.noreply.github.com> --- .github/workflows/ci-pull-requests.yml | 3 + .prettierignore | 8 + .vscode/extensions.json | 1 + .vscode/settings.default.json | 16 ++ biome.jsonc | 48 ++++ cypress/biome.jsonc | 7 + cypress/e2e/24-ndv-paired-item.cy.ts | 3 +- cypress/e2e/6-code-node.cy.ts | 8 +- cypress/package.json | 3 +- lefthook.yml | 10 + n8n.code-workspace | 6 +- package.json | 4 + packages/@n8n/api-types/package.json | 3 +- packages/@n8n/benchmark/biome.jsonc | 7 + packages/@n8n/benchmark/package.json | 2 + packages/@n8n/chat/package.json | 3 +- packages/@n8n/chat/src/css/markdown.scss | 70 ++--- packages/@n8n/client-oauth2/package.json | 3 +- packages/@n8n/codemirror-lang/.eslintrc.cjs | 4 +- packages/@n8n/codemirror-lang/package.json | 3 +- packages/@n8n/config/package.json | 3 +- packages/@n8n/imap/package.json | 3 +- packages/@n8n/nodes-langchain/.prettierrc.js | 51 ---- .../nodes-langchain/.vscode/extensions.json | 6 +- packages/@n8n/nodes-langchain/package.json | 3 +- packages/@n8n/permissions/package.json | 3 +- packages/@n8n_io/eslint-config/base.js | 28 -- packages/@n8n_io/eslint-config/package.json | 1 - packages/@n8n_io/eslint-config/shared.js | 2 +- packages/cli/package.json | 3 +- packages/cli/src/config/types.ts | 11 +- .../cli/src/controllers/e2e.controller.ts | 17 +- .../src/databases/entities/auth-identity.ts | 5 +- .../1674138566000-AddStatusToExecutions.ts | 4 +- packages/cli/src/events/event-relay.ts | 8 +- .../to-save-settings.ts | 4 +- .../external-secrets-manager.ee.ts | 2 +- packages/cli/src/license.ts | 2 +- .../orchestration/main/multi-main-setup.ee.ts | 9 +- packages/core/package.json | 3 +- packages/core/src/WorkflowExecute.ts | 6 +- packages/design-system/.storybook/preview.js | 2 +- packages/design-system/biome.jsonc | 7 + packages/design-system/chromatic.config.json | 4 +- packages/design-system/package.json | 3 +- .../design-system/src/css/_tokens.dark.scss | 2 +- packages/design-system/src/css/_tokens.scss | 10 +- packages/design-system/tsconfig.json | 7 +- packages/design-system/vite.config.mts | 6 +- packages/editor-ui/biome.jsonc | 8 + packages/editor-ui/package.json | 3 +- .../src/components/CodeNodeEditor/theme.ts | 2 +- .../src/components/Node/NodeCreator/utils.ts | 2 +- .../src/composables/useExpressionEditor.ts | 5 +- .../plugins/connectors/N8nCustomConnector.ts | 6 +- packages/editor-ui/src/plugins/i18n/index.ts | 2 +- packages/editor-ui/src/router.ts | 2 +- .../editor-ui/src/stores/credentials.store.ts | 2 +- packages/editor-ui/src/stores/ndv.store.ts | 2 +- .../src/stores/workflows.ee.store.ts | 2 +- .../editor-ui/src/styles/plugins/index.scss | 4 +- packages/editor-ui/src/types/externalHooks.ts | 6 +- packages/editor-ui/vite.config.mts | 8 +- packages/node-dev/package.json | 3 +- packages/nodes-base/biome.jsonc | 7 + .../nodes/Baserow/GenericFunctions.ts | 2 +- .../nodes/Brevo/GenericFunctions.ts | 12 +- .../nodes/Cortex/AnalyzerInterface.ts | 26 +- .../nodes/Google/Chat/MessageInterface.ts | 6 +- .../Google/Sheet/v2/helpers/GoogleSheet.ts | 3 +- .../Google/Sheet/v2/methods/listSearch.ts | 1 - .../KoBoToolbox/KoBoToolboxTrigger.node.ts | 7 +- .../nodes/Notion/shared/GenericFunctions.ts | 15 +- .../nodes/Postgres/v1/genericFunctions.ts | 12 +- .../nodes/QuickBase/GenericFunctions.ts | 7 +- .../nodes/Telegram/GenericFunctions.ts | 7 +- .../TheHive/interfaces/ObservableInterface.ts | 26 +- packages/nodes-base/package.json | 3 +- packages/workflow/package.json | 3 +- .../ExpressionExtension.test.ts | 6 +- packages/workflow/test/RoutingNode.test.ts | 2 +- .../WorkflowDataProxy/pindata_workflow.json | 199 ++++++------- pnpm-lock.yaml | 270 +++++++++++++----- scripts/format.mjs | 67 +++-- turbo.json | 1 + 85 files changed, 701 insertions(+), 465 deletions(-) create mode 100644 biome.jsonc create mode 100644 cypress/biome.jsonc create mode 100644 lefthook.yml create mode 100644 packages/@n8n/benchmark/biome.jsonc delete mode 100644 packages/@n8n/nodes-langchain/.prettierrc.js create mode 100644 packages/design-system/biome.jsonc create mode 100644 packages/editor-ui/biome.jsonc create mode 100644 packages/nodes-base/biome.jsonc diff --git a/.github/workflows/ci-pull-requests.yml b/.github/workflows/ci-pull-requests.yml index d9938983b1..48a34c5eab 100644 --- a/.github/workflows/ci-pull-requests.yml +++ b/.github/workflows/ci-pull-requests.yml @@ -30,6 +30,9 @@ jobs: - name: Build run: pnpm build + - name: Run formatcheck + run: pnpm format:check + - name: Run typecheck run: pnpm typecheck diff --git a/.prettierignore b/.prettierignore index 4ac8f0dafb..2f5967e399 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,3 +7,11 @@ packages/nodes-base/nodes/**/test packages/cli/templates/form-trigger.handlebars cypress/fixtures CHANGELOG.md +.github/pull_request_template.md +# Ignored for now +**/*.md +# Handled by biome +**/*.ts +**/*.js +**/*.json +**/*.jsonc diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 158d03fdc8..681de6c024 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,6 @@ { "recommendations": [ + "biomejs.biome", "streetsidesoftware.code-spell-checker", "dangmai.workspace-default-settings", "dbaeumer.vscode-eslint", diff --git a/.vscode/settings.default.json b/.vscode/settings.default.json index 87db2ca2ee..99c514f741 100644 --- a/.vscode/settings.default.json +++ b/.vscode/settings.default.json @@ -1,6 +1,22 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.organizeImports.biome": "never" + }, "search.exclude": { "node_modules": true, "dist": true, diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000000..356c964cd9 --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,48 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "vcs": { + "clientKind": "git", + "enabled": true, + "useIgnoreFile": true + }, + "files": { + "ignore": [ + "**/.turbo", + "**/coverage", + "**/dist", + "**/package.json", + "**/pnpm-lock.yaml", + "**/CHANGELOG.md" + ] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "tab", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 100, + "attributePosition": "auto", + "ignore": [ + // Handled by prettier + "**/*.vue" + ] + }, + "organizeImports": { "enabled": false }, + "linter": { + "enabled": false + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto" + } + } +} diff --git a/cypress/biome.jsonc b/cypress/biome.jsonc new file mode 100644 index 0000000000..5a63363ac8 --- /dev/null +++ b/cypress/biome.jsonc @@ -0,0 +1,7 @@ +{ + "$schema": "../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["../biome.jsonc"], + "formatter": { + "ignore": ["fixtures/**"] + } +} diff --git a/cypress/e2e/24-ndv-paired-item.cy.ts b/cypress/e2e/24-ndv-paired-item.cy.ts index 8324144343..1261a0fcd1 100644 --- a/cypress/e2e/24-ndv-paired-item.cy.ts +++ b/cypress/e2e/24-ndv-paired-item.cy.ts @@ -227,7 +227,7 @@ describe('NDV', () => { workflowPage.actions.zoomToFit(); - /* prettier-ignore */ + // biome-ignore format: const PINNED_DATA = [ { "id": "abc", @@ -263,7 +263,6 @@ describe('NDV', () => { ] } ]; - /* prettier-ignore */ workflowPage.actions.openNode('Get thread details1'); ndv.actions.pastePinnedData(PINNED_DATA); ndv.actions.close(); diff --git a/cypress/e2e/6-code-node.cy.ts b/cypress/e2e/6-code-node.cy.ts index 43486590c7..d26e0ded5d 100644 --- a/cypress/e2e/6-code-node.cy.ts +++ b/cypress/e2e/6-code-node.cy.ts @@ -43,7 +43,9 @@ describe('Code node', () => { const getParameter = () => ndv.getters.parameterInput('jsCode').should('be.visible'); const getEditor = () => getParameter().find('.cm-content').should('exist'); - getEditor().type('{selectall}').paste(`$input.itemMatching() + getEditor() + .type('{selectall}') + .paste(`$input.itemMatching() $input.item $('When clicking ‘Test workflow’').item $input.first(1) @@ -68,7 +70,9 @@ return ndv.getters.parameterInput('mode').click(); ndv.actions.selectOptionInParameterDropdown('mode', 'Run Once for Each Item'); - getEditor().type('{selectall}').paste(`$input.itemMatching() + getEditor() + .type('{selectall}') + .paste(`$input.itemMatching() $input.all() $input.first() $input.item() diff --git a/cypress/package.json b/cypress/package.json index 5084e0b10c..509abca04b 100644 --- a/cypress/package.json +++ b/cypress/package.json @@ -7,7 +7,8 @@ "test:e2e:ui": "scripts/run-e2e.js ui", "test:e2e:dev": "scripts/run-e2e.js dev", "test:e2e:all": "scripts/run-e2e.js all", - "format": "prettier --write . --ignore-path ../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "develop": "cd ..; pnpm dev", diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000000..bb58014db9 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,10 @@ +pre-commit: + commands: + biome_check: + glob: 'packages/**/*.{js,ts,json}' + run: ./node_modules/.bin/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} + stage_fixed: true + prettier_check: + glob: 'packages/**/*.{vue,yml,md}' + run: ./node_modules/.bin/prettier --write --ignore-unknown --no-error-on-unmatched-pattern {staged_files} + stage_fixed: true diff --git a/n8n.code-workspace b/n8n.code-workspace index 9d32d7aa04..8f4183e8f0 100644 --- a/n8n.code-workspace +++ b/n8n.code-workspace @@ -1,7 +1,7 @@ { "folders": [ { - "path": ".", - }, - ], + "path": "." + } + ] } diff --git a/package.json b/package.json index 93ec1b5369..733edd2e24 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "packageManager": "pnpm@9.6.0", "scripts": { + "prepare": "lefthook install", "preinstall": "node scripts/block-npm-install.js", "build": "turbo run build", "build:backend": "turbo run build:backend", @@ -19,6 +20,7 @@ "clean": "turbo run clean --parallel", "reset": "node scripts/ensure-zx.mjs && zx scripts/reset.mjs", "format": "turbo run format && node scripts/format.mjs", + "format:check": "turbo run format:check", "lint": "turbo run lint", "lintfix": "turbo run lintfix", "lint:backend": "turbo run lint:backend", @@ -38,6 +40,7 @@ "worker": "./packages/cli/bin/n8n worker" }, "devDependencies": { + "@biomejs/biome": "^1.9.0", "@n8n_io/eslint-config": "workspace:*", "@types/jest": "^29.5.3", "@types/supertest": "^6.0.2", @@ -46,6 +49,7 @@ "jest-expect-message": "^1.1.3", "jest-mock": "^29.6.2", "jest-mock-extended": "^3.0.4", + "lefthook": "^1.7.15", "nock": "^13.3.2", "nodemon": "^3.0.1", "p-limit": "^3.1.0", diff --git a/packages/@n8n/api-types/package.json b/packages/@n8n/api-types/package.json index 2e6d17a2a8..07466a7a71 100644 --- a/packages/@n8n/api-types/package.json +++ b/packages/@n8n/api-types/package.json @@ -6,7 +6,8 @@ "dev": "pnpm watch", "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", - "format": "prettier --write . --ignore-path ../../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint .", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/@n8n/benchmark/biome.jsonc b/packages/@n8n/benchmark/biome.jsonc new file mode 100644 index 0000000000..3db16975c6 --- /dev/null +++ b/packages/@n8n/benchmark/biome.jsonc @@ -0,0 +1,7 @@ +{ + "$schema": "../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["../../../biome.jsonc"], + "files": { + "ignore": ["scripts/mock-api/**"] + } +} diff --git a/packages/@n8n/benchmark/package.json b/packages/@n8n/benchmark/package.json index 67292b07c9..6294391c4c 100644 --- a/packages/@n8n/benchmark/package.json +++ b/packages/@n8n/benchmark/package.json @@ -5,6 +5,8 @@ "main": "dist/index", "scripts": { "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint .", "lintfix": "eslint . --fix", "start": "./bin/n8n-benchmark", diff --git a/packages/@n8n/chat/package.json b/packages/@n8n/chat/package.json index 8a3b5b343c..1d319a743c 100644 --- a/packages/@n8n/chat/package.json +++ b/packages/@n8n/chat/package.json @@ -12,7 +12,8 @@ "typecheck": "vue-tsc --noEmit", "lint": "eslint . --ext .js,.ts,.vue --quiet", "lintfix": "eslint . --ext .js,.ts,.vue --fix", - "format": "prettier --write src/", + "format": "biome format --write src .storybook && prettier --write src/ --ignore-path ../../.prettierignore", + "format:check": "biome ci src .storybook && prettier --check src/ --ignore-path ../../.prettierignore", "storybook": "storybook dev -p 6006 --no-open", "build:storybook": "storybook build" }, diff --git a/packages/@n8n/chat/src/css/markdown.scss b/packages/@n8n/chat/src/css/markdown.scss index f2ea3ea226..6d219bbe02 100644 --- a/packages/@n8n/chat/src/css/markdown.scss +++ b/packages/@n8n/chat/src/css/markdown.scss @@ -2,7 +2,7 @@ // https://github.com/pxlrbt/markdown-css .chat-message-markdown { - /* + /* universalize.css (v1.0.2) — by Alexander Sandberg (https://alexandersandberg.com) ------------------------------------------------------------------------------ @@ -45,8 +45,6 @@ vertical-align: inherit; /* 2 */ } - - /* Remove inconsistent and unnecessary margins */ @@ -63,7 +61,8 @@ button, /* (Safari) 3 lines */ input, select, - textarea { /* (Firefox, Safari) */ + textarea { + /* (Firefox, Safari) */ margin: 0; } @@ -80,11 +79,13 @@ Add correct display */ main, /* (IE11) */ - details { /* (Edge 18-, IE) */ + details { + /* (Edge 18-, IE) */ display: block; } - summary { /* (all) */ + summary { + /* (all) */ display: list-item; } @@ -106,18 +107,19 @@ kbd, samp { font-family: - /* macOS 10.10+ */ "Menlo", - /* Windows 6+ */ "Consolas", - /* Android 4+ */ "Roboto Mono", - /* Ubuntu 10.10+ */ "Ubuntu Monospace", - /* KDE Plasma 5+ */ "Noto Mono", - /* KDE Plasma 4+ */ "Oxygen Mono", - /* Linux/OpenOffice fallback */ "Liberation Mono", + /* macOS 10.10+ */ + 'Menlo', + /* Windows 6+ */ 'Consolas', + /* Android 4+ */ 'Roboto Mono', + /* Ubuntu 10.10+ */ 'Ubuntu Monospace', + /* KDE Plasma 5+ */ 'Noto Mono', + /* KDE Plasma 4+ */ 'Oxygen Mono', + /* Linux/OpenOffice fallback */ 'Liberation Mono', /* fallback */ monospace, - /* macOS emoji */ "Apple Color Emoji", - /* Windows emoji */ "Segoe UI Emoji", - /* Windows emoji */ "Segoe UI Symbol", - /* Linux emoji */ "Noto Color Emoji"; /* 1 */ + /* macOS emoji */ 'Apple Color Emoji', + /* Windows emoji */ 'Segoe UI Emoji', + /* Windows emoji */ 'Segoe UI Symbol', + /* Linux emoji */ 'Noto Color Emoji'; /* 1 */ font-size: 1em; /* 2 */ } @@ -130,7 +132,7 @@ cursor: help; /* 1 */ text-decoration: underline; /* 2 */ -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; /* 2 */ + text-decoration: underline dotted; /* 2 */ } /* @@ -201,9 +203,9 @@ Correct inability to style buttons (iOS, Safari) */ button, - [type="button"], - [type="reset"], - [type="submit"] { + [type='button'], + [type='reset'], + [type='submit'] { -webkit-appearance: button; } @@ -249,7 +251,7 @@ 1. Correct outline style (Safari) 2. Correct odd appearance (Chrome, Edge, Safari) */ - [type="search"] { + [type='search'] { outline-offset: -2px; /* 1 */ -webkit-appearance: textfield; /* 2 */ } @@ -311,7 +313,7 @@ /* Change cursor on busy elements (all) */ - [aria-busy="true"] { + [aria-busy='true'] { cursor: progress; } @@ -325,7 +327,7 @@ /* Change cursor on disabled, non-editable, or inoperable elements (all) */ - [aria-disabled="true"], + [aria-disabled='true'], [disabled] { cursor: not-allowed; } @@ -333,12 +335,12 @@ /* Change display on visually hidden accessible elements (all) */ - [aria-hidden="false"][hidden] { + [aria-hidden='false'][hidden] { display: inline; display: initial; } - [aria-hidden="false"][hidden]:not(:focus) { + [aria-hidden='false'][hidden]:not(:focus) { clip: rect(0, 0, 0, 0); position: absolute; } @@ -347,8 +349,8 @@ Print out URLs after links (all) */ @media print { - a[href^="http"]::after { - content: " (" attr(href) ")"; + a[href^='http']::after { + content: ' (' attr(href) ')'; } } /* ----- Variables ----- */ @@ -484,8 +486,8 @@ */ pre { -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; + -o-tab-size: 4; + tab-size: 4; } /* @@ -563,7 +565,7 @@ padding: 0.1em 0.25em; border-radius: 0.2rem; -webkit-box-decoration-break: clone; - box-decoration-break: clone; + box-decoration-break: clone; } kbd > kbd { @@ -573,8 +575,8 @@ pre { -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; + -o-tab-size: 4; + tab-size: 4; } pre code { @@ -586,7 +588,7 @@ /* ----- Forms ----- */ /* ----- Misc ----- */ - [tabindex="-1"]:focus { + [tabindex='-1']:focus { outline: none; } diff --git a/packages/@n8n/client-oauth2/package.json b/packages/@n8n/client-oauth2/package.json index 7ec91b9839..1bd8cc3c03 100644 --- a/packages/@n8n/client-oauth2/package.json +++ b/packages/@n8n/client-oauth2/package.json @@ -6,7 +6,8 @@ "dev": "pnpm watch", "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", - "format": "prettier --write . --ignore-path ../../../.prettierignore", + "format": "biome format --write src test", + "format:check": "biome ci src test", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/@n8n/codemirror-lang/.eslintrc.cjs b/packages/@n8n/codemirror-lang/.eslintrc.cjs index 25eba96d79..d07f6ff6fa 100644 --- a/packages/@n8n/codemirror-lang/.eslintrc.cjs +++ b/packages/@n8n/codemirror-lang/.eslintrc.cjs @@ -8,7 +8,5 @@ module.exports = { ...sharedOptions(__dirname), - ignorePatterns: [ - 'src/expressions/grammar*.ts' - ] + ignorePatterns: ['src/expressions/grammar*.ts'], }; diff --git a/packages/@n8n/codemirror-lang/package.json b/packages/@n8n/codemirror-lang/package.json index a8450b419d..31a8b1a379 100644 --- a/packages/@n8n/codemirror-lang/package.json +++ b/packages/@n8n/codemirror-lang/package.json @@ -24,7 +24,8 @@ "test": "jest", "lint": "eslint . --ext .ts --quiet", "lintfix": "eslint . --ext .ts --fix", - "format": "prettier --write --ignore-path ../../.prettierignore src test" + "format": "biome format --write src test", + "format:check": "biome ci src test" }, "peerDependencies": { "@codemirror/language": "*", diff --git a/packages/@n8n/config/package.json b/packages/@n8n/config/package.json index 875d6ca797..aec7071c08 100644 --- a/packages/@n8n/config/package.json +++ b/packages/@n8n/config/package.json @@ -6,7 +6,8 @@ "dev": "pnpm watch", "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", - "format": "prettier --write . --ignore-path ../../../.prettierignore", + "format": "biome format --write src test", + "format:check": "biome ci src test", "lint": "eslint .", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/@n8n/imap/package.json b/packages/@n8n/imap/package.json index 77b6254330..bfb2259202 100644 --- a/packages/@n8n/imap/package.json +++ b/packages/@n8n/imap/package.json @@ -6,7 +6,8 @@ "dev": "pnpm watch", "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", - "format": "prettier --write . --ignore-path ../../../.prettierignore", + "format": "biome format --write src test", + "format:check": "biome ci src test", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/@n8n/nodes-langchain/.prettierrc.js b/packages/@n8n/nodes-langchain/.prettierrc.js deleted file mode 100644 index ebf28d8091..0000000000 --- a/packages/@n8n/nodes-langchain/.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/packages/@n8n/nodes-langchain/.vscode/extensions.json b/packages/@n8n/nodes-langchain/.vscode/extensions.json index 306a6af39a..a15593feb1 100644 --- a/packages/@n8n/nodes-langchain/.vscode/extensions.json +++ b/packages/@n8n/nodes-langchain/.vscode/extensions.json @@ -1,7 +1,3 @@ { - "recommendations": [ - "dbaeumer.vscode-eslint", - "EditorConfig.EditorConfig", - "esbenp.prettier-vscode", - ] + "recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig", "biomejs.biome"] } diff --git a/packages/@n8n/nodes-langchain/package.json b/packages/@n8n/nodes-langchain/package.json index 56f675f09f..65adaad31a 100644 --- a/packages/@n8n/nodes-langchain/package.json +++ b/packages/@n8n/nodes-langchain/package.json @@ -9,7 +9,8 @@ "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json && pnpm n8n-copy-icons && pnpm build:metadata", "build:metadata": "pnpm n8n-generate-known && pnpm n8n-generate-ui-types", - "format": "prettier nodes credentials --write", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint nodes credentials --quiet", "lintfix": "eslint nodes credentials --fix", "watch": "tsc-watch -p tsconfig.build.json --onCompilationComplete \"tsc-alias -p tsconfig.build.json\" --onSuccess \"pnpm n8n-generate-ui-types\"", diff --git a/packages/@n8n/permissions/package.json b/packages/@n8n/permissions/package.json index 8f369a8a23..bbb046f111 100644 --- a/packages/@n8n/permissions/package.json +++ b/packages/@n8n/permissions/package.json @@ -6,7 +6,8 @@ "dev": "pnpm watch", "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", - "format": "prettier --write . --ignore-path ../../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/@n8n_io/eslint-config/base.js b/packages/@n8n_io/eslint-config/base.js index 682c5d68b5..1ec0410a88 100644 --- a/packages/@n8n_io/eslint-config/base.js +++ b/packages/@n8n_io/eslint-config/base.js @@ -22,12 +22,6 @@ const config = (module.exports = { */ '@typescript-eslint', - /** - * Plugin to report formatting violations as lint violations - * https://github.com/prettier/eslint-plugin-prettier - */ - 'eslint-plugin-prettier', - /* * Plugin to allow specifying local ESLint rules. * https://github.com/ivov/eslint-plugin-n8n-local-rules @@ -76,28 +70,6 @@ const config = (module.exports = { ], rules: { - // ****************************************************************** - // required by prettier plugin - // ****************************************************************** - - // The following rule enables eslint-plugin-prettier - // See: https://github.com/prettier/eslint-plugin-prettier#recommended-configuration - - 'prettier/prettier': ['error', { endOfLine: 'auto' }], - - // The following two rules must be disabled when using eslint-plugin-prettier: - // See: https://github.com/prettier/eslint-plugin-prettier#arrow-body-style-and-prefer-arrow-callback-issue - - /** - * https://eslint.org/docs/rules/arrow-body-style - */ - 'arrow-body-style': 'off', - - /** - * https://eslint.org/docs/rules/prefer-arrow-callback - */ - 'prefer-arrow-callback': 'off', - // ****************************************************************** // additions to base ruleset // ****************************************************************** diff --git a/packages/@n8n_io/eslint-config/package.json b/packages/@n8n_io/eslint-config/package.json index 6f776d0e64..e7b2845a24 100644 --- a/packages/@n8n_io/eslint-config/package.json +++ b/packages/@n8n_io/eslint-config/package.json @@ -15,7 +15,6 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-n8n-local-rules": "^1.0.0", - "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-unicorn": "^51.0.1", "eslint-plugin-unused-imports": "^3.1.0", "eslint-plugin-vue": "^9.23.0", diff --git a/packages/@n8n_io/eslint-config/shared.js b/packages/@n8n_io/eslint-config/shared.js index 0332606f0c..f77a70df2f 100644 --- a/packages/@n8n_io/eslint-config/shared.js +++ b/packages/@n8n_io/eslint-config/shared.js @@ -13,7 +13,7 @@ module.exports = (tsconfigRootDir, mode) => { vue: 'vue-eslint-parser', template: 'vue-eslint-parser', }, - } + } : {}; const settings = { diff --git a/packages/cli/package.json b/packages/cli/package.json index 3b2d9ceffc..1b33555a96 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -17,7 +17,8 @@ "dev": "concurrently -k -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold\" \"npm run watch\" \"nodemon\"", "dev:worker": "concurrently -k -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold\" \"npm run watch\" \"nodemon worker\"", "dev:webhook": "concurrently -k -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold\" \"npm run watch\" \"nodemon webhook\"", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "start": "run-script-os", diff --git a/packages/cli/src/config/types.ts b/packages/cli/src/config/types.ts index b1a4b22b98..0d3c5db2cb 100644 --- a/packages/cli/src/config/types.ts +++ b/packages/cli/src/config/types.ts @@ -84,12 +84,11 @@ type ExceptionPaths = { // string literals map // ----------------------------------- -type GetPathSegmentsWithUnions = - T extends ReadonlyArray - ? [C] - : { - [K in ValidKeys]: [K, ...GetPathSegmentsWithUnions]; - }[ValidKeys]; +type GetPathSegmentsWithUnions = T extends ReadonlyArray + ? [C] + : { + [K in ValidKeys]: [K, ...GetPathSegmentsWithUnions]; + }[ValidKeys]; type ToPathUnionPair = T extends [...infer Path, infer Union] ? Path extends string[] diff --git a/packages/cli/src/controllers/e2e.controller.ts b/packages/cli/src/controllers/e2e.controller.ts index 2e4d39acc0..5137d5b4af 100644 --- a/packages/cli/src/controllers/e2e.controller.ts +++ b/packages/cli/src/controllers/e2e.controller.ts @@ -12,6 +12,7 @@ import { UserRepository } from '@/databases/repositories/user.repository'; import { Patch, Post, RestController } from '@/decorators'; import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus'; import type { BooleanLicenseFeature, NumericLicenseFeature } from '@/interfaces'; +import type { FeatureReturnType } from '@/license'; import { License } from '@/license'; import { Logger } from '@/logger'; import { MfaService } from '@/mfa/mfa.service'; @@ -115,10 +116,18 @@ export class E2EController { ) { license.isFeatureEnabled = (feature: BooleanLicenseFeature) => this.enabledFeatures[feature] ?? false; - // @ts-expect-error Overriding method - // eslint-disable-next-line @typescript-eslint/unbound-method - license.getFeatureValue = (feature: NumericLicenseFeature) => - this.numericFeatures[feature] ?? UNLIMITED_LICENSE_QUOTA; + + // Ugly hack to satisfy biome parser + const getFeatureValue = ( + feature: T, + ): FeatureReturnType[T] => { + if (feature in this.numericFeatures) { + return this.numericFeatures[feature as NumericLicenseFeature] as FeatureReturnType[T]; + } else { + return UNLIMITED_LICENSE_QUOTA as FeatureReturnType[T]; + } + }; + license.getFeatureValue = getFeatureValue; license.getPlanName = () => 'Enterprise'; } diff --git a/packages/cli/src/databases/entities/auth-identity.ts b/packages/cli/src/databases/entities/auth-identity.ts index f54b1b6ef4..88d382bb3a 100644 --- a/packages/cli/src/databases/entities/auth-identity.ts +++ b/packages/cli/src/databases/entities/auth-identity.ts @@ -11,7 +11,10 @@ export class AuthIdentity extends WithTimestamps { @Column() userId: string; - @ManyToOne(() => User, (user) => user.authIdentities) + @ManyToOne( + () => User, + (user) => user.authIdentities, + ) user: User; @PrimaryColumn() diff --git a/packages/cli/src/databases/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts b/packages/cli/src/databases/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts index b41948eb70..b8d86c63ca 100644 --- a/packages/cli/src/databases/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts +++ b/packages/cli/src/databases/migrations/mysqldb/1674138566000-AddStatusToExecutions.ts @@ -8,6 +8,8 @@ export class AddStatusToExecutions1674138566000 implements ReversibleMigration { } async down({ queryRunner, tablePrefix }: MigrationContext) { - await queryRunner.query(`ALTER TABLE \`${tablePrefix}execution_entity\` DROP COLUMN \`status\``); + await queryRunner.query( + `ALTER TABLE \`${tablePrefix}execution_entity\` DROP COLUMN \`status\``, + ); } } diff --git a/packages/cli/src/events/event-relay.ts b/packages/cli/src/events/event-relay.ts index dde983884f..3202b69c15 100644 --- a/packages/cli/src/events/event-relay.ts +++ b/packages/cli/src/events/event-relay.ts @@ -8,9 +8,11 @@ import { EventService } from './event.service'; export class EventRelay { constructor(readonly eventService: EventService) {} - protected setupListeners(map: { - [EventName in EventNames]?: (event: RelayEventMap[EventName]) => void | Promise; - }) { + protected setupListeners( + map: { + [EventName in EventNames]?: (event: RelayEventMap[EventName]) => void | Promise; + }, + ) { for (const [eventName, handler] of Object.entries(map) as Array< [EventNames, (event: RelayEventMap[EventNames]) => void | Promise] >) { diff --git a/packages/cli/src/execution-lifecycle-hooks/to-save-settings.ts b/packages/cli/src/execution-lifecycle-hooks/to-save-settings.ts index 71d012a1d6..7a25adaeba 100644 --- a/packages/cli/src/execution-lifecycle-hooks/to-save-settings.ts +++ b/packages/cli/src/execution-lifecycle-hooks/to-save-settings.ts @@ -28,10 +28,10 @@ export function toSaveSettings(workflowSettings: IWorkflowSettings = {}) { manual: workflowSettings === undefined || workflowSettings.saveManualExecutions === 'DEFAULT' ? DEFAULTS.MANUAL - : workflowSettings.saveManualExecutions ?? DEFAULTS.MANUAL, + : (workflowSettings.saveManualExecutions ?? DEFAULTS.MANUAL), progress: workflowSettings === undefined || workflowSettings.saveExecutionProgress === 'DEFAULT' ? DEFAULTS.PROGRESS - : workflowSettings.saveExecutionProgress ?? DEFAULTS.PROGRESS, + : (workflowSettings.saveExecutionProgress ?? DEFAULTS.PROGRESS), }; } diff --git a/packages/cli/src/external-secrets/external-secrets-manager.ee.ts b/packages/cli/src/external-secrets/external-secrets-manager.ee.ts index 5ac8a5a1bf..dd33132d37 100644 --- a/packages/cli/src/external-secrets/external-secrets-manager.ee.ts +++ b/packages/cli/src/external-secrets/external-secrets-manager.ee.ts @@ -292,7 +292,7 @@ export class ExternalSecretsManager { } settings[provider] = { connected, - connectedAt: connected ? new Date() : settings[provider]?.connectedAt ?? null, + connectedAt: connected ? new Date() : (settings[provider]?.connectedAt ?? null), settings: settings[provider]?.settings ?? {}, }; diff --git a/packages/cli/src/license.ts b/packages/cli/src/license.ts index 7f6ef42f3c..fde17a8fcc 100644 --- a/packages/cli/src/license.ts +++ b/packages/cli/src/license.ts @@ -21,7 +21,7 @@ import type { BooleanLicenseFeature, NumericLicenseFeature } from './interfaces' import type { RedisServicePubSubPublisher } from './services/redis/redis-service-pub-sub-publisher'; import { RedisService } from './services/redis.service'; -type FeatureReturnType = Partial< +export type FeatureReturnType = Partial< { planName: string; } & { [K in NumericLicenseFeature]: number } & { [K in BooleanLicenseFeature]: boolean } diff --git a/packages/cli/src/services/orchestration/main/multi-main-setup.ee.ts b/packages/cli/src/services/orchestration/main/multi-main-setup.ee.ts index bdc3ab5316..aa0b02ffc2 100644 --- a/packages/cli/src/services/orchestration/main/multi-main-setup.ee.ts +++ b/packages/cli/src/services/orchestration/main/multi-main-setup.ee.ts @@ -42,12 +42,9 @@ export class MultiMainSetup extends TypedEmitter { await this.tryBecomeLeader(); // prevent initial wait - this.leaderCheckInterval = setInterval( - async () => { - await this.checkLeader(); - }, - config.getEnv('multiMainSetup.interval') * TIME.SECOND, - ); + this.leaderCheckInterval = setInterval(async () => { + await this.checkLeader(); + }, config.getEnv('multiMainSetup.interval') * TIME.SECOND); } async shutdown() { diff --git a/packages/core/package.json b/packages/core/package.json index 8661527771..75189b51df 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -15,7 +15,8 @@ "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", "dev": "pnpm watch", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/core/src/WorkflowExecute.ts b/packages/core/src/WorkflowExecute.ts index a7c282e434..fe4d60587b 100644 --- a/packages/core/src/WorkflowExecute.ts +++ b/packages/core/src/WorkflowExecute.ts @@ -1651,9 +1651,9 @@ export class WorkflowExecute { // array as this shows that the parent nodes executed but they did not have any // data to pass on. const inputsWithData = this.runExecutionData - .executionData!.waitingExecution[ - nodeName - ][firstRunIndex].main.map((data, index) => (data === null ? null : index)) + .executionData!.waitingExecution[nodeName][firstRunIndex].main.map((data, index) => + data === null ? null : index, + ) .filter((data) => data !== null); if (requiredInputs !== undefined) { diff --git a/packages/design-system/.storybook/preview.js b/packages/design-system/.storybook/preview.js index bb44f598ea..e39bc50436 100644 --- a/packages/design-system/.storybook/preview.js +++ b/packages/design-system/.storybook/preview.js @@ -8,7 +8,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { fas } from '@fortawesome/free-solid-svg-icons'; import ElementPlus from 'element-plus'; -import lang from 'element-plus/dist/locale/en.mjs' +import lang from 'element-plus/dist/locale/en.mjs'; import { N8nPlugin } from '../src/plugin'; diff --git a/packages/design-system/biome.jsonc b/packages/design-system/biome.jsonc new file mode 100644 index 0000000000..2c06b58894 --- /dev/null +++ b/packages/design-system/biome.jsonc @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["../../biome.jsonc"], + "formatter": { + "ignore": ["theme/**"] + } +} diff --git a/packages/design-system/chromatic.config.json b/packages/design-system/chromatic.config.json index ce95f3e2fb..c37fc04267 100644 --- a/packages/design-system/chromatic.config.json +++ b/packages/design-system/chromatic.config.json @@ -1,4 +1,4 @@ { - "projectId": "Project:65f085d72c13e4e1154414db", - "buildScriptName": "build:storybook" + "projectId": "Project:65f085d72c13e4e1154414db", + "buildScriptName": "build:storybook" } diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 631bbd5dfc..d2cbb0678b 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -13,7 +13,8 @@ "build:storybook": "storybook build", "storybook": "storybook dev -p 6006", "chromatic": "chromatic", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write . && prettier --write . --ignore-path ../../.prettierignore", + "format:check": "biome ci . && prettier --check . --ignore-path ../../.prettierignore", "lint": "eslint src --ext .js,.ts,.vue --quiet", "lintfix": "eslint src --ext .js,.ts,.vue --fix" }, diff --git a/packages/design-system/src/css/_tokens.dark.scss b/packages/design-system/src/css/_tokens.dark.scss index 398a00e538..8377f524c6 100644 --- a/packages/design-system/src/css/_tokens.dark.scss +++ b/packages/design-system/src/css/_tokens.dark.scss @@ -37,7 +37,7 @@ --color-assistant-highlight-1: #8c90f2; --color-assistant-highlight-2: #a977f0; --color-assistant-highlight-3: #f0778b; - --color-askAssistant-button-background: #2E2E2E; + --color-askAssistant-button-background: #2e2e2e; --color-askAssistant-button-background-hover: #383839; --color-askAssistant-button-background-active: #414244; --color-assistant-inner-highlight-hover: var(--color-askAssistant-button-background-hover); diff --git a/packages/design-system/src/css/_tokens.scss b/packages/design-system/src/css/_tokens.scss index 3176b4e398..1690926232 100644 --- a/packages/design-system/src/css/_tokens.scss +++ b/packages/design-system/src/css/_tokens.scss @@ -80,11 +80,11 @@ --color-canvas-read-only-line: var(--prim-gray-30); --color-canvas-selected: var(--prim-gray-70); --color-canvas-selected-transparent: hsla(var(--prim-gray-h), 47%, 30%, 0.1); - --color-canvas-label-background: hsla( - var(--color-canvas-background-h), - var(--color-canvas-background-s), - var(--color-canvas-background-l), - 0.85 + --color-canvas-label-background: hsla( + var(--color-canvas-background-h), + var(--color-canvas-background-s), + var(--color-canvas-background-l), + 0.85 ); // Nodes diff --git a/packages/design-system/tsconfig.json b/packages/design-system/tsconfig.json index fd2232a2be..1b96b238c1 100644 --- a/packages/design-system/tsconfig.json +++ b/packages/design-system/tsconfig.json @@ -11,7 +11,12 @@ "allowSyntheticDefaultImports": true, "baseUrl": ".", "types": ["vitest/globals"], - "typeRoots": ["./node_modules/@testing-library", "./node_modules/@types", "../../node_modules", "../../node_modules/@types"], + "typeRoots": [ + "./node_modules/@testing-library", + "./node_modules/@types", + "../../node_modules", + "../../node_modules/@types" + ], "paths": { "n8n-design-system/*": ["./src/*"] }, diff --git a/packages/design-system/vite.config.mts b/packages/design-system/vite.config.mts index 59bab8aa74..783218b793 100644 --- a/packages/design-system/vite.config.mts +++ b/packages/design-system/vite.config.mts @@ -44,9 +44,9 @@ export default mergeConfig( dts: false, resolvers: [ iconsResolver({ - prefix: 'icon' - }) - ] + prefix: 'icon', + }), + ], }), ], resolve: { diff --git a/packages/editor-ui/biome.jsonc b/packages/editor-ui/biome.jsonc new file mode 100644 index 0000000000..a8cf126857 --- /dev/null +++ b/packages/editor-ui/biome.jsonc @@ -0,0 +1,8 @@ +{ + "$schema": "../../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["../../biome.jsonc"] + // Although nothing is extended here, it is required so biome use the + // editor-ui gitignore file: + // > For now, Biome only takes the ignore file in the working directory into account. + // https://biomejs.dev/guides/integrate-in-vcs/#use-the-ignore-file +} diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index 68c984fe5b..693529136d 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -10,7 +10,8 @@ "dev": "pnpm serve", "lint": "eslint src --ext .js,.ts,.vue --quiet", "lintfix": "eslint src --ext .js,.ts,.vue --fix", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write . && prettier --write . --ignore-path ../../.prettierignore", + "format:check": "biome ci . && prettier --check . --ignore-path ../../.prettierignore", "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" diff --git a/packages/editor-ui/src/components/CodeNodeEditor/theme.ts b/packages/editor-ui/src/components/CodeNodeEditor/theme.ts index 0b6d923a97..e8e10aaad8 100644 --- a/packages/editor-ui/src/components/CodeNodeEditor/theme.ts +++ b/packages/editor-ui/src/components/CodeNodeEditor/theme.ts @@ -95,7 +95,7 @@ export const codeNodeEditorTheme = ({ : { minHeight: rows && rows !== -1 ? `${Number(rows + 1) * 1.3}em` : 'auto' }), }, '.cm-gutter,.cm-content': { - minHeight: rows && rows !== -1 ? 'auto' : minHeight ?? 'calc(35vh - var(--spacing-2xl))', + minHeight: rows && rows !== -1 ? 'auto' : (minHeight ?? 'calc(35vh - var(--spacing-2xl))'), }, '.cm-diagnosticAction': { backgroundColor: BASE_STYLING.diagnosticButton.backgroundColor, diff --git a/packages/editor-ui/src/components/Node/NodeCreator/utils.ts b/packages/editor-ui/src/components/Node/NodeCreator/utils.ts index 7bacf6b701..f8c1d1d3d2 100644 --- a/packages/editor-ui/src/components/Node/NodeCreator/utils.ts +++ b/packages/editor-ui/src/components/Node/NodeCreator/utils.ts @@ -142,7 +142,7 @@ export function groupItemsInSections( title: section.title, children: sortAlphabetically ? sortNodeCreateElements(children[section.key] ?? []) - : children[section.key] ?? [], + : (children[section.key] ?? []), }), ); diff --git a/packages/editor-ui/src/composables/useExpressionEditor.ts b/packages/editor-ui/src/composables/useExpressionEditor.ts index 416080a8ad..9b52589a7a 100644 --- a/packages/editor-ui/src/composables/useExpressionEditor.ts +++ b/packages/editor-ui/src/composables/useExpressionEditor.ts @@ -405,7 +405,8 @@ export const useExpressionEditor = ({ if (pos === 'lastExpression') { const END_OF_EXPRESSION = ' }}'; const endOfLastExpression = readEditorValue().lastIndexOf(END_OF_EXPRESSION); - pos = endOfLastExpression !== -1 ? endOfLastExpression : editor.value?.state.doc.length ?? 0; + pos = + endOfLastExpression !== -1 ? endOfLastExpression : (editor.value?.state.doc.length ?? 0); } else if (pos === 'end') { pos = editor.value?.state.doc.length ?? 0; } @@ -414,7 +415,7 @@ export const useExpressionEditor = ({ function select(anchor: number, head: number | 'end' = 'end'): void { editor.value?.dispatch({ - selection: { anchor, head: head === 'end' ? editor.value?.state.doc.length ?? 0 : head }, + selection: { anchor, head: head === 'end' ? (editor.value?.state.doc.length ?? 0) : head }, }); } diff --git a/packages/editor-ui/src/plugins/connectors/N8nCustomConnector.ts b/packages/editor-ui/src/plugins/connectors/N8nCustomConnector.ts index 07bd3609d0..6b41ab77a9 100644 --- a/packages/editor-ui/src/plugins/connectors/N8nCustomConnector.ts +++ b/packages/editor-ui/src/plugins/connectors/N8nCustomConnector.ts @@ -433,12 +433,14 @@ export class N8nConnector extends AbstractConnector { const sourceStubWithOffset = sourceStub + (this.getEndpointOffset && params.sourceEndpoint - ? this.getEndpointOffset(params.sourceEndpoint) ?? 0 + ? (this.getEndpointOffset(params.sourceEndpoint) ?? 0) : 0); const targetStubWithOffset = targetStub + - (this.getEndpointOffset && targetEndpoint ? this.getEndpointOffset(targetEndpoint) ?? 0 : 0); + (this.getEndpointOffset && targetEndpoint + ? (this.getEndpointOffset(targetEndpoint) ?? 0) + : 0); // same as paintinfo generated by jsplumb AbstractConnector type const result = { diff --git a/packages/editor-ui/src/plugins/i18n/index.ts b/packages/editor-ui/src/plugins/i18n/index.ts index d461349f56..6c7372dce2 100644 --- a/packages/editor-ui/src/plugins/i18n/index.ts +++ b/packages/editor-ui/src/plugins/i18n/index.ts @@ -76,7 +76,7 @@ export class I18nClass { * Render a string of dynamic text, i.e. a string with a constructed path to the localized value. */ private dynamicRender({ key, fallback }: { key: string; fallback?: string }) { - return this.i18n.te(key) ? this.i18n.t(key).toString() : fallback ?? ''; + return this.i18n.te(key) ? this.i18n.t(key).toString() : (fallback ?? ''); } displayTimer(msPassed: number, showMs = false): string { diff --git a/packages/editor-ui/src/router.ts b/packages/editor-ui/src/router.ts index 6c6a68b22d..c304d6bd75 100644 --- a/packages/editor-ui/src/router.ts +++ b/packages/editor-ui/src/router.ts @@ -739,7 +739,7 @@ function withCanvasReadOnlyMeta(route: RouteRecordRaw) { } const router = createRouter({ - history: createWebHistory(import.meta.env.DEV ? '/' : window.BASE_PATH ?? '/'), + history: createWebHistory(import.meta.env.DEV ? '/' : (window.BASE_PATH ?? '/')), scrollBehavior(to: RouteLocationNormalized, _, savedPosition) { // saved position == null means the page is NOT visited from history (back button) if (savedPosition === null && to.name === VIEWS.TEMPLATES && to.meta?.setScrollPosition) { diff --git a/packages/editor-ui/src/stores/credentials.store.ts b/packages/editor-ui/src/stores/credentials.store.ts index 663303572b..ec71aa5b29 100644 --- a/packages/editor-ui/src/stores/credentials.store.ts +++ b/packages/editor-ui/src/stores/credentials.store.ts @@ -189,7 +189,7 @@ export const useCredentialsStore = defineStore(STORES.CREDENTIALS, () => { ? email ? `${name} (${email})` : name - : email ?? i18n.baseText('credentialEdit.credentialSharing.info.sharee.fallback'); + : (email ?? i18n.baseText('credentialEdit.credentialSharing.info.sharee.fallback')); }; }); diff --git a/packages/editor-ui/src/stores/ndv.store.ts b/packages/editor-ui/src/stores/ndv.store.ts index 1e7d5da363..e3be5db5fe 100644 --- a/packages/editor-ui/src/stores/ndv.store.ts +++ b/packages/editor-ui/src/stores/ndv.store.ts @@ -91,7 +91,7 @@ export const useNDVStore = defineStore(STORES.NDV, { ndvInputDataWithPinnedData(): INodeExecutionData[] { const data = this.ndvInputData; return this.ndvInputNodeName - ? useWorkflowsStore().pinDataByNodeName(this.ndvInputNodeName) ?? data + ? (useWorkflowsStore().pinDataByNodeName(this.ndvInputNodeName) ?? data) : data; }, hasInputData(): boolean { diff --git a/packages/editor-ui/src/stores/workflows.ee.store.ts b/packages/editor-ui/src/stores/workflows.ee.store.ts index 18bb81cdf2..de3589f9fe 100644 --- a/packages/editor-ui/src/stores/workflows.ee.store.ts +++ b/packages/editor-ui/src/stores/workflows.ee.store.ts @@ -21,7 +21,7 @@ export const useWorkflowsEEStore = defineStore(STORES.WORKFLOWS_EE, { const workflow = useWorkflowsStore().getWorkflowById(workflowId); const { name, email } = splitName(workflow?.homeProject?.name ?? ''); - return name ? (email ? `${name} (${email})` : name) : email ?? fallback; + return name ? (email ? `${name} (${email})` : name) : (email ?? fallback); }; }, }, diff --git a/packages/editor-ui/src/styles/plugins/index.scss b/packages/editor-ui/src/styles/plugins/index.scss index c5d099d5d1..9914829eea 100644 --- a/packages/editor-ui/src/styles/plugins/index.scss +++ b/packages/editor-ui/src/styles/plugins/index.scss @@ -1,2 +1,2 @@ -@import "codemirror"; -@import "vueflow"; +@import 'codemirror'; +@import 'vueflow'; diff --git a/packages/editor-ui/src/types/externalHooks.ts b/packages/editor-ui/src/types/externalHooks.ts index 005762e759..d2c8b01821 100644 --- a/packages/editor-ui/src/types/externalHooks.ts +++ b/packages/editor-ui/src/types/externalHooks.ts @@ -302,8 +302,10 @@ export type ExternalHooksKey = { [K in keyof ExternalHooks]: `${K}.${Extract}`; }[keyof ExternalHooks]; -type ExtractHookMethodArray

= - ExternalHooks[P][S] extends Array ? U : never; +type ExtractHookMethodArray< + P extends keyof ExternalHooks, + S extends keyof ExternalHooks[P], +> = ExternalHooks[P][S] extends Array ? U : never; type ExtractHookMethodFunction = T extends ExternalHooksMethod ? T : never; diff --git a/packages/editor-ui/vite.config.mts b/packages/editor-ui/vite.config.mts index 9fc8b15718..f6824d31a5 100644 --- a/packages/editor-ui/vite.config.mts +++ b/packages/editor-ui/vite.config.mts @@ -6,7 +6,7 @@ import { sentryVitePlugin } from '@sentry/vite-plugin'; import packageJSON from './package.json'; import { vitestConfig } from '../design-system/vite.config.mts'; import icons from 'unplugin-icons/vite'; -import iconsResolver from 'unplugin-icons/resolver' +import iconsResolver from 'unplugin-icons/resolver'; import components from 'unplugin-vue-components/vite'; const vendorChunks = ['vue', 'vue-router']; @@ -80,9 +80,9 @@ const plugins = [ dts: './src/components.d.ts', resolvers: [ iconsResolver({ - prefix: 'icon' - }) - ] + prefix: 'icon', + }), + ], }), vue(), ]; diff --git a/packages/node-dev/package.json b/packages/node-dev/package.json index 0b538e613a..4bcfd04d6c 100644 --- a/packages/node-dev/package.json +++ b/packages/node-dev/package.json @@ -13,7 +13,8 @@ "dev": "pnpm watch", "build": "tsc --noEmit", "build-node-dev": "tsc", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "prepack": "echo \"Building project...\" && rm -rf dist && tsc -b", diff --git a/packages/nodes-base/biome.jsonc b/packages/nodes-base/biome.jsonc new file mode 100644 index 0000000000..6f4325bafd --- /dev/null +++ b/packages/nodes-base/biome.jsonc @@ -0,0 +1,7 @@ +{ + "$schema": "../../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["../../biome.jsonc"], + "formatter": { + "ignore": ["nodes/**/test/*.json"] + } +} diff --git a/packages/nodes-base/nodes/Baserow/GenericFunctions.ts b/packages/nodes-base/nodes/Baserow/GenericFunctions.ts index d08d0c2f5e..ba33755e2f 100644 --- a/packages/nodes-base/nodes/Baserow/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Baserow/GenericFunctions.ts @@ -169,7 +169,7 @@ export class TableFieldMapper { } setField(field: string) { - return this.mapIds ? field : this.nameToIdMapping[field] ?? field; + return this.mapIds ? field : (this.nameToIdMapping[field] ?? field); } idsToNames(obj: Record) { diff --git a/packages/nodes-base/nodes/Brevo/GenericFunctions.ts b/packages/nodes-base/nodes/Brevo/GenericFunctions.ts index d43f3e8bfd..4b5da056c1 100644 --- a/packages/nodes-base/nodes/Brevo/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Brevo/GenericFunctions.ts @@ -19,15 +19,15 @@ export namespace BrevoNode { type ValidatedEmail = ToEmail | SenderEmail | CCEmail | BBCEmail; const enum OVERRIDE_MAP_VALUES { - 'CATEGORY' = 'category', - 'NORMAL' = 'boolean', - 'TRANSACTIONAL' = 'id', + CATEGORY = 'category', + NORMAL = 'boolean', + TRANSACTIONAL = 'id', } const enum OVERRIDE_MAP_TYPE { - 'CATEGORY' = 'category', - 'NORMAL' = 'normal', - 'TRANSACTIONAL' = 'transactional', + CATEGORY = 'category', + NORMAL = 'normal', + TRANSACTIONAL = 'transactional', } export const INTERCEPTORS = new Map void>([ diff --git a/packages/nodes-base/nodes/Cortex/AnalyzerInterface.ts b/packages/nodes-base/nodes/Cortex/AnalyzerInterface.ts index 5f9f8fe827..a20948d01b 100644 --- a/packages/nodes-base/nodes/Cortex/AnalyzerInterface.ts +++ b/packages/nodes-base/nodes/Cortex/AnalyzerInterface.ts @@ -16,19 +16,19 @@ export const enum TLP { } export const enum ObservableDataType { - 'domain' = 'domain', - 'file' = 'file', - 'filename' = 'filename', - 'fqdn' = 'fqdn', - 'hash' = 'hash', - 'ip' = 'ip', - 'mail' = 'mail', - 'mail_subject' = 'mail_subject', - 'other' = 'other', - 'regexp' = 'regexp', - 'registry' = 'registry', - 'uri_path' = 'uri_path', - 'url' = 'url', + domain = 'domain', + file = 'file', + filename = 'filename', + fqdn = 'fqdn', + hash = 'hash', + ip = 'ip', + mail = 'mail', + mail_subject = 'mail_subject', + other = 'other', + regexp = 'regexp', + registry = 'registry', + uri_path = 'uri_path', + url = 'url', 'user-agent' = 'user-agent', } export interface IJob { diff --git a/packages/nodes-base/nodes/Google/Chat/MessageInterface.ts b/packages/nodes-base/nodes/Google/Chat/MessageInterface.ts index a03ab9f130..b2193f9820 100644 --- a/packages/nodes-base/nodes/Google/Chat/MessageInterface.ts +++ b/packages/nodes-base/nodes/Google/Chat/MessageInterface.ts @@ -32,9 +32,9 @@ export interface IUser { isAnonymous?: boolean; } const enum Type { - 'TYPE_UNSPECIFIED', - 'HUMAN', - 'BOT', + TYPE_UNSPECIFIED, + HUMAN, + BOT, } // // TODO: define other interfaces diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheet.ts b/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheet.ts index fa96649464..c5f8a8dc79 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheet.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheet.ts @@ -485,8 +485,7 @@ export class GoogleSheet { columnValuesList?: string[]; }) { const decodedRange = this.getDecodedSheetRange(range); - // prettier-ignore - const keyRowRange = `${decodedRange.name}!${decodedRange.start?.column || ''}${keyRowIndex + 1}:${decodedRange.end?.column || ''}${keyRowIndex + 1}`; + const keyRowRange = `${decodedRange.name}!${decodedRange.start?.column || ''}${keyRowIndex + 1}:${decodedRange.end?.column || ''}${keyRowIndex + 1}`; const sheetDatakeyRow = columnNamesList || (await this.getData(keyRowRange, valueRenderMode)); diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/methods/listSearch.ts b/packages/nodes-base/nodes/Google/Sheet/v2/methods/listSearch.ts index 36f18521e4..6c0c8b74ca 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/methods/listSearch.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/methods/listSearch.ts @@ -84,7 +84,6 @@ export async function sheetsSearch( returnData.push({ name: sheet.properties!.title as string, value: (sheet.properties!.sheetId as number) || 'gid=0', - //prettier-ignore url: `https://docs.google.com/spreadsheets/d/${spreadsheetId}/edit#gid=${sheet.properties!.sheetId}`, }); } diff --git a/packages/nodes-base/nodes/KoBoToolbox/KoBoToolboxTrigger.node.ts b/packages/nodes-base/nodes/KoBoToolbox/KoBoToolboxTrigger.node.ts index 436f9d86a7..503c100741 100644 --- a/packages/nodes-base/nodes/KoBoToolbox/KoBoToolboxTrigger.node.ts +++ b/packages/nodes-base/nodes/KoBoToolbox/KoBoToolboxTrigger.node.ts @@ -144,9 +144,12 @@ export class KoBoToolboxTrigger implements INodeType { const req = this.getRequestObject(); const formatOptions = this.getNodeParameter('formatOptions') as IDataObject; - // prettier-ignore const responseData = formatOptions.reformat - ? formatSubmission(req.body as IDataObject, parseStringList(formatOptions.selectMask as string), parseStringList(formatOptions.numberMask as string)) + ? formatSubmission( + req.body as IDataObject, + parseStringList(formatOptions.selectMask as string), + parseStringList(formatOptions.numberMask as string), + ) : req.body; if (formatOptions.download) { diff --git a/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts b/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts index af27d2c4cb..1b6ba6563d 100644 --- a/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts @@ -27,7 +27,6 @@ import { filters } from './descriptions/Filters'; function uuidValidateWithoutDashes(this: IExecuteFunctions, value: string) { if (uuidValidate(value)) return true; if (value.length == 32) { - //prettier-ignore const strWithDashes = `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`; if (uuidValidate(strWithDashes)) return true; } @@ -309,7 +308,6 @@ export function formatBlocks(blocks: IDataObject[]) { [block.type as string]: { ...(block.type === 'to_do' ? { checked: block.checked } : {}), ...(block.type === 'image' ? { type: 'external', external: { url: block.url } } : {}), - // prettier-ignore, ...(!['image'].includes(block.type as string) ? getTextBlocks(block) : {}), }, }); @@ -867,9 +865,12 @@ export type FileRecord = { }; }; }; -// prettier-ignore -export async function downloadFiles(this: IExecuteFunctions | IPollFunctions, records: FileRecord[], pairedItem?: IPairedItemData[]): Promise { +export async function downloadFiles( + this: IExecuteFunctions | IPollFunctions, + records: FileRecord[], + pairedItem?: IPairedItemData[], +): Promise { const elements: INodeExecutionData[] = []; for (const record of records) { const element: INodeExecutionData = { json: {}, binary: {} }; @@ -887,10 +888,12 @@ export async function downloadFiles(this: IExecuteFunctions | IPollFunctions, re '', {}, {}, - file?.file?.url as string || file?.external?.url as string, + (file?.file?.url as string) || (file?.external?.url as string), { json: false, encoding: null }, ); - element.binary![`${key}_${index}`] = await this.helpers.prepareBinaryData(data as Buffer); + element.binary![`${key}_${index}`] = await this.helpers.prepareBinaryData( + data as Buffer, + ); } } } diff --git a/packages/nodes-base/nodes/Postgres/v1/genericFunctions.ts b/packages/nodes-base/nodes/Postgres/v1/genericFunctions.ts index 9420c427a1..834779d1a0 100644 --- a/packages/nodes-base/nodes/Postgres/v1/genericFunctions.ts +++ b/packages/nodes-base/nodes/Postgres/v1/genericFunctions.ts @@ -536,8 +536,10 @@ export async function pgUpdate( } else { const where = ' WHERE ' + - // eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string - updateKeys.map((entry) => pgp.as.name(entry.name) + ' = ${' + entry.prop + '}').join(' AND '); + updateKeys + // eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string + .map((entry) => pgp.as.name(entry.name) + ' = ${' + entry.prop + '}') + .join(' AND '); if (mode === 'transaction') { return await db.tx(async (t) => { const result: IDataObject[] = []; @@ -664,8 +666,10 @@ export async function pgUpdateV2( } else { const where = ' WHERE ' + - // eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string - updateKeys.map((entry) => pgp.as.name(entry.name) + ' = ${' + entry.prop + '}').join(' AND '); + updateKeys + // eslint-disable-next-line n8n-local-rules/no-interpolation-in-regular-string + .map((entry) => pgp.as.name(entry.name) + ' = ${' + entry.prop + '}') + .join(' AND '); if (mode === 'transaction') { return await db.tx(async (t) => { const result: IDataObject[] = []; diff --git a/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts b/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts index 73d8232aa6..0f2cbee6db 100644 --- a/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts +++ b/packages/nodes-base/nodes/QuickBase/GenericFunctions.ts @@ -62,9 +62,10 @@ export async function quickbaseApiRequest( } } -//@ts-ignore -// prettier-ignore -export async function getFieldsObject(this: IHookFunctions | ILoadOptionsFunctions | IExecuteFunctions, tableId: string): any { +export async function getFieldsObject( + this: IHookFunctions | ILoadOptionsFunctions | IExecuteFunctions, + tableId: string, +): Promise { const fieldsLabelKey: { [key: string]: number } = {}; const fieldsIdKey: { [key: number]: string } = {}; const data = await quickbaseApiRequest.call(this, 'GET', '/fields', {}, { tableId }); diff --git a/packages/nodes-base/nodes/Telegram/GenericFunctions.ts b/packages/nodes-base/nodes/Telegram/GenericFunctions.ts index cbffe21d5f..309b23c176 100644 --- a/packages/nodes-base/nodes/Telegram/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Telegram/GenericFunctions.ts @@ -158,9 +158,12 @@ export function addAdditionalFields( } sendRows.push(sendButtonData); } + // @ts-ignore - // prettier-ignore - ((body.reply_markup as ITelegramInlineReply | ITelegramReplyKeyboard)[setParameterName] as ITelegramKeyboardButton[][]).push(sendRows); + const array = (body.reply_markup as ITelegramInlineReply | ITelegramReplyKeyboard)[ + setParameterName + ] as ITelegramKeyboardButton[][]; + array.push(sendRows); } } } else if (replyMarkupOption === 'forceReply') { diff --git a/packages/nodes-base/nodes/TheHive/interfaces/ObservableInterface.ts b/packages/nodes-base/nodes/TheHive/interfaces/ObservableInterface.ts index cb35df2189..da792ba07a 100644 --- a/packages/nodes-base/nodes/TheHive/interfaces/ObservableInterface.ts +++ b/packages/nodes-base/nodes/TheHive/interfaces/ObservableInterface.ts @@ -5,19 +5,19 @@ export const enum ObservableStatus { DELETED = 'Deleted', } export const enum ObservableDataType { - 'domain' = 'domain', - 'file' = 'file', - 'filename' = 'filename', - 'fqdn' = 'fqdn', - 'hash' = 'hash', - 'ip' = 'ip', - 'mail' = 'mail', - 'mail_subject' = 'mail_subject', - 'other' = 'other', - 'regexp' = 'regexp', - 'registry' = 'registry', - 'uri_path' = 'uri_path', - 'url' = 'url', + domain = 'domain', + file = 'file', + filename = 'filename', + fqdn = 'fqdn', + hash = 'hash', + ip = 'ip', + mail = 'mail', + mail_subject = 'mail_subject', + other = 'other', + regexp = 'regexp', + registry = 'registry', + uri_path = 'uri_path', + url = 'url', 'user-agent' = 'user-agent', } diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index d1a16ef2c6..053eb4abeb 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -9,7 +9,8 @@ "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && pnpm n8n-copy-icons && pnpm n8n-generate-translations && pnpm build:metadata", "build:metadata": "pnpm n8n-generate-known && pnpm n8n-generate-ui-types", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet && node ./scripts/validate-load-options-methods.js", "lintfix": "eslint . --fix", "watch": "tsc-watch -p tsconfig.build.json --onCompilationComplete \"tsc-alias -p tsconfig.build.json\" --onSuccess \"pnpm n8n-generate-ui-types\"", diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 723994f917..be6eae2ba6 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -18,7 +18,8 @@ "dev": "pnpm watch", "typecheck": "tsc --noEmit", "build": "tsc -p tsconfig.build.json", - "format": "prettier --write . --ignore-path ../../.prettierignore", + "format": "biome format --write .", + "format:check": "biome ci .", "lint": "eslint . --quiet", "lintfix": "eslint . --fix", "watch": "tsc -p tsconfig.build.json --watch", diff --git a/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts b/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts index b35cd2c728..15980c67e2 100644 --- a/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts +++ b/packages/workflow/test/ExpressionExtensions/ExpressionExtension.test.ts @@ -157,13 +157,11 @@ 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/packages/workflow/test/RoutingNode.test.ts b/packages/workflow/test/RoutingNode.test.ts index e2638d8c90..16f9735d37 100644 --- a/packages/workflow/test/RoutingNode.test.ts +++ b/packages/workflow/test/RoutingNode.test.ts @@ -1959,7 +1959,7 @@ describe('RoutingNode', () => { executeSingleFunctions.getNodeParameter = (parameterName: string) => parameterName in testData.input.node.parameters ? testData.input.node.parameters[parameterName] - : getNodeParameter(parameterName) ?? {}; + : (getNodeParameter(parameterName) ?? {}); const result = await routingNode.runNode( inputData, diff --git a/packages/workflow/test/fixtures/WorkflowDataProxy/pindata_workflow.json b/packages/workflow/test/fixtures/WorkflowDataProxy/pindata_workflow.json index 543bdb814b..0941baaeb0 100644 --- a/packages/workflow/test/fixtures/WorkflowDataProxy/pindata_workflow.json +++ b/packages/workflow/test/fixtures/WorkflowDataProxy/pindata_workflow.json @@ -1,106 +1,97 @@ { - "meta": { - "instanceId": "a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0" - }, - "nodes": [ - { - "parameters": { - "assignments": { - "assignments": [ - { - "id": "3058c300-b377-41b7-9c90-a01372f9b581", - "name": "firstName", - "value": "Joe", - "type": "string" - }, - { - "id": "bb871662-c23c-4234-ac0c-b78c279bbf34", - "name": "lastName", - "value": "Smith", - "type": "string" - } - ] - }, - "options": {} - }, - "id": "baee2bf4-5083-4cbe-8e51-4eddcf859ef5", - "name": "PinnedSet", - "type": "n8n-nodes-base.set", - "typeVersion": 3.3, - "position": [ - 1120, - 380 - ] - }, - { - "parameters": { - "assignments": { - "assignments": [ - { - "id": "a482f1fd-4815-4da4-a733-7beafb43c500", - "name": "test", - "value": "={{ $('PinnedSet').all().json }}\n{{ $('PinnedSet').item.json.firstName }}\n{{ $('PinnedSet').first().json.firstName }}\n{{ $('PinnedSet').itemMatching(0).json.firstName }}\n{{ $('PinnedSet').itemMatching(1).json.firstName }}\n{{ $('PinnedSet').last().json.firstName }}\n{{ $('PinnedSet').all()[0].json.firstName }}\n{{ $('PinnedSet').all()[1].json.firstName }}\n\n{{ $input.first().json.firstName }}\n{{ $input.last().json.firstName }}\n{{ $input.item.json.firstName }}\n\n{{ $json.firstName }}\n{{ $data.firstName }}\n\n{{ $items()[0].json.firstName }}", - "type": "string" - } - ] - }, - "options": {} - }, - "id": "2a543169-e2c1-4764-ac63-09534310b2b9", - "name": "NotPinnedSet1", - "type": "n8n-nodes-base.set", - "typeVersion": 3.3, - "position": [ - 1360, - 380 - ] - }, - { - "parameters": {}, - "id": "f36672e5-8c87-480e-a5b8-de9da6b63192", - "name": "Start", - "type": "n8n-nodes-base.manualTrigger", - "position": [ - 920, - 380 - ], - "typeVersion": 1 - } - ], - "connections": { - "PinnedSet": { - "main": [ - [ - { - "node": "NotPinnedSet1", - "type": "main", - "index": 0 - } - ] - ] - }, - "Start": { - "main": [ - [ - { - "node": "PinnedSet", - "type": "main", - "index": 0 - } - ] - ] - } - }, - "pinData": { - "PinnedSet": [ - { - "firstName": "Joe", - "lastName": "Smith" - }, - { - "firstName": "Joan", - "lastName": "Summers" - } - ] - } + "meta": { + "instanceId": "a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0" + }, + "nodes": [ + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "3058c300-b377-41b7-9c90-a01372f9b581", + "name": "firstName", + "value": "Joe", + "type": "string" + }, + { + "id": "bb871662-c23c-4234-ac0c-b78c279bbf34", + "name": "lastName", + "value": "Smith", + "type": "string" + } + ] + }, + "options": {} + }, + "id": "baee2bf4-5083-4cbe-8e51-4eddcf859ef5", + "name": "PinnedSet", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [1120, 380] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "a482f1fd-4815-4da4-a733-7beafb43c500", + "name": "test", + "value": "={{ $('PinnedSet').all().json }}\n{{ $('PinnedSet').item.json.firstName }}\n{{ $('PinnedSet').first().json.firstName }}\n{{ $('PinnedSet').itemMatching(0).json.firstName }}\n{{ $('PinnedSet').itemMatching(1).json.firstName }}\n{{ $('PinnedSet').last().json.firstName }}\n{{ $('PinnedSet').all()[0].json.firstName }}\n{{ $('PinnedSet').all()[1].json.firstName }}\n\n{{ $input.first().json.firstName }}\n{{ $input.last().json.firstName }}\n{{ $input.item.json.firstName }}\n\n{{ $json.firstName }}\n{{ $data.firstName }}\n\n{{ $items()[0].json.firstName }}", + "type": "string" + } + ] + }, + "options": {} + }, + "id": "2a543169-e2c1-4764-ac63-09534310b2b9", + "name": "NotPinnedSet1", + "type": "n8n-nodes-base.set", + "typeVersion": 3.3, + "position": [1360, 380] + }, + { + "parameters": {}, + "id": "f36672e5-8c87-480e-a5b8-de9da6b63192", + "name": "Start", + "type": "n8n-nodes-base.manualTrigger", + "position": [920, 380], + "typeVersion": 1 + } + ], + "connections": { + "PinnedSet": { + "main": [ + [ + { + "node": "NotPinnedSet1", + "type": "main", + "index": 0 + } + ] + ] + }, + "Start": { + "main": [ + [ + { + "node": "PinnedSet", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "pinData": { + "PinnedSet": [ + { + "firstName": "Joe", + "lastName": "Smith" + }, + { + "firstName": "Joan", + "lastName": "Summers" + } + ] + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 131970bbf7..2c1cfd13ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -123,6 +123,9 @@ importers: .: devDependencies: + '@biomejs/biome': + specifier: ^1.9.0 + version: 1.9.0 '@n8n_io/eslint-config': specifier: workspace:* version: link:packages/@n8n_io/eslint-config @@ -147,6 +150,9 @@ importers: jest-mock-extended: specifier: ^3.0.4 version: 3.0.4(jest@29.6.2(@types/node@18.16.16)(ts-node@10.9.2(@types/node@18.16.16)(typescript@5.6.2)))(typescript@5.6.2) + lefthook: + specifier: ^1.7.15 + version: 1.7.15 nock: specifier: ^13.3.2 version: 13.3.2 @@ -641,9 +647,6 @@ importers: eslint-plugin-n8n-local-rules: specifier: ^1.0.0 version: 1.0.0 - eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.1.3(@types/eslint@8.56.5)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5) eslint-plugin-unicorn: specifier: ^51.0.1 version: 51.0.1(eslint@8.57.0) @@ -1853,7 +1856,7 @@ importers: devDependencies: '@langchain/core': specifier: 'catalog:' - version: 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0) + version: 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8)) '@types/deep-equal': specifier: ^1.0.1 version: 1.0.1 @@ -3137,6 +3140,59 @@ 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==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.0': + resolution: {integrity: sha512-2w9v/NRtYSmodx5QWQ49OGcyGKSECdWKbzc7n532Iq5sBhkKk996fd19icT6BuL54f01KFKRCRibAW+A2rg1Kw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.0': + resolution: {integrity: sha512-fBVt8jJQi0zX0SJ1C+tdzUbRpuX/07sgtBXEhunWRkPjdi6W/2S1sYHQ1wKn4OKiRAKfHM2Cf2FNO7hQvY61dA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.0': + resolution: {integrity: sha512-Jy84mZ4vcppdmWMgQWOCfd8qIVC/vHmlaS5gy7GXkdWlBKSQ56YxEXTU58MHTbZ16LwJQpK2IulqRCC/rqWLBA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.0': + resolution: {integrity: sha512-l8U2lcqsl9yKPP5WUdIrKH//C1pWyM2cSUfcTBn6GSvXmsSjBNEdGSdM4Wfne777Oe/9ONaD1Ga53U2HksHHLw==} + 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==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.0': + resolution: {integrity: sha512-8jAzjrrJTj510pwq4aVs7ZKkOvEy1D+nzl9DKvrPh4TOyUw5Ie+0EDwXGE2RAkCKHkGNOQBZ78WtIdsATgz5sA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.0': + resolution: {integrity: sha512-AIjwJTGfdWGMRluSQ9pDB29nzce077dfHh0/HMqzztKzgD3spyuo2R9VoaFpbR0hLHPWEH6g6OxxDO7hfkXNkQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.0': + resolution: {integrity: sha512-4/4wTjNSoyNkm1SzcUaStDx46baX1VJRXtUoeEHjX9LfedR5N3qwZz5KfrRUnCd2fl5bmXK1CwMqKBkoF6zEiA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + '@chromatic-com/storybook@1.5.0': resolution: {integrity: sha512-LkLKv7SWu/6kGep1ft2HA1T/cm14wU0zoW71gE4cZRcgUoRQJtyhITFTLHrjqAxz6bVqNgqzQtd5oBZ2nK3L3g==} engines: {node: '>=16.0.0', yarn: '>=1.22.18'} @@ -9956,6 +10012,60 @@ packages: leac@0.6.0: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} + lefthook-darwin-arm64@1.7.15: + resolution: {integrity: sha512-o8JgCnLM7UgF9g0MwarHJFoj6aVSSkUInHpsQZegV1c7CVQY/LIXgSeAWRb9XBvuUjByJ/HiHFMp9/hAALTwxQ==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@1.7.15: + resolution: {integrity: sha512-nrdoex0icmXYl7AAvG7WtfEzjQtX/kWvM88jPu/gijH6VhAjp110Y8VScB7rWOcApb5kNNeqd1nKMAFgZ8KhAg==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@1.7.15: + resolution: {integrity: sha512-zl1TPynklJZZ/YsWb2H0gfErQbey318i2W85wIKGEk8kC2UzOgYTuPffnfi7kANei9ntZnhvGgilc6tqYOPuGQ==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@1.7.15: + resolution: {integrity: sha512-/gKPwhWhZ3Q/efGs73/qw6nyR4WCT74oSTgn8wabAJO5+T/2FXTKzo7IiKkQmScmY5OcnD/0teJbJZ17VWSSOg==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@1.7.15: + resolution: {integrity: sha512-re2f8WmYw19n8ojit0rnKbERAzD1/iCpU/Y8anXOjD/ROw/cpSfO88uKQrUCNY9Rp4XLtkkp9oDJs3Eg7JS7vA==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@1.7.15: + resolution: {integrity: sha512-Kj6ieTlhFGlbPDyVFeOb296MS9x/Jj5y/xTPLBM+EKbdsTJSvUYu5FdtEWfhpLyWmPfkZtULHcTQE1hoo9Q4Cg==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@1.7.15: + resolution: {integrity: sha512-85amE23mJ4BC9OThLkt+QCeVwue2Cr0ezN9LSwP0h8+royyj7YRcSu0VM/Et3B9LO50T2bpdI9norOqTcPZ9yA==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@1.7.15: + resolution: {integrity: sha512-vXx/PpcalFgdvqkoHLI4KTGZp0ti+VCCL7RqDTA6n+GZpxPTWEXSOz3GuwNALX93Dn6MOYQYktKtXADwy24fcA==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@1.7.15: + resolution: {integrity: sha512-jPKdQOLWQLRPO3VfI3ptpmdQBBsXTwaCLKXMo/gcSyU0xE/ltPD4QqvHzTAFJo00VcKRHjv9QeH69qhENjJtjw==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@1.7.15: + resolution: {integrity: sha512-tlkSU669+b64AsqytGy1W3au7h8kFjt5ejLhTkErJpylTqThZIHm/GI0wUmpX+ud8kekM+9j407dweAHYOQ1XA==} + cpu: [x64] + os: [win32] + + lefthook@1.7.15: + resolution: {integrity: sha512-HW2mYkhg0a3RH2t57+ZJwacJiSIuDEhsXQAaCw6iGeN7zowdUV7g5QtnRdFdPkaK2eaNFpG6Rp0GsTrl/v0gNg==} + hasBin: true + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -16142,6 +16252,41 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@biomejs/biome@1.9.0': + 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.0': + optional: true + + '@biomejs/cli-darwin-x64@1.9.0': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.0': + optional: true + + '@biomejs/cli-linux-arm64@1.9.0': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.0': + optional: true + + '@biomejs/cli-linux-x64@1.9.0': + optional: true + + '@biomejs/cli-win32-arm64@1.9.0': + optional: true + + '@biomejs/cli-win32-x64@1.9.0': + optional: true + '@chromatic-com/storybook@1.5.0(react@18.2.0)': dependencies: chromatic: 11.4.1 @@ -17149,20 +17294,7 @@ snapshots: dependencies: '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8)) js-tiktoken: 1.0.12 - openai: 4.58.0(zod@3.23.8) - zod: 3.23.8 - zod-to-json-schema: 3.23.2(zod@3.23.8) - transitivePeerDependencies: - - encoding - - langchain - - supports-color - optional: true - - '@langchain/openai@0.2.10(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))': - dependencies: - '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)) - js-tiktoken: 1.0.12 - openai: 4.58.0(zod@3.23.8) + openai: 4.58.0(encoding@0.1.13)(zod@3.23.8) zod: 3.23.8 zod-to-json-schema: 3.23.2(zod@3.23.8) transitivePeerDependencies: @@ -22425,7 +22557,7 @@ snapshots: eslint-import-resolver-node@0.3.9: dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) is-core-module: 2.13.1 resolve: 1.22.8 transitivePeerDependencies: @@ -22450,7 +22582,7 @@ snapshots: eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) optionalDependencies: '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 @@ -22470,7 +22602,7 @@ snapshots: array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -23336,7 +23468,7 @@ snapshots: array-parallel: 0.1.3 array-series: 0.1.5 cross-spawn: 4.0.2 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -24816,34 +24948,7 @@ snapshots: optionalDependencies: '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)))(openai@4.58.0(zod@3.23.8)) langchain: 0.2.18(axios@1.7.4)(openai@4.58.0(zod@3.23.8)) - openai: 4.58.0(zod@3.23.8) - - langsmith@0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)): - dependencies: - '@types/uuid': 10.0.0 - commander: 10.0.1 - p-queue: 6.6.2 - p-retry: 4.6.2 - semver: 7.6.0 - uuid: 10.0.0 - optionalDependencies: - '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0(zod@3.23.8)) - langchain: 0.2.18(axios@1.7.4)(openai@4.58.0) - openai: 4.58.0(zod@3.23.8) - optional: true - - langsmith@0.1.51(@langchain/core@0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0))(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0): - dependencies: - '@types/uuid': 10.0.0 - commander: 10.0.1 - p-queue: 6.6.2 - p-retry: 4.6.2 - semver: 7.6.0 - uuid: 10.0.0 - optionalDependencies: - '@langchain/core': 0.2.31(langchain@0.2.18(axios@1.7.4)(openai@4.58.0))(openai@4.58.0) - langchain: 0.2.18(axios@1.7.4)(openai@4.58.0) - openai: 4.58.0(zod@3.23.8) + openai: 4.58.0(encoding@0.1.13)(zod@3.23.8) lazy-ass@1.6.0: {} @@ -24867,6 +24972,49 @@ snapshots: leac@0.6.0: {} + lefthook-darwin-arm64@1.7.15: + optional: true + + lefthook-darwin-x64@1.7.15: + optional: true + + lefthook-freebsd-arm64@1.7.15: + optional: true + + lefthook-freebsd-x64@1.7.15: + optional: true + + lefthook-linux-arm64@1.7.15: + optional: true + + lefthook-linux-x64@1.7.15: + optional: true + + lefthook-openbsd-arm64@1.7.15: + optional: true + + lefthook-openbsd-x64@1.7.15: + optional: true + + lefthook-windows-arm64@1.7.15: + optional: true + + lefthook-windows-x64@1.7.15: + optional: true + + lefthook@1.7.15: + optionalDependencies: + lefthook-darwin-arm64: 1.7.15 + lefthook-darwin-x64: 1.7.15 + lefthook-freebsd-arm64: 1.7.15 + lefthook-freebsd-x64: 1.7.15 + lefthook-linux-arm64: 1.7.15 + lefthook-linux-x64: 1.7.15 + lefthook-openbsd-arm64: 1.7.15 + lefthook-openbsd-x64: 1.7.15 + lefthook-windows-arm64: 1.7.15 + lefthook-windows-x64: 1.7.15 + leven@3.1.0: {} levn@0.3.0: @@ -26152,24 +26300,6 @@ snapshots: - encoding - supports-color - openai@4.58.0(zod@3.23.8): - dependencies: - '@types/node': 18.16.16 - '@types/node-fetch': 2.6.4 - '@types/qs': 6.9.15 - abort-controller: 3.0.0 - agentkeepalive: 4.2.1 - form-data-encoder: 1.7.2 - formdata-node: 4.4.1 - node-fetch: 2.7.0(encoding@0.1.13) - qs: 6.11.0 - optionalDependencies: - zod: 3.23.8 - transitivePeerDependencies: - - encoding - - supports-color - optional: true - openapi-sampler@1.4.0: dependencies: '@types/json-schema': 7.0.15 @@ -26374,7 +26504,7 @@ snapshots: pdf-parse@1.1.1: dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) node-ensure: 0.0.0 transitivePeerDependencies: - supports-color @@ -27272,7 +27402,7 @@ snapshots: rhea@1.0.24: dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color diff --git a/scripts/format.mjs b/scripts/format.mjs index 11b267b477..69bbfce015 100644 --- a/scripts/format.mjs +++ b/scripts/format.mjs @@ -5,42 +5,61 @@ 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'); -if (!fs.existsSync(prettier)) { - throw new Error( - [`Prettier not found at path: ${prettier}`, 'Please run `pnpm i` first'].join('\n'), - ); -} +[prettier, 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'), + ); + } +}); -const config = path.resolve('.prettierrc.js'); +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']; -const EXTENSIONS_TO_FORMAT = ['.md', '.yml', '.js', '.json', '.ts']; +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 isDir = (path) => fs.lstatSync(path).isDirectory(); -const isTarget = (path) => EXTENSIONS_TO_FORMAT.some((ext) => path.endsWith(ext)); +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 walk = (dir, test, found = []) => { +const biomeTargets = []; +const prettierTargets = []; + +const walk = (dir) => { fs.readdirSync(dir).forEach((entry) => { const entryPath = path.resolve(dir, entry); - if (isDir(entryPath)) walk(entryPath, test, found); - if (test(entryPath)) found.push(entryPath); + if (isDir(entryPath)) walk(entryPath); + if (isPrettierTarget(entryPath)) prettierTargets.push(entryPath); + if (isBiomeTarget(entryPath)) biomeTargets.push(entryPath); }); - - return found; }; -const targets = fs - .readdirSync('.') - .reduce((acc, cur) => { - if (ROOT_DIRS_TO_SKIP.includes(cur)) return acc; - if (isDir(cur)) return [...acc, ...walk(cur, isTarget)]; - if (isTarget(cur)) return [...acc, cur]; +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); +}); - return acc; - }, []) - .join(' '); +execSync( + [ + prettier, + '--config', + prettierConfig, + '--ignore-path', + ignore, + '--write', + prettierTargets.join(' '), + ].join(' '), +); -execSync([prettier, '--config', config, '--ignore-path', ignore, '--write', targets].join(' ')); +execSync( + [biome, 'format', '--write', `--config-path=${biomeConfig}`, biomeTargets.join(' ')].join(' '), +); diff --git a/turbo.json b/turbo.json index 55e67cae94..cd38cc5045 100644 --- a/turbo.json +++ b/turbo.json @@ -23,6 +23,7 @@ "dependsOn": ["^typecheck"] }, "format": {}, + "format:check": {}, "lint:backend": { "dependsOn": [ "@n8n/api-types#lint",