From 44e5fb9b06c794033204ef1744b54b3b87160082 Mon Sep 17 00:00:00 2001
From: Csaba Tuncsik
Date: Wed, 18 Sep 2024 08:49:41 +0200
Subject: [PATCH 1/5] fix(editor): Replace v-html with custom directive to
sanitize html (#10804)
Co-authored-by: Tomi Turtiainen <10324676+tomi@users.noreply.github.com>
---
packages/design-system/package.json | 1 -
.../AskAssistantChat/AskAssistantChat.vue | 14 +-
.../__tests__/AskAssistantChat.spec.ts | 21 ++
.../AskAssistantChat.spec.ts.snap | 18 --
.../src/components/N8nActionBox/ActionBox.vue | 4 +-
.../N8nInfoAccordion/InfoAccordion.vue | 4 +-
.../components/N8nInputLabel/InputLabel.vue | 2 +-
.../src/components/N8nMarkdown/Markdown.vue | 2 +-
.../N8nMarkdown/__tests__/Markdown.spec.ts | 21 ++
.../src/components/N8nNotice/Notice.vue | 2 +-
.../N8nNotice/__tests__/Notice.spec.ts | 4 +
.../src/components/N8nSticky/Sticky.vue | 2 +-
.../src/components/N8nTabs/Tabs.vue | 2 +-
.../src/components/N8nTooltip/Tooltip.vue | 2 +-
.../design-system/src/directives/index.ts | 1 +
.../src/directives/n8n-html.test.ts | 45 ++++
.../design-system/src/directives/n8n-html.ts | 37 +++
.../src/components/Error/NodeErrorView.vue | 2 +-
.../src/components/ExpressionEditModal.vue | 2 +-
.../src/components/FeatureComingSoon.vue | 4 +-
.../InlineExpressionTip.vue | 6 +-
.../editor-ui/src/components/InputPanel.vue | 2 +-
.../editor-ui/src/components/MappingPill.vue | 2 +-
packages/editor-ui/src/components/Node.vue | 2 +-
.../Node/NodeCreator/ItemTypes/NodeItem.vue | 2 +-
.../Node/NodeCreator/Modes/ActionsMode.vue | 12 +-
.../Renderers/CategorizedItemsRenderer.vue | 2 +-
.../src/components/ParameterInput.vue | 4 +-
.../src/components/ParameterInputHint.vue | 4 +-
.../src/components/PushConnectionTracker.vue | 2 +-
.../ResourceMapper/MappingModeSelect.vue | 2 +-
packages/editor-ui/src/components/RunData.vue | 4 +-
packages/editor-ui/src/components/RunInfo.vue | 2 +-
.../editor-ui/src/components/TitledList.vue | 2 +-
.../editor-ui/src/components/TriggerPanel.vue | 2 +-
.../editor-ui/src/components/VersionCard.vue | 4 +-
.../src/components/WorkflowActivator.vue | 2 +-
.../src/components/WorkflowSettings.vue | 2 +-
.../src/components/banners/V1Banner.vue | 4 +-
.../banners/__tests__/V1Banner.spec.ts | 8 +-
.../__snapshots__/V1Banner.spec.ts.snap | 226 ++++++++++++++----
.../nodes/render-types/CanvasNodeDefault.vue | 2 +-
.../WorkflowExecutionAnnotationPanel.vue | 2 +-
.../editor-ui/src/views/SettingsLdapView.vue | 2 +-
.../src/views/SettingsLogStreamingView.vue | 8 +-
.../AppsRequiringCredsNotice.vue | 2 +-
.../SetupTemplateFormStep.vue | 2 +-
.../src/views/TemplatesSearchView.vue | 2 +-
pnpm-lock.yaml | 3 -
49 files changed, 379 insertions(+), 130 deletions(-)
create mode 100644 packages/design-system/src/directives/n8n-html.test.ts
create mode 100644 packages/design-system/src/directives/n8n-html.ts
diff --git a/packages/design-system/package.json b/packages/design-system/package.json
index d2cbb0678b301..e8f1f99196412 100644
--- a/packages/design-system/package.json
+++ b/packages/design-system/package.json
@@ -29,7 +29,6 @@
"@types/sanitize-html": "^2.11.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vitest/coverage-v8": "catalog:frontend",
- "@vue/test-utils": "^2.4.3",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"sass": "^1.64.1",
diff --git a/packages/design-system/src/components/AskAssistantChat/AskAssistantChat.vue b/packages/design-system/src/components/AskAssistantChat/AskAssistantChat.vue
index de2f5e17685ea..63f4bf9a865aa 100644
--- a/packages/design-system/src/components/AskAssistantChat/AskAssistantChat.vue
+++ b/packages/design-system/src/components/AskAssistantChat/AskAssistantChat.vue
@@ -151,8 +151,7 @@ function growInput() {
/>
-
-
+
@@ -160,19 +159,20 @@ function growInput() {
-
-
-
+
{
it('renders default placeholder chat correctly', () => {
@@ -12,6 +13,11 @@ describe('AskAssistantChat', () => {
});
it('renders chat with messages correctly', () => {
const { container } = render(AskAssistantChat, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
user: { firstName: 'Kobi', lastName: 'Dog' },
messages: [
@@ -86,6 +92,11 @@ describe('AskAssistantChat', () => {
});
it('renders streaming chat correctly', () => {
const { container } = render(AskAssistantChat, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
user: { firstName: 'Kobi', lastName: 'Dog' },
messages: [
@@ -105,6 +116,11 @@ describe('AskAssistantChat', () => {
});
it('renders end of session chat correctly', () => {
const { container } = render(AskAssistantChat, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
user: { firstName: 'Kobi', lastName: 'Dog' },
messages: [
@@ -130,6 +146,11 @@ describe('AskAssistantChat', () => {
});
it('renders message with code snippet', () => {
const { container } = render(AskAssistantChat, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
user: { firstName: 'Kobi', lastName: 'Dog' },
messages: [
diff --git a/packages/design-system/src/components/AskAssistantChat/__tests__/__snapshots__/AskAssistantChat.spec.ts.snap b/packages/design-system/src/components/AskAssistantChat/__tests__/__snapshots__/AskAssistantChat.spec.ts.snap
index 8baba648f9f74..3a587f4fe75f1 100644
--- a/packages/design-system/src/components/AskAssistantChat/__tests__/__snapshots__/AskAssistantChat.spec.ts.snap
+++ b/packages/design-system/src/components/AskAssistantChat/__tests__/__snapshots__/AskAssistantChat.spec.ts.snap
@@ -129,9 +129,6 @@ exports[`AskAssistantChat > renders chat with messages correctly 1`] = `
-
-
-
@@ -145,7 +142,6 @@ exports[`AskAssistantChat > renders chat with messages correctly 1`] = `
-
@@ -438,7 +434,6 @@ exports[`AskAssistantChat > renders chat with messages correctly 1`] = `
-
Give it to me
@@ -516,7 +511,6 @@ exports[`AskAssistantChat > renders chat with messages correctly 1`] = `
-
Solution steps:
@@ -1060,9 +1054,6 @@ exports[`AskAssistantChat > renders end of session chat correctly 1`] = `
-
-
-
@@ -1076,7 +1067,6 @@ exports[`AskAssistantChat > renders end of session chat correctly 1`] = `
-
@@ -1309,9 +1299,6 @@ exports[`AskAssistantChat > renders message with code snippet 1`] = `
-
-
-
@@ -1325,7 +1312,6 @@ exports[`AskAssistantChat > renders message with code snippet 1`] = `
-
renders streaming chat correctly 1`] = `
-
-
-
@@ -1568,7 +1551,6 @@ exports[`AskAssistantChat > renders streaming chat correctly 1`] = `
-
diff --git a/packages/design-system/src/components/N8nActionBox/ActionBox.vue b/packages/design-system/src/components/N8nActionBox/ActionBox.vue
index c048c3f6438c5..edb877b3d650f 100644
--- a/packages/design-system/src/components/N8nActionBox/ActionBox.vue
+++ b/packages/design-system/src/components/N8nActionBox/ActionBox.vue
@@ -37,7 +37,7 @@ withDefaults(defineProps
(), {
-
+
@@ -61,7 +61,7 @@ withDefaults(defineProps(), {
:class="$style.callout"
>
-
+
diff --git a/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue b/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue
index 71830b02dcac6..e500c73cd65f1 100644
--- a/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue
+++ b/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue
@@ -75,7 +75,7 @@ const onTooltipClick = (item: string, event: MouseEvent) => emit('tooltipClick',
-
+
@@ -83,7 +83,7 @@ const onTooltipClick = (item: string, event: MouseEvent) => emit('tooltipClick',
-
+
diff --git a/packages/design-system/src/components/N8nInputLabel/InputLabel.vue b/packages/design-system/src/components/N8nInputLabel/InputLabel.vue
index 6c527549ed0f3..bda96c2e21feb 100644
--- a/packages/design-system/src/components/N8nInputLabel/InputLabel.vue
+++ b/packages/design-system/src/components/N8nInputLabel/InputLabel.vue
@@ -58,7 +58,7 @@ const addTargetBlank = (html: string) =>
-
+
diff --git a/packages/design-system/src/components/N8nMarkdown/Markdown.vue b/packages/design-system/src/components/N8nMarkdown/Markdown.vue
index c953ff9d657e5..45de891020bb3 100644
--- a/packages/design-system/src/components/N8nMarkdown/Markdown.vue
+++ b/packages/design-system/src/components/N8nMarkdown/Markdown.vue
@@ -202,7 +202,7 @@ const onCheckboxChange = (index: number) => {
@click="onClick"
@mousedown="onMouseDown"
@change="onChange"
- v-html="htmlContent"
+ v-n8n-html="htmlContent"
/>
diff --git a/packages/design-system/src/components/N8nMarkdown/__tests__/Markdown.spec.ts b/packages/design-system/src/components/N8nMarkdown/__tests__/Markdown.spec.ts
index 2c826f5192800..ac2faac7b308f 100644
--- a/packages/design-system/src/components/N8nMarkdown/__tests__/Markdown.spec.ts
+++ b/packages/design-system/src/components/N8nMarkdown/__tests__/Markdown.spec.ts
@@ -1,10 +1,16 @@
import { render, fireEvent } from '@testing-library/vue';
import N8nMarkdown from '../Markdown.vue';
+import { n8nHtml } from 'n8n-design-system/directives';
describe('components', () => {
describe('N8nMarkdown', () => {
it('should render unchecked checkboxes', () => {
const wrapper = render(N8nMarkdown, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
content: '__TODO__\n- [ ] Buy milk\n- [ ] Buy socks\n',
},
@@ -18,6 +24,11 @@ describe('components', () => {
it('should render checked checkboxes', () => {
const wrapper = render(N8nMarkdown, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
content: '__TODO__\n- [X] Buy milk\n- [X] Buy socks\n',
},
@@ -31,6 +42,11 @@ describe('components', () => {
it('should toggle checkboxes when clicked', async () => {
const wrapper = render(N8nMarkdown, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
content: '__TODO__\n- [ ] Buy milk\n- [ ] Buy socks\n',
},
@@ -50,6 +66,11 @@ describe('components', () => {
it('should render inputs as plain text', () => {
const wrapper = render(N8nMarkdown, {
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
props: {
content:
'__TODO__\n- [X] Buy milk\n- \n',
diff --git a/packages/design-system/src/components/N8nNotice/Notice.vue b/packages/design-system/src/components/N8nNotice/Notice.vue
index eb27aa2efdf8f..f630e95e59c77 100644
--- a/packages/design-system/src/components/N8nNotice/Notice.vue
+++ b/packages/design-system/src/components/N8nNotice/Notice.vue
@@ -73,7 +73,7 @@ const onClick = (event: MouseEvent) => {
:id="`${id}-content`"
:class="showFullContent ? $style['expanded'] : $style['truncated']"
role="region"
- v-html="displayContent"
+ v-n8n-html="displayContent"
/>
diff --git a/packages/design-system/src/components/N8nNotice/__tests__/Notice.spec.ts b/packages/design-system/src/components/N8nNotice/__tests__/Notice.spec.ts
index 84617dab515ec..180815e5367b0 100644
--- a/packages/design-system/src/components/N8nNotice/__tests__/Notice.spec.ts
+++ b/packages/design-system/src/components/N8nNotice/__tests__/Notice.spec.ts
@@ -1,6 +1,7 @@
import { render } from '@testing-library/vue';
import N8nNotice from '../Notice.vue';
import { N8nText } from 'n8n-design-system/components';
+import { n8nHtml } from 'n8n-design-system/directives';
describe('components', () => {
describe('N8nNotice', () => {
@@ -41,6 +42,9 @@ describe('components', () => {
content: 'Hello world! This is a notice.',
},
global: {
+ directives: {
+ n8nHtml,
+ },
components: {
'n8n-text': N8nText,
},
diff --git a/packages/design-system/src/components/N8nSticky/Sticky.vue b/packages/design-system/src/components/N8nSticky/Sticky.vue
index 4b7dca944acb0..9e258b4afa75a 100644
--- a/packages/design-system/src/components/N8nSticky/Sticky.vue
+++ b/packages/design-system/src/components/N8nSticky/Sticky.vue
@@ -116,7 +116,7 @@ const onInputScroll = (event: WheelEvent) => {
-
+
diff --git a/packages/design-system/src/components/N8nTabs/Tabs.vue b/packages/design-system/src/components/N8nTabs/Tabs.vue
index 64277ca8630e9..ff1b142e516e2 100644
--- a/packages/design-system/src/components/N8nTabs/Tabs.vue
+++ b/packages/design-system/src/components/N8nTabs/Tabs.vue
@@ -89,7 +89,7 @@ const scrollRight = () => scroll(50);
>
-
+
-
+
',
+};
+
+describe('Directive n8n-html', () => {
+ it('should sanitize html', async () => {
+ const { html } = render(TestComponent, {
+ props: {
+ html: 'text malicious ',
+ },
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
+ });
+ expect(html()).toBe(
+ '',
+ );
+ });
+
+ it('should not touch safe html', async () => {
+ const { html } = render(TestComponent, {
+ props: {
+ html: 'text safe ',
+ },
+ global: {
+ directives: {
+ n8nHtml,
+ },
+ },
+ });
+ expect(html()).toBe(
+ '',
+ );
+ });
+});
diff --git a/packages/design-system/src/directives/n8n-html.ts b/packages/design-system/src/directives/n8n-html.ts
new file mode 100644
index 0000000000000..875905d1d9ff0
--- /dev/null
+++ b/packages/design-system/src/directives/n8n-html.ts
@@ -0,0 +1,37 @@
+import sanitize from 'sanitize-html';
+import type { DirectiveBinding, ObjectDirective } from 'vue';
+
+/**
+ * Custom directive `n8nHtml` to replace v-html from Vue to sanitize content.
+ *
+ * Usage:
+ * In your Vue template, use the directive `v-n8n-html` passing the unsafe HTML.
+ *
+ * Example:
+ * link'">
+ *
+ * Compiles to:
link
+ *
+ * Hint: Do not use it on components
+ * https://vuejs.org/guide/reusability/custom-directives#usage-on-components
+ */
+
+const configuredSanitize = (html: string) =>
+ sanitize(html, {
+ allowedTags: sanitize.defaults.allowedTags.concat(['img', 'input']),
+ allowedAttributes: {
+ ...sanitize.defaults.allowedAttributes,
+ input: ['type', 'id', 'checked'],
+ code: ['class'],
+ a: sanitize.defaults.allowedAttributes.a.concat(['data-*']),
+ },
+ });
+
+export const n8nHtml: ObjectDirective = {
+ beforeMount(el: HTMLElement, binding: DirectiveBinding) {
+ el.innerHTML = configuredSanitize(binding.value);
+ },
+ beforeUpdate(el: HTMLElement, binding: DirectiveBinding) {
+ el.innerHTML = configuredSanitize(binding.value);
+ },
+};
diff --git a/packages/editor-ui/src/components/Error/NodeErrorView.vue b/packages/editor-ui/src/components/Error/NodeErrorView.vue
index 0bc3bf5387d03..aa0eac4c69ff0 100644
--- a/packages/editor-ui/src/components/Error/NodeErrorView.vue
+++ b/packages/editor-ui/src/components/Error/NodeErrorView.vue
@@ -445,7 +445,7 @@ async function onAskAssistantClick() {
v-if="error.description || error.context?.descriptionKey"
data-test-id="node-error-description"
class="node-error-view__header-description"
- v-html="getErrorDescription()"
+ v-n8n-html="getErrorDescription()"
>
diff --git a/packages/editor-ui/src/components/FeatureComingSoon.vue b/packages/editor-ui/src/components/FeatureComingSoon.vue
index a96b3d0ec31f8..fd24a35196b49 100644
--- a/packages/editor-ui/src/components/FeatureComingSoon.vue
+++ b/packages/editor-ui/src/components/FeatureComingSoon.vue
@@ -56,7 +56,7 @@ export default defineComponent({
-
+
@@ -68,7 +68,7 @@ export default defineComponent({
@click:button="openLinkPage"
>
-
+
diff --git a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue
index 9e0744025c26b..73f12a0ec3852 100644
--- a/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue
+++ b/packages/editor-ui/src/components/InlineExpressionEditor/InlineExpressionTip.vue
@@ -115,15 +115,15 @@ watchDebounced(
-
+
-
+
-
+
diff --git a/packages/editor-ui/src/components/InputPanel.vue b/packages/editor-ui/src/components/InputPanel.vue
index 7bc38c811ed56..a9a6dd3909c7f 100644
--- a/packages/editor-ui/src/components/InputPanel.vue
+++ b/packages/editor-ui/src/components/InputPanel.vue
@@ -406,7 +406,7 @@ export default defineComponent({
(), {
diff --git a/packages/editor-ui/src/components/Node.vue b/packages/editor-ui/src/components/Node.vue
index 83efe3b0a718d..56ca2cecf82b9 100644
--- a/packages/editor-ui/src/components/Node.vue
+++ b/packages/editor-ui/src/components/Node.vue
@@ -633,7 +633,7 @@ function openContextMenu(event: MouseEvent, source: 'node-button' | 'node-right-
-
+
diff --git a/packages/editor-ui/src/components/Node/NodeCreator/ItemTypes/NodeItem.vue b/packages/editor-ui/src/components/Node/NodeCreator/ItemTypes/NodeItem.vue
index ebea3cba41979..49916381762a2 100644
--- a/packages/editor-ui/src/components/Node/NodeCreator/ItemTypes/NodeItem.vue
+++ b/packages/editor-ui/src/components/Node/NodeCreator/ItemTypes/NodeItem.vue
@@ -163,7 +163,7 @@ function onCommunityNodeTooltipClick(event: MouseEvent) {
{
data-test-id="actions-panel-no-triggers-callout"
>
{
@@ -293,13 +293,13 @@ onMounted(() => {
slim
data-test-id="actions-panel-activation-callout"
>
-
+
{
:class="$style.resetSearch"
data-test-id="actions-panel-no-matching-actions"
@click="resetSearch"
- v-html="i18n.baseText('nodeCreator.actionsCategory.noMatchingActions')"
+ v-n8n-html="i18n.baseText('nodeCreator.actionsCategory.noMatchingActions')"
/>
@@ -320,7 +320,7 @@ onMounted(() => {
-
+
diff --git a/packages/editor-ui/src/components/ParameterInput.vue b/packages/editor-ui/src/components/ParameterInput.vue
index b5ca14dd887fd..df63a8b3228f4 100644
--- a/packages/editor-ui/src/components/ParameterInput.vue
+++ b/packages/editor-ui/src/components/ParameterInput.vue
@@ -1391,7 +1391,7 @@ onUpdated(async () => {
@@ -1424,7 +1424,7 @@ onUpdated(async () => {
diff --git a/packages/editor-ui/src/components/ParameterInputHint.vue b/packages/editor-ui/src/components/ParameterInputHint.vue
index 87ce1a92ab992..1c28e4e44a937 100644
--- a/packages/editor-ui/src/components/ParameterInputHint.vue
+++ b/packages/editor-ui/src/components/ParameterInputHint.vue
@@ -46,13 +46,13 @@ const simplyText = computed(() => {
[$style.highlight]: highlight,
}"
>
-
+
diff --git a/packages/editor-ui/src/components/PushConnectionTracker.vue b/packages/editor-ui/src/components/PushConnectionTracker.vue
index bd4ecc865494b..1be8fb5b6aaef 100644
--- a/packages/editor-ui/src/components/PushConnectionTracker.vue
+++ b/packages/editor-ui/src/components/PushConnectionTracker.vue
@@ -16,7 +16,7 @@ export default defineComponent({
-
+
diff --git a/packages/editor-ui/src/components/ResourceMapper/MappingModeSelect.vue b/packages/editor-ui/src/components/ResourceMapper/MappingModeSelect.vue
index 2c69e1555086c..ab250a07d3989 100644
--- a/packages/editor-ui/src/components/ResourceMapper/MappingModeSelect.vue
+++ b/packages/editor-ui/src/components/ResourceMapper/MappingModeSelect.vue
@@ -131,7 +131,7 @@ defineExpose({
{{ option.name }}
-
+
diff --git a/packages/editor-ui/src/components/RunData.vue b/packages/editor-ui/src/components/RunData.vue
index f85800fa160f1..348e3a455b9db 100644
--- a/packages/editor-ui/src/components/RunData.vue
+++ b/packages/editor-ui/src/components/RunData.vue
@@ -1350,7 +1350,7 @@ export default defineComponent({
:class="$style.hintCallout"
:theme="hint.type || 'info'"
>
-
+
{{ tooMuchDataTitle }}
{
data-test-id="node-run-info-stale"
>
diff --git a/packages/editor-ui/src/components/TriggerPanel.vue b/packages/editor-ui/src/components/TriggerPanel.vue
index db8a64736a2df..0702f34c49979 100644
--- a/packages/editor-ui/src/components/TriggerPanel.vue
+++ b/packages/editor-ui/src/components/TriggerPanel.vue
@@ -441,7 +441,7 @@ export default defineComponent({
-
+
{
{{ `${$locale.baseText('versionCard.version')} ${version.name}` }}
-
+
{
diff --git a/packages/editor-ui/src/components/WorkflowSettings.vue b/packages/editor-ui/src/components/WorkflowSettings.vue
index 2d915611ff07a..1ecac538a6a70 100644
--- a/packages/editor-ui/src/components/WorkflowSettings.vue
+++ b/packages/editor-ui/src/components/WorkflowSettings.vue
@@ -573,7 +573,7 @@ export default defineComponent({
{{ $locale.baseText('workflowSettings.errorWorkflow') + ':' }}
-
+
diff --git a/packages/editor-ui/src/components/banners/V1Banner.vue b/packages/editor-ui/src/components/banners/V1Banner.vue
index 72077f1a3c55c..6ea90c712c148 100644
--- a/packages/editor-ui/src/components/banners/V1Banner.vue
+++ b/packages/editor-ui/src/components/banners/V1Banner.vue
@@ -17,14 +17,14 @@ const hasOwnerPermission = computed(() => hasPermission(['instanceOwner']));
-
+
-
+
diff --git a/packages/editor-ui/src/components/banners/__tests__/V1Banner.spec.ts b/packages/editor-ui/src/components/banners/__tests__/V1Banner.spec.ts
index d9cbedd9e8084..f01ea4c3f6176 100644
--- a/packages/editor-ui/src/components/banners/__tests__/V1Banner.spec.ts
+++ b/packages/editor-ui/src/components/banners/__tests__/V1Banner.spec.ts
@@ -1,10 +1,12 @@
-import { render } from '@testing-library/vue';
+import { createComponentRenderer } from '@/__tests__/render';
import V1Banner from '../V1Banner.vue';
import { createPinia, setActivePinia } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { ROLE } from '@/constants';
import type { IUser } from '@/Interface';
+const renderComponent = createComponentRenderer(V1Banner);
+
describe('V1 Banner', () => {
let pinia: ReturnType;
let usersStore: ReturnType;
@@ -17,7 +19,7 @@ describe('V1 Banner', () => {
});
it('should render banner', () => {
- const { container } = render(V1Banner);
+ const { container } = renderComponent();
expect(container).toMatchSnapshot();
expect(container.querySelectorAll('a')).toHaveLength(1);
});
@@ -26,7 +28,7 @@ describe('V1 Banner', () => {
usersStore.usersById = { '1': { role: ROLE.Owner } as IUser };
usersStore.currentUserId = '1';
- const { container } = render(V1Banner);
+ const { container } = renderComponent();
expect(container).toMatchSnapshot();
expect(container.querySelectorAll('a')).toHaveLength(2);
});
diff --git a/packages/editor-ui/src/components/banners/__tests__/__snapshots__/V1Banner.spec.ts.snap b/packages/editor-ui/src/components/banners/__tests__/__snapshots__/V1Banner.spec.ts.snap
index afc0523e0cad7..41daf105174c4 100644
--- a/packages/editor-ui/src/components/banners/__tests__/__snapshots__/V1Banner.spec.ts.snap
+++ b/packages/editor-ui/src/components/banners/__tests__/__snapshots__/V1Banner.spec.ts.snap
@@ -2,69 +2,209 @@
exports[`V1 Banner > should render banner 1`] = `
-
-
-
- n8n has been updated to version 1, introducing some breaking changes. Please consult the
-
+
+
+
+
+
+
+
+
+
+
+
+
- migration guide
-
- for more information.
+
+
+ n8n has been updated to version 1, introducing some breaking changes. Please consult the
+
+ migration guide
+
+ for more information.
+
+
+
+
+
+
-
+
+
-
+
+
+
+
`;
exports[`V1 Banner > should render banner with dismiss call if user is owner 1`] = `
+
+
-
+
+
`;
diff --git a/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue b/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue
index 85d8dedad7153..bc443c1732027 100644
--- a/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue
+++ b/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue
@@ -96,7 +96,7 @@ function openContextMenu(event: MouseEvent) {
-
+
diff --git a/packages/editor-ui/src/components/executions/workflow/WorkflowExecutionAnnotationPanel.vue b/packages/editor-ui/src/components/executions/workflow/WorkflowExecutionAnnotationPanel.vue
index 1ae4ef0e5c4df..437cfd8e12f7f 100644
--- a/packages/editor-ui/src/components/executions/workflow/WorkflowExecutionAnnotationPanel.vue
+++ b/packages/editor-ui/src/components/executions/workflow/WorkflowExecutionAnnotationPanel.vue
@@ -179,7 +179,7 @@ const onTagsEditEsc = () => {
-
+
diff --git a/packages/editor-ui/src/views/SettingsLdapView.vue b/packages/editor-ui/src/views/SettingsLdapView.vue
index 8feca49da78c4..6cab6b1ba54d5 100644
--- a/packages/editor-ui/src/views/SettingsLdapView.vue
+++ b/packages/editor-ui/src/views/SettingsLdapView.vue
@@ -633,7 +633,7 @@ export default defineComponent({
-
+
diff --git a/packages/editor-ui/src/views/SettingsLogStreamingView.vue b/packages/editor-ui/src/views/SettingsLogStreamingView.vue
index e8abb67e64d2a..0f62a31aeed1c 100644
--- a/packages/editor-ui/src/views/SettingsLogStreamingView.vue
+++ b/packages/editor-ui/src/views/SettingsLogStreamingView.vue
@@ -175,7 +175,7 @@ export default defineComponent({
-
+
@@ -207,7 +207,7 @@ export default defineComponent({
@click:button="addDestination"
>
-
+
@@ -215,7 +215,7 @@ export default defineComponent({
-
+
@@ -225,7 +225,7 @@ export default defineComponent({
@click:button="goToUpgrade"
>
-
+
diff --git a/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/AppsRequiringCredsNotice.vue b/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/AppsRequiringCredsNotice.vue
index a640b49f9da50..ac5bfbe63a4eb 100644
--- a/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/AppsRequiringCredsNotice.vue
+++ b/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/AppsRequiringCredsNotice.vue
@@ -28,7 +28,7 @@ const appNodeCounts = computed(() => {
-
+
diff --git a/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/SetupTemplateFormStep.vue b/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/SetupTemplateFormStep.vue
index 2e64dece86b02..c482d3111477e 100644
--- a/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/SetupTemplateFormStep.vue
+++ b/packages/editor-ui/src/views/SetupWorkflowFromTemplateView/SetupTemplateFormStep.vue
@@ -95,7 +95,7 @@ const onCredentialModalOpened = () => {
:plural="credentials.usedBy.length"
scope="global"
>
-
+
diff --git a/packages/editor-ui/src/views/TemplatesSearchView.vue b/packages/editor-ui/src/views/TemplatesSearchView.vue
index 61ce8b42e0fe0..af0381d8209dd 100644
--- a/packages/editor-ui/src/views/TemplatesSearchView.vue
+++ b/packages/editor-ui/src/views/TemplatesSearchView.vue
@@ -410,7 +410,7 @@ export default defineComponent({
/>
-
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0b9e8ca0510d4..d94ec4a582b7d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1205,9 +1205,6 @@ importers:
'@vitest/coverage-v8':
specifier: catalog:frontend
version: 1.6.0(vitest@1.6.0(@types/node@18.16.16)(jsdom@23.0.1)(sass@1.64.1)(terser@5.16.1))
- '@vue/test-utils':
- specifier: ^2.4.3
- version: 2.4.3(@vue/server-renderer@3.4.21(vue@3.4.21(typescript@5.6.2)))(vue@3.4.21(typescript@5.6.2))
autoprefixer:
specifier: ^10.4.19
version: 10.4.19(postcss@8.4.38)
From c1d88f3bb3c24b22051276b75ef9182c887d52c8 Mon Sep 17 00:00:00 2001
From: Tomi Turtiainen <10324676+tomi@users.noreply.github.com>
Date: Wed, 18 Sep 2024 09:58:09 +0300
Subject: [PATCH 2/5] ci(benchmark): Fix bootstrap script (#10863)
---
packages/@n8n/benchmark/scripts/bootstrap.sh | 1 -
packages/@n8n/benchmark/scripts/vm-benchmark.sh | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/packages/@n8n/benchmark/scripts/bootstrap.sh b/packages/@n8n/benchmark/scripts/bootstrap.sh
index c5a8b57db53b7..02858094c8d58 100644
--- a/packages/@n8n/benchmark/scripts/bootstrap.sh
+++ b/packages/@n8n/benchmark/scripts/bootstrap.sh
@@ -43,7 +43,6 @@ sudo systemctl disable getty@tty1.service
sudo systemctl disable serial-getty@ttyS0.service
# Snap
sudo systemctl disable snapd.service
-sudo apt remove snapd
# Unattended upgrades
sudo systemctl disable unattended-upgrades.service
# Cron
diff --git a/packages/@n8n/benchmark/scripts/vm-benchmark.sh b/packages/@n8n/benchmark/scripts/vm-benchmark.sh
index 6bf215cd67963..13b7eb2b1a7fd 100644
--- a/packages/@n8n/benchmark/scripts/vm-benchmark.sh
+++ b/packages/@n8n/benchmark/scripts/vm-benchmark.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Install fio
-sudo apt-get -y install fio > /dev/null
+DEBIAN_FRONTEND=noninteractive sudo apt-get -y install fio > /dev/null
# Run the disk benchmark
fio --name=rand_rw --ioengine=libaio --rw=randrw --rwmixread=70 --bs=4k --numjobs=4 --size=1G --runtime=30 --directory=/n8n --group_reporting
@@ -10,4 +10,4 @@ fio --name=rand_rw --ioengine=libaio --rw=randrw --rwmixread=70 --bs=4k --numjob
sudo rm /n8n/rand_rw.*
# Uninstall fio
-sudo apt-get -y remove fio
+DEBIAN_FRONTEND=noninteractive sudo apt-get -y remove fio > /dev/null
From 5a1db6db1adad43887e839181719818474bc66b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ra=C3=BAl=20G=C3=B3mez=20Morales?=
Date: Wed, 18 Sep 2024 09:10:51 +0200
Subject: [PATCH 3/5] fix(editor): Restore V1 keybinding, Space Key to toggle
panning (#10841)
---
packages/editor-ui/src/components/canvas/Canvas.spec.ts | 8 ++++----
packages/editor-ui/src/components/canvas/Canvas.vue | 5 ++++-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/packages/editor-ui/src/components/canvas/Canvas.spec.ts b/packages/editor-ui/src/components/canvas/Canvas.spec.ts
index 256377a8f3bed..8768e97798617 100644
--- a/packages/editor-ui/src/components/canvas/Canvas.spec.ts
+++ b/packages/editor-ui/src/components/canvas/Canvas.spec.ts
@@ -164,7 +164,7 @@ describe('Canvas', () => {
const pane = canvas.querySelector('.vue-flow__pane');
if (!pane) throw new Error('VueFlow pane not found');
- await fireEvent.keyDown(pane, { view: window, key: 'Shift' });
+ await fireEvent.keyDown(pane, { view: window, key: ' ' });
await fireEvent.mouseDown(pane, { view: window });
await fireEvent.mouseMove(pane, {
view: window,
@@ -172,7 +172,7 @@ describe('Canvas', () => {
clientY: 100,
});
await fireEvent.mouseUp(pane, { view: window });
- await fireEvent.keyUp(pane, { view: window, key: 'Shift' });
+ await fireEvent.keyUp(pane, { view: window, key: ' ' });
vi.advanceTimersByTime(minimapTransitionDuration);
await waitFor(() => expect(getByTestId('canvas-minimap')).toBeVisible());
@@ -196,7 +196,7 @@ describe('Canvas', () => {
const pane = canvas.querySelector('.vue-flow__pane');
if (!pane) throw new Error('VueFlow pane not found');
- await fireEvent.keyDown(pane, { view: window, key: 'Shift' });
+ await fireEvent.keyDown(pane, { view: window, key: ' ' });
await fireEvent.mouseDown(pane, { view: window });
await fireEvent.mouseMove(pane, {
view: window,
@@ -204,7 +204,7 @@ describe('Canvas', () => {
clientY: 100,
});
await fireEvent.mouseUp(pane, { view: window });
- await fireEvent.keyUp(pane, { view: window, key: 'Shift' });
+ await fireEvent.keyUp(pane, { view: window, key: ' ' });
vi.advanceTimersByTime(minimapTransitionDuration);
await waitFor(() => expect(getByTestId('canvas-minimap')).toBeVisible());
diff --git a/packages/editor-ui/src/components/canvas/Canvas.vue b/packages/editor-ui/src/components/canvas/Canvas.vue
index 8efb8fcea513c..a552c5bd23e24 100644
--- a/packages/editor-ui/src/components/canvas/Canvas.vue
+++ b/packages/editor-ui/src/components/canvas/Canvas.vue
@@ -122,7 +122,10 @@ const classes = computed(() => ({
const disableKeyBindings = computed(() => !props.keyBindings);
-const panningKeyCode = 'Shift';
+/**
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values#whitespace_keys
+ */
+const panningKeyCode = ' ';
const isPanningEnabled = ref(false);
onKeyDown(panningKeyCode, () => {
From 4f0a1a953f9cbd9ff069b906cc8b15ec83a5a543 Mon Sep 17 00:00:00 2001
From: Tomi Turtiainen <10324676+tomi@users.noreply.github.com>
Date: Wed, 18 Sep 2024 10:19:33 +0300
Subject: [PATCH 4/5] refactor: Enable import/order for design-system, workflow
and @n8n packages (#10847)
---
cypress/composables/workflow.ts | 2 +-
cypress/e2e/1-workflows.cy.ts | 2 +-
cypress/e2e/10-settings-log-streaming.cy.ts | 2 +-
cypress/e2e/10-undo-redo.cy.ts | 2 +-
cypress/e2e/12-canvas-actions.cy.ts | 4 +-
cypress/e2e/12-canvas.cy.ts | 4 +-
cypress/e2e/14-mapping.cy.ts | 4 +-
cypress/e2e/16-webhook-node.cy.ts | 3 +-
cypress/e2e/17-sharing.cy.ts | 2 +-
cypress/e2e/18-user-management.cy.ts | 2 +-
cypress/e2e/19-execution.cy.ts | 2 +-
cypress/e2e/2-credentials.cy.ts | 1 +
cypress/e2e/20-workflow-executions.cy.ts | 3 +-
cypress/e2e/21-community-nodes.cy.ts | 11 ++--
.../e2e/233-AI-switch-to-logs-on-error.cy.ts | 29 +++++----
cypress/e2e/27-cloud.cy.ts | 2 +-
.../e2e/27-two-factor-authentication.cy.ts | 5 +-
cypress/e2e/29-templates.cy.ts | 6 +-
cypress/e2e/30-langchain.cy.ts | 64 +++++++++----------
cypress/e2e/31-demo.cy.ts | 2 +-
.../e2e/34-template-credentials-setup.cy.ts | 10 +--
cypress/e2e/36-versions.cy.ts | 2 +-
cypress/e2e/39-projects.cy.ts | 2 +-
cypress/e2e/4-node-creator.cy.ts | 4 +-
cypress/e2e/44-routing.cy.ts | 6 +-
cypress/e2e/5-ndv.cy.ts | 4 +-
cypress/e2e/6-code-node.cy.ts | 3 +-
cypress/e2e/7-workflow-actions.cy.ts | 4 +-
cypress/pages/mfa-login.ts | 2 +-
cypress/pages/modals/credentials-modal.ts | 2 +-
cypress/pages/ndv.ts | 2 +-
cypress/pages/settings-log-streaming.ts | 2 +-
cypress/pages/settings-personal.ts | 3 +-
cypress/pages/settings-users.ts | 4 +-
cypress/pages/signin.ts | 2 +-
cypress/pages/template-credential-setup.ts | 4 +-
cypress/pages/variables.ts | 1 +
cypress/pages/workflow.ts | 4 +-
cypress/support/commands.ts | 5 +-
cypress/support/e2e.ts | 1 +
cypress/utils/executions.ts | 3 +-
packages/@n8n/api-types/src/push/index.ts | 8 +--
packages/@n8n/benchmark/src/commands/list.ts | 3 +-
packages/@n8n/benchmark/src/commands/run.ts | 7 +-
.../authenticated-n8n-api-client.ts | 1 +
.../n8n-api-client/workflows-api-client.ts | 3 +-
.../src/scenario/scenario-data-loader.ts | 3 +-
.../benchmark/src/scenario/scenario-loader.ts | 3 +-
.../src/test-execution/k6-executor.ts | 5 +-
.../src/test-execution/scenario-runner.ts | 7 +-
.../src/test-execution/test-report.ts | 1 +
packages/@n8n/chat/src/App.vue | 5 +-
.../@n8n/chat/src/__stories__/App.stories.ts | 3 +-
.../@n8n/chat/src/__tests__/index.spec.ts | 1 +
.../chat/src/__tests__/utils/selectors.ts | 1 +
packages/@n8n/chat/src/components/Chat.vue | 5 +-
.../@n8n/chat/src/components/ChatFile.vue | 7 +-
.../@n8n/chat/src/components/ChatWindow.vue | 1 +
.../chat/src/components/GetStartedFooter.vue | 2 +-
packages/@n8n/chat/src/components/Input.vue | 8 ++-
packages/@n8n/chat/src/components/Layout.vue | 1 +
packages/@n8n/chat/src/components/Message.vue | 16 +++--
.../chat/src/components/MessageTyping.vue | 4 +-
.../@n8n/chat/src/components/MessagesList.vue | 3 +-
packages/@n8n/chat/src/composables/useChat.ts | 1 +
packages/@n8n/chat/src/composables/useI18n.ts | 1 +
.../@n8n/chat/src/composables/useOptions.ts | 1 +
packages/@n8n/chat/src/constants/symbols.ts | 1 +
packages/@n8n/chat/src/index.ts | 8 ++-
packages/@n8n/chat/src/plugins/chat.ts | 7 +-
packages/@n8n/chat/src/types/chat.ts | 1 +
.../@n8n/client-oauth2/src/ClientOAuth2.ts | 7 +-
.../client-oauth2/src/ClientOAuth2Token.ts | 2 +-
packages/@n8n/client-oauth2/src/CodeFlow.ts | 1 +
.../@n8n/client-oauth2/test/CodeFlow.test.ts | 6 +-
.../test/CredentialsFlow.test.ts | 5 +-
.../codemirror-lang/src/expressions/index.ts | 1 +
.../test/expressions/expressions.test.ts | 3 +-
packages/@n8n/config/src/index.ts | 18 +++---
packages/@n8n/config/test/config.test.ts | 3 +-
packages/@n8n/config/test/decorators.test.ts | 1 +
packages/@n8n/imap/src/ImapSimple.ts | 2 +-
packages/@n8n/imap/src/PartData.ts | 2 +-
packages/@n8n/imap/src/helpers/getMessage.ts | 1 +
packages/@n8n/imap/src/index.ts | 3 +-
packages/@n8n_io/eslint-config/base.js | 12 +++-
packages/cli/.eslintrc.js | 11 ----
packages/design-system/.eslintrc.js | 1 -
packages/design-system/src/__tests__/setup.ts | 1 +
.../AssistantAvatar.stories.ts | 3 +-
.../__tests__/AskAssistantAvatar.spec.ts | 1 +
.../AskAssistantButton.stories.ts | 3 +-
.../AskAssistantButton/AskAssistantButton.vue | 3 +-
.../__tests__/AskAssistantButton.spec.ts | 1 +
.../AskAssistantChat.stories.ts | 3 +-
.../AskAssistantChat/AskAssistantChat.vue | 18 +++---
.../__tests__/AskAssistantChat.spec.ts | 1 +
.../AskAssistantIcon/AssistantIcon.stories.ts | 3 +-
.../__tests__/AssistantIcon.spec.ts | 1 +
.../AssistantLoadingMessage.stories.ts | 3 +-
.../AssistantLoadingMessage.vue | 1 +
.../DemoComponent.stories.ts | 3 +-
.../DemoComponent.vue | 1 +
.../AskAssistantLoadingMessage.spec.ts | 1 +
.../AskAssistantText/AssistantText.stories.ts | 3 +-
.../__tests__/AssistantText.spec.ts | 1 +
.../src/components/BetaTag/BetaTag.stories.ts | 3 +-
.../BetaTag/__tests__/BetaTag.spec.ts | 1 +
.../BlinkingCursor/BlinkingCursor.stories.ts | 3 +-
.../__tests__/BlinkingCursor.spec.ts | 1 +
.../components/CodeDiff/CodeDiff.stories.ts | 3 +-
.../src/components/CodeDiff/CodeDiff.vue | 1 +
.../CodeDiff/__tests__/CodeDiff.spec.ts | 1 +
.../__tests__/ConditionalRouterLink.spec.ts | 1 +
.../InlineAskAssistantButton.stories.ts | 3 +-
.../InlineAskAssistantButton.vue | 3 +-
.../N8nActionBox/ActionBox.stories.ts | 3 +-
.../src/components/N8nActionBox/ActionBox.vue | 7 +-
.../N8nActionBox/__tests__/ActionBox.spec.ts | 1 +
.../ActionDropdown.stories.ts | 3 +-
.../N8nActionDropdown/ActionDropdown.vue | 8 ++-
.../__tests__/ActionDropdown.spec.ts | 1 +
.../N8nActionToggle/ActionToggle.stories.ts | 3 +-
.../N8nActionToggle/ActionToggle.vue | 4 +-
.../src/components/N8nAlert/Alert.stories.ts | 1 +
.../src/components/N8nAlert/Alert.vue | 1 +
.../N8nAlert/__tests__/Alert.spec.ts | 3 +-
.../components/N8nAvatar/Avatar.stories.ts | 1 +
.../src/components/N8nAvatar/Avatar.vue | 1 +
.../N8nAvatar/__tests__/Avatar.test.ts | 1 +
.../src/components/N8nBadge/Badge.stories.ts | 1 +
.../src/components/N8nBadge/Badge.vue | 1 +
.../N8nBadge/__tests__/Badge.spec.ts | 1 +
.../components/N8nBlockUi/BlockUi.stories.ts | 1 +
.../N8nBlockUi/__tests__/BlockUi.spec.ts | 1 +
.../components/N8nButton/Button.stories.ts | 3 +-
.../src/components/N8nButton/Button.vue | 4 +-
.../N8nButton/__tests__/Button.spec.ts | 1 +
.../components/N8nCallout/Callout.stories.ts | 3 +-
.../src/components/N8nCallout/Callout.vue | 6 +-
.../N8nCallout/__tests__/Callout.spec.ts | 1 +
.../src/components/N8nCard/Card.stories.ts | 3 +-
.../components/N8nCard/__tests__/Card.spec.ts | 1 +
.../N8nCheckbox/Checkbox.stories.ts | 5 +-
.../src/components/N8nCheckbox/Checkbox.vue | 3 +-
.../N8nCheckbox/__tests__/Checkbox.spec.ts | 1 +
.../N8nCircleLoader/CircleLoader.stories.ts | 3 +-
.../__tests__/CircleLoader.spec.ts | 1 +
.../N8nColorPicker/ColorPicker.stories.ts | 1 +
.../components/N8nColorPicker/ColorPicker.vue | 3 +-
.../__tests__/ColorPicker.spec.ts | 1 +
.../N8nDatatable/Datatable.stories.ts | 3 +-
.../src/components/N8nDatatable/Datatable.vue | 9 +--
.../N8nDatatable/__tests__/Datatable.spec.ts | 6 +-
.../components/N8nDatatable/__tests__/data.ts | 1 +
.../components/N8nFormBox/FormBox.stories.ts | 3 +-
.../src/components/N8nFormBox/FormBox.vue | 7 +-
.../N8nFormInput/FormInput.stories.ts | 3 +-
.../src/components/N8nFormInput/FormInput.vue | 16 ++---
.../N8nFormInputs/FormInputs.stories.ts | 3 +-
.../components/N8nFormInputs/FormInputs.vue | 5 +-
.../components/N8nHeading/Heading.stories.ts | 1 +
.../src/components/N8nIcon/Icon.stories.ts | 1 +
.../src/components/N8nIcon/Icon.vue | 2 +
.../N8nIconButton/IconButton.stories.ts | 3 +-
.../components/N8nIconButton/IconButton.vue | 1 +
.../N8nInfoAccordion/InfoAccordion.stories.ts | 5 +-
.../N8nInfoAccordion/InfoAccordion.vue | 6 +-
.../components/N8nInfoTip/InfoTip.stories.ts | 1 +
.../src/components/N8nInfoTip/InfoTip.vue | 3 +-
.../N8nInfoTip/__tests__/InfoTip.spec.ts | 1 +
.../src/components/N8nInput/Input.stories.ts | 5 +-
.../src/components/N8nInput/Input.vue | 8 ++-
.../N8nInput/__tests__/Input.spec.ts | 1 +
.../N8nInputLabel/InputLabel.stories.ts | 3 +-
.../components/N8nInputLabel/InputLabel.vue | 5 +-
.../N8nInputNumber/InputNumber.stories.ts | 3 +-
.../components/N8nInputNumber/InputNumber.vue | 3 +-
.../KeyboardShortcut.stories.ts | 3 +-
.../N8nKeyboardShortcut.vue | 1 +
.../src/components/N8nLink/Link.stories.ts | 3 +-
.../src/components/N8nLink/Link.vue | 6 +-
.../components/N8nLoading/Loading.stories.ts | 1 +
.../N8nMarkdown/Markdown.stories.ts | 1 +
.../src/components/N8nMarkdown/Markdown.vue | 6 +-
.../N8nMarkdown/__tests__/Markdown.spec.ts | 1 +
.../src/components/N8nMenu/Menu.stories.ts | 5 +-
.../src/components/N8nMenu/Menu.vue | 5 +-
.../N8nMenuItem/MenuItem.stories.ts | 5 +-
.../src/components/N8nMenuItem/MenuItem.vue | 11 ++--
.../src/components/N8nMenuItem/routerUtil.ts | 3 +-
.../NodeCreatorNode.stories.ts | 3 +-
.../N8nNodeCreatorNode/NodeCreatorNode.vue | 5 +-
.../N8nNodeIcon/NodeIcon.stories.ts | 3 +-
.../src/components/N8nNodeIcon/NodeIcon.vue | 3 +-
.../components/N8nNotice/Notice.stories.ts | 3 +-
.../src/components/N8nNotice/Notice.vue | 3 +-
.../N8nNotice/__tests__/Notice.spec.ts | 4 +-
.../N8nPagination/Pagination.stories.ts | 1 +
.../components/N8nPopover/Popover.stories.ts | 1 +
.../src/components/N8nPulse/Pulse.stories.ts | 3 +-
.../N8nRadioButtons/RadioButtons.stories.ts | 4 +-
.../RecycleScroller.stories.ts | 3 +-
.../__tests__/RecycleScroller.spec.ts | 1 +
.../N8nResizeWrapper/ResizeWrapper.stories.ts | 5 +-
.../ResizeableSticky.stories.ts | 1 +
.../N8nResizeableSticky/ResizeableSticky.vue | 3 +-
.../N8nRoute/__tests__/Route.spec.ts | 1 +
.../components/N8nSelect/Select.stories.ts | 5 +-
.../src/components/N8nSelect/Select.vue | 4 +-
.../N8nSelect/__tests__/Select.spec.ts | 10 +--
.../components/N8nSpinner/Spinner.stories.ts | 1 +
.../src/components/N8nSpinner/Spinner.vue | 1 +
.../components/N8nSticky/Sticky.stories.ts | 1 +
.../src/components/N8nSticky/Sticky.vue | 7 +-
.../src/components/N8nTabs/Tabs.stories.ts | 4 +-
.../src/components/N8nTabs/Tabs.vue | 3 +-
.../src/components/N8nTag/Tag.stories.ts | 1 +
.../src/components/N8nTags/Tags.stories.ts | 1 +
.../src/components/N8nTags/Tags.vue | 5 +-
.../src/components/N8nText/Text.stories.ts | 1 +
.../src/components/N8nText/Text.vue | 1 +
.../components/N8nTooltip/Tooltip.stories.ts | 1 +
.../src/components/N8nTooltip/Tooltip.vue | 4 +-
.../N8nTooltip/__tests__/Tooltip.spec.ts | 3 +-
.../src/components/N8nTree/Tree.stories.ts | 3 +-
.../components/N8nTree/__tests__/Tree.spec.ts | 1 +
.../N8nUserInfo/UserInfo.stories.ts | 1 +
.../src/components/N8nUserInfo/UserInfo.vue | 5 +-
.../N8nUserSelect/UserSelect.stories.ts | 3 +-
.../components/N8nUserSelect/UserSelect.vue | 7 +-
.../N8nUserStack/UserStack.stories.ts | 1 +
.../src/components/N8nUserStack/UserStack.vue | 2 +
.../N8nUserStack/__tests__/UserStack.spec.ts | 4 +-
.../N8nUsersList/UsersList.stories.ts | 4 +-
.../src/components/N8nUsersList/UsersList.vue | 5 +-
.../src/directives/n8n-truncate.test.ts | 1 +
.../src/directives/n8n-truncate.ts | 1 +
packages/design-system/src/locale/index.ts | 5 +-
packages/design-system/src/plugin.ts | 1 +
.../src/styleguide/ColorCircles.vue | 1 +
.../styleguide/__tests__/ColorCircles.spec.ts | 1 +
.../src/styleguide/__tests__/Sizes.spec.ts | 1 +
.../src/styleguide/border.stories.ts | 1 +
.../src/styleguide/colors.stories.ts | 1 +
.../styleguide/colorsprimitives.stories.ts | 1 +
.../src/styleguide/fonts.stories.ts | 1 +
.../src/styleguide/spacing.stories.ts | 1 +
.../styleguide/utilities/spacing.stories.ts | 1 +
packages/workflow/.eslintrc.js | 1 -
packages/workflow/src/ErrorReporterProxy.ts | 2 +-
packages/workflow/src/Expression.ts | 23 ++++---
.../workflow/src/ExpressionEvaluatorProxy.ts | 5 +-
packages/workflow/src/ExpressionSandboxing.ts | 1 +
.../src/Extensions/ArrayExtensions.ts | 4 +-
.../workflow/src/Extensions/DateExtensions.ts | 6 +-
.../src/Extensions/ExpressionExtension.ts | 19 +++---
.../src/Extensions/ExtendedFunctions.ts | 4 +-
.../src/Extensions/NumberExtensions.ts | 3 +-
.../src/Extensions/ObjectExtensions.ts | 2 +-
.../src/Extensions/StringExtensions.ts | 9 +--
packages/workflow/src/Extensions/utils.ts | 1 +
packages/workflow/src/Interfaces.ts | 20 +++---
packages/workflow/src/MessageEventBus.ts | 1 +
packages/workflow/src/NativeMethods/index.ts | 4 +-
packages/workflow/src/NodeHelpers.ts | 9 ++-
.../src/NodeParameters/FilterParameter.ts | 5 +-
packages/workflow/src/RoutingNode.ts | 9 +--
packages/workflow/src/TelemetryHelpers.ts | 26 ++++----
packages/workflow/src/TypeValidation.ts | 5 +-
packages/workflow/src/Workflow.ts | 19 +++---
packages/workflow/src/WorkflowDataProxy.ts | 14 ++--
.../src/errors/abstract/node.error.ts | 4 +-
.../workflow/src/errors/application.error.ts | 2 +-
.../src/errors/credential-access-error.ts | 2 +-
.../workflow/src/errors/expression.error.ts | 2 +-
.../workflow/src/errors/node-api.error.ts | 19 +++---
.../src/errors/node-operation.error.ts | 4 +-
.../src/errors/trigger-close.error.ts | 2 +-
.../src/errors/workflow-activation.error.ts | 2 +-
.../src/errors/workflow-operation.error.ts | 2 +-
packages/workflow/src/utils.ts | 13 ++--
packages/workflow/test/AugmentObject.test.ts | 2 +-
packages/workflow/test/Expression.test.ts | 14 ++--
.../ArrayExtensions.test.ts | 2 +-
.../BooleanExtensions.test.ts | 2 +-
.../DateExtensions.test.ts | 2 +
.../ExpressionExtension.test.ts | 1 +
.../test/ExpressionExtensions/Helpers.ts | 1 +
.../NumberExtensions.test.ts | 1 +
.../ObjectExtensions.test.ts | 2 +-
.../StringExtensions.test.ts | 1 +
.../workflow/test/ExpressionFixtures/base.ts | 2 +-
.../test/ExpressionSandboxing.test.ts | 3 +-
.../workflow/test/FilterParameter.test.ts | 5 +-
packages/workflow/test/Helpers.ts | 3 +-
packages/workflow/test/NodeErrors.test.ts | 3 +-
packages/workflow/test/NodeHelpers.test.ts | 2 +-
packages/workflow/test/NodeTypes.ts | 1 +
packages/workflow/test/RoutingNode.test.ts | 8 +--
.../workflow/test/TelemetryHelpers.test.ts | 13 ++--
packages/workflow/test/TypeValidation.test.ts | 1 +
packages/workflow/test/Workflow.test.ts | 3 +-
.../workflow/test/WorkflowDataProxy.test.ts | 3 +-
.../workflow/test/errors/node.error.test.ts | 3 +-
305 files changed, 723 insertions(+), 484 deletions(-)
diff --git a/cypress/composables/workflow.ts b/cypress/composables/workflow.ts
index b3d6f20c2840c..8d37d5f2adf85 100644
--- a/cypress/composables/workflow.ts
+++ b/cypress/composables/workflow.ts
@@ -1,5 +1,5 @@
-import { ROUTES } from '../constants';
import { getManualChatModal } from './modals/chat-modal';
+import { ROUTES } from '../constants';
/**
* Types
diff --git a/cypress/e2e/1-workflows.cy.ts b/cypress/e2e/1-workflows.cy.ts
index d01f046d75375..68353460122a6 100644
--- a/cypress/e2e/1-workflows.cy.ts
+++ b/cypress/e2e/1-workflows.cy.ts
@@ -1,5 +1,5 @@
-import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
+import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
const WorkflowsPage = new WorkflowsPageClass();
diff --git a/cypress/e2e/10-settings-log-streaming.cy.ts b/cypress/e2e/10-settings-log-streaming.cy.ts
index 9acec76f420bc..1954543ca0816 100644
--- a/cypress/e2e/10-settings-log-streaming.cy.ts
+++ b/cypress/e2e/10-settings-log-streaming.cy.ts
@@ -1,6 +1,6 @@
import { SettingsLogStreamingPage } from '../pages';
-import { getVisibleModalOverlay } from '../utils/modal';
import { getVisibleDropdown } from '../utils';
+import { getVisibleModalOverlay } from '../utils/modal';
const settingsLogStreamingPage = new SettingsLogStreamingPage();
diff --git a/cypress/e2e/10-undo-redo.cy.ts b/cypress/e2e/10-undo-redo.cy.ts
index 645344337675b..7e3b5ef8adc1d 100644
--- a/cypress/e2e/10-undo-redo.cy.ts
+++ b/cypress/e2e/10-undo-redo.cy.ts
@@ -4,9 +4,9 @@ import {
SET_NODE_NAME,
EDIT_FIELDS_SET_NODE_NAME,
} from '../constants';
-import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { MessageBox as MessageBoxClass } from '../pages/modals/message-box';
import { NDV } from '../pages/ndv';
+import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
// Suite-specific constants
const CODE_NODE_NEW_NAME = 'Something else';
diff --git a/cypress/e2e/12-canvas-actions.cy.ts b/cypress/e2e/12-canvas-actions.cy.ts
index 53dad1cc89669..8a42521d845c5 100644
--- a/cypress/e2e/12-canvas-actions.cy.ts
+++ b/cypress/e2e/12-canvas-actions.cy.ts
@@ -1,5 +1,3 @@
-import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
-import { successToast } from '../pages/notifications';
import {
MANUAL_TRIGGER_NODE_NAME,
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
@@ -9,6 +7,8 @@ import {
IF_NODE_NAME,
HTTP_REQUEST_NODE_NAME,
} from './../constants';
+import { successToast } from '../pages/notifications';
+import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
const WorkflowPage = new WorkflowPageClass();
describe('Canvas Actions', () => {
diff --git a/cypress/e2e/12-canvas.cy.ts b/cypress/e2e/12-canvas.cy.ts
index 325e509e797dc..4c7cccaafef5f 100644
--- a/cypress/e2e/12-canvas.cy.ts
+++ b/cypress/e2e/12-canvas.cy.ts
@@ -1,5 +1,3 @@
-import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
-import { NDV, WorkflowExecutionsTab } from '../pages';
import {
MANUAL_TRIGGER_NODE_NAME,
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
@@ -9,6 +7,8 @@ import {
SWITCH_NODE_NAME,
MERGE_NODE_NAME,
} from './../constants';
+import { NDV, WorkflowExecutionsTab } from '../pages';
+import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
const WorkflowPage = new WorkflowPageClass();
const ExecutionsTab = new WorkflowExecutionsTab();
diff --git a/cypress/e2e/14-mapping.cy.ts b/cypress/e2e/14-mapping.cy.ts
index 43103415e3c04..3bbbd0b293459 100644
--- a/cypress/e2e/14-mapping.cy.ts
+++ b/cypress/e2e/14-mapping.cy.ts
@@ -1,10 +1,10 @@
-import { WorkflowPage, NDV } from '../pages';
-import { getVisibleSelect } from '../utils';
import {
MANUAL_TRIGGER_NODE_NAME,
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
SCHEDULE_TRIGGER_NODE_NAME,
} from './../constants';
+import { WorkflowPage, NDV } from '../pages';
+import { getVisibleSelect } from '../utils';
const workflowPage = new WorkflowPage();
const ndv = new NDV();
diff --git a/cypress/e2e/16-webhook-node.cy.ts b/cypress/e2e/16-webhook-node.cy.ts
index 791a704174e8d..93460043881b0 100644
--- a/cypress/e2e/16-webhook-node.cy.ts
+++ b/cypress/e2e/16-webhook-node.cy.ts
@@ -1,7 +1,8 @@
import { nanoid } from 'nanoid';
+
+import { BACKEND_BASE_URL, EDIT_FIELDS_SET_NODE_NAME } from '../constants';
import { WorkflowPage, NDV, CredentialsModal } from '../pages';
import { cowBase64 } from '../support/binaryTestFiles';
-import { BACKEND_BASE_URL, EDIT_FIELDS_SET_NODE_NAME } from '../constants';
import { getVisibleSelect } from '../utils';
const workflowPage = new WorkflowPage();
diff --git a/cypress/e2e/17-sharing.cy.ts b/cypress/e2e/17-sharing.cy.ts
index c90a884325239..e2af15f10180c 100644
--- a/cypress/e2e/17-sharing.cy.ts
+++ b/cypress/e2e/17-sharing.cy.ts
@@ -1,3 +1,4 @@
+import * as projects from '../composables/projects';
import { INSTANCE_MEMBERS, INSTANCE_OWNER, INSTANCE_ADMIN, NOTION_NODE_NAME } from '../constants';
import {
CredentialsModal,
@@ -8,7 +9,6 @@ import {
WorkflowsPage,
} from '../pages';
import { getVisibleDropdown, getVisiblePopper, getVisibleSelect } from '../utils';
-import * as projects from '../composables/projects';
/**
* User U1 - Instance owner
diff --git a/cypress/e2e/18-user-management.cy.ts b/cypress/e2e/18-user-management.cy.ts
index b53b0fdf53a9d..fe91a7293555e 100644
--- a/cypress/e2e/18-user-management.cy.ts
+++ b/cypress/e2e/18-user-management.cy.ts
@@ -1,8 +1,8 @@
import { INSTANCE_MEMBERS, INSTANCE_OWNER, INSTANCE_ADMIN } from '../constants';
import { MainSidebar, SettingsSidebar, SettingsUsersPage } from '../pages';
+import { errorToast, successToast } from '../pages/notifications';
import { PersonalSettingsPage } from '../pages/settings-personal';
import { getVisibleSelect } from '../utils';
-import { errorToast, successToast } from '../pages/notifications';
/**
* User A - Instance owner
diff --git a/cypress/e2e/19-execution.cy.ts b/cypress/e2e/19-execution.cy.ts
index d2c463f1bb153..d6b8d08fd5f4b 100644
--- a/cypress/e2e/19-execution.cy.ts
+++ b/cypress/e2e/19-execution.cy.ts
@@ -1,5 +1,5 @@
-import { NDV, WorkflowExecutionsTab, WorkflowPage as WorkflowPageClass } from '../pages';
import { SCHEDULE_TRIGGER_NODE_NAME, EDIT_FIELDS_SET_NODE_NAME } from '../constants';
+import { NDV, WorkflowExecutionsTab, WorkflowPage as WorkflowPageClass } from '../pages';
import { clearNotifications, errorToast, successToast } from '../pages/notifications';
const workflowPage = new WorkflowPageClass();
diff --git a/cypress/e2e/2-credentials.cy.ts b/cypress/e2e/2-credentials.cy.ts
index 9dbe6c6b5d763..dbc613bd64e60 100644
--- a/cypress/e2e/2-credentials.cy.ts
+++ b/cypress/e2e/2-credentials.cy.ts
@@ -1,4 +1,5 @@
import { type ICredentialType } from 'n8n-workflow';
+
import {
AGENT_NODE_NAME,
AI_TOOL_HTTP_NODE_NAME,
diff --git a/cypress/e2e/20-workflow-executions.cy.ts b/cypress/e2e/20-workflow-executions.cy.ts
index 5f2a26014376f..19256f3bf9d32 100644
--- a/cypress/e2e/20-workflow-executions.cy.ts
+++ b/cypress/e2e/20-workflow-executions.cy.ts
@@ -1,7 +1,8 @@
import type { RouteHandler } from 'cypress/types/net-stubbing';
+
+import executionOutOfMemoryServerResponse from '../fixtures/responses/execution-out-of-memory-server-response.json';
import { WorkflowPage } from '../pages';
import { WorkflowExecutionsTab } from '../pages/workflow-executions-tab';
-import executionOutOfMemoryServerResponse from '../fixtures/responses/execution-out-of-memory-server-response.json';
import { getVisibleSelect } from '../utils';
const workflowPage = new WorkflowPage();
diff --git a/cypress/e2e/21-community-nodes.cy.ts b/cypress/e2e/21-community-nodes.cy.ts
index bf88d3d24ce91..17f82ec573ec9 100644
--- a/cypress/e2e/21-community-nodes.cy.ts
+++ b/cypress/e2e/21-community-nodes.cy.ts
@@ -1,11 +1,11 @@
import type { ICredentialType } from 'n8n-workflow';
-import { NodeCreator } from '../pages/features/node-creator';
+
+import CustomCredential from '../fixtures/Custom_credential.json';
import CustomNodeFixture from '../fixtures/Custom_node.json';
-import { CredentialsModal, WorkflowPage } from '../pages';
-import CustomNodeWithN8nCredentialFixture from '../fixtures/Custom_node_n8n_credential.json';
import CustomNodeWithCustomCredentialFixture from '../fixtures/Custom_node_custom_credential.json';
-import CustomCredential from '../fixtures/Custom_credential.json';
-import { getVisibleSelect } from '../utils';
+import CustomNodeWithN8nCredentialFixture from '../fixtures/Custom_node_n8n_credential.json';
+import { CredentialsModal, WorkflowPage } from '../pages';
+import { NodeCreator } from '../pages/features/node-creator';
import {
confirmCommunityNodeUninstall,
confirmCommunityNodeUpdate,
@@ -13,6 +13,7 @@ import {
installFirstCommunityNode,
visitCommunityNodesSettings,
} from '../pages/settings-community-nodes';
+import { getVisibleSelect } from '../utils';
const credentialsModal = new CredentialsModal();
const nodeCreatorFeature = new NodeCreator();
diff --git a/cypress/e2e/233-AI-switch-to-logs-on-error.cy.ts b/cypress/e2e/233-AI-switch-to-logs-on-error.cy.ts
index 4c733df90dc48..eca3af81fbc32 100644
--- a/cypress/e2e/233-AI-switch-to-logs-on-error.cy.ts
+++ b/cypress/e2e/233-AI-switch-to-logs-on-error.cy.ts
@@ -1,5 +1,18 @@
import type { ExecutionError } from 'n8n-workflow/src';
-import { NDV, WorkflowPage as WorkflowPageClass } from '../pages';
+
+import {
+ closeManualChatModal,
+ getManualChatMessages,
+ getManualChatModalLogs,
+ getManualChatModalLogsEntries,
+ sendManualChatMessage,
+} from '../composables/modals/chat-modal';
+import { setCredentialValues } from '../composables/modals/credential-modal';
+import {
+ clickCreateNewCredential,
+ clickExecuteNode,
+ clickGetBackToCanvas,
+} from '../composables/ndv';
import {
addLanguageModelNodeToParent,
addMemoryNodeToParent,
@@ -18,19 +31,7 @@ import {
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
MANUAL_TRIGGER_NODE_NAME,
} from '../constants';
-import {
- clickCreateNewCredential,
- clickExecuteNode,
- clickGetBackToCanvas,
-} from '../composables/ndv';
-import { setCredentialValues } from '../composables/modals/credential-modal';
-import {
- closeManualChatModal,
- getManualChatMessages,
- getManualChatModalLogs,
- getManualChatModalLogsEntries,
- sendManualChatMessage,
-} from '../composables/modals/chat-modal';
+import { NDV, WorkflowPage as WorkflowPageClass } from '../pages';
import { createMockNodeExecutionData, getVisibleSelect, runMockWorkflowExecution } from '../utils';
const ndv = new NDV();
diff --git a/cypress/e2e/27-cloud.cy.ts b/cypress/e2e/27-cloud.cy.ts
index dd0d3b06ba6cc..e9b814597d8de 100644
--- a/cypress/e2e/27-cloud.cy.ts
+++ b/cypress/e2e/27-cloud.cy.ts
@@ -1,3 +1,4 @@
+import planData from '../fixtures/Plan_data_opt_in_trial.json';
import {
BannerStack,
MainSidebar,
@@ -5,7 +6,6 @@ import {
visitPublicApiPage,
getPublicApiUpgradeCTA,
} from '../pages';
-import planData from '../fixtures/Plan_data_opt_in_trial.json';
const mainSidebar = new MainSidebar();
const bannerStack = new BannerStack();
diff --git a/cypress/e2e/27-two-factor-authentication.cy.ts b/cypress/e2e/27-two-factor-authentication.cy.ts
index 21319dd79b5a5..dc62a0c58c087 100644
--- a/cypress/e2e/27-two-factor-authentication.cy.ts
+++ b/cypress/e2e/27-two-factor-authentication.cy.ts
@@ -1,9 +1,10 @@
import generateOTPToken from 'cypress-otp';
+
+import { MainSidebar } from './../pages/sidebar/main-sidebar';
import { INSTANCE_OWNER, INSTANCE_ADMIN, BACKEND_BASE_URL } from '../constants';
import { SigninPage } from '../pages';
-import { PersonalSettingsPage } from '../pages/settings-personal';
import { MfaLoginPage } from '../pages/mfa-login';
-import { MainSidebar } from './../pages/sidebar/main-sidebar';
+import { PersonalSettingsPage } from '../pages/settings-personal';
const MFA_SECRET = 'KVKFKRCPNZQUYMLXOVYDSQKJKZDTSRLD';
diff --git a/cypress/e2e/29-templates.cy.ts b/cypress/e2e/29-templates.cy.ts
index 5cc6657416a7b..5b52889c94d10 100644
--- a/cypress/e2e/29-templates.cy.ts
+++ b/cypress/e2e/29-templates.cy.ts
@@ -1,9 +1,9 @@
+import OnboardingWorkflow from '../fixtures/Onboarding_workflow.json';
+import WorkflowTemplate from '../fixtures/Workflow_template_write_http_query.json';
+import { MainSidebar } from '../pages/sidebar/main-sidebar';
import { TemplatesPage } from '../pages/templates';
import { WorkflowPage } from '../pages/workflow';
import { WorkflowsPage } from '../pages/workflows';
-import { MainSidebar } from '../pages/sidebar/main-sidebar';
-import OnboardingWorkflow from '../fixtures/Onboarding_workflow.json';
-import WorkflowTemplate from '../fixtures/Workflow_template_write_http_query.json';
const templatesPage = new TemplatesPage();
const workflowPage = new WorkflowPage();
diff --git a/cypress/e2e/30-langchain.cy.ts b/cypress/e2e/30-langchain.cy.ts
index c6d0f4ab4d3e7..0deec76e9f99d 100644
--- a/cypress/e2e/30-langchain.cy.ts
+++ b/cypress/e2e/30-langchain.cy.ts
@@ -1,4 +1,34 @@
-import { createMockNodeExecutionData, runMockWorkflowExecution } from '../utils';
+import {
+ AGENT_NODE_NAME,
+ MANUAL_CHAT_TRIGGER_NODE_NAME,
+ AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
+ MANUAL_TRIGGER_NODE_NAME,
+ AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME,
+ AI_TOOL_CALCULATOR_NODE_NAME,
+ AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME,
+ AI_TOOL_CODE_NODE_NAME,
+ AI_TOOL_WIKIPEDIA_NODE_NAME,
+ BASIC_LLM_CHAIN_NODE_NAME,
+ EDIT_FIELDS_SET_NODE_NAME,
+ CHAT_TRIGGER_NODE_DISPLAY_NAME,
+} from './../constants';
+import {
+ closeManualChatModal,
+ getManualChatDialog,
+ getManualChatMessages,
+ getManualChatModal,
+ getManualChatModalLogs,
+ getManualChatModalLogsEntries,
+ getManualChatModalLogsTree,
+ sendManualChatMessage,
+} from '../composables/modals/chat-modal';
+import { setCredentialValues } from '../composables/modals/credential-modal';
+import {
+ clickCreateNewCredential,
+ clickExecuteNode,
+ clickGetBackToCanvas,
+ toggleParameterCheckboxInputByName,
+} from '../composables/ndv';
import {
addLanguageModelNodeToParent,
addMemoryNodeToParent,
@@ -14,37 +44,7 @@ import {
openNode,
getConnectionBySourceAndTarget,
} from '../composables/workflow';
-import {
- clickCreateNewCredential,
- clickExecuteNode,
- clickGetBackToCanvas,
- toggleParameterCheckboxInputByName,
-} from '../composables/ndv';
-import { setCredentialValues } from '../composables/modals/credential-modal';
-import {
- closeManualChatModal,
- getManualChatDialog,
- getManualChatMessages,
- getManualChatModal,
- getManualChatModalLogs,
- getManualChatModalLogsEntries,
- getManualChatModalLogsTree,
- sendManualChatMessage,
-} from '../composables/modals/chat-modal';
-import {
- AGENT_NODE_NAME,
- MANUAL_CHAT_TRIGGER_NODE_NAME,
- AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
- MANUAL_TRIGGER_NODE_NAME,
- AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME,
- AI_TOOL_CALCULATOR_NODE_NAME,
- AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME,
- AI_TOOL_CODE_NODE_NAME,
- AI_TOOL_WIKIPEDIA_NODE_NAME,
- BASIC_LLM_CHAIN_NODE_NAME,
- EDIT_FIELDS_SET_NODE_NAME,
- CHAT_TRIGGER_NODE_DISPLAY_NAME,
-} from './../constants';
+import { createMockNodeExecutionData, runMockWorkflowExecution } from '../utils';
describe('Langchain Integration', () => {
beforeEach(() => {
diff --git a/cypress/e2e/31-demo.cy.ts b/cypress/e2e/31-demo.cy.ts
index eed3198c83687..32307361fdbca 100644
--- a/cypress/e2e/31-demo.cy.ts
+++ b/cypress/e2e/31-demo.cy.ts
@@ -1,7 +1,7 @@
import workflow from '../fixtures/Manual_wait_set.json';
import { importWorkflow, visitDemoPage } from '../pages/demo';
-import { WorkflowPage } from '../pages/workflow';
import { errorToast } from '../pages/notifications';
+import { WorkflowPage } from '../pages/workflow';
const workflowPage = new WorkflowPage();
diff --git a/cypress/e2e/34-template-credentials-setup.cy.ts b/cypress/e2e/34-template-credentials-setup.cy.ts
index c5d9f2643f24d..815f4b1cebfcb 100644
--- a/cypress/e2e/34-template-credentials-setup.cy.ts
+++ b/cypress/e2e/34-template-credentials-setup.cy.ts
@@ -1,3 +1,8 @@
+import * as setupCredsModal from '../composables/modals/workflow-credential-setup-modal';
+import * as formStep from '../composables/setup-template-form-step';
+import { getSetupWorkflowCredentialsButton } from '../composables/setup-workflow-credentials-button';
+import TestTemplate1 from '../fixtures/Test_Template_1.json';
+import TestTemplate2 from '../fixtures/Test_Template_2.json';
import {
clickUseWorkflowButtonByTitle,
visitTemplateCollectionPage,
@@ -5,11 +10,6 @@ import {
} from '../pages/template-collection';
import * as templateCredentialsSetupPage from '../pages/template-credential-setup';
import { WorkflowPage } from '../pages/workflow';
-import * as formStep from '../composables/setup-template-form-step';
-import { getSetupWorkflowCredentialsButton } from '../composables/setup-workflow-credentials-button';
-import * as setupCredsModal from '../composables/modals/workflow-credential-setup-modal';
-import TestTemplate1 from '../fixtures/Test_Template_1.json';
-import TestTemplate2 from '../fixtures/Test_Template_2.json';
const workflowPage = new WorkflowPage();
diff --git a/cypress/e2e/36-versions.cy.ts b/cypress/e2e/36-versions.cy.ts
index 1d4fc5180882f..d749ae4537b21 100644
--- a/cypress/e2e/36-versions.cy.ts
+++ b/cypress/e2e/36-versions.cy.ts
@@ -1,10 +1,10 @@
-import { WorkflowsPage } from '../pages/workflows';
import {
closeVersionUpdatesPanel,
getVersionCard,
getVersionUpdatesPanelOpenButton,
openVersionUpdatesPanel,
} from '../composables/versions';
+import { WorkflowsPage } from '../pages/workflows';
const workflowsPage = new WorkflowsPage();
diff --git a/cypress/e2e/39-projects.cy.ts b/cypress/e2e/39-projects.cy.ts
index e2bf63df7dc46..59ed6bcb848a9 100644
--- a/cypress/e2e/39-projects.cy.ts
+++ b/cypress/e2e/39-projects.cy.ts
@@ -1,3 +1,4 @@
+import * as projects from '../composables/projects';
import { INSTANCE_MEMBERS, MANUAL_TRIGGER_NODE_NAME, NOTION_NODE_NAME } from '../constants';
import {
WorkflowsPage,
@@ -8,7 +9,6 @@ import {
NDV,
MainSidebar,
} from '../pages';
-import * as projects from '../composables/projects';
import { getVisibleDropdown, getVisibleModalOverlay, getVisibleSelect } from '../utils';
const workflowsPage = new WorkflowsPage();
diff --git a/cypress/e2e/4-node-creator.cy.ts b/cypress/e2e/4-node-creator.cy.ts
index bb47ef4765dc7..9dfe128322914 100644
--- a/cypress/e2e/4-node-creator.cy.ts
+++ b/cypress/e2e/4-node-creator.cy.ts
@@ -1,8 +1,8 @@
+import { IF_NODE_NAME } from '../constants';
import { NodeCreator } from '../pages/features/node-creator';
-import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { NDV } from '../pages/ndv';
+import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { getVisibleSelect } from '../utils';
-import { IF_NODE_NAME } from '../constants';
const nodeCreatorFeature = new NodeCreator();
const WorkflowPage = new WorkflowPageClass();
diff --git a/cypress/e2e/44-routing.cy.ts b/cypress/e2e/44-routing.cy.ts
index 67a092235bff2..1d3a8746a93ec 100644
--- a/cypress/e2e/44-routing.cy.ts
+++ b/cypress/e2e/44-routing.cy.ts
@@ -1,7 +1,7 @@
-import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
-import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
-import { EDIT_FIELDS_SET_NODE_NAME } from '../constants';
import { getSaveChangesModal } from '../composables/modals/save-changes-modal';
+import { EDIT_FIELDS_SET_NODE_NAME } from '../constants';
+import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
+import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
const WorkflowsPage = new WorkflowsPageClass();
const WorkflowPage = new WorkflowPageClass();
diff --git a/cypress/e2e/5-ndv.cy.ts b/cypress/e2e/5-ndv.cy.ts
index d38eb402b93ba..4608b5eefc94a 100644
--- a/cypress/e2e/5-ndv.cy.ts
+++ b/cypress/e2e/5-ndv.cy.ts
@@ -1,8 +1,8 @@
+import { setCredentialValues } from '../composables/modals/credential-modal';
+import { clickCreateNewCredential } from '../composables/ndv';
import { MANUAL_TRIGGER_NODE_DISPLAY_NAME, NOTION_NODE_NAME } from '../constants';
import { NDV, WorkflowPage } from '../pages';
import { NodeCreator } from '../pages/features/node-creator';
-import { clickCreateNewCredential } from '../composables/ndv';
-import { setCredentialValues } from '../composables/modals/credential-modal';
const workflowPage = new WorkflowPage();
const ndv = new NDV();
diff --git a/cypress/e2e/6-code-node.cy.ts b/cypress/e2e/6-code-node.cy.ts
index d26e0ded5dd1c..5b422b4589f04 100644
--- a/cypress/e2e/6-code-node.cy.ts
+++ b/cypress/e2e/6-code-node.cy.ts
@@ -1,7 +1,8 @@
import { nanoid } from 'nanoid';
-import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
+
import { NDV } from '../pages/ndv';
import { successToast } from '../pages/notifications';
+import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
const WorkflowPage = new WorkflowPageClass();
const ndv = new NDV();
diff --git a/cypress/e2e/7-workflow-actions.cy.ts b/cypress/e2e/7-workflow-actions.cy.ts
index 7c7c3be554073..8571b174d9f43 100644
--- a/cypress/e2e/7-workflow-actions.cy.ts
+++ b/cypress/e2e/7-workflow-actions.cy.ts
@@ -5,11 +5,11 @@ import {
EDIT_FIELDS_SET_NODE_NAME,
NOTION_NODE_NAME,
} from '../constants';
+import { WorkflowExecutionsTab } from '../pages';
+import { errorToast, successToast } from '../pages/notifications';
import { WorkflowPage as WorkflowPageClass } from '../pages/workflow';
import { WorkflowsPage as WorkflowsPageClass } from '../pages/workflows';
import { getVisibleSelect } from '../utils';
-import { WorkflowExecutionsTab } from '../pages';
-import { errorToast, successToast } from '../pages/notifications';
const NEW_WORKFLOW_NAME = 'Something else';
const DUPLICATE_WORKFLOW_NAME = 'Duplicated workflow';
diff --git a/cypress/pages/mfa-login.ts b/cypress/pages/mfa-login.ts
index ae4d916ba911c..66fc197e3f5d0 100644
--- a/cypress/pages/mfa-login.ts
+++ b/cypress/pages/mfa-login.ts
@@ -1,7 +1,7 @@
-import { N8N_AUTH_COOKIE } from '../constants';
import { BasePage } from './base';
import { SigninPage } from './signin';
import { WorkflowsPage } from './workflows';
+import { N8N_AUTH_COOKIE } from '../constants';
export class MfaLoginPage extends BasePage {
url = '/mfa';
diff --git a/cypress/pages/modals/credentials-modal.ts b/cypress/pages/modals/credentials-modal.ts
index f14f6be0b7f13..cd3ded63f8922 100644
--- a/cypress/pages/modals/credentials-modal.ts
+++ b/cypress/pages/modals/credentials-modal.ts
@@ -1,5 +1,5 @@
-import { BasePage } from '../base';
import { getVisibleSelect } from '../../utils';
+import { BasePage } from '../base';
export class CredentialsModal extends BasePage {
getters = {
diff --git a/cypress/pages/ndv.ts b/cypress/pages/ndv.ts
index 8bd7ccf95fd80..b775deec6d233 100644
--- a/cypress/pages/ndv.ts
+++ b/cypress/pages/ndv.ts
@@ -1,5 +1,5 @@
-import { getVisiblePopper, getVisibleSelect } from '../utils';
import { BasePage } from './base';
+import { getVisiblePopper, getVisibleSelect } from '../utils';
export class NDV extends BasePage {
getters = {
diff --git a/cypress/pages/settings-log-streaming.ts b/cypress/pages/settings-log-streaming.ts
index cc1ea1250d80d..9063b8dc41e3a 100644
--- a/cypress/pages/settings-log-streaming.ts
+++ b/cypress/pages/settings-log-streaming.ts
@@ -1,5 +1,5 @@
-import { getVisibleSelect } from '../utils';
import { BasePage } from './base';
+import { getVisibleSelect } from '../utils';
export class SettingsLogStreamingPage extends BasePage {
url = '/settings/log-streaming';
diff --git a/cypress/pages/settings-personal.ts b/cypress/pages/settings-personal.ts
index 9872fbc668d33..4574f95691fa8 100644
--- a/cypress/pages/settings-personal.ts
+++ b/cypress/pages/settings-personal.ts
@@ -1,7 +1,8 @@
import generateOTPToken from 'cypress-otp';
+
+import { BasePage } from './base';
import { ChangePasswordModal } from './modals/change-password-modal';
import { MfaSetupModal } from './modals/mfa-setup-modal';
-import { BasePage } from './base';
const changePasswordModal = new ChangePasswordModal();
const mfaSetupModal = new MfaSetupModal();
diff --git a/cypress/pages/settings-users.ts b/cypress/pages/settings-users.ts
index d188896225b04..1eaebc911a00e 100644
--- a/cypress/pages/settings-users.ts
+++ b/cypress/pages/settings-users.ts
@@ -1,8 +1,8 @@
-import { SettingsSidebar } from './sidebar/settings-sidebar';
+import { BasePage } from './base';
import { MainSidebar } from './sidebar/main-sidebar';
+import { SettingsSidebar } from './sidebar/settings-sidebar';
import { WorkflowPage } from './workflow';
import { WorkflowsPage } from './workflows';
-import { BasePage } from './base';
const workflowPage = new WorkflowPage();
const workflowsPage = new WorkflowsPage();
diff --git a/cypress/pages/signin.ts b/cypress/pages/signin.ts
index 22d0fd163aaa1..a97fe4888ea1f 100644
--- a/cypress/pages/signin.ts
+++ b/cypress/pages/signin.ts
@@ -1,6 +1,6 @@
-import { N8N_AUTH_COOKIE } from '../constants';
import { BasePage } from './base';
import { WorkflowsPage } from './workflows';
+import { N8N_AUTH_COOKIE } from '../constants';
export class SigninPage extends BasePage {
url = '/signin';
diff --git a/cypress/pages/template-credential-setup.ts b/cypress/pages/template-credential-setup.ts
index 3fa4d2067103d..06c1baab8eb62 100644
--- a/cypress/pages/template-credential-setup.ts
+++ b/cypress/pages/template-credential-setup.ts
@@ -1,6 +1,6 @@
-import * as formStep from '../composables/setup-template-form-step';
-import { overrideFeatureFlag } from '../composables/featureFlags';
import { CredentialsModal, MessageBox } from './modals';
+import { overrideFeatureFlag } from '../composables/featureFlags';
+import * as formStep from '../composables/setup-template-form-step';
const credentialsModal = new CredentialsModal();
const messageBox = new MessageBox();
diff --git a/cypress/pages/variables.ts b/cypress/pages/variables.ts
index c74624686eafb..6ac9a939b2999 100644
--- a/cypress/pages/variables.ts
+++ b/cypress/pages/variables.ts
@@ -1,4 +1,5 @@
import { BasePage } from './base';
+
import Chainable = Cypress.Chainable;
export class VariablesPage extends BasePage {
diff --git a/cypress/pages/workflow.ts b/cypress/pages/workflow.ts
index 0c2a26960768d..89186ee34ed2e 100644
--- a/cypress/pages/workflow.ts
+++ b/cypress/pages/workflow.ts
@@ -1,8 +1,8 @@
+import { BasePage } from './base';
+import { NodeCreator } from './features/node-creator';
import { META_KEY } from '../constants';
import { getVisibleSelect } from '../utils';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
-import { BasePage } from './base';
-import { NodeCreator } from './features/node-creator';
const nodeCreator = new NodeCreator();
export class WorkflowPage extends BasePage {
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
index 808c0b6aca01f..35f100fded64f 100644
--- a/cypress/support/commands.ts
+++ b/cypress/support/commands.ts
@@ -1,7 +1,7 @@
import 'cypress-real-events';
-import FakeTimers from '@sinonjs/fake-timers';
import type { FrontendSettings } from '@n8n/api-types';
-import { WorkflowPage } from '../pages';
+import FakeTimers from '@sinonjs/fake-timers';
+
import {
BACKEND_BASE_URL,
INSTANCE_ADMIN,
@@ -9,6 +9,7 @@ import {
INSTANCE_OWNER,
N8N_AUTH_COOKIE,
} from '../constants';
+import { WorkflowPage } from '../pages';
import { getUniqueWorkflowName } from '../utils/workflowUtils';
Cypress.Commands.add('setAppDate', (targetDate: number | Date) => {
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
index 4d5d7a7f9af75..0fe782499d1d7 100644
--- a/cypress/support/e2e.ts
+++ b/cypress/support/e2e.ts
@@ -1,5 +1,6 @@
import cloneDeep from 'lodash/cloneDeep';
import merge from 'lodash/merge';
+
import { settings } from './commands';
before(() => {
diff --git a/cypress/utils/executions.ts b/cypress/utils/executions.ts
index e42e2152d6d80..eb0dbfc251f7e 100644
--- a/cypress/utils/executions.ts
+++ b/cypress/utils/executions.ts
@@ -1,5 +1,6 @@
-import { nanoid } from 'nanoid';
import type { IDataObject, IPinData, ITaskData, ITaskDataConnections } from 'n8n-workflow';
+import { nanoid } from 'nanoid';
+
import { clickExecuteWorkflowButton } from '../composables/workflow';
export function createMockNodeExecutionData(
diff --git a/packages/@n8n/api-types/src/push/index.ts b/packages/@n8n/api-types/src/push/index.ts
index 3eefb0851c1cb..b97a179141dff 100644
--- a/packages/@n8n/api-types/src/push/index.ts
+++ b/packages/@n8n/api-types/src/push/index.ts
@@ -1,10 +1,10 @@
+import type { CollaborationPushMessage } from './collaboration';
+import type { DebugPushMessage } from './debug';
import type { ExecutionPushMessage } from './execution';
-import type { WorkflowPushMessage } from './workflow';
import type { HotReloadPushMessage } from './hot-reload';
-import type { WorkerPushMessage } from './worker';
import type { WebhookPushMessage } from './webhook';
-import type { CollaborationPushMessage } from './collaboration';
-import type { DebugPushMessage } from './debug';
+import type { WorkerPushMessage } from './worker';
+import type { WorkflowPushMessage } from './workflow';
export type PushMessage =
| ExecutionPushMessage
diff --git a/packages/@n8n/benchmark/src/commands/list.ts b/packages/@n8n/benchmark/src/commands/list.ts
index 7bcc4de2ce1e8..34b82732098f1 100644
--- a/packages/@n8n/benchmark/src/commands/list.ts
+++ b/packages/@n8n/benchmark/src/commands/list.ts
@@ -1,6 +1,7 @@
import { Command } from '@oclif/core';
-import { ScenarioLoader } from '@/scenario/scenario-loader';
+
import { testScenariosPath } from '@/config/common-flags';
+import { ScenarioLoader } from '@/scenario/scenario-loader';
export default class ListCommand extends Command {
static description = 'List all available scenarios';
diff --git a/packages/@n8n/benchmark/src/commands/run.ts b/packages/@n8n/benchmark/src/commands/run.ts
index eb895c842e320..164eef0f419d6 100644
--- a/packages/@n8n/benchmark/src/commands/run.ts
+++ b/packages/@n8n/benchmark/src/commands/run.ts
@@ -1,11 +1,12 @@
import { Command, Flags } from '@oclif/core';
-import { ScenarioLoader } from '@/scenario/scenario-loader';
-import { ScenarioRunner } from '@/test-execution/scenario-runner';
+
+import { testScenariosPath } from '@/config/common-flags';
import { N8nApiClient } from '@/n8n-api-client/n8n-api-client';
import { ScenarioDataFileLoader } from '@/scenario/scenario-data-loader';
+import { ScenarioLoader } from '@/scenario/scenario-loader';
import type { K6Tag } from '@/test-execution/k6-executor';
import { K6Executor } from '@/test-execution/k6-executor';
-import { testScenariosPath } from '@/config/common-flags';
+import { ScenarioRunner } from '@/test-execution/scenario-runner';
export default class RunCommand extends Command {
static description = 'Run all (default) or specified test scenarios';
diff --git a/packages/@n8n/benchmark/src/n8n-api-client/authenticated-n8n-api-client.ts b/packages/@n8n/benchmark/src/n8n-api-client/authenticated-n8n-api-client.ts
index 0272181799399..2555ea8061a30 100644
--- a/packages/@n8n/benchmark/src/n8n-api-client/authenticated-n8n-api-client.ts
+++ b/packages/@n8n/benchmark/src/n8n-api-client/authenticated-n8n-api-client.ts
@@ -1,4 +1,5 @@
import type { AxiosRequestConfig } from 'axios';
+
import { N8nApiClient } from './n8n-api-client';
export class AuthenticatedN8nApiClient extends N8nApiClient {
diff --git a/packages/@n8n/benchmark/src/n8n-api-client/workflows-api-client.ts b/packages/@n8n/benchmark/src/n8n-api-client/workflows-api-client.ts
index 76eea4284cbad..92bcfad89fe75 100644
--- a/packages/@n8n/benchmark/src/n8n-api-client/workflows-api-client.ts
+++ b/packages/@n8n/benchmark/src/n8n-api-client/workflows-api-client.ts
@@ -1,6 +1,7 @@
-import type { AuthenticatedN8nApiClient } from './authenticated-n8n-api-client';
import type { Workflow } from '@/n8n-api-client/n8n-api-client.types';
+import type { AuthenticatedN8nApiClient } from './authenticated-n8n-api-client';
+
export class WorkflowApiClient {
constructor(private readonly apiClient: AuthenticatedN8nApiClient) {}
diff --git a/packages/@n8n/benchmark/src/scenario/scenario-data-loader.ts b/packages/@n8n/benchmark/src/scenario/scenario-data-loader.ts
index b601d19902707..12fcc58ee382e 100644
--- a/packages/@n8n/benchmark/src/scenario/scenario-data-loader.ts
+++ b/packages/@n8n/benchmark/src/scenario/scenario-data-loader.ts
@@ -1,7 +1,8 @@
import * as fs from 'node:fs';
import * as path from 'node:path';
-import type { Scenario } from '@/types/scenario';
+
import type { Workflow } from '@/n8n-api-client/n8n-api-client.types';
+import type { Scenario } from '@/types/scenario';
/**
* Loads scenario data files from FS
diff --git a/packages/@n8n/benchmark/src/scenario/scenario-loader.ts b/packages/@n8n/benchmark/src/scenario/scenario-loader.ts
index 13cc52daf0d3e..4f315c1bf7c1a 100644
--- a/packages/@n8n/benchmark/src/scenario/scenario-loader.ts
+++ b/packages/@n8n/benchmark/src/scenario/scenario-loader.ts
@@ -1,6 +1,7 @@
+import { createHash } from 'node:crypto';
import * as fs from 'node:fs';
import * as path from 'path';
-import { createHash } from 'node:crypto';
+
import type { Scenario, ScenarioManifest } from '@/types/scenario';
export class ScenarioLoader {
diff --git a/packages/@n8n/benchmark/src/test-execution/k6-executor.ts b/packages/@n8n/benchmark/src/test-execution/k6-executor.ts
index f99ffd80d90b6..4fcf11d45b509 100644
--- a/packages/@n8n/benchmark/src/test-execution/k6-executor.ts
+++ b/packages/@n8n/benchmark/src/test-execution/k6-executor.ts
@@ -1,9 +1,10 @@
import fs from 'fs';
-import path from 'path';
import assert from 'node:assert/strict';
+import path from 'path';
import { $, which, tmpfile } from 'zx';
-import type { Scenario } from '@/types/scenario';
+
import { buildTestReport, type K6Tag } from '@/test-execution/test-report';
+import type { Scenario } from '@/types/scenario';
export type { K6Tag };
export type K6ExecutorOpts = {
diff --git a/packages/@n8n/benchmark/src/test-execution/scenario-runner.ts b/packages/@n8n/benchmark/src/test-execution/scenario-runner.ts
index 135ebc6007829..84d1d8b0967b0 100644
--- a/packages/@n8n/benchmark/src/test-execution/scenario-runner.ts
+++ b/packages/@n8n/benchmark/src/test-execution/scenario-runner.ts
@@ -1,9 +1,10 @@
-import type { K6Executor } from './k6-executor';
-import type { Scenario } from '@/types/scenario';
+import { AuthenticatedN8nApiClient } from '@/n8n-api-client/authenticated-n8n-api-client';
import type { N8nApiClient } from '@/n8n-api-client/n8n-api-client';
import type { ScenarioDataFileLoader } from '@/scenario/scenario-data-loader';
import { ScenarioDataImporter } from '@/test-execution/scenario-data-importer';
-import { AuthenticatedN8nApiClient } from '@/n8n-api-client/authenticated-n8n-api-client';
+import type { Scenario } from '@/types/scenario';
+
+import type { K6Executor } from './k6-executor';
/**
* Runs scenarios
diff --git a/packages/@n8n/benchmark/src/test-execution/test-report.ts b/packages/@n8n/benchmark/src/test-execution/test-report.ts
index d3177aeb79650..8e858c5e66612 100644
--- a/packages/@n8n/benchmark/src/test-execution/test-report.ts
+++ b/packages/@n8n/benchmark/src/test-execution/test-report.ts
@@ -1,4 +1,5 @@
import { nanoid } from 'nanoid';
+
import type { Scenario } from '@/types/scenario';
export type K6Tag = {
diff --git a/packages/@n8n/chat/src/App.vue b/packages/@n8n/chat/src/App.vue
index ec90bef42583e..0614b7cf73485 100644
--- a/packages/@n8n/chat/src/App.vue
+++ b/packages/@n8n/chat/src/App.vue
@@ -1,8 +1,9 @@
diff --git a/packages/@n8n/chat/src/components/Input.vue b/packages/@n8n/chat/src/components/Input.vue
index af4b3343b7a38..3e823917e0c22 100644
--- a/packages/@n8n/chat/src/components/Input.vue
+++ b/packages/@n8n/chat/src/components/Input.vue
@@ -1,12 +1,14 @@