From 7fb88e623f3c3203cd8f81ca521760e6e082a645 Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Thu, 27 Feb 2025 09:58:31 +0200 Subject: [PATCH] feat: Add new `@n8n/utils` package (no-changelog) (#13536) --- packages/@n8n/utils/.eslintrc.cjs | 10 +++ packages/@n8n/utils/.gitignore | 24 ++++++ packages/@n8n/utils/README.md | 25 ++++++ packages/@n8n/utils/biome.jsonc | 4 + packages/@n8n/utils/package.json | 40 +++++++++ packages/@n8n/utils/src/__tests__/setup.ts | 1 + .../src/utils => @n8n/utils/src}/assert.ts | 1 + .../utils/src}/event-bus.test.ts | 0 .../src/utils => @n8n/utils/src}/event-bus.ts | 6 +- .../utils/src/search/sublimeSearch.ts} | 85 ++++++++----------- packages/@n8n/utils/src/shims.d.ts | 1 + .../utils/src/sort/sortByProperty.test.ts} | 12 +-- .../@n8n/utils/src/sort/sortByProperty.ts | 12 +++ .../@n8n/utils/src/string/truncate.test.ts | 15 ++++ .../utils/src/string/truncate.ts} | 0 packages/@n8n/utils/tsconfig.json | 11 +++ packages/@n8n/utils/tsup.config.ts | 11 +++ packages/@n8n/utils/vite.config.ts | 4 + packages/design-system/package.json | 1 + .../N8nInfoAccordion/InfoAccordion.vue | 2 +- .../src/directives/n8n-truncate.ts | 3 +- .../design-system/src/utils/form-event-bus.ts | 2 +- packages/design-system/src/utils/index.ts | 2 - .../design-system/src/utils/string.test.ts | 17 ---- packages/design-system/tsconfig.json | 3 +- packages/design-system/vite.config.mts | 2 + packages/editor-ui/package.json | 1 + .../editor-ui/src/__tests__/data/canvas.ts | 4 +- .../editor-ui/src/components/AboutModal.vue | 2 +- .../components/AnnotationTagsDropdown.ee.vue | 2 +- .../components/ApiKeyCreateOrEditModal.vue | 2 +- .../src/components/ChangePasswordModal.vue | 3 +- .../src/components/ChatEmbedModal.vue | 4 +- .../CommunityPackageInstallModal.vue | 2 +- .../CommunityPackageManageConfirmModal.vue | 2 +- .../CommunityPlusEnrollmentModal.vue | 2 +- .../src/components/ContactPromptModal.vue | 2 +- .../CredentialEdit/CredentialEdit.vue | 4 +- .../CredentialEdit/CredentialSharing.ee.vue | 2 +- .../CredentialPicker/CredentialPicker.vue | 2 +- .../src/components/CredentialsSelectModal.vue | 2 +- .../src/components/DeleteUserModal.vue | 2 +- .../components/DuplicateWorkflowDialog.vue | 2 +- .../ExpandableInput/ExpandableInputEdit.vue | 2 +- .../components/ExpressionParameterInput.vue | 2 +- ...rnalSecretsProviderConnectionSwitch.ee.vue | 2 +- .../ExternalSecretsProviderModal.ee.vue | 4 +- .../src/components/ImportCurlModal.vue | 2 +- .../src/components/InlineTextEdit.vue | 2 +- .../src/components/InputNodeSelect.vue | 2 +- .../src/components/IntersectionObserved.vue | 4 +- .../src/components/IntersectionObserver.vue | 4 +- .../src/components/InviteUsersModal.vue | 3 +- .../components/MainHeader/WorkflowDetails.vue | 2 +- .../components/MainSidebarSourceControl.vue | 2 +- packages/editor-ui/src/components/Modal.vue | 2 +- .../editor-ui/src/components/ModalDrawer.vue | 2 +- packages/editor-ui/src/components/Modals.vue | 2 +- .../src/components/Node/NodeCreator/utils.ts | 2 +- .../src/components/NodeCredentials.vue | 2 +- .../src/components/NodeDetailsView.vue | 2 +- .../editor-ui/src/components/NodeSettings.vue | 2 +- .../editor-ui/src/components/NpsSurvey.vue | 2 +- .../src/components/ParameterInput.test.ts | 2 +- .../src/components/ParameterInput.vue | 4 +- .../src/components/ParameterInputExpanded.vue | 2 +- .../src/components/ParameterInputFull.vue | 2 +- .../src/components/ParameterInputWrapper.vue | 4 +- .../src/components/PersonalizationModal.vue | 3 +- .../Projects/ProjectCardBadge.test.ts | 2 +- .../Projects/ProjectMoveResourceModal.vue | 6 +- .../ProjectMoveSuccessToastMessage.vue | 2 +- .../components/Projects/ProjectSharing.vue | 2 +- .../PromptMfaCodeModal/PromptMfaCodeModal.vue | 2 +- .../ResourceLocator/ResourceLocator.vue | 4 +- .../ResourceLocatorDropdown.vue | 4 +- .../EventDestinationCard.ee.vue | 4 +- .../EventDestinationSettingsModal.ee.vue | 4 +- .../SourceControlPullModal.ee.test.ts | 2 +- .../components/SourceControlPullModal.ee.vue | 2 +- .../SourceControlPushModal.ee.test.ts | 2 +- .../components/SourceControlPushModal.ee.vue | 2 +- .../src/components/TagsContainer.vue | 2 +- .../editor-ui/src/components/TagsDropdown.vue | 2 +- .../components/TagsManager/TagsManager.vue | 2 +- .../EditDefinition/NodesPinning.vue | 3 +- .../EditDefinition/TagsInput.vue | 2 +- .../editor-ui/src/components/TriggerPanel.vue | 2 +- .../src/components/Workers/WorkerCard.ee.vue | 2 +- .../editor-ui/src/components/WorkflowCard.vue | 2 +- .../WorkflowSelectorParameterInput.vue | 4 +- .../src/components/WorkflowSettings.vue | 2 +- .../src/components/WorkflowShareModal.ee.vue | 2 +- .../src/components/WorkflowTagsDropdown.vue | 2 +- .../src/components/canvas/Canvas.vue | 4 +- .../components/canvas/WorkflowCanvas.test.ts | 2 +- .../src/components/canvas/WorkflowCanvas.vue | 4 +- .../canvas/elements/nodes/CanvasNode.vue | 4 +- .../WorkflowExecutionAnnotationPanel.ee.vue | 2 +- .../composables/useGlobalEntityCreation.ts | 2 +- .../src/composables/useImportCurlCommand.ts | 2 +- .../src/event-bus/code-node-editor.ts | 2 +- .../editor-ui/src/event-bus/data-pinning.ts | 2 +- .../src/event-bus/global-link-actions.ts | 2 +- .../editor-ui/src/event-bus/html-editor.ts | 2 +- .../editor-ui/src/event-bus/import-curl.ts | 2 +- packages/editor-ui/src/event-bus/mfa.ts | 2 +- packages/editor-ui/src/event-bus/ndv.ts | 2 +- packages/editor-ui/src/event-bus/node-view.ts | 2 +- .../editor-ui/src/event-bus/source-control.ts | 2 +- packages/editor-ui/src/models/history.ts | 2 +- .../editor-ui/src/stores/assistant.store.ts | 2 +- .../editor-ui/src/stores/npsSurvey.store.ts | 2 +- packages/editor-ui/src/types/canvas.ts | 2 +- packages/editor-ui/src/types/externalHooks.ts | 2 +- packages/editor-ui/src/utils/apiUtils.ts | 2 +- .../src/utils/templates/templateActions.ts | 2 +- packages/editor-ui/src/views/NodeView.vue | 3 +- .../src/views/SettingsLogStreamingView.vue | 2 +- .../editor-ui/src/views/WorkflowsView.vue | 2 +- packages/editor-ui/tsconfig.json | 3 +- packages/editor-ui/vite.config.mts | 12 +-- .../frontend/@n8n/composables/tsconfig.json | 3 +- .../frontend/@n8n/composables/tsup.config.ts | 2 +- pnpm-lock.yaml | 39 +++++++++ 125 files changed, 379 insertions(+), 202 deletions(-) create mode 100644 packages/@n8n/utils/.eslintrc.cjs create mode 100644 packages/@n8n/utils/.gitignore create mode 100644 packages/@n8n/utils/README.md create mode 100644 packages/@n8n/utils/biome.jsonc create mode 100644 packages/@n8n/utils/package.json create mode 100644 packages/@n8n/utils/src/__tests__/setup.ts rename packages/{editor-ui/src/utils => @n8n/utils/src}/assert.ts (75%) rename packages/{design-system/src/utils => @n8n/utils/src}/event-bus.test.ts (100%) rename packages/{design-system/src/utils => @n8n/utils/src}/event-bus.ts (90%) rename packages/{editor-ui/src/utils/sortUtils.ts => @n8n/utils/src/search/sublimeSearch.ts} (91%) create mode 100644 packages/@n8n/utils/src/shims.d.ts rename packages/{editor-ui/src/utils/sortUtils.test.ts => @n8n/utils/src/sort/sortByProperty.test.ts} (70%) create mode 100644 packages/@n8n/utils/src/sort/sortByProperty.ts create mode 100644 packages/@n8n/utils/src/string/truncate.test.ts rename packages/{design-system/src/utils/string.ts => @n8n/utils/src/string/truncate.ts} (100%) create mode 100644 packages/@n8n/utils/tsconfig.json create mode 100644 packages/@n8n/utils/tsup.config.ts create mode 100644 packages/@n8n/utils/vite.config.ts delete mode 100644 packages/design-system/src/utils/string.test.ts diff --git a/packages/@n8n/utils/.eslintrc.cjs b/packages/@n8n/utils/.eslintrc.cjs new file mode 100644 index 0000000000..8050caa04e --- /dev/null +++ b/packages/@n8n/utils/.eslintrc.cjs @@ -0,0 +1,10 @@ +const sharedOptions = require('@n8n/eslint-config/shared'); + +/** + * @type {import('@types/eslint').ESLint.ConfigData} + */ +module.exports = { + extends: ['@n8n/eslint-config/node'], + + ...sharedOptions(__dirname), +}; diff --git a/packages/@n8n/utils/.gitignore b/packages/@n8n/utils/.gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/packages/@n8n/utils/.gitignore @@ -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? diff --git a/packages/@n8n/utils/README.md b/packages/@n8n/utils/README.md new file mode 100644 index 0000000000..4bcf167a3e --- /dev/null +++ b/packages/@n8n/utils/README.md @@ -0,0 +1,25 @@ +# @n8n/utils + +A collection of utility functions that provide common functionality for both Front-End and Back-End packages. + +## Table of Contents + +- [Features](#features) +- [Contributing](#contributing) +- [License](#license) + +## Features + +- **Reusable Logic**: Build complex, stateful functionality using modular composable functions that you can easily reuse. +- **Consistent Patterns**: Enjoy a unified approach across n8n packages, making integration and maintenance a breeze. +- **Type-Safe & Reliable**: Benefit from TypeScript support, which improves the developer experience and code robustness. +- **Universal Functionality**: Designed to work seamlessly on both the front-end and back-end. +- **Easily Testable**: A modular design that simplifies testing, maintenance, and rapid development. + +## Contributing + +For more details, please read our [CONTRIBUTING.md](CONTRIBUTING.md). + +## License + +For more details, please read our [LICENSE.md](LICENSE.md). diff --git a/packages/@n8n/utils/biome.jsonc b/packages/@n8n/utils/biome.jsonc new file mode 100644 index 0000000000..0c0bdac000 --- /dev/null +++ b/packages/@n8n/utils/biome.jsonc @@ -0,0 +1,4 @@ +{ + "$schema": "../../../node_modules/@biomejs/biome/configuration_schema.json", + "extends": ["../../../biome.jsonc"] +} diff --git a/packages/@n8n/utils/package.json b/packages/@n8n/utils/package.json new file mode 100644 index 0000000000..08c7bbe2da --- /dev/null +++ b/packages/@n8n/utils/package.json @@ -0,0 +1,40 @@ +{ + "name": "@n8n/utils", + "type": "module", + "version": "1.2.0", + "files": [ + "dist" + ], + "exports": { + "./*": { + "types": "./dist/*.d.ts", + "import": "./dist/*.js", + "require": "./dist/*.cjs" + } + }, + "scripts": { + "dev": "vite", + "build": "pnpm run typecheck && tsup", + "preview": "vite preview", + "typecheck": "tsc --noEmit", + "test": "vitest run", + "test:dev": "vitest --silent=false", + "lint": "eslint src --ext .js,.ts,.vue --quiet", + "lintfix": "eslint src --ext .js,.ts,.vue --fix", + "format": "biome format --write . && prettier --write . --ignore-path ../../../.prettierignore", + "format:check": "biome ci . && prettier --check . --ignore-path ../../../.prettierignore" + }, + "devDependencies": { + "@n8n/eslint-config": "workspace:*", + "@n8n/typescript-config": "workspace:*", + "@n8n/vitest-config": "workspace:*", + "@testing-library/jest-dom": "catalog:frontend", + "@testing-library/user-event": "catalog:frontend", + "tsup": "catalog:frontend", + "typescript": "catalog:frontend", + "vite": "catalog:frontend", + "vite-plugin-dts": "catalog:frontend", + "vitest": "catalog:frontend" + }, + "license": "See LICENSE.md file in the root of the repository" +} diff --git a/packages/@n8n/utils/src/__tests__/setup.ts b/packages/@n8n/utils/src/__tests__/setup.ts new file mode 100644 index 0000000000..7b0828bfa8 --- /dev/null +++ b/packages/@n8n/utils/src/__tests__/setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom'; diff --git a/packages/editor-ui/src/utils/assert.ts b/packages/@n8n/utils/src/assert.ts similarity index 75% rename from packages/editor-ui/src/utils/assert.ts rename to packages/@n8n/utils/src/assert.ts index 4366324141..6038ccce6e 100644 --- a/packages/editor-ui/src/utils/assert.ts +++ b/packages/@n8n/utils/src/assert.ts @@ -3,6 +3,7 @@ */ export function assert(condition: unknown, message?: string): asserts condition { if (!condition) { + // eslint-disable-next-line n8n-local-rules/no-plain-errors throw new Error(message ?? 'Assertion failed'); } } diff --git a/packages/design-system/src/utils/event-bus.test.ts b/packages/@n8n/utils/src/event-bus.test.ts similarity index 100% rename from packages/design-system/src/utils/event-bus.test.ts rename to packages/@n8n/utils/src/event-bus.test.ts diff --git a/packages/design-system/src/utils/event-bus.ts b/packages/@n8n/utils/src/event-bus.ts similarity index 90% rename from packages/design-system/src/utils/event-bus.ts rename to packages/@n8n/utils/src/event-bus.ts index eb08228b47..b25358fec8 100644 --- a/packages/design-system/src/utils/event-bus.ts +++ b/packages/@n8n/utils/src/event-bus.ts @@ -7,7 +7,6 @@ type Payloads = { type Listener = (payload: Payload) => void; -// TODO: Fix all usages of `createEventBus` and convert `any` to `unknown` // eslint-disable-next-line @typescript-eslint/no-explicit-any export interface EventBus = Record> { on( @@ -42,7 +41,6 @@ export interface EventBus = Record(); */ export function createEventBus< - // TODO: Fix all usages of `createEventBus` and convert `any` to `unknown` // eslint-disable-next-line @typescript-eslint/no-explicit-any ListenerMap extends Payloads = Record, >(): EventBus { @@ -77,7 +75,9 @@ export function createEventBus< emit(eventName, event) { const eventFns = handlers.get(eventName); if (eventFns) { - eventFns.slice().forEach((handler) => handler(event)); + eventFns.slice().forEach((handler) => { + handler(event); + }); } }, }; diff --git a/packages/editor-ui/src/utils/sortUtils.ts b/packages/@n8n/utils/src/search/sublimeSearch.ts similarity index 91% rename from packages/editor-ui/src/utils/sortUtils.ts rename to packages/@n8n/utils/src/search/sublimeSearch.ts index 5e5534cdda..e358352a67 100644 --- a/packages/editor-ui/src/utils/sortUtils.ts +++ b/packages/@n8n/utils/src/search/sublimeSearch.ts @@ -1,8 +1,7 @@ /* - Constants and utility functions used for searching for node types in node creator component -*/ - -// based on https://github.com/forrestthewoods/lib_fts/blob/master/code/fts_fuzzy_match.js + * Constants and utility functions used for searching for node types in node creator component + * based on https://github.com/forrestthewoods/lib_fts/blob/master/code/fts_fuzzy_match.js + */ const SEQUENTIAL_BONUS = 60; // bonus for adjacent matches const SEPARATOR_BONUS = 30; // bonus if match occurs after a separator @@ -34,33 +33,6 @@ function fuzzyMatchSimple(pattern: string, target: string): boolean { return pattern.length !== 0 && target.length !== 0 && patternIdx === pattern.length; } -/** - * Does a fuzzy search to find pattern inside a string. - * @param {*} pattern string pattern to search for - * @param {*} target string string which is being searched - * @returns [boolean, number] a boolean which tells if pattern was - * found or not and a search score - */ -function fuzzyMatch(pattern: string, target: string): { matched: boolean; outScore: number } { - const recursionCount = 0; - const recursionLimit = 5; - const matches: number[] = []; - const maxMatches = 256; - - return fuzzyMatchRecursive( - pattern, - target, - 0 /* patternCurIndex */, - 0 /* strCurrIndex */, - null /* srcMatces */, - matches, - maxMatches, - 0 /* nextMatch */, - recursionCount, - recursionLimit, - ); -} - function fuzzyMatchRecursive( pattern: string, target: string, @@ -195,6 +167,33 @@ function fuzzyMatchRecursive( return { matched: false, outScore }; } +/** + * Does a fuzzy search to find pattern inside a string. + * @param {*} pattern string pattern to search for + * @param {*} target string string which is being searched + * @returns [boolean, number] a boolean which tells if pattern was + * found or not and a search score + */ +function fuzzyMatch(pattern: string, target: string): { matched: boolean; outScore: number } { + const recursionCount = 0; + const recursionLimit = 5; + const matches: number[] = []; + const maxMatches = 256; + + return fuzzyMatchRecursive( + pattern, + target, + 0 /* patternCurIndex */, + 0 /* strCurrIndex */, + null /* srcMatces */, + matches, + maxMatches, + 0 /* nextMatch */, + recursionCount, + recursionLimit, + ); +} + // prop = 'key' // prop = 'key1.key2' // prop = ['key1', 'key2'] @@ -225,6 +224,7 @@ export function sublimeSearch( keys.forEach(({ key, weight }) => { const value = getValue(item, key); if (Array.isArray(value)) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment values = values.concat(value.map((v) => ({ value: v, weight }))); } else if (typeof value === 'string') { values.push({ @@ -237,24 +237,24 @@ export function sublimeSearch( // for each item, check every key and get maximum score const itemMatch = values.reduce( ( - accu: null | { matched: boolean; outScore: number }, + result: null | { matched: boolean; outScore: number }, { value, weight }: { value: string; weight: number }, ) => { if (!fuzzyMatchSimple(filter, value)) { - return accu; + return result; } const match = fuzzyMatch(filter, value); match.outScore *= weight; const { matched, outScore } = match; - if (!accu && matched) { + if (!result && matched) { return match; } - if (matched && accu && outScore > accu.outScore) { + if (matched && result && outScore > result.outScore) { return match; } - return accu; + return result; }, null, ); @@ -275,16 +275,3 @@ export function sublimeSearch( return results; } - -export const sortByProperty = ( - property: keyof T, - arr: T[], - order: 'asc' | 'desc' = 'asc', -): T[] => - arr.sort((a, b) => { - const result = String(a[property]).localeCompare(String(b[property]), undefined, { - numeric: true, - sensitivity: 'base', - }); - return order === 'asc' ? result : -result; - }); diff --git a/packages/@n8n/utils/src/shims.d.ts b/packages/@n8n/utils/src/shims.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/packages/@n8n/utils/src/shims.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/editor-ui/src/utils/sortUtils.test.ts b/packages/@n8n/utils/src/sort/sortByProperty.test.ts similarity index 70% rename from packages/editor-ui/src/utils/sortUtils.test.ts rename to packages/@n8n/utils/src/sort/sortByProperty.test.ts index 45a657df07..97c903b053 100644 --- a/packages/editor-ui/src/utils/sortUtils.test.ts +++ b/packages/@n8n/utils/src/sort/sortByProperty.test.ts @@ -1,4 +1,4 @@ -import { sortByProperty } from '@/utils/sortUtils'; +import { sortByProperty } from './sortByProperty'; const arrayOfObjects = [ { name: 'Álvaro', age: 30 }, @@ -7,8 +7,8 @@ const arrayOfObjects = [ { name: 'Bob', age: 35 }, ]; -describe('sortUtils', () => { - it('"sortByProperty" should sort an array of objects by a property', () => { +describe('sortByProperty', () => { + it('should sort an array of objects by a property', () => { const sortedArray = sortByProperty('name', arrayOfObjects); expect(sortedArray).toEqual([ { name: 'Álvaro', age: 30 }, @@ -18,7 +18,7 @@ describe('sortUtils', () => { ]); }); - it('"sortByProperty" should sort an array of objects by a property in descending order', () => { + it('should sort an array of objects by a property in descending order', () => { const sortedArray = sortByProperty('name', arrayOfObjects, 'desc'); expect(sortedArray).toEqual([ { name: 'Željko', age: 25 }, @@ -28,7 +28,7 @@ describe('sortUtils', () => { ]); }); - it('"sortByProperty" should sort an array of objects by a property if its number', () => { + it('should sort an array of objects by a property if its number', () => { const sortedArray = sortByProperty('age', arrayOfObjects); expect(sortedArray).toEqual([ { name: 'Željko', age: 25 }, @@ -38,7 +38,7 @@ describe('sortUtils', () => { ]); }); - it('"sortByProperty" should sort an array of objects by a property in descending order if its number', () => { + it('should sort an array of objects by a property in descending order if its number', () => { const sortedArray = sortByProperty('age', arrayOfObjects, 'desc'); expect(sortedArray).toEqual([ { name: 'Bob', age: 35 }, diff --git a/packages/@n8n/utils/src/sort/sortByProperty.ts b/packages/@n8n/utils/src/sort/sortByProperty.ts new file mode 100644 index 0000000000..228cc04332 --- /dev/null +++ b/packages/@n8n/utils/src/sort/sortByProperty.ts @@ -0,0 +1,12 @@ +export const sortByProperty = ( + property: keyof T, + arr: T[], + order: 'asc' | 'desc' = 'asc', +): T[] => + arr.sort((a, b) => { + const result = String(a[property]).localeCompare(String(b[property]), undefined, { + numeric: true, + sensitivity: 'base', + }); + return order === 'asc' ? result : -result; + }); diff --git a/packages/@n8n/utils/src/string/truncate.test.ts b/packages/@n8n/utils/src/string/truncate.test.ts new file mode 100644 index 0000000000..4684fb2bb8 --- /dev/null +++ b/packages/@n8n/utils/src/string/truncate.test.ts @@ -0,0 +1,15 @@ +import { truncate } from './truncate'; + +describe('truncate', () => { + it('should truncate text to 30 chars by default', () => { + expect(truncate('This is a very long text that should be truncated')).toBe( + 'This is a very long text that ...', + ); + }); + + it('should truncate text to given length', () => { + expect(truncate('This is a very long text that should be truncated', 25)).toBe( + 'This is a very long text ...', + ); + }); +}); diff --git a/packages/design-system/src/utils/string.ts b/packages/@n8n/utils/src/string/truncate.ts similarity index 100% rename from packages/design-system/src/utils/string.ts rename to packages/@n8n/utils/src/string/truncate.ts diff --git a/packages/@n8n/utils/tsconfig.json b/packages/@n8n/utils/tsconfig.json new file mode 100644 index 0000000000..10f9ee1b73 --- /dev/null +++ b/packages/@n8n/utils/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@n8n/typescript-config/tsconfig.frontend.json", + "compilerOptions": { + "baseUrl": ".", + "rootDir": ".", + "outDir": "dist", + "types": ["vite/client", "vitest/globals"], + "isolatedModules": true + }, + "include": ["src/**/*.ts", "src/**/*.vue", "vite.config.ts", "tsup.config.ts"] +} diff --git a/packages/@n8n/utils/tsup.config.ts b/packages/@n8n/utils/tsup.config.ts new file mode 100644 index 0000000000..0d555b1ab0 --- /dev/null +++ b/packages/@n8n/utils/tsup.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: ['src/**/*.ts', '!src/**/*.test.ts', '!src/**/*.d.ts', '!src/__tests__**/*'], + format: ['cjs', 'esm'], + clean: true, + dts: true, + cjsInterop: true, + splitting: true, + sourcemap: true, +}); diff --git a/packages/@n8n/utils/vite.config.ts b/packages/@n8n/utils/vite.config.ts new file mode 100644 index 0000000000..784f3fb497 --- /dev/null +++ b/packages/@n8n/utils/vite.config.ts @@ -0,0 +1,4 @@ +import { defineConfig, mergeConfig } from 'vite'; +import { vitestConfig } from '@n8n/vitest-config/frontend'; + +export default mergeConfig(defineConfig({}), vitestConfig); diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 6df36b3518..fab4c8f986 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -45,6 +45,7 @@ }, "dependencies": { "@n8n/composables": "workspace:*", + "@n8n/utils": "workspace:*", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/vue-fontawesome": "^3.0.3", diff --git a/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue b/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue index ff2b5f2c8a..e84c18cc4c 100644 --- a/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue +++ b/packages/design-system/src/components/N8nInfoAccordion/InfoAccordion.vue @@ -1,9 +1,9 @@