From 20ee7984f81159c6ff61cdf559ee9071570d1a89 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 08:55:01 +0100 Subject: [PATCH 01/12] :rocket: Release 1.81.0 (#13469) Co-authored-by: tomi <10324676+tomi@users.noreply.github.com> --- CHANGELOG.md | 39 +++++++++++++++++++ package.json | 2 +- packages/@n8n/api-types/package.json | 2 +- packages/@n8n/config/package.json | 2 +- packages/@n8n/nodes-langchain/package.json | 2 +- packages/@n8n/permissions/package.json | 2 +- packages/@n8n/task-runner/package.json | 2 +- packages/cli/package.json | 2 +- packages/core/package.json | 2 +- packages/design-system/package.json | 2 +- packages/editor-ui/package.json | 2 +- .../frontend/@n8n/composables/package.json | 2 +- packages/node-dev/package.json | 2 +- packages/nodes-base/package.json | 2 +- packages/workflow/package.json | 2 +- 15 files changed, 53 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b288cc0af7..18175ee50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,42 @@ +# [1.81.0](https://github.com/n8n-io/n8n/compare/n8n@1.80.0...n8n@1.81.0) (2025-02-24) + + +### Bug Fixes + +* Always clear popupWindowState before showing popup from form trigger ([#13363](https://github.com/n8n-io/n8n/issues/13363)) ([b7f1265](https://github.com/n8n-io/n8n/commit/b7f12650f1f42c0ff15c1da3e5ade350fb1e23d2)) +* **Code Node:** Fix `$items` in Code node when using task runner ([#13368](https://github.com/n8n-io/n8n/issues/13368)) ([87b3c50](https://github.com/n8n-io/n8n/commit/87b3c508b3d5a7d6f3b9f8377de66567a04fa970)) +* **core:** Avoid renewing the license on init to prevent excessive duplicate renewal calls ([#13347](https://github.com/n8n-io/n8n/issues/13347)) ([1e1f528](https://github.com/n8n-io/n8n/commit/1e1f52846641515ad4479ab1088e78a9266e452d)) +* **core:** Ensure that 'workflow-post-execute' event has userId whenever it's available ([#13326](https://github.com/n8n-io/n8n/issues/13326)) ([f41e353](https://github.com/n8n-io/n8n/commit/f41e353887fef4269510d25fa87b73da4cf925f9)) +* **core:** Fix DB migrations for MySQL ([#13261](https://github.com/n8n-io/n8n/issues/13261)) ([d0968a1](https://github.com/n8n-io/n8n/commit/d0968a10d56ac5c97974129742ba8f8a85997dac)) +* **core:** Fix resuming executions on test webhooks from Wait forms ([#13410](https://github.com/n8n-io/n8n/issues/13410)) ([8ffd316](https://github.com/n8n-io/n8n/commit/8ffd3167d58d30f087fd31010e6f79f1398d8f49)) +* **core:** Handle connections for missing nodes in a workflow ([#13362](https://github.com/n8n-io/n8n/issues/13362)) ([1e5feb1](https://github.com/n8n-io/n8n/commit/1e5feb195d50054939f85c9e1b5a32885c579901)) +* **core:** Make sure middleware works with legacy API Keys ([#13390](https://github.com/n8n-io/n8n/issues/13390)) ([ca76ef4](https://github.com/n8n-io/n8n/commit/ca76ef4bc248a3bcde844bc8378d38eed269f032)) +* **core:** Return original hooks errors to the frontend ([#13365](https://github.com/n8n-io/n8n/issues/13365)) ([5439181](https://github.com/n8n-io/n8n/commit/5439181e92f20fef1423575cabec7acbe1740b26)) +* **editor:** Correctly close node creator when selecting/deselecting a node ([#13338](https://github.com/n8n-io/n8n/issues/13338)) ([c3dc66e](https://github.com/n8n-io/n8n/commit/c3dc66ee7372927fcfd6baac3b9d853690e39c99)) +* **editor:** Do not show credential details popup for users without necessary scopes with direct link ([#13264](https://github.com/n8n-io/n8n/issues/13264)) ([a5401d0](https://github.com/n8n-io/n8n/commit/a5401d06a58ef026f44499d05b42a8d0dbe2520e)) +* **editor:** Do not show project settings for users without permission with direct link ([#13246](https://github.com/n8n-io/n8n/issues/13246)) ([fa488f1](https://github.com/n8n-io/n8n/commit/fa488f15619f798a0360c96492f2928ac661d9ee)) +* **editor:** Don't open form popup window if different trigger node is used ([#13391](https://github.com/n8n-io/n8n/issues/13391)) ([57a9a5b](https://github.com/n8n-io/n8n/commit/57a9a5b15f55aae0301851e93847ed87feb081e8)) +* **editor:** Fix configurable node description margins and text alignment ([#13318](https://github.com/n8n-io/n8n/issues/13318)) ([c881ea2](https://github.com/n8n-io/n8n/commit/c881ea2c7b43a4fb610533dd553520a6de51f22d)) +* **editor:** Fix workflow moving E2E tests ([#13396](https://github.com/n8n-io/n8n/issues/13396)) ([073b05b](https://github.com/n8n-io/n8n/commit/073b05b10c81e3a0451c310bc0bde25170e1591e)) +* **editor:** Optionally share credentials used by the workflow when moving the workflow between projects ([#12524](https://github.com/n8n-io/n8n/issues/12524)) ([7bd83d7](https://github.com/n8n-io/n8n/commit/7bd83d7d330b6f01b5798461f2218254a9964d87)) +* **editor:** Polyfill `Array.prototype.toSorted` (no-chanhelog) ([#13463](https://github.com/n8n-io/n8n/issues/13463)) ([f2b15ea](https://github.com/n8n-io/n8n/commit/f2b15ea086fcc541a5a584998985d712335210ec)) +* **editor:** Register/unregister keybindings on window focus/blur ([#13419](https://github.com/n8n-io/n8n/issues/13419)) ([7a504dc](https://github.com/n8n-io/n8n/commit/7a504dc30fcf0c7641528ed469835811f82bb098)) +* **editor:** Switch back to selection mode on window blur ([#13341](https://github.com/n8n-io/n8n/issues/13341)) ([415e25b](https://github.com/n8n-io/n8n/commit/415e25b5d524b0d3c391403f129468e57bbb918e)) +* Prevent flicker during paginated workflow navigation ([#13348](https://github.com/n8n-io/n8n/issues/13348)) ([d277e0b](https://github.com/n8n-io/n8n/commit/d277e0ba0e5d87500457538b4b0f1363e267f071)) + + +### Features + +* **core:** Hackmation - Add last activity metric ([#13237](https://github.com/n8n-io/n8n/issues/13237)) ([272f55b](https://github.com/n8n-io/n8n/commit/272f55b80f1d4576d1675040bd2775210c4ab5e9)) +* **editor:** Change rename node keyboard shortcut to Space on new canvas ([#11872](https://github.com/n8n-io/n8n/issues/11872)) ([c90d0d9](https://github.com/n8n-io/n8n/commit/c90d0d9161ec161cd1afd6aa5b56345c1611f9c9)) +* **editor:** Implement breadcrumbs component ([#13317](https://github.com/n8n-io/n8n/issues/13317)) ([db297f1](https://github.com/n8n-io/n8n/commit/db297f107d81738d57e298135a9c279ad83345dc)) +* **editor:** Implement folder navigation in workflows list ([#13370](https://github.com/n8n-io/n8n/issues/13370)) ([0eae14e](https://github.com/n8n-io/n8n/commit/0eae14e27ab4fab3229750d6b2a32868db1e8dd4)) +* **editor:** Rename 'Text' fields on AI nodes to 'Prompt' ([#13416](https://github.com/n8n-io/n8n/issues/13416)) ([4fa666b](https://github.com/n8n-io/n8n/commit/4fa666b976423365299e915130384e10c8e12528)) +* Enable partial exections v2 by default ([#13344](https://github.com/n8n-io/n8n/issues/13344)) ([29ae239](https://github.com/n8n-io/n8n/commit/29ae2396c99d54d8f3db71e6370516f0dc354d00)) +* **n8n Form Node:** Limit wait time parameters ([#13160](https://github.com/n8n-io/n8n/issues/13160)) ([14b6f8b](https://github.com/n8n-io/n8n/commit/14b6f8b97275e38ba4a4c1819e8e32b711de21ba)) + + + # [1.80.0](https://github.com/n8n-io/n8n/compare/n8n@1.79.0...n8n@1.80.0) (2025-02-17) diff --git a/package.json b/package.json index 6750279c84..200ada1b88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-monorepo", - "version": "1.80.0", + "version": "1.81.0", "private": true, "engines": { "node": ">=20.15", diff --git a/packages/@n8n/api-types/package.json b/packages/@n8n/api-types/package.json index 3d63c0916e..64b3cdfaf3 100644 --- a/packages/@n8n/api-types/package.json +++ b/packages/@n8n/api-types/package.json @@ -1,6 +1,6 @@ { "name": "@n8n/api-types", - "version": "0.15.0", + "version": "0.16.0", "scripts": { "clean": "rimraf dist .turbo", "dev": "pnpm watch", diff --git a/packages/@n8n/config/package.json b/packages/@n8n/config/package.json index b1a2bead32..45d97232eb 100644 --- a/packages/@n8n/config/package.json +++ b/packages/@n8n/config/package.json @@ -1,6 +1,6 @@ { "name": "@n8n/config", - "version": "1.29.0", + "version": "1.30.0", "scripts": { "clean": "rimraf dist .turbo", "dev": "pnpm watch", diff --git a/packages/@n8n/nodes-langchain/package.json b/packages/@n8n/nodes-langchain/package.json index b9c316618c..68d3745641 100644 --- a/packages/@n8n/nodes-langchain/package.json +++ b/packages/@n8n/nodes-langchain/package.json @@ -1,6 +1,6 @@ { "name": "@n8n/n8n-nodes-langchain", - "version": "1.80.0", + "version": "1.81.0", "description": "", "main": "index.js", "scripts": { diff --git a/packages/@n8n/permissions/package.json b/packages/@n8n/permissions/package.json index c408abe0b8..628150a0ee 100644 --- a/packages/@n8n/permissions/package.json +++ b/packages/@n8n/permissions/package.json @@ -1,6 +1,6 @@ { "name": "@n8n/permissions", - "version": "0.17.0", + "version": "0.18.0", "scripts": { "clean": "rimraf dist .turbo", "dev": "pnpm watch", diff --git a/packages/@n8n/task-runner/package.json b/packages/@n8n/task-runner/package.json index 391ee81347..f7d424504e 100644 --- a/packages/@n8n/task-runner/package.json +++ b/packages/@n8n/task-runner/package.json @@ -1,6 +1,6 @@ { "name": "@n8n/task-runner", - "version": "1.17.0", + "version": "1.18.0", "scripts": { "clean": "rimraf dist .turbo", "start": "node dist/start.js", diff --git a/packages/cli/package.json b/packages/cli/package.json index 4a0968d4f2..7ee8951135 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "n8n", - "version": "1.80.0", + "version": "1.81.0", "description": "n8n Workflow Automation Tool", "main": "dist/index", "types": "dist/index.d.ts", diff --git a/packages/core/package.json b/packages/core/package.json index 715e7a4fb0..9634ebb136 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "n8n-core", - "version": "1.79.0", + "version": "1.80.0", "description": "Core functionality of n8n", "main": "dist/index", "types": "dist/index.d.ts", diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 3ddc30ebbe..304f6489a8 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -1,6 +1,6 @@ { "name": "n8n-design-system", - "version": "1.68.0", + "version": "1.69.0", "main": "src/index.ts", "import": "src/index.ts", "scripts": { diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index e1da571499..73ad4b07f8 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -1,6 +1,6 @@ { "name": "n8n-editor-ui", - "version": "1.80.0", + "version": "1.81.0", "description": "Workflow Editor UI for n8n", "main": "index.js", "scripts": { diff --git a/packages/frontend/@n8n/composables/package.json b/packages/frontend/@n8n/composables/package.json index 92c125461c..a1ba27cffe 100644 --- a/packages/frontend/@n8n/composables/package.json +++ b/packages/frontend/@n8n/composables/package.json @@ -1,7 +1,7 @@ { "name": "@n8n/composables", "type": "module", - "version": "1.1.0", + "version": "1.2.0", "files": [ "dist" ], diff --git a/packages/node-dev/package.json b/packages/node-dev/package.json index 0aa5f544e0..81345477d7 100644 --- a/packages/node-dev/package.json +++ b/packages/node-dev/package.json @@ -1,6 +1,6 @@ { "name": "n8n-node-dev", - "version": "1.79.0", + "version": "1.80.0", "description": "CLI to simplify n8n credentials/node development", "main": "dist/src/index", "types": "dist/src/index.d.ts", diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 59bab64334..8c17b8f9f7 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -1,6 +1,6 @@ { "name": "n8n-nodes-base", - "version": "1.79.0", + "version": "1.80.0", "description": "Base nodes of n8n", "main": "index.js", "scripts": { diff --git a/packages/workflow/package.json b/packages/workflow/package.json index c021e998d0..43d120fd52 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -1,6 +1,6 @@ { "name": "n8n-workflow", - "version": "1.78.0", + "version": "1.79.0", "description": "Workflow base code of n8n", "main": "dist/index.js", "module": "src/index.ts", From f8a7fb38ccf433e79b1916a159f203d44a94f2d2 Mon Sep 17 00:00:00 2001 From: Danny Martini Date: Tue, 25 Feb 2025 11:35:52 +0100 Subject: [PATCH 02/12] feat(core): Add tables for reporting dashboard (no-changelog) (#13336) --- packages/cli/src/databases/dsl/column.ts | 80 +++++++++++-- .../1739549398681-CreateAnalyticsTables.ts | 106 ++++++++++++++++++ .../src/databases/migrations/mysqldb/index.ts | 2 + .../databases/migrations/postgresdb/index.ts | 2 + .../src/databases/migrations/sqlite/index.ts | 2 + 5 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 packages/cli/src/databases/migrations/common/1739549398681-CreateAnalyticsTables.ts diff --git a/packages/cli/src/databases/dsl/column.ts b/packages/cli/src/databases/dsl/column.ts index 95ff31c200..83f2f8fe58 100644 --- a/packages/cli/src/databases/dsl/column.ts +++ b/packages/cli/src/databases/dsl/column.ts @@ -1,10 +1,20 @@ import type { Driver, TableColumnOptions } from '@n8n/typeorm'; export class Column { - private type: 'int' | 'boolean' | 'varchar' | 'text' | 'json' | 'timestamp' | 'uuid'; + private type: + | 'int' + | 'boolean' + | 'varchar' + | 'text' + | 'json' + | 'timestamptz' + | 'timestamp' + | 'uuid'; private isGenerated = false; + private isGenerated2 = false; + private isNullable = true; private isPrimary = false; @@ -15,6 +25,8 @@ export class Column { private primaryKeyConstraintName: string | undefined; + private commentValue: string | undefined; + constructor(private name: string) {} get bool() { @@ -43,7 +55,22 @@ export class Column { return this; } + /** + * @deprecated use `timestampTimezone` instead + **/ timestamp(msPrecision = 3) { + this.type = 'timestamptz'; + this.length = msPrecision ?? 'auto'; + return this; + } + + timestampTimezone(msPrecision = 3) { + this.type = 'timestamptz'; + this.length = msPrecision ?? 'auto'; + return this; + } + + timestampNoTimezone(msPrecision = 3) { this.type = 'timestamp'; this.length = msPrecision ?? 'auto'; return this; @@ -75,15 +102,40 @@ export class Column { return this; } + /** + * @deprecated, use autoGenerate2 instead + **/ get autoGenerate() { this.isGenerated = true; return this; } + /** + * Prefers `identity` over `increment` (which turns to `serial` for pg) + * See https://wiki.postgresql.org/wiki/Don%27t_Do_This#Don.27t_use_serial + **/ + get autoGenerate2() { + this.isGenerated2 = true; + return this; + } + + comment(comment: string) { + this.commentValue = comment; + return this; + } + // eslint-disable-next-line complexity toOptions(driver: Driver): TableColumnOptions { - const { name, type, isNullable, isPrimary, isGenerated, length, primaryKeyConstraintName } = - this; + const { + name, + type, + isNullable, + isPrimary, + isGenerated, + isGenerated2, + length, + primaryKeyConstraintName, + } = this; const isMysql = 'mysql' in driver; const isPostgres = 'postgres' in driver; const isSqlite = 'sqlite' in driver; @@ -100,8 +152,10 @@ export class Column { options.type = 'integer'; } else if (type === 'boolean' && isMysql) { options.type = 'tinyint(1)'; - } else if (type === 'timestamp') { + } else if (type === 'timestamptz') { options.type = isPostgres ? 'timestamptz' : 'datetime'; + } else if (type === 'timestamp') { + options.type = isPostgres ? 'timestamp' : 'datetime'; } else if (type === 'json' && isSqlite) { options.type = 'text'; } else if (type === 'uuid') { @@ -111,7 +165,10 @@ export class Column { if (isSqlite) options.type = 'varchar'; } - if ((type === 'varchar' || type === 'timestamp') && length !== 'auto') { + if ( + (type === 'varchar' || type === 'timestamptz' || type === 'timestamp') && + length !== 'auto' + ) { options.type = `${options.type}(${length})`; } @@ -120,12 +177,17 @@ export class Column { options.generationStrategy = type === 'uuid' ? 'uuid' : 'increment'; } - if (isPrimary || isGenerated) { + if (isGenerated2) { + options.isGenerated = true; + options.generationStrategy = type === 'uuid' ? 'uuid' : 'identity'; + } + + if (isPrimary || isGenerated || isGenerated2) { options.isNullable = false; } if (this.defaultValue !== undefined) { - if (type === 'timestamp' && this.defaultValue === 'NOW()') { + if ((type === 'timestamptz' || type === 'timestamp') && this.defaultValue === 'NOW()') { options.default = isSqlite ? "STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')" : 'CURRENT_TIMESTAMP(3)'; @@ -134,6 +196,10 @@ export class Column { } } + if (this.commentValue) { + options.comment = this.commentValue; + } + return options; } } diff --git a/packages/cli/src/databases/migrations/common/1739549398681-CreateAnalyticsTables.ts b/packages/cli/src/databases/migrations/common/1739549398681-CreateAnalyticsTables.ts new file mode 100644 index 0000000000..ee1bdb4ccf --- /dev/null +++ b/packages/cli/src/databases/migrations/common/1739549398681-CreateAnalyticsTables.ts @@ -0,0 +1,106 @@ +import type { MigrationContext, ReversibleMigration } from '@/databases/types'; + +const names = { + // table names + t: { + analyticsMetadata: 'analytics_metadata', + analyticsRaw: 'analytics_raw', + analyticsByPeriod: 'analytics_by_period', + workflowEntity: 'workflow_entity', + project: 'project', + }, + // column names by table + c: { + analyticsMetadata: { + metaId: 'metaId', + projectId: 'projectId', + workflowId: 'workflowId', + }, + analyticsRaw: { + metaId: 'metaId', + }, + analyticsByPeriod: { + metaId: 'metaId', + type: 'type', + periodUnit: 'periodUnit', + periodStart: 'periodStart', + }, + project: { + id: 'id', + }, + workflowEntity: { + id: 'id', + }, + }, +}; + +export class CreateAnalyticsTables1739549398681 implements ReversibleMigration { + async up({ schemaBuilder: { createTable, column } }: MigrationContext) { + await createTable(names.t.analyticsMetadata) + .withColumns( + column(names.c.analyticsMetadata.metaId).int.primary.autoGenerate2, + column(names.c.analyticsMetadata.workflowId).varchar(16), + column(names.c.analyticsMetadata.projectId).varchar(36), + column('workflowName').varchar(128).notNull, + column('projectName').varchar(255).notNull, + ) + .withForeignKey(names.c.analyticsMetadata.workflowId, { + tableName: names.t.workflowEntity, + columnName: names.c.workflowEntity.id, + onDelete: 'SET NULL', + }) + .withForeignKey(names.c.analyticsMetadata.projectId, { + tableName: names.t.project, + columnName: names.c.project.id, + onDelete: 'SET NULL', + }); + + const typeComment = '0: time_saved_minutes, 1: runtime_milliseconds, 2: success, 3: failure'; + + await createTable(names.t.analyticsRaw) + .withColumns( + column('id').int.primary.autoGenerate2, + column(names.c.analyticsRaw.metaId).int.notNull, + column('type').int.notNull.comment(typeComment), + column('value').int.notNull, + column('timestamp').timestampNoTimezone(0).default('CURRENT_TIMESTAMP').notNull, + ) + .withForeignKey(names.c.analyticsRaw.metaId, { + tableName: names.t.analyticsMetadata, + columnName: names.c.analyticsMetadata.metaId, + onDelete: 'CASCADE', + }); + + await createTable(names.t.analyticsByPeriod) + .withColumns( + column('id').int.primary.autoGenerate2, + column(names.c.analyticsByPeriod.metaId).int.notNull, + column(names.c.analyticsByPeriod.type).int.notNull.comment(typeComment), + column('value').int.notNull, + column(names.c.analyticsByPeriod.periodUnit).int.notNull.comment( + '0: hour, 1: day, 2: week', + ), + column(names.c.analyticsByPeriod.periodStart).timestampNoTimezone(0), + ) + .withForeignKey(names.c.analyticsByPeriod.metaId, { + tableName: names.t.analyticsMetadata, + columnName: names.c.analyticsMetadata.metaId, + onDelete: 'CASCADE', + }) + .withIndexOn( + [ + names.c.analyticsByPeriod.periodStart, + names.c.analyticsByPeriod.type, + names.c.analyticsByPeriod.periodUnit, + names.c.analyticsByPeriod.metaId, + ], + true, + ); + } + + async down({ schemaBuilder: { dropTable } }: MigrationContext) { + await dropTable(names.t.analyticsMetadata); + await dropTable(names.t.analyticsRaw); + await dropTable(names.t.analyticsByPeriod); + } +} diff --git a/packages/cli/src/databases/migrations/mysqldb/index.ts b/packages/cli/src/databases/migrations/mysqldb/index.ts index e16c387167..5e727487dd 100644 --- a/packages/cli/src/databases/migrations/mysqldb/index.ts +++ b/packages/cli/src/databases/migrations/mysqldb/index.ts @@ -81,6 +81,7 @@ import { AddManagedColumnToCredentialsTable1734479635324 } from '../common/17344 import { CreateTestCaseExecutionTable1736947513045 } from '../common/1736947513045-CreateTestCaseExecutionTable'; import { AddErrorColumnsToTestRuns1737715421462 } from '../common/1737715421462-AddErrorColumnsToTestRuns'; import { CreateFolderTable1738709609940 } from '../common/1738709609940-CreateFolderTable'; +import { CreateAnalyticsTables1739549398681 } from '../common/1739549398681-CreateAnalyticsTables'; export const mysqlMigrations: Migration[] = [ InitialMigration1588157391238, @@ -164,4 +165,5 @@ export const mysqlMigrations: Migration[] = [ AddErrorColumnsToTestRuns1737715421462, CreateFolderTable1738709609940, FixTestDefinitionPrimaryKey1739873751194, + CreateAnalyticsTables1739549398681, ]; diff --git a/packages/cli/src/databases/migrations/postgresdb/index.ts b/packages/cli/src/databases/migrations/postgresdb/index.ts index cb667aabed..0d5d7d72bd 100644 --- a/packages/cli/src/databases/migrations/postgresdb/index.ts +++ b/packages/cli/src/databases/migrations/postgresdb/index.ts @@ -80,6 +80,7 @@ import { AddStatsColumnsToTestRun1736172058779 } from '../common/1736172058779-A import { CreateTestCaseExecutionTable1736947513045 } from '../common/1736947513045-CreateTestCaseExecutionTable'; import { AddErrorColumnsToTestRuns1737715421462 } from '../common/1737715421462-AddErrorColumnsToTestRuns'; import { CreateFolderTable1738709609940 } from '../common/1738709609940-CreateFolderTable'; +import { CreateAnalyticsTables1739549398681 } from '../common/1739549398681-CreateAnalyticsTables'; export const postgresMigrations: Migration[] = [ InitialMigration1587669153312, @@ -162,4 +163,5 @@ export const postgresMigrations: Migration[] = [ CreateTestCaseExecutionTable1736947513045, AddErrorColumnsToTestRuns1737715421462, CreateFolderTable1738709609940, + CreateAnalyticsTables1739549398681, ]; diff --git a/packages/cli/src/databases/migrations/sqlite/index.ts b/packages/cli/src/databases/migrations/sqlite/index.ts index 5e26e91075..73e1bc180c 100644 --- a/packages/cli/src/databases/migrations/sqlite/index.ts +++ b/packages/cli/src/databases/migrations/sqlite/index.ts @@ -77,6 +77,7 @@ import { AddManagedColumnToCredentialsTable1734479635324 } from '../common/17344 import { AddStatsColumnsToTestRun1736172058779 } from '../common/1736172058779-AddStatsColumnsToTestRun'; import { CreateTestCaseExecutionTable1736947513045 } from '../common/1736947513045-CreateTestCaseExecutionTable'; import { AddErrorColumnsToTestRuns1737715421462 } from '../common/1737715421462-AddErrorColumnsToTestRuns'; +import { CreateAnalyticsTables1739549398681 } from '../common/1739549398681-CreateAnalyticsTables'; const sqliteMigrations: Migration[] = [ InitialMigration1588102412422, @@ -156,6 +157,7 @@ const sqliteMigrations: Migration[] = [ CreateTestCaseExecutionTable1736947513045, AddErrorColumnsToTestRuns1737715421462, CreateFolderTable1738709609940, + CreateAnalyticsTables1739549398681, ]; export { sqliteMigrations }; From 6953b0d53a28448022c9de0a2f6294c9390a3b48 Mon Sep 17 00:00:00 2001 From: Michael Kret <88898367+michael-radency@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:14:38 +0200 Subject: [PATCH 03/12] feat: Hackmation - automatically switch to expression mode (#13213) Co-authored-by: Michael Kret Co-authored-by: Elias Meire --- .../AssignmentCollection.vue | 2 +- .../components/FilterConditions/Condition.vue | 4 +- .../FilterConditions/FilterConditions.vue | 2 +- .../src/components/ParameterInput.vue | 12 ++++- .../editor-ui/src/utils/expressions.test.ts | 48 ++++++++++++++++++- packages/editor-ui/src/utils/expressions.ts | 18 +++++++ 6 files changed, 80 insertions(+), 6 deletions(-) diff --git a/packages/editor-ui/src/components/AssignmentCollection/AssignmentCollection.vue b/packages/editor-ui/src/components/AssignmentCollection/AssignmentCollection.vue index d1828c3647..213269ab2f 100644 --- a/packages/editor-ui/src/components/AssignmentCollection/AssignmentCollection.vue +++ b/packages/editor-ui/src/components/AssignmentCollection/AssignmentCollection.vue @@ -153,7 +153,7 @@ function optionSelected(action: string) { { :is-read-only="readOnly" :parameter="leftParameter" :value="condition.leftValue" - :path="`${path}.left`" + :path="`${path}.leftValue`" :class="[$style.input, $style.inputLeft]" data-test-id="filter-condition-left" @update="onLeftValueChange" @@ -212,7 +212,7 @@ const onBlur = (): void => { :options-position="breakpoint === 'default' ? 'top' : 'bottom'" :parameter="rightParameter" :value="condition.rightValue" - :path="`${path}.right`" + :path="`${path}.rightValue`" :class="[$style.input, $style.inputRight]" data-test-id="filter-condition-right" @update="onRightValueChange" diff --git a/packages/editor-ui/src/components/FilterConditions/FilterConditions.vue b/packages/editor-ui/src/components/FilterConditions/FilterConditions.vue index b891b0c3bc..241f656c88 100644 --- a/packages/editor-ui/src/components/FilterConditions/FilterConditions.vue +++ b/packages/editor-ui/src/components/FilterConditions/FilterConditions.vue @@ -195,7 +195,7 @@ function getIssues(index: number): string[] { :read-only="readOnly" :can-remove="index !== 0 || state.paramValue.conditions.length > 1" :can-drag="index !== 0 || state.paramValue.conditions.length > 1" - :path="`${path}.${index}`" + :path="`${path}.conditions.${index}`" :issues="getIssues(index)" :class="$style.condition" @update="(value) => onConditionUpdate(index, value)" diff --git a/packages/editor-ui/src/components/ParameterInput.vue b/packages/editor-ui/src/components/ParameterInput.vue index 4183ab562e..4c92c82615 100644 --- a/packages/editor-ui/src/components/ParameterInput.vue +++ b/packages/editor-ui/src/components/ParameterInput.vue @@ -66,6 +66,7 @@ import type { EventBus } from 'n8n-design-system/utils'; import { createEventBus } from 'n8n-design-system/utils'; import { useRouter } from 'vue-router'; import { useElementSize } from '@vueuse/core'; +import { completeExpressionSyntax, isStringWithExpressionSyntax } from '@/utils/expressions'; type Picker = { $emit: (arg0: string, arg1: Date) => void }; @@ -813,16 +814,25 @@ function valueChanged(value: NodeParameterValueType | {} | Date) { if (remoteParameterOptionsLoading.value) { return; } - // Only update the value if it has changed + const oldValue = get(node.value, props.path); + if (oldValue !== undefined && oldValue === value) { + // Only update the value if it has changed return; } + if (!oldValue && oldValue !== undefined && isStringWithExpressionSyntax(value)) { + // if empty old value and updated value has an expression, add '=' prefix to switch to expression mode + value = '=' + value; + } + if (props.parameter.name === 'nodeCredentialType') { activeCredentialType.value = value as string; } + value = completeExpressionSyntax(value); + if (value instanceof Date) { value = value.toISOString(); } diff --git a/packages/editor-ui/src/utils/expressions.test.ts b/packages/editor-ui/src/utils/expressions.test.ts index b2b11728c5..1ae1a47f5e 100644 --- a/packages/editor-ui/src/utils/expressions.test.ts +++ b/packages/editor-ui/src/utils/expressions.test.ts @@ -1,5 +1,11 @@ import { ExpressionError } from 'n8n-workflow'; -import { removeExpressionPrefix, stringifyExpressionResult, unwrapExpression } from './expressions'; +import { + completeExpressionSyntax, + isStringWithExpressionSyntax, + removeExpressionPrefix, + stringifyExpressionResult, + unwrapExpression, +} from './expressions'; describe('Utils: Expressions', () => { describe('stringifyExpressionResult()', () => { @@ -53,4 +59,44 @@ describe('Utils: Expressions', () => { expect(removeExpressionPrefix(input)).toBe(output); }); }); + + describe('completeExpressionSyntax', () => { + it('should complete expressions with "{{ " at the end', () => { + expect(completeExpressionSyntax('test {{ ')).toBe('=test {{ }}'); + }); + + it('should complete expressions with "{{$" at the end', () => { + expect(completeExpressionSyntax('test {{$')).toBe('=test {{ $ }}'); + }); + + it('should not modify already valid expressions', () => { + expect(completeExpressionSyntax('=valid expression')).toBe('=valid expression'); + }); + + it('should return non-string values unchanged', () => { + expect(completeExpressionSyntax(123)).toBe(123); + expect(completeExpressionSyntax(true)).toBe(true); + expect(completeExpressionSyntax(null)).toBe(null); + }); + }); + + describe('isStringWithExpressionSyntax', () => { + it('should return true for strings with expression syntax', () => { + expect(isStringWithExpressionSyntax('test {{ value }}')).toBe(true); + }); + + it('should return false for strings without expression syntax', () => { + expect(isStringWithExpressionSyntax('just a string')).toBe(false); + }); + + it('should return false for strings starting with "="', () => { + expect(isStringWithExpressionSyntax('=expression {{ value }}')).toBe(false); + }); + + it('should return false for non-string values', () => { + expect(isStringWithExpressionSyntax(123)).toBe(false); + expect(isStringWithExpressionSyntax(true)).toBe(false); + expect(isStringWithExpressionSyntax(null)).toBe(false); + }); + }); }); diff --git a/packages/editor-ui/src/utils/expressions.ts b/packages/editor-ui/src/utils/expressions.ts index d572006ad5..155b83d9da 100644 --- a/packages/editor-ui/src/utils/expressions.ts +++ b/packages/editor-ui/src/utils/expressions.ts @@ -139,3 +139,21 @@ export const stringifyExpressionResult = ( return typeof result.result === 'string' ? result.result : String(result.result); }; + +export const completeExpressionSyntax = (value: T) => { + if (typeof value === 'string' && !value.startsWith('=')) { + if (value.endsWith('{{ ')) return '=' + value + ' }}'; + if (value.endsWith('{{$')) return '=' + value.slice(0, -1) + ' $ }}'; + } + + return value; +}; + +export const isStringWithExpressionSyntax = (value: T): boolean => { + return ( + typeof value === 'string' && + !value.startsWith('=') && + value.includes('{{') && + value.includes('}}') + ); +}; From 6706aa6664a6aa24cdea8347c0cf01c24f5f8bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Tue, 25 Feb 2025 12:22:13 +0100 Subject: [PATCH 04/12] fix(editor): Fix the path to which tree-sitter wasm files are copied to (no-changelog) (#13389) --- packages/editor-ui/vite.config.mts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/editor-ui/vite.config.mts b/packages/editor-ui/vite.config.mts index df9841eacc..1d7514ca09 100644 --- a/packages/editor-ui/vite.config.mts +++ b/packages/editor-ui/vite.config.mts @@ -66,10 +66,13 @@ const plugins = [ }), viteStaticCopy({ targets: [ - { src: pathPosix.resolve('node_modules/web-tree-sitter/tree-sitter.wasm'), dest: 'public' }, + { + src: pathPosix.resolve('node_modules/web-tree-sitter/tree-sitter.wasm'), + dest: resolve(__dirname, 'dist'), + }, { src: pathPosix.resolve('node_modules/curlconverter/dist/tree-sitter-bash.wasm'), - dest: 'public', + dest: resolve(__dirname, 'dist'), }, ], }), From a4f674115e95742c365e06de7915e0558609f9de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Tue, 25 Feb 2025 13:00:44 +0100 Subject: [PATCH 05/12] chore: Upgrade task runner launcher to 1.1.1 (#13495) --- docker/images/n8n-custom/Dockerfile | 2 +- docker/images/n8n/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/images/n8n-custom/Dockerfile b/docker/images/n8n-custom/Dockerfile index ee9d956afb..51d3707546 100644 --- a/docker/images/n8n-custom/Dockerfile +++ b/docker/images/n8n-custom/Dockerfile @@ -33,7 +33,7 @@ COPY docker/images/n8n/docker-entrypoint.sh / # Setup the Task Runner Launcher ARG TARGETPLATFORM -ARG LAUNCHER_VERSION=1.1.0 +ARG LAUNCHER_VERSION=1.1.1 COPY docker/images/n8n/n8n-task-runners.json /etc/n8n-task-runners.json # Download, verify, then extract the launcher binary RUN \ diff --git a/docker/images/n8n/Dockerfile b/docker/images/n8n/Dockerfile index 8b258d157b..8edff951d4 100644 --- a/docker/images/n8n/Dockerfile +++ b/docker/images/n8n/Dockerfile @@ -27,7 +27,7 @@ RUN set -eux; \ # Setup the Task Runner Launcher ARG TARGETPLATFORM -ARG LAUNCHER_VERSION=1.1.0 +ARG LAUNCHER_VERSION=1.1.1 COPY n8n-task-runners.json /etc/n8n-task-runners.json # Download, verify, then extract the launcher binary RUN \ From 59389194c24aa81ace3a64d94d2ad1adb0fd3907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Tue, 25 Feb 2025 13:01:34 +0100 Subject: [PATCH 06/12] chore: Upgrade license SDK to 2.17.0 (#13494) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ --- packages/cli/package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 7ee8951135..5236f480a8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -97,7 +97,7 @@ "@n8n/task-runner": "workspace:*", "@n8n/typeorm": "0.3.20-12", "@n8n_io/ai-assistant-sdk": "1.13.0", - "@n8n_io/license-sdk": "2.16.1", + "@n8n_io/license-sdk": "2.17.0", "@oclif/core": "4.0.7", "@rudderstack/rudder-sdk-node": "2.0.9", "@sentry/node": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2777a30fac..ef82e4a279 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -775,8 +775,8 @@ importers: specifier: 1.13.0 version: 1.13.0 '@n8n_io/license-sdk': - specifier: 2.16.1 - version: 2.16.1 + specifier: 2.17.0 + version: 2.17.0 '@oclif/core': specifier: 4.0.7 version: 4.0.7 @@ -4567,8 +4567,8 @@ packages: resolution: {integrity: sha512-16kftFTeX3/lBinHJaBK0OL1lB4FpPaUoHX4h25AkvgHvmjUHpWNY2ZtKos0rY89+pkzDsNxMZqSUkeKU45iRg==} engines: {node: '>=20.15', pnpm: '>=8.14'} - '@n8n_io/license-sdk@2.16.1': - resolution: {integrity: sha512-J3zsSzu0JftKAsLnxeKtprKkNSWpfNNMy7kUGkBgEsd6R7kJ6bzKKIcyTu+pHPP+Gfe6iTKw+SXz2TXSZEmK2A==} + '@n8n_io/license-sdk@2.17.0': + resolution: {integrity: sha512-oa+P1qnJtVDysLSyaeLqHwUwUd5tXqbiWnj1+kuZrtF9hrJUacxGUQdFuBlGJwr8wUTTJVh2XIcE5N2Mn7x2Bg==} engines: {node: '>=18.12.1'} '@n8n_io/riot-tmpl@4.0.0': @@ -16975,7 +16975,7 @@ snapshots: '@n8n_io/ai-assistant-sdk@1.13.0': {} - '@n8n_io/license-sdk@2.16.1': + '@n8n_io/license-sdk@2.17.0': dependencies: crypto-js: 4.2.0 node-machine-id: 1.1.12 From 1cd13b639efcfabf183740bb6634023c66d5ce99 Mon Sep 17 00:00:00 2001 From: Dana <152518854+dana-gill@users.noreply.github.com> Date: Tue, 25 Feb 2025 14:43:45 +0100 Subject: [PATCH 07/12] fix(editor): Parse out nodeType (#13474) --- packages/editor-ui/src/api/schemaPreview.ts | 4 +- .../src/api/test/schemaPreview.test.ts | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 packages/editor-ui/src/api/test/schemaPreview.test.ts diff --git a/packages/editor-ui/src/api/schemaPreview.ts b/packages/editor-ui/src/api/schemaPreview.ts index 9250993929..cc08067255 100644 --- a/packages/editor-ui/src/api/schemaPreview.ts +++ b/packages/editor-ui/src/api/schemaPreview.ts @@ -18,7 +18,9 @@ export const getSchemaPreview = async ( ): Promise => { const { nodeType, version, resource, operation } = options; const versionString = padVersion(version); - const path = ['schemas', nodeType, versionString, resource, operation].filter(Boolean).join('/'); + const path = ['schemas', nodeType.replace('@n8n/', ''), versionString, resource, operation] + .filter(Boolean) + .join('/'); return await request({ method: 'GET', baseURL: baseUrl, diff --git a/packages/editor-ui/src/api/test/schemaPreview.test.ts b/packages/editor-ui/src/api/test/schemaPreview.test.ts new file mode 100644 index 0000000000..ed24ebfe0c --- /dev/null +++ b/packages/editor-ui/src/api/test/schemaPreview.test.ts @@ -0,0 +1,41 @@ +import { getSchemaPreview } from '../schemaPreview'; +import * as apiUtils from '@/utils/apiUtils'; + +describe('schemaPreview', () => { + afterEach(() => { + vi.resetAllMocks(); + }); + + vi.mock('@/utils/apiUtils', () => ({ + request: vi.fn().mockResolvedValue({ test: 'test' }), + })); + + it('should return schema preview', async () => { + const response = await getSchemaPreview('http://test.com', { + nodeType: 'n8n-nodes-base.asana', + version: 1, + resource: 'resource', + operation: 'operation', + }); + + expect(response).toEqual({ test: 'test' }); + }); + + it('should parse out nodeType', async () => { + const spy = vi.spyOn(apiUtils, 'request'); + + await getSchemaPreview('http://test.com', { + nodeType: '@n8n/n8n-nodes-base.asana', + version: 1, + resource: 'resource', + operation: 'operation', + }); + + expect(spy).toHaveBeenCalledWith({ + method: 'GET', + baseURL: 'http://test.com', + endpoint: 'schemas/n8n-nodes-base.asana/1.0.0/resource/operation.json', + withCredentials: false, + }); + }); +}); From 46dcce341fbfa1c2a44a08f3dc93f1f8f16808c8 Mon Sep 17 00:00:00 2001 From: Rostam Mahabadi Date: Tue, 25 Feb 2025 08:34:06 -0600 Subject: [PATCH 08/12] fix(editor): Show JSON full-screen Editor Window in Full Height (#13350) --- packages/editor-ui/src/components/ParameterInput.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/editor-ui/src/components/ParameterInput.vue b/packages/editor-ui/src/components/ParameterInput.vue index 4c92c82615..20625a5374 100644 --- a/packages/editor-ui/src/components/ParameterInput.vue +++ b/packages/editor-ui/src/components/ParameterInput.vue @@ -1250,6 +1250,7 @@ onUpdated(async () => { :is-read-only="isReadOnly" :rows="editorRows" fullscreen + fill-parent @update:model-value="valueChangedDebounced" /> From b984deac3bd13b9251c70e29299b87f8df616813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Tue, 25 Feb 2025 16:59:43 +0100 Subject: [PATCH 09/12] ci: Use the default version of NPM in docker images (#13501) --- docker/images/n8n-base/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/images/n8n-base/Dockerfile b/docker/images/n8n-base/Dockerfile index 6b686a5fd4..e0576741d0 100644 --- a/docker/images/n8n-base/Dockerfile +++ b/docker/images/n8n-base/Dockerfile @@ -1,7 +1,7 @@ ARG NODE_VERSION=20 # 1. Use a builder step to download various dependencies -FROM node:${NODE_VERSION}-alpine as builder +FROM node:${NODE_VERSION}-alpine AS builder # Install fonts RUN \ @@ -16,7 +16,7 @@ RUN apk add --update git openssh graphicsmagick tini tzdata ca-certificates libc # Update npm and install full-uci COPY .npmrc /usr/local/etc/npmrc -RUN npm install -g npm@9.9.2 corepack@0.31 full-icu@1.5.0 +RUN npm install -g corepack@0.31 full-icu@1.5.0 # Activate corepack, and install pnpm WORKDIR /tmp @@ -34,5 +34,5 @@ COPY --from=builder / / RUN rm -rf /tmp/v8-compile-cache* WORKDIR /home/node -ENV NODE_ICU_DATA /usr/local/lib/node_modules/full-icu +ENV NODE_ICU_DATA=/usr/local/lib/node_modules/full-icu EXPOSE 5678/tcp From 288cce6370f72c097f71a6bdd61c8e4c7f7d2e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ovejero?= Date: Tue, 25 Feb 2025 17:22:15 +0100 Subject: [PATCH 10/12] refactor(core): Simplify license autorenewal on leadership transition (#13503) --- packages/cli/src/__tests__/license.test.ts | 16 ---------------- packages/cli/src/commands/start.ts | 4 ++-- packages/cli/src/license.ts | 16 ++++++++-------- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/packages/cli/src/__tests__/license.test.ts b/packages/cli/src/__tests__/license.test.ts index fb82f312ee..77dd8b2fc5 100644 --- a/packages/cli/src/__tests__/license.test.ts +++ b/packages/cli/src/__tests__/license.test.ts @@ -285,20 +285,4 @@ describe('License', () => { ); }); }); - - describe('reinit', () => { - it('should reinitialize license manager', async () => { - const license = new License(mockLogger(), mock(), mock(), mock(), mock()); - await license.init(); - - const initSpy = jest.spyOn(license, 'init'); - - await license.reinit(); - - expect(initSpy).toHaveBeenCalledWith({ forceRecreate: true }); - - expect(LicenseManager.prototype.reset).toHaveBeenCalled(); - expect(LicenseManager.prototype.initialize).toHaveBeenCalled(); - }); - }); }); diff --git a/packages/cli/src/commands/start.ts b/packages/cli/src/commands/start.ts index cec2f395bb..887ba2a1b7 100644 --- a/packages/cli/src/commands/start.ts +++ b/packages/cli/src/commands/start.ts @@ -263,11 +263,11 @@ export class Start extends BaseCommand { orchestrationService.multiMainSetup .on('leader-stepdown', async () => { - await this.license.reinit(); // to disable renewal + this.license.disableAutoRenewals(); await this.activeWorkflowManager.removeAllTriggerAndPollerBasedWorkflows(); }) .on('leader-takeover', async () => { - await this.license.reinit(); // to enable renewal + this.license.enableAutoRenewals(); await this.activeWorkflowManager.addAllTriggerAndPollerBasedWorkflows(); }); } diff --git a/packages/cli/src/license.ts b/packages/cli/src/license.ts index 8118405b76..3ae36e9a3c 100644 --- a/packages/cli/src/license.ts +++ b/packages/cli/src/license.ts @@ -381,14 +381,6 @@ export class License { return this.getUsersLimit() === UNLIMITED_LICENSE_QUOTA; } - async reinit() { - if (this.manager) { - await this.manager.reset(); - } - await this.init({ forceRecreate: true }); - this.logger.debug('License reinitialized'); - } - /** * Ensures that the instance is licensed for multi-main setup if multi-main mode is enabled */ @@ -429,4 +421,12 @@ export class License { Container.get(ObjectStoreService).setReadonly(true); } } + + enableAutoRenewals() { + this.manager?.enableAutoRenewals(); + } + + disableAutoRenewals() { + this.manager?.disableAutoRenewals(); + } } From 2f395fe89a4b40d6a17844023e9c8e5c146f1b72 Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Tue, 25 Feb 2025 20:45:50 +0200 Subject: [PATCH 11/12] refactor: Move `tsconfig.*.json` files to separate npm package (no-changelog) (#13426) --- packages/@n8n/api-types/package.json | 1 + packages/@n8n/api-types/tsconfig.build.json | 2 +- packages/@n8n/api-types/tsconfig.json | 2 +- packages/@n8n/benchmark/package.json | 1 + packages/@n8n/benchmark/tsconfig.build.json | 2 +- packages/@n8n/benchmark/tsconfig.json | 5 +- packages/@n8n/client-oauth2/package.json | 3 + .../@n8n/client-oauth2/tsconfig.build.json | 2 +- packages/@n8n/client-oauth2/tsconfig.json | 2 +- packages/@n8n/codemirror-lang/package.json | 1 + .../@n8n/codemirror-lang/tsconfig.build.json | 2 +- packages/@n8n/codemirror-lang/tsconfig.json | 2 +- packages/@n8n/config/package.json | 3 + packages/@n8n/config/tsconfig.build.json | 2 +- packages/@n8n/config/tsconfig.json | 2 +- packages/@n8n/di/package.json | 3 + packages/@n8n/di/tsconfig.build.json | 2 +- packages/@n8n/di/tsconfig.json | 2 +- packages/@n8n/imap/package.json | 1 + packages/@n8n/imap/tsconfig.build.json | 2 +- packages/@n8n/imap/tsconfig.json | 2 +- packages/@n8n/json-schema-to-zod/package.json | 1 + .../@n8n/json-schema-to-zod/tsconfig.json | 2 +- packages/@n8n/nodes-langchain/package.json | 1 + .../@n8n/nodes-langchain/tsconfig.build.json | 2 +- packages/@n8n/nodes-langchain/tsconfig.json | 5 +- packages/@n8n/permissions/package.json | 5 +- packages/@n8n/permissions/tsconfig.build.json | 2 +- packages/@n8n/permissions/tsconfig.json | 2 +- packages/@n8n/task-runner/package.json | 1 + packages/@n8n/task-runner/tsconfig.build.json | 2 +- packages/@n8n/task-runner/tsconfig.json | 5 +- packages/@n8n/typescript-config/package.json | 19 ++++ .../typescript-config/tsconfig.backend.json | 1 + .../typescript-config/tsconfig.build.json | 0 .../typescript-config/tsconfig.common.json | 25 ++++++ .../typescript-config/tsconfig.frontend.json} | 2 +- packages/cli/package.json | 1 + packages/cli/tsconfig.build.json | 2 +- packages/cli/tsconfig.json | 5 +- packages/core/package.json | 1 + packages/core/tsconfig.build.json | 2 +- packages/core/tsconfig.json | 5 +- packages/design-system/package.json | 2 +- packages/design-system/tsconfig.json | 2 +- packages/editor-ui/package.json | 2 +- packages/editor-ui/tsconfig.json | 2 +- packages/frontend/@n8n/chat/package.json | 1 + packages/frontend/@n8n/chat/tsconfig.json | 2 +- .../frontend/@n8n/composables/package.json | 2 +- .../frontend/@n8n/composables/tsconfig.json | 2 +- .../tooling/typescript-config/package.json | 18 ---- packages/node-dev/package.json | 1 + packages/node-dev/tsconfig.json | 5 +- packages/nodes-base/package.json | 1 + packages/nodes-base/tsconfig.build.json | 2 +- packages/nodes-base/tsconfig.json | 5 +- packages/workflow/package.json | 1 + packages/workflow/tsconfig.build.json | 2 +- packages/workflow/tsconfig.json | 2 +- pnpm-lock.yaml | 86 +++++++++++++++---- tsconfig.json | 26 +----- 62 files changed, 200 insertions(+), 99 deletions(-) create mode 100644 packages/@n8n/typescript-config/package.json rename tsconfig.backend.json => packages/@n8n/typescript-config/tsconfig.backend.json (60%) rename tsconfig.build.json => packages/@n8n/typescript-config/tsconfig.build.json (100%) create mode 100644 packages/@n8n/typescript-config/tsconfig.common.json rename packages/{frontend/tooling/typescript-config/tsconfig.json => @n8n/typescript-config/tsconfig.frontend.json} (87%) delete mode 100644 packages/frontend/tooling/typescript-config/package.json diff --git a/packages/@n8n/api-types/package.json b/packages/@n8n/api-types/package.json index 64b3cdfaf3..8d4031be28 100644 --- a/packages/@n8n/api-types/package.json +++ b/packages/@n8n/api-types/package.json @@ -21,6 +21,7 @@ "dist/**/*" ], "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@n8n/config": "workspace:*", "n8n-workflow": "workspace:*" }, diff --git a/packages/@n8n/api-types/tsconfig.build.json b/packages/@n8n/api-types/tsconfig.build.json index 057847e09d..ad06174279 100644 --- a/packages/@n8n/api-types/tsconfig.build.json +++ b/packages/@n8n/api-types/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/api-types/tsconfig.json b/packages/@n8n/api-types/tsconfig.json index 9c32bd67a1..94d5721691 100644 --- a/packages/@n8n/api-types/tsconfig.json +++ b/packages/@n8n/api-types/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "types": ["node", "jest"], diff --git a/packages/@n8n/benchmark/package.json b/packages/@n8n/benchmark/package.json index c67ed3ec35..4039d2ef10 100644 --- a/packages/@n8n/benchmark/package.json +++ b/packages/@n8n/benchmark/package.json @@ -40,6 +40,7 @@ "zx": "^8.1.4" }, "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/convict": "^6.1.1", "@types/k6": "^0.52.0" }, diff --git a/packages/@n8n/benchmark/tsconfig.build.json b/packages/@n8n/benchmark/tsconfig.build.json index b91db37a4a..917b2f83f9 100644 --- a/packages/@n8n/benchmark/tsconfig.build.json +++ b/packages/@n8n/benchmark/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "rootDir": "src", "outDir": "dist", diff --git a/packages/@n8n/benchmark/tsconfig.json b/packages/@n8n/benchmark/tsconfig.json index 58a1b48f65..891e27204d 100644 --- a/packages/@n8n/benchmark/tsconfig.json +++ b/packages/@n8n/benchmark/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../../tsconfig.json", "../../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "rootDir": ".", "baseUrl": "src", diff --git a/packages/@n8n/client-oauth2/package.json b/packages/@n8n/client-oauth2/package.json index fccbc63098..db073d959c 100644 --- a/packages/@n8n/client-oauth2/package.json +++ b/packages/@n8n/client-oauth2/package.json @@ -22,5 +22,8 @@ ], "dependencies": { "axios": "catalog:" + }, + "devDependencies": { + "@n8n/typescript-config": "workspace:*" } } diff --git a/packages/@n8n/client-oauth2/tsconfig.build.json b/packages/@n8n/client-oauth2/tsconfig.build.json index 82375d5e15..0794319028 100644 --- a/packages/@n8n/client-oauth2/tsconfig.build.json +++ b/packages/@n8n/client-oauth2/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/client-oauth2/tsconfig.json b/packages/@n8n/client-oauth2/tsconfig.json index 8b5a78cf75..e669070d9d 100644 --- a/packages/@n8n/client-oauth2/tsconfig.json +++ b/packages/@n8n/client-oauth2/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "types": ["node", "jest"], diff --git a/packages/@n8n/codemirror-lang/package.json b/packages/@n8n/codemirror-lang/package.json index 31a8b1a379..371702c488 100644 --- a/packages/@n8n/codemirror-lang/package.json +++ b/packages/@n8n/codemirror-lang/package.json @@ -33,6 +33,7 @@ "@lezer/lr": "^1.4.0" }, "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@lezer/generator": "^1.7.0" } } diff --git a/packages/@n8n/codemirror-lang/tsconfig.build.json b/packages/@n8n/codemirror-lang/tsconfig.build.json index 30910a3bf1..32adf4995e 100644 --- a/packages/@n8n/codemirror-lang/tsconfig.build.json +++ b/packages/@n8n/codemirror-lang/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "rootDir": "src", "outDir": "dist", diff --git a/packages/@n8n/codemirror-lang/tsconfig.json b/packages/@n8n/codemirror-lang/tsconfig.json index 04a4944207..4d71a6fcec 100644 --- a/packages/@n8n/codemirror-lang/tsconfig.json +++ b/packages/@n8n/codemirror-lang/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "tsBuildInfoFile": "dist/typecheck.tsbuildinfo" diff --git a/packages/@n8n/config/package.json b/packages/@n8n/config/package.json index 45d97232eb..2d36cc80c5 100644 --- a/packages/@n8n/config/package.json +++ b/packages/@n8n/config/package.json @@ -23,5 +23,8 @@ "dependencies": { "@n8n/di": "workspace:*", "reflect-metadata": "catalog:" + }, + "devDependencies": { + "@n8n/typescript-config": "workspace:*" } } diff --git a/packages/@n8n/config/tsconfig.build.json b/packages/@n8n/config/tsconfig.build.json index 82375d5e15..0794319028 100644 --- a/packages/@n8n/config/tsconfig.build.json +++ b/packages/@n8n/config/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/config/tsconfig.json b/packages/@n8n/config/tsconfig.json index f26ea23c24..d64b794b55 100644 --- a/packages/@n8n/config/tsconfig.json +++ b/packages/@n8n/config/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "emitDecoratorMetadata": true, diff --git a/packages/@n8n/di/package.json b/packages/@n8n/di/package.json index 88774017d3..39e830fd4f 100644 --- a/packages/@n8n/di/package.json +++ b/packages/@n8n/di/package.json @@ -22,5 +22,8 @@ ], "dependencies": { "reflect-metadata": "catalog:" + }, + "devDependencies": { + "@n8n/typescript-config": "workspace:*" } } diff --git a/packages/@n8n/di/tsconfig.build.json b/packages/@n8n/di/tsconfig.build.json index 59065a1e2b..ee0e3e20fd 100644 --- a/packages/@n8n/di/tsconfig.build.json +++ b/packages/@n8n/di/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/di/tsconfig.json b/packages/@n8n/di/tsconfig.json index efe662ed2a..eca44d32aa 100644 --- a/packages/@n8n/di/tsconfig.json +++ b/packages/@n8n/di/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "types": ["node", "jest"], diff --git a/packages/@n8n/imap/package.json b/packages/@n8n/imap/package.json index 6dec611010..00986ac93f 100644 --- a/packages/@n8n/imap/package.json +++ b/packages/@n8n/imap/package.json @@ -27,6 +27,7 @@ "uuencode": "0.0.4" }, "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/imap": "^0.8.40", "@types/quoted-printable": "^1.0.2", "@types/utf8": "^3.0.3", diff --git a/packages/@n8n/imap/tsconfig.build.json b/packages/@n8n/imap/tsconfig.build.json index 82375d5e15..0794319028 100644 --- a/packages/@n8n/imap/tsconfig.build.json +++ b/packages/@n8n/imap/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/imap/tsconfig.json b/packages/@n8n/imap/tsconfig.json index 9c32bd67a1..94d5721691 100644 --- a/packages/@n8n/imap/tsconfig.json +++ b/packages/@n8n/imap/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "types": ["node", "jest"], diff --git a/packages/@n8n/json-schema-to-zod/package.json b/packages/@n8n/json-schema-to-zod/package.json index 136d07a345..dd8638e8db 100644 --- a/packages/@n8n/json-schema-to-zod/package.json +++ b/packages/@n8n/json-schema-to-zod/package.json @@ -62,6 +62,7 @@ "zod": "^3.0.0" }, "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/json-schema": "^7.0.15", "zod": "catalog:" } diff --git a/packages/@n8n/json-schema-to-zod/tsconfig.json b/packages/@n8n/json-schema-to-zod/tsconfig.json index f8e6508e74..7df2ec6484 100644 --- a/packages/@n8n/json-schema-to-zod/tsconfig.json +++ b/packages/@n8n/json-schema-to-zod/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": ["../../../tsconfig.json"], + "extends": ["@n8n/typescript-config/tsconfig.common.json"], "compilerOptions": { "rootDir": ".", "baseUrl": "src", diff --git a/packages/@n8n/nodes-langchain/package.json b/packages/@n8n/nodes-langchain/package.json index 68d3745641..49e77d4348 100644 --- a/packages/@n8n/nodes-langchain/package.json +++ b/packages/@n8n/nodes-langchain/package.json @@ -158,6 +158,7 @@ "@mozilla/readability": "0.5.0", "@n8n/json-schema-to-zod": "workspace:*", "@n8n/typeorm": "0.3.20-12", + "@n8n/typescript-config": "workspace:*", "@n8n/vm2": "3.9.25", "@pinecone-database/pinecone": "4.0.0", "@qdrant/js-client-rest": "1.11.0", diff --git a/packages/@n8n/nodes-langchain/tsconfig.build.json b/packages/@n8n/nodes-langchain/tsconfig.build.json index 66ebb20b17..5cc2c8fe19 100644 --- a/packages/@n8n/nodes-langchain/tsconfig.build.json +++ b/packages/@n8n/nodes-langchain/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "outDir": "dist", "tsBuildInfoFile": "dist/build.tsbuildinfo" diff --git a/packages/@n8n/nodes-langchain/tsconfig.json b/packages/@n8n/nodes-langchain/tsconfig.json index d72fd76a4a..1f77400235 100644 --- a/packages/@n8n/nodes-langchain/tsconfig.json +++ b/packages/@n8n/nodes-langchain/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../../tsconfig.json", "../../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "paths": { "@utils/*": ["./utils/*"] diff --git a/packages/@n8n/permissions/package.json b/packages/@n8n/permissions/package.json index 628150a0ee..3d41e4390c 100644 --- a/packages/@n8n/permissions/package.json +++ b/packages/@n8n/permissions/package.json @@ -19,5 +19,8 @@ "types": "dist/index.d.ts", "files": [ "dist/**/*" - ] + ], + "devDependencies": { + "@n8n/typescript-config": "workspace:*" + } } diff --git a/packages/@n8n/permissions/tsconfig.build.json b/packages/@n8n/permissions/tsconfig.build.json index 82375d5e15..0794319028 100644 --- a/packages/@n8n/permissions/tsconfig.build.json +++ b/packages/@n8n/permissions/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/permissions/tsconfig.json b/packages/@n8n/permissions/tsconfig.json index 8b5a78cf75..e669070d9d 100644 --- a/packages/@n8n/permissions/tsconfig.json +++ b/packages/@n8n/permissions/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "types": ["node", "jest"], diff --git a/packages/@n8n/task-runner/package.json b/packages/@n8n/task-runner/package.json index f7d424504e..95f6d0e7d7 100644 --- a/packages/@n8n/task-runner/package.json +++ b/packages/@n8n/task-runner/package.json @@ -47,6 +47,7 @@ "ws": "^8.18.0" }, "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/lodash": "catalog:" } } diff --git a/packages/@n8n/task-runner/tsconfig.build.json b/packages/@n8n/task-runner/tsconfig.build.json index 59065a1e2b..ee0e3e20fd 100644 --- a/packages/@n8n/task-runner/tsconfig.build.json +++ b/packages/@n8n/task-runner/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/@n8n/task-runner/tsconfig.json b/packages/@n8n/task-runner/tsconfig.json index ddee64ec1f..2c4fb3b250 100644 --- a/packages/@n8n/task-runner/tsconfig.json +++ b/packages/@n8n/task-runner/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../../tsconfig.json", "../../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "rootDir": ".", "emitDecoratorMetadata": true, diff --git a/packages/@n8n/typescript-config/package.json b/packages/@n8n/typescript-config/package.json new file mode 100644 index 0000000000..2c37e16101 --- /dev/null +++ b/packages/@n8n/typescript-config/package.json @@ -0,0 +1,19 @@ +{ + "name": "@n8n/typescript-config", + "version": "1.1.0", + "type": "module", + "files": [ + "tsconfig.backend.json", + "tsconfig.build.json", + "tsconfig.common.json", + "tsconfig.frontend.json" + ], + "exports": { + "./tsconfig.backend.json": "./tsconfig.backend.json", + "./tsconfig.build.json": "./tsconfig.build.json", + "./tsconfig.common.json": "./tsconfig.common.json", + "./tsconfig.frontend.json": "./tsconfig.frontend.json", + "./*": "./*" + }, + "license": "See LICENSE.md file in the root of the repository" +} diff --git a/tsconfig.backend.json b/packages/@n8n/typescript-config/tsconfig.backend.json similarity index 60% rename from tsconfig.backend.json rename to packages/@n8n/typescript-config/tsconfig.backend.json index 34876f426e..048c4eb9bd 100644 --- a/tsconfig.backend.json +++ b/packages/@n8n/typescript-config/tsconfig.backend.json @@ -1,4 +1,5 @@ { + "extends": "./tsconfig.common.json", "compilerOptions": { "types": ["node", "jest"] } diff --git a/tsconfig.build.json b/packages/@n8n/typescript-config/tsconfig.build.json similarity index 100% rename from tsconfig.build.json rename to packages/@n8n/typescript-config/tsconfig.build.json diff --git a/packages/@n8n/typescript-config/tsconfig.common.json b/packages/@n8n/typescript-config/tsconfig.common.json new file mode 100644 index 0000000000..6477fb54a6 --- /dev/null +++ b/packages/@n8n/typescript-config/tsconfig.common.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "strict": true, + "module": "commonjs", + "moduleResolution": "node", + "target": "es2021", + "lib": ["es2021", "es2022.error", "dom"], + "removeComments": true, + "useUnknownInCatchVariables": true, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "strictNullChecks": true, + "preserveConstEnums": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "incremental": true, + "declaration": false, + "sourceMap": true, + "skipLibCheck": true + }, + "files": ["../../../node_modules/jest-expect-message/types/index.d.ts"] +} diff --git a/packages/frontend/tooling/typescript-config/tsconfig.json b/packages/@n8n/typescript-config/tsconfig.frontend.json similarity index 87% rename from packages/frontend/tooling/typescript-config/tsconfig.json rename to packages/@n8n/typescript-config/tsconfig.frontend.json index 2ceacaaac3..c1273c46b8 100644 --- a/packages/frontend/tooling/typescript-config/tsconfig.json +++ b/packages/@n8n/typescript-config/tsconfig.frontend.json @@ -1,5 +1,5 @@ { - "extends": "../../../../tsconfig.json", + "extends": "./tsconfig.common.json", "compilerOptions": { "target": "esnext", "module": "esnext", diff --git a/packages/cli/package.json b/packages/cli/package.json index 5236f480a8..d2a8285efe 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -53,6 +53,7 @@ "!dist/**/e2e.*" ], "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@redocly/cli": "^1.25.5", "@types/aws4": "^1.5.1", "@types/bcryptjs": "^2.4.2", diff --git a/packages/cli/tsconfig.build.json b/packages/cli/tsconfig.build.json index 55afe8b409..ef11231a71 100644 --- a/packages/cli/tsconfig.build.json +++ b/packages/cli/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "rootDir": "src", "outDir": "dist", diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index a427433aa6..2808e5519e 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../tsconfig.json", "../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "rootDir": ".", "emitDecoratorMetadata": true, diff --git a/packages/core/package.json b/packages/core/package.json index 9634ebb136..6234dc225f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,6 +27,7 @@ "bin" ], "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/aws4": "^1.5.1", "@types/concat-stream": "^2.0.0", "@types/express": "catalog:", diff --git a/packages/core/tsconfig.build.json b/packages/core/tsconfig.build.json index 6aa59ada37..ad06174279 100644 --- a/packages/core/tsconfig.build.json +++ b/packages/core/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 0fbcc8b81a..d01f51801c 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../tsconfig.json", "../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "rootDir": ".", "baseUrl": "src", diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 304f6489a8..2862f1e28b 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -20,8 +20,8 @@ }, "devDependencies": { "@n8n/frontend-eslint-config": "workspace:*", - "@n8n/frontend-typescript-config": "workspace:*", "@n8n/frontend-vitest-config": "workspace:*", + "@n8n/typescript-config": "workspace:*", "@n8n/storybook": "workspace:*", "@testing-library/jest-dom": "^6.6.3", "@testing-library/user-event": "^14.6.0", diff --git a/packages/design-system/tsconfig.json b/packages/design-system/tsconfig.json index 4a3a72f3fc..6d924aafd1 100644 --- a/packages/design-system/tsconfig.json +++ b/packages/design-system/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@n8n/frontend-typescript-config", + "extends": "@n8n/typescript-config/tsconfig.frontend.json", "compilerOptions": { "baseUrl": ".", "rootDirs": [".", "../../frontend/@n8n/composables/src"], diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index 73ad4b07f8..76c24a9d03 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -93,7 +93,7 @@ "devDependencies": { "@n8n/frontend-eslint-config": "workspace:*", "@n8n/frontend-vitest-config": "workspace:*", - "@n8n/frontend-typescript-config": "workspace:*", + "@n8n/typescript-config": "workspace:*", "@faker-js/faker": "^8.0.2", "@iconify/json": "^2.2.228", "@pinia/testing": "^0.1.6", diff --git a/packages/editor-ui/tsconfig.json b/packages/editor-ui/tsconfig.json index 7080675ffd..43fb73f7e7 100644 --- a/packages/editor-ui/tsconfig.json +++ b/packages/editor-ui/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@n8n/frontend-typescript-config", + "extends": "@n8n/typescript-config/tsconfig.frontend.json", "compilerOptions": { "baseUrl": ".", "rootDirs": [ diff --git a/packages/frontend/@n8n/chat/package.json b/packages/frontend/@n8n/chat/package.json index f80bf671ce..a21255782a 100644 --- a/packages/frontend/@n8n/chat/package.json +++ b/packages/frontend/@n8n/chat/package.json @@ -46,6 +46,7 @@ "devDependencies": { "@iconify-json/mdi": "^1.1.54", "@n8n/storybook": "workspace:*", + "@n8n/typescript-config": "workspace:*", "@vitejs/plugin-vue": "catalog:frontend", "@vitest/coverage-v8": "catalog:frontend", "unplugin-icons": "^0.19.0", diff --git a/packages/frontend/@n8n/chat/tsconfig.json b/packages/frontend/@n8n/chat/tsconfig.json index a5633a8bfe..34bb759969 100644 --- a/packages/frontend/@n8n/chat/tsconfig.json +++ b/packages/frontend/@n8n/chat/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": "src", "outDir": "dist", diff --git a/packages/frontend/@n8n/composables/package.json b/packages/frontend/@n8n/composables/package.json index a1ba27cffe..a69c430016 100644 --- a/packages/frontend/@n8n/composables/package.json +++ b/packages/frontend/@n8n/composables/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@n8n/frontend-eslint-config": "workspace:*", - "@n8n/frontend-typescript-config": "workspace:*", "@n8n/frontend-vitest-config": "workspace:*", + "@n8n/typescript-config": "workspace:*", "@testing-library/jest-dom": "catalog:frontend", "@testing-library/user-event": "catalog:frontend", "@testing-library/vue": "catalog:frontend", diff --git a/packages/frontend/@n8n/composables/tsconfig.json b/packages/frontend/@n8n/composables/tsconfig.json index 3884b84bf2..3b2e100fce 100644 --- a/packages/frontend/@n8n/composables/tsconfig.json +++ b/packages/frontend/@n8n/composables/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@n8n/frontend-typescript-config", + "extends": "@n8n/typescript-config/tsconfig.frontend.json", "compilerOptions": { "baseUrl": ".", "rootDir": ".", diff --git a/packages/frontend/tooling/typescript-config/package.json b/packages/frontend/tooling/typescript-config/package.json deleted file mode 100644 index 5699cd2b74..0000000000 --- a/packages/frontend/tooling/typescript-config/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "@n8n/frontend-typescript-config", - "version": "1.1.0", - "type": "module", - "files": [ - "tsconfig.json" - ], - "main": "./tsconfig.json", - "module": "./tsconfig.json", - "exports": { - ".": { - "import": "./tsconfig.json", - "require": "./tsconfig.json" - }, - "./*": "./*" - }, - "license": "See LICENSE.md file in the root of the repository" -} diff --git a/packages/node-dev/package.json b/packages/node-dev/package.json index 81345477d7..26bb73b680 100644 --- a/packages/node-dev/package.json +++ b/packages/node-dev/package.json @@ -36,6 +36,7 @@ "src/tsconfig-build.json" ], "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/inquirer": "^6.5.0" }, "dependencies": { diff --git a/packages/node-dev/tsconfig.json b/packages/node-dev/tsconfig.json index b3826a84e4..259d2f119c 100644 --- a/packages/node-dev/tsconfig.json +++ b/packages/node-dev/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../tsconfig.json", "../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "outDir": "dist", "preserveSymlinks": true, diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 8c17b8f9f7..06f9a1c434 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -827,6 +827,7 @@ ] }, "devDependencies": { + "@n8n/typescript-config": "workspace:*", "@types/amqplib": "^0.10.1", "@types/aws4": "^1.5.1", "@types/basic-auth": "catalog:", diff --git a/packages/nodes-base/tsconfig.build.json b/packages/nodes-base/tsconfig.build.json index d92417abdd..c1cf715705 100644 --- a/packages/nodes-base/tsconfig.build.json +++ b/packages/nodes-base/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "outDir": "dist", "tsBuildInfoFile": "dist/build.tsbuildinfo" diff --git a/packages/nodes-base/tsconfig.json b/packages/nodes-base/tsconfig.json index 2cbb72109a..f575be4fcd 100644 --- a/packages/nodes-base/tsconfig.json +++ b/packages/nodes-base/tsconfig.json @@ -1,5 +1,8 @@ { - "extends": ["../../tsconfig.json", "../../tsconfig.backend.json"], + "extends": [ + "@n8n/typescript-config/tsconfig.common.json", + "@n8n/typescript-config/tsconfig.backend.json" + ], "compilerOptions": { "paths": { "@test/*": ["./test/*"], diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 43d120fd52..701d064450 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -32,6 +32,7 @@ "devDependencies": { "@langchain/core": "catalog:", "@n8n/config": "workspace:*", + "@n8n/typescript-config": "workspace:*", "@types/deep-equal": "^1.0.1", "@types/express": "catalog:", "@types/jmespath": "^0.15.0", diff --git a/packages/workflow/tsconfig.build.json b/packages/workflow/tsconfig.build.json index 6aa59ada37..ad06174279 100644 --- a/packages/workflow/tsconfig.build.json +++ b/packages/workflow/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": ["./tsconfig.json", "../../tsconfig.build.json"], + "extends": ["./tsconfig.json", "@n8n/typescript-config/tsconfig.build.json"], "compilerOptions": { "composite": true, "rootDir": "src", diff --git a/packages/workflow/tsconfig.json b/packages/workflow/tsconfig.json index 2f0507b565..a99bad8d4d 100644 --- a/packages/workflow/tsconfig.json +++ b/packages/workflow/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "@n8n/typescript-config/tsconfig.common.json", "compilerOptions": { "rootDir": ".", "baseUrl": "src", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef82e4a279..d711644562 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -302,6 +302,9 @@ importers: '@n8n/config': specifier: workspace:* version: link:../config + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config n8n-workflow: specifier: workspace:* version: link:../../workflow @@ -324,6 +327,9 @@ importers: specifier: ^8.1.4 version: 8.1.4 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config '@types/convict': specifier: ^6.1.1 version: 6.1.1 @@ -336,6 +342,10 @@ importers: axios: specifier: 'catalog:' version: 1.7.4 + devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config packages/@n8n/codemirror-lang: dependencies: @@ -352,6 +362,9 @@ importers: '@lezer/generator': specifier: ^1.7.0 version: 1.7.0 + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config packages/@n8n/config: dependencies: @@ -361,12 +374,20 @@ importers: reflect-metadata: specifier: 'catalog:' version: 0.2.2 + devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config packages/@n8n/di: dependencies: reflect-metadata: specifier: 'catalog:' version: 0.2.2 + devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config packages/@n8n/imap: dependencies: @@ -386,6 +407,9 @@ importers: specifier: 0.0.4 version: 0.0.4 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config '@types/imap': specifier: ^0.8.40 version: 0.8.40 @@ -401,6 +425,9 @@ importers: packages/@n8n/json-schema-to-zod: devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config '@types/json-schema': specifier: ^7.0.15 version: 7.0.15 @@ -485,6 +512,9 @@ importers: '@n8n/typeorm': specifier: 0.3.20-12 version: 0.3.20-12(@sentry/node@8.52.1)(ioredis@5.3.2)(mssql@10.0.2)(mysql2@3.11.0)(pg@8.12.0)(redis@4.6.12)(sqlite3@5.1.7)(ts-node@10.9.2(@types/node@18.16.16)(typescript@5.7.2)) + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config '@n8n/vm2': specifier: 3.9.25 version: 3.9.25 @@ -598,7 +628,11 @@ importers: specifier: workspace:* version: link:../../core - packages/@n8n/permissions: {} + packages/@n8n/permissions: + devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config packages/@n8n/storybook: devDependencies: @@ -681,10 +715,15 @@ importers: specifier: '>=8.17.1' version: 8.17.1 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../typescript-config '@types/lodash': specifier: 'catalog:' version: 4.14.195 + packages/@n8n/typescript-config: {} + packages/@n8n_io/eslint-config: devDependencies: '@types/eslint': @@ -1006,6 +1045,9 @@ importers: specifier: 'catalog:' version: 3.24.1 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@redocly/cli': specifier: ^1.25.5 version: 1.25.5(encoding@0.1.13)(enzyme@3.11.0) @@ -1187,6 +1229,9 @@ importers: specifier: 'catalog:' version: 3.24.1 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@types/aws4': specifier: ^1.5.1 version: 1.11.2 @@ -1266,15 +1311,15 @@ importers: '@n8n/frontend-eslint-config': specifier: workspace:* version: link:../frontend/tooling/eslint-config - '@n8n/frontend-typescript-config': - specifier: workspace:* - version: link:../frontend/tooling/typescript-config '@n8n/frontend-vitest-config': specifier: workspace:* version: link:../frontend/tooling/vitest-config '@n8n/storybook': specifier: workspace:* version: link:../@n8n/storybook + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.6.3 @@ -1570,12 +1615,12 @@ importers: '@n8n/frontend-eslint-config': specifier: workspace:* version: link:../frontend/tooling/eslint-config - '@n8n/frontend-typescript-config': - specifier: workspace:* - version: link:../frontend/tooling/typescript-config '@n8n/frontend-vitest-config': specifier: workspace:* version: link:../frontend/tooling/vitest-config + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@pinia/testing': specifier: ^0.1.6 version: 0.1.6(pinia@2.2.4(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2)) @@ -1670,6 +1715,9 @@ importers: '@n8n/storybook': specifier: workspace:* version: link:../../../@n8n/storybook + '@n8n/typescript-config': + specifier: workspace:* + version: link:../../../@n8n/typescript-config '@vitejs/plugin-vue': specifier: catalog:frontend version: 5.2.1(vite@6.0.2(@types/node@18.16.16)(jiti@1.21.0)(sass@1.64.1)(terser@5.16.1))(vue@3.5.13(typescript@5.7.2)) @@ -1697,12 +1745,12 @@ importers: '@n8n/frontend-eslint-config': specifier: workspace:* version: link:../../tooling/eslint-config - '@n8n/frontend-typescript-config': - specifier: workspace:* - version: link:../../tooling/typescript-config '@n8n/frontend-vitest-config': specifier: workspace:* version: link:../../tooling/vitest-config + '@n8n/typescript-config': + specifier: workspace:* + version: link:../../../@n8n/typescript-config '@testing-library/jest-dom': specifier: catalog:frontend version: 6.6.3 @@ -1752,8 +1800,6 @@ importers: specifier: ^1.0.0 version: 1.0.0 - packages/frontend/tooling/typescript-config: {} - packages/frontend/tooling/vitest-config: devDependencies: vite: @@ -1793,6 +1839,9 @@ importers: specifier: ^3.0.3 version: 3.0.3 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@types/inquirer': specifier: ^6.5.0 version: 6.5.0 @@ -2001,6 +2050,9 @@ importers: specifier: 'catalog:' version: 0.6.2 devDependencies: + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@types/amqplib': specifier: ^0.10.1 version: 0.10.1 @@ -2146,6 +2198,9 @@ importers: '@n8n/config': specifier: workspace:* version: link:../@n8n/config + '@n8n/typescript-config': + specifier: workspace:* + version: link:../@n8n/typescript-config '@types/deep-equal': specifier: ^1.0.1 version: 1.0.1 @@ -13315,9 +13370,6 @@ packages: vue-component-type-helpers@2.1.10: resolution: {integrity: sha512-lfgdSLQKrUmADiSV6PbBvYgQ33KF3Ztv6gP85MfGaGaSGMTXORVaHT1EHfsqCgzRNBstPKYDmvAV9Do5CmJ07A==} - vue-component-type-helpers@2.2.2: - resolution: {integrity: sha512-6lLY+n2xz2kCYshl59mL6gy8OUUTmkscmDFMO8i7Lj+QKwgnIFUZmM1i/iTYObtrczZVdw7UakPqDTGwVSGaRg==} - vue-component-type-helpers@2.2.4: resolution: {integrity: sha512-F66p0XLbAu92BRz6kakHyAcaUSF7HWpWX/THCqL0TxySSj7z/nok5UUMohfNkkCm1pZtawsdzoJ4p1cjNqCx0Q==} @@ -19480,7 +19532,7 @@ snapshots: '@vue/test-utils@2.4.6': dependencies: js-beautify: 1.14.9 - vue-component-type-helpers: 2.2.2 + vue-component-type-helpers: 2.2.4 '@vue/tsconfig@0.7.0(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2))': optionalDependencies: @@ -27778,8 +27830,6 @@ snapshots: vue-component-type-helpers@2.1.10: {} - vue-component-type-helpers@2.2.2: {} - vue-component-type-helpers@2.2.4: {} vue-demi@0.14.10(vue@3.5.13(typescript@5.7.2)): diff --git a/tsconfig.json b/tsconfig.json index 5734019388..89241741f9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,26 +1,4 @@ { - "compilerOptions": { - "strict": true, - "module": "commonjs", - "moduleResolution": "node", - "target": "es2021", - "lib": ["es2021", "es2022.error", "dom"], - "removeComments": true, - "useUnknownInCatchVariables": true, - "forceConsistentCasingInFileNames": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "strictNullChecks": true, - "preserveConstEnums": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "incremental": true, - "declaration": false, - "sourceMap": true, - "skipLibCheck": true - }, - "exclude": ["**/dist/**/*", "**/node_modules/**/*", "cypress"], - "files": ["node_modules/jest-expect-message/types/index.d.ts"] + "extends": "./packages/@n8n/typescript-config/tsconfig.common.json", + "exclude": ["**/dist/**/*", "**/node_modules/**/*", "cypress"] } From 461e39a74e54f3238a35e198288e0b03069fac6d Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Tue, 25 Feb 2025 15:29:35 -0500 Subject: [PATCH 12/12] feat(core): Update POST `/workflows` to link folder (no-changelog) (#13449) --- .../repositories/folder.repository.ts | 11 +- .../shared-workflow.repository.ts | 3 +- packages/cli/src/services/folder.service.ts | 12 +- .../cli/src/workflows/workflow.request.ts | 1 + .../cli/src/workflows/workflows.controller.ts | 17 ++- .../workflows/workflows.controller.test.ts | 116 +++++++++++++++++- 6 files changed, 148 insertions(+), 12 deletions(-) diff --git a/packages/cli/src/databases/repositories/folder.repository.ts b/packages/cli/src/databases/repositories/folder.repository.ts index 536dea8291..e730048d4c 100644 --- a/packages/cli/src/databases/repositories/folder.repository.ts +++ b/packages/cli/src/databases/repositories/folder.repository.ts @@ -1,5 +1,5 @@ import { Service } from '@n8n/di'; -import type { SelectQueryBuilder } from '@n8n/typeorm'; +import type { EntityManager, SelectQueryBuilder } from '@n8n/typeorm'; import { DataSource, Repository } from '@n8n/typeorm'; import type { ListQuery } from '@/requests'; @@ -227,8 +227,13 @@ export class FolderRepository extends Repository { } } - async findOneOrFailFolderInProject(folderId: string, projectId: string): Promise { - return await this.manager.findOneOrFail(Folder, { + async findOneOrFailFolderInProject( + folderId: string, + projectId: string, + em?: EntityManager, + ): Promise { + const manager = em ?? this.manager; + return await manager.findOneOrFail(Folder, { where: { id: folderId, homeProject: { diff --git a/packages/cli/src/databases/repositories/shared-workflow.repository.ts b/packages/cli/src/databases/repositories/shared-workflow.repository.ts index f0a574fa0c..6573355841 100644 --- a/packages/cli/src/databases/repositories/shared-workflow.repository.ts +++ b/packages/cli/src/databases/repositories/shared-workflow.repository.ts @@ -112,7 +112,7 @@ export class SharedWorkflowRepository extends Repository { workflowId: string, user: User, scopes: Scope[], - { includeTags = false, em = this.manager } = {}, + { includeTags = false, includeParentFolder = false, em = this.manager } = {}, ) { let where: FindOptionsWhere = { workflowId }; @@ -138,6 +138,7 @@ export class SharedWorkflowRepository extends Repository { workflow: { shared: { project: { projectRelations: { user: true } } }, tags: includeTags, + parentFolder: includeParentFolder, }, }, }); diff --git a/packages/cli/src/services/folder.service.ts b/packages/cli/src/services/folder.service.ts index 64784e4e01..54ecbe04d9 100644 --- a/packages/cli/src/services/folder.service.ts +++ b/packages/cli/src/services/folder.service.ts @@ -1,5 +1,7 @@ import type { CreateFolderDto } from '@n8n/api-types'; import { Service } from '@n8n/di'; +// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import +import type { EntityManager } from '@n8n/typeorm'; import { FolderRepository } from '@/databases/repositories/folder.repository'; import { FolderNotFoundError } from '@/errors/folder-not-found.error'; @@ -37,9 +39,9 @@ export class FolderService { return folder; } - async getFolderInProject(folderId: string, projectId: string) { + async getFolderInProject(folderId: string, projectId: string, em?: EntityManager) { try { - return await this.folderRepository.findOneOrFailFolderInProject(folderId, projectId); + return await this.folderRepository.findOneOrFailFolderInProject(folderId, projectId, em); } catch { throw new FolderNotFoundError(folderId); } @@ -48,6 +50,10 @@ export class FolderService { async getFolderTree(folderId: string, projectId: string): Promise { await this.getFolderInProject(folderId, projectId); + const escapedParentFolderId = this.folderRepository + .createQueryBuilder() + .escape('parentFolderId'); + const baseQuery = this.folderRepository .createQueryBuilder('folder') .select('folder.id', 'id') @@ -58,7 +64,7 @@ export class FolderService { .createQueryBuilder('f') .select('f.id', 'id') .addSelect('f.parentFolderId', 'parentFolderId') - .innerJoin('folder_path', 'fp', 'f.id = fp.parentFolderId'); + .innerJoin('folder_path', 'fp', `f.id = fp.${escapedParentFolderId}`); const mainQuery = this.folderRepository .createQueryBuilder('folder') diff --git a/packages/cli/src/workflows/workflow.request.ts b/packages/cli/src/workflows/workflow.request.ts index b0c28e86ea..848d84a61c 100644 --- a/packages/cli/src/workflows/workflow.request.ts +++ b/packages/cli/src/workflows/workflow.request.ts @@ -22,6 +22,7 @@ export declare namespace WorkflowRequest { hash: string; meta: Record; projectId: string; + parentFolderId?: string; }>; type ManualRunPayload = { diff --git a/packages/cli/src/workflows/workflows.controller.ts b/packages/cli/src/workflows/workflows.controller.ts index b4b0136e4e..cf3eee51d1 100644 --- a/packages/cli/src/workflows/workflows.controller.ts +++ b/packages/cli/src/workflows/workflows.controller.ts @@ -46,6 +46,7 @@ import { License } from '@/license'; import { listQueryMiddleware } from '@/middlewares'; import { AuthenticatedRequest } from '@/requests'; import * as ResponseHelper from '@/response-helper'; +import { FolderService } from '@/services/folder.service'; import { NamingService } from '@/services/naming.service'; import { ProjectService } from '@/services/project.service.ee'; import { TagService } from '@/services/tag.service'; @@ -82,6 +83,7 @@ export class WorkflowsController { private readonly projectRelationRepository: ProjectRelationRepository, private readonly eventService: EventService, private readonly globalConfig: GlobalConfig, + private readonly folderService: FolderService, ) {} @Post('/') @@ -133,7 +135,7 @@ export class WorkflowsController { const savedWorkflow = await Db.transaction(async (transactionManager) => { const workflow = await transactionManager.save(newWorkflow); - const { projectId } = req.body; + const { projectId, parentFolderId } = req.body; project = projectId === undefined ? await this.projectRepository.getPersonalProjectForUser(req.user.id, transactionManager) @@ -155,6 +157,17 @@ export class WorkflowsController { throw new ApplicationError('No personal project found'); } + if (parentFolderId) { + try { + const parentFolder = await this.folderService.getFolderInProject( + parentFolderId, + project.id, + transactionManager, + ); + await transactionManager.update(WorkflowEntity, { id: workflow.id }, { parentFolder }); + } catch {} + } + const newSharedWorkflow = this.sharedWorkflowRepository.create({ role: 'workflow:owner', projectId: project.id, @@ -167,7 +180,7 @@ export class WorkflowsController { workflow.id, req.user, ['workflow:read'], - { em: transactionManager, includeTags: true }, + { em: transactionManager, includeTags: true, includeParentFolder: true }, ); }); diff --git a/packages/cli/test/integration/workflows/workflows.controller.test.ts b/packages/cli/test/integration/workflows/workflows.controller.test.ts index 0f8406b895..a9f948d21f 100644 --- a/packages/cli/test/integration/workflows/workflows.controller.test.ts +++ b/packages/cli/test/integration/workflows/workflows.controller.test.ts @@ -58,13 +58,14 @@ let projectService: ProjectService; beforeEach(async () => { await testDb.truncate([ - 'Workflow', 'SharedWorkflow', - 'Tag', 'WorkflowHistory', - 'Project', 'ProjectRelation', 'Folder', + 'Workflow', + 'Tag', + 'Project', + 'User', ]); projectRepository = Container.get(ProjectRepository); projectService = Container.get(ProjectService); @@ -378,6 +379,115 @@ describe('POST /workflows', () => { message: "You don't have the permissions to save the workflow in this project.", }); }); + + test('create link workflow with folder if one is provided', async () => { + // + // ARRANGE + // + const personalProject = await projectRepository.getPersonalProjectForUserOrFail(owner.id); + const folder = await createFolder(personalProject, { name: 'Folder 1' }); + + const workflow = makeWorkflow(); + + // + // ACT + // + const response = await authOwnerAgent + .post('/workflows') + .send({ ...workflow, parentFolderId: folder.id }); + + // + // ASSERT + // + + expect(response.body.data).toMatchObject({ + active: false, + id: expect.any(String), + name: workflow.name, + sharedWithProjects: [], + usedCredentials: [], + homeProject: { + id: personalProject.id, + name: personalProject.name, + type: personalProject.type, + }, + parentFolder: { + id: folder.id, + name: folder.name, + }, + }); + expect(response.body.data.shared).toBeUndefined(); + }); + + test('create workflow without parent folder if no folder is provided', async () => { + // + // ARRANGE + // + const personalProject = await projectRepository.getPersonalProjectForUserOrFail(owner.id); + const workflow = makeWorkflow(); + + // + // ACT + // + const response = await authOwnerAgent + .post('/workflows') + .send({ ...workflow }) + .expect(200); + + // + // ASSERT + // + + expect(response.body.data).toMatchObject({ + active: false, + id: expect.any(String), + name: workflow.name, + sharedWithProjects: [], + usedCredentials: [], + homeProject: { + id: personalProject.id, + name: personalProject.name, + type: personalProject.type, + }, + parentFolder: null, + }); + expect(response.body.data.shared).toBeUndefined(); + }); + + test('create workflow without parent is provided folder does not exist in the project', async () => { + // + // ARRANGE + // + const personalProject = await projectRepository.getPersonalProjectForUserOrFail(owner.id); + const workflow = makeWorkflow(); + + // + // ACT + // + const response = await authOwnerAgent + .post('/workflows') + .send({ ...workflow, parentFolderId: 'non-existing-folder-id' }) + .expect(200); + + // + // ASSERT + // + + expect(response.body.data).toMatchObject({ + active: false, + id: expect.any(String), + name: workflow.name, + sharedWithProjects: [], + usedCredentials: [], + homeProject: { + id: personalProject.id, + name: personalProject.name, + type: personalProject.type, + }, + parentFolder: null, + }); + expect(response.body.data.shared).toBeUndefined(); + }); }); describe('GET /workflows/:workflowId', () => {