refactor(editor): Move htmlUtils into new @n8n/frontend-utils package behind re-export shims (no-changelog) (#34355)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Alex Grozav
2026-07-20 12:02:40 +02:00
committed by GitHub
parent 0fb07ca6ad
commit e845882c5c
20 changed files with 197 additions and 16 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
{
"issues": 168
"issues": 169
}
@@ -4,11 +4,7 @@ import { frontendConfig } from '@n8n/eslint-config/frontend';
export default defineConfig(frontendConfig, {
files: ['**/*.test.ts'],
rules: {
// Vitest spies stored in untyped `let`s surface as `any`; align with the
// sibling FE app-libs (editor-ui) that treat these as warnings in tests.
'@typescript-eslint/no-unsafe-assignment': 'warn',
'@typescript-eslint/no-unsafe-call': 'warn',
'@typescript-eslint/no-unsafe-member-access': 'warn',
// Component tests key DOM attributes (e.g. `data-test-id`) via string
// literals; align with the sibling FE app-libs that treat this as a warning.
'@typescript-eslint/naming-convention': 'warn',
@@ -30,8 +30,7 @@
"dependencies": {
"@vueuse/core": "catalog:frontend",
"lodash": "catalog:",
"vue": "catalog:frontend",
"xss": "catalog:"
"vue": "catalog:frontend"
},
"devDependencies": {
"@n8n/eslint-config": "workspace:*",
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
@@ -0,0 +1,25 @@
# @n8n/frontend-utils
A collection of framework-light utility functions shared across n8n's front-end
packages — HTML sanitization, DOM helpers, and other pure utilities that are not
Vue composables.
## Table of Contents
- [Features](#features)
- [Contributing](#contributing)
- [License](#license)
## Features
- **Pure utilities**: Stateless helpers with no component or store coupling.
- **Consistency**: A single home for cross-package front-end utilities.
- **Extensible**: A foundation for utilities as the front end grows.
## Contributing
For more details, please read our [CONTRIBUTING.md](CONTRIBUTING.md).
## License
For more details, please read our [LICENSE.md](LICENSE.md).
@@ -0,0 +1,4 @@
{
"$schema": "../../../../node_modules/@biomejs/biome/configuration_schema.json",
"extends": ["../../../../biome.jsonc"]
}
@@ -0,0 +1,15 @@
import { defineConfig } from 'eslint/config';
import { frontendConfig } from '@n8n/eslint-config/frontend';
export default defineConfig(frontendConfig, {
files: ['**/*.test.ts'],
rules: {
// Test spies (e.g. `vi.spyOn`) surface as loosely-typed values; align with
// the sibling FE app-libs (composables, editor-ui) that treat these as
// warnings in test files rather than errors.
'@typescript-eslint/no-unsafe-assignment': 'warn',
'@typescript-eslint/no-unsafe-call': 'warn',
'@typescript-eslint/no-unsafe-member-access': 'warn',
'@typescript-eslint/naming-convention': 'warn',
},
});
@@ -0,0 +1,46 @@
{
"name": "@n8n/frontend-utils",
"type": "module",
"version": "0.1.0",
"files": [
"dist"
],
"exports": {
"./*": {
"types": "./dist/*.d.mts",
"import": "./dist/*.mjs",
"require": "./dist/*.cjs"
}
},
"scripts": {
"clean": "rimraf dist .turbo",
"dev": "tsdown --watch",
"build": "tsdown",
"build:unchecked": "pnpm run build",
"preview": "vite preview",
"typecheck": "vue-tsc --noEmit",
"test": "vitest run",
"test:dev": "vitest --silent=false",
"lint": "eslint src --quiet",
"lint:fix": "eslint src --fix",
"format": "biome format --write . && prettier --write . --ignore-path ../../../../.prettierignore",
"format:check": "biome ci . && prettier --check . --ignore-path ../../../../.prettierignore"
},
"dependencies": {
"vue": "catalog:frontend",
"xss": "catalog:"
},
"devDependencies": {
"@n8n/eslint-config": "workspace:*",
"@n8n/typescript-config": "workspace:*",
"@n8n/vitest-config": "workspace:*",
"@testing-library/jest-dom": "catalog:frontend",
"@testing-library/vue": "catalog:frontend",
"tsdown": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vitest": "catalog:",
"vue-tsc": "catalog:frontend"
},
"license": "LicenseRef-n8n-sustainable-use"
}
@@ -0,0 +1,4 @@
import '@testing-library/jest-dom/vitest';
import { configure } from '@testing-library/vue';
configure({ testIdAttribute: 'data-test-id' });
@@ -0,0 +1,10 @@
{
"extends": "@n8n/typescript-config/tsconfig.frontend.json",
"compilerOptions": {
"moduleResolution": "bundler",
"outDir": "dist",
"types": ["vite/client", "vitest/globals", "@testing-library/jest-dom"],
"isolatedModules": true
},
"include": ["src/**/*.ts", "vite.config.ts", "tsdown.config.ts"]
}
@@ -0,0 +1,11 @@
import { defineConfig } from 'tsdown';
// eslint-disable-next-line import-x/no-default-export
export default defineConfig({
entry: ['src/**/*.ts', '!src/**/*.test.ts', '!src/**/*.d.ts', '!src/__tests__/**/*'],
format: ['cjs', 'esm'],
clean: true,
dts: true,
sourcemap: true,
hash: false,
});
@@ -0,0 +1,4 @@
import { defineConfig, mergeConfig } from 'vite';
import { vitestConfig } from '@n8n/vitest-config/frontend';
export default mergeConfig(defineConfig({}), vitestConfig);
+1
View File
@@ -49,6 +49,7 @@
"@n8n/constants": "workspace:*",
"@n8n/design-system": "workspace:*",
"@n8n/frontend-module-sdk": "workspace:*",
"@n8n/frontend-utils": "workspace:*",
"@n8n/i18n": "workspace:*",
"@n8n/permissions": "workspace:*",
"@n8n/rest-api-client": "workspace:*",
@@ -1,6 +1,6 @@
/**
* @deprecated Import from `@n8n/composables/constants/sanitization` instead. These
* constants moved into `@n8n/composables` (folded in with their only consumer
* @deprecated Import from `@n8n/frontend-utils/constants/sanitization` instead. These
* constants moved into `@n8n/frontend-utils` (alongside their only consumer
* `htmlUtils`) during the CAT-3686 frontend-modularization migration; this
* re-export keeps `@/app/constants` consumers working until they are retired.
* (N8N-36)
@@ -8,4 +8,4 @@
export {
ALLOWED_HTML_ATTRIBUTES,
ALLOWED_HTML_TAGS,
} from '@n8n/composables/constants/sanitization';
} from '@n8n/frontend-utils/constants/sanitization';
@@ -1,5 +1,5 @@
/**
* @deprecated Import from `@n8n/composables/htmlUtils` instead. This re-export
* @deprecated Import from `@n8n/frontend-utils/htmlUtils` instead. This re-export
* shim keeps existing `@/app/utils/htmlUtils` call sites working during the
* CAT-3686 frontend-modularization migration and will be removed once importers
* are retired per-directory. (N8N-36)
@@ -13,4 +13,4 @@ export {
openSafeUrl,
sanitizeHtml,
sanitizeIfString,
} from '@n8n/composables/htmlUtils';
} from '@n8n/frontend-utils/htmlUtils';
+3 -1
View File
@@ -8,7 +8,8 @@
"../@n8n/composables/src",
"../@n8n/chat/src",
"../@n8n/design-system/src",
"../@n8n/frontend-module-sdk/src"
"../@n8n/frontend-module-sdk/src",
"../@n8n/frontend-utils/src"
],
"noEmit": true,
"types": [
@@ -23,6 +24,7 @@
"@n8n/composables*": ["../@n8n/composables/src*"],
"@n8n/constants*": ["../../@n8n/constants/src*"],
"@n8n/frontend-module-sdk": ["../@n8n/frontend-module-sdk/src/index.ts"],
"@n8n/frontend-utils*": ["../@n8n/frontend-utils/src*"],
"@n8n/chat*": ["../@n8n/chat/src*"],
"@n8n/chat-hub*": ["../../@n8n/chat-hub/src*"],
"@n8n/design-system*": ["../@n8n/design-system/src*"],
+43 -3
View File
@@ -4839,9 +4839,6 @@ importers:
vue:
specifier: catalog:frontend
version: 3.5.26(typescript@6.0.2)
xss:
specifier: 'catalog:'
version: 1.0.15
devDependencies:
'@n8n/eslint-config':
specifier: workspace:*
@@ -5146,6 +5143,46 @@ importers:
specifier: ^2.2.8
version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@6.0.2)
packages/frontend/@n8n/frontend-utils:
dependencies:
vue:
specifier: catalog:frontend
version: 3.5.26(typescript@6.0.2)
xss:
specifier: 'catalog:'
version: 1.0.15
devDependencies:
'@n8n/eslint-config':
specifier: workspace:*
version: link:../../../@n8n/eslint-config
'@n8n/typescript-config':
specifier: workspace:*
version: link:../../../@n8n/typescript-config
'@n8n/vitest-config':
specifier: workspace:*
version: link:../../../@n8n/vitest-config
'@testing-library/jest-dom':
specifier: catalog:frontend
version: 6.6.3
'@testing-library/vue':
specifier: catalog:frontend
version: 8.1.0(@vue/compiler-sfc@3.5.26)(vue@3.5.26(typescript@6.0.2))
tsdown:
specifier: 'catalog:'
version: 0.16.5(typescript@6.0.2)(vue-tsc@2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@6.0.2))
typescript:
specifier: 'catalog:'
version: 6.0.2
vite:
specifier: 'catalog:'
version: 8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3)
vitest:
specifier: 'catalog:'
version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@20.19.41)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(jsdom@23.0.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(vite@8.0.2(@types/node@20.19.41)(esbuild@0.28.1)(jiti@2.6.1)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.16.1)(tsx@4.19.3)(yaml@2.8.3))
vue-tsc:
specifier: ^2.2.8
version: 2.2.8(patch_hash=e2aee939ccac8a57fe449bfd92bedd8117841579526217bc39aca26c6b8c317f)(typescript@6.0.2)
packages/frontend/@n8n/i18n:
dependencies:
n8n-workflow:
@@ -5527,6 +5564,9 @@ importers:
'@n8n/frontend-module-sdk':
specifier: workspace:*
version: link:../@n8n/frontend-module-sdk
'@n8n/frontend-utils':
specifier: workspace:*
version: link:../@n8n/frontend-utils
'@n8n/i18n':
specifier: workspace:*
version: link:../@n8n/i18n