diff --git a/.github/workflows/check-documentation-urls.yml b/.github/workflows/check-documentation-urls.yml index 34db00aa9bfc5d..0a2796abe7dddf 100644 --- a/.github/workflows/check-documentation-urls.yml +++ b/.github/workflows/check-documentation-urls.yml @@ -26,7 +26,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Build relevant packages - run: pnpm --filter @n8n/client-oauth2 --filter @n8n/imap --filter n8n-workflow --filter n8n-core --filter n8n-nodes-base --filter @n8n/n8n-nodes-langchain build + run: pnpm build:nodes - run: npm install --prefix=.github/scripts --no-package-lock diff --git a/packages/@n8n/api-types/.eslintrc.js b/packages/@n8n/api-types/.eslintrc.js new file mode 100644 index 00000000000000..1c42fddcdcc948 --- /dev/null +++ b/packages/@n8n/api-types/.eslintrc.js @@ -0,0 +1,7 @@ +const sharedOptions = require('@n8n_io/eslint-config/shared'); + +/** @type {import('@types/eslint').ESLint.ConfigData} */ +module.exports = { + extends: ['@n8n_io/eslint-config/base'], + ...sharedOptions(__dirname), +}; diff --git a/packages/@n8n/api-types/README.md b/packages/@n8n/api-types/README.md new file mode 100644 index 00000000000000..818f3f77566257 --- /dev/null +++ b/packages/@n8n/api-types/README.md @@ -0,0 +1,3 @@ +## @n8n/api-types + +This package contains types and schema definitions for the n8n internal API, so that these can be shared between the backend and the frontend code. diff --git a/packages/@n8n/api-types/jest.config.js b/packages/@n8n/api-types/jest.config.js new file mode 100644 index 00000000000000..d6c48554a79a45 --- /dev/null +++ b/packages/@n8n/api-types/jest.config.js @@ -0,0 +1,2 @@ +/** @type {import('jest').Config} */ +module.exports = require('../../../jest.config'); diff --git a/packages/@n8n/api-types/package.json b/packages/@n8n/api-types/package.json new file mode 100644 index 00000000000000..2e6d17a2a81dad --- /dev/null +++ b/packages/@n8n/api-types/package.json @@ -0,0 +1,24 @@ +{ + "name": "@n8n/api-types", + "version": "0.1.0", + "scripts": { + "clean": "rimraf dist .turbo", + "dev": "pnpm watch", + "typecheck": "tsc --noEmit", + "build": "tsc -p tsconfig.build.json", + "format": "prettier --write . --ignore-path ../../../.prettierignore", + "lint": "eslint .", + "lintfix": "eslint . --fix", + "watch": "tsc -p tsconfig.build.json --watch", + "test": "echo \"No tests yet\" && exit 0" + }, + "main": "dist/index.js", + "module": "src/index.ts", + "types": "dist/index.d.ts", + "files": [ + "dist/**/*" + ], + "devDependencies": { + "n8n-workflow": "workspace:*" + } +} diff --git a/packages/@n8n/api-types/src/datetime.ts b/packages/@n8n/api-types/src/datetime.ts new file mode 100644 index 00000000000000..5175b3931dfa94 --- /dev/null +++ b/packages/@n8n/api-types/src/datetime.ts @@ -0,0 +1,2 @@ +/** Date time in the ISO 8601 format, e.g. 2024-10-31T00:00:00.123Z */ +export type Iso8601DateTimeString = string; diff --git a/packages/@n8n/api-types/src/index.ts b/packages/@n8n/api-types/src/index.ts new file mode 100644 index 00000000000000..5d59a1b7689d5a --- /dev/null +++ b/packages/@n8n/api-types/src/index.ts @@ -0,0 +1,7 @@ +export type * from './push'; +export type * from './scaling'; +export type * from './datetime'; +export type * from './user'; + +export type { Collaborator } from './push/collaboration'; +export type { SendWorkerStatusMessage } from './push/worker'; diff --git a/packages/@n8n/api-types/src/push/collaboration.ts b/packages/@n8n/api-types/src/push/collaboration.ts new file mode 100644 index 00000000000000..f2ec6fcc6cd5c6 --- /dev/null +++ b/packages/@n8n/api-types/src/push/collaboration.ts @@ -0,0 +1,17 @@ +import type { Iso8601DateTimeString } from '../datetime'; +import type { MinimalUser } from '../user'; + +export type Collaborator = { + user: MinimalUser; + lastSeen: Iso8601DateTimeString; +}; + +type CollaboratorsChanged = { + type: 'collaboratorsChanged'; + data: { + workflowId: string; + collaborators: Collaborator[]; + }; +}; + +export type CollaborationPushMessage = CollaboratorsChanged; diff --git a/packages/@n8n/api-types/src/push/debug.ts b/packages/@n8n/api-types/src/push/debug.ts new file mode 100644 index 00000000000000..99c8dc447f80a3 --- /dev/null +++ b/packages/@n8n/api-types/src/push/debug.ts @@ -0,0 +1,9 @@ +type SendConsoleMessage = { + type: 'sendConsoleMessage'; + data: { + source: string; + messages: unknown[]; + }; +}; + +export type DebugPushMessage = SendConsoleMessage; diff --git a/packages/@n8n/api-types/src/push/execution.ts b/packages/@n8n/api-types/src/push/execution.ts new file mode 100644 index 00000000000000..78c0b34a363249 --- /dev/null +++ b/packages/@n8n/api-types/src/push/execution.ts @@ -0,0 +1,53 @@ +import type { IRun, ITaskData, WorkflowExecuteMode } from 'n8n-workflow'; + +type ExecutionStarted = { + type: 'executionStarted'; + data: { + executionId: string; + mode: WorkflowExecuteMode; + startedAt: Date; + workflowId: string; + workflowName?: string; + retryOf?: string; + }; +}; + +type ExecutionFinished = { + type: 'executionFinished'; + data: { + executionId: string; + data: IRun; + retryOf?: string; + }; +}; + +type ExecutionRecovered = { + type: 'executionRecovered'; + data: { + executionId: string; + }; +}; + +type NodeExecuteBefore = { + type: 'nodeExecuteBefore'; + data: { + executionId: string; + nodeName: string; + }; +}; + +type NodeExecuteAfter = { + type: 'nodeExecuteAfter'; + data: { + executionId: string; + nodeName: string; + data: ITaskData; + }; +}; + +export type ExecutionPushMessage = + | ExecutionStarted + | ExecutionFinished + | ExecutionRecovered + | NodeExecuteBefore + | NodeExecuteAfter; diff --git a/packages/@n8n/api-types/src/push/hot-reload.ts b/packages/@n8n/api-types/src/push/hot-reload.ts new file mode 100644 index 00000000000000..e8f9eba31696cb --- /dev/null +++ b/packages/@n8n/api-types/src/push/hot-reload.ts @@ -0,0 +1,21 @@ +type NodeTypeData = { + name: string; + version: number; +}; + +type ReloadNodeType = { + type: 'reloadNodeType'; + data: NodeTypeData; +}; + +type RemoveNodeType = { + type: 'removeNodeType'; + data: NodeTypeData; +}; + +type NodeDescriptionUpdated = { + type: 'nodeDescriptionUpdated'; + data: {}; +}; + +export type HotReloadPushMessage = ReloadNodeType | RemoveNodeType | NodeDescriptionUpdated; diff --git a/packages/@n8n/api-types/src/push/index.ts b/packages/@n8n/api-types/src/push/index.ts new file mode 100644 index 00000000000000..3eefb0851c1cb0 --- /dev/null +++ b/packages/@n8n/api-types/src/push/index.ts @@ -0,0 +1,20 @@ +import type { ExecutionPushMessage } from './execution'; +import type { WorkflowPushMessage } from './workflow'; +import type { HotReloadPushMessage } from './hot-reload'; +import type { WorkerPushMessage } from './worker'; +import type { WebhookPushMessage } from './webhook'; +import type { CollaborationPushMessage } from './collaboration'; +import type { DebugPushMessage } from './debug'; + +export type PushMessage = + | ExecutionPushMessage + | WorkflowPushMessage + | HotReloadPushMessage + | WebhookPushMessage + | WorkerPushMessage + | CollaborationPushMessage + | DebugPushMessage; + +export type PushType = PushMessage['type']; + +export type PushPayload = Extract['data']; diff --git a/packages/@n8n/api-types/src/push/webhook.ts b/packages/@n8n/api-types/src/push/webhook.ts new file mode 100644 index 00000000000000..31e2d9919f21fa --- /dev/null +++ b/packages/@n8n/api-types/src/push/webhook.ts @@ -0,0 +1,17 @@ +type TestWebhookDeleted = { + type: 'testWebhookDeleted'; + data: { + executionId?: string; + workflowId: string; + }; +}; + +type TestWebhookReceived = { + type: 'testWebhookReceived'; + data: { + executionId: string; + workflowId: string; + }; +}; + +export type WebhookPushMessage = TestWebhookDeleted | TestWebhookReceived; diff --git a/packages/@n8n/api-types/src/push/worker.ts b/packages/@n8n/api-types/src/push/worker.ts new file mode 100644 index 00000000000000..84676e6543fe2c --- /dev/null +++ b/packages/@n8n/api-types/src/push/worker.ts @@ -0,0 +1,11 @@ +import type { WorkerStatus } from '../scaling'; + +export type SendWorkerStatusMessage = { + type: 'sendWorkerStatusMessage'; + data: { + workerId: string; + status: WorkerStatus; + }; +}; + +export type WorkerPushMessage = SendWorkerStatusMessage; diff --git a/packages/@n8n/api-types/src/push/workflow.ts b/packages/@n8n/api-types/src/push/workflow.ts new file mode 100644 index 00000000000000..0dcf9ad78dd8a3 --- /dev/null +++ b/packages/@n8n/api-types/src/push/workflow.ts @@ -0,0 +1,26 @@ +type WorkflowActivated = { + type: 'workflowActivated'; + data: { + workflowId: string; + }; +}; + +type WorkflowFailedToActivate = { + type: 'workflowFailedToActivate'; + data: { + workflowId: string; + errorMessage: string; + }; +}; + +type WorkflowDeactivated = { + type: 'workflowDeactivated'; + data: { + workflowId: string; + }; +}; + +export type WorkflowPushMessage = + | WorkflowActivated + | WorkflowFailedToActivate + | WorkflowDeactivated; diff --git a/packages/@n8n/api-types/src/scaling.ts b/packages/@n8n/api-types/src/scaling.ts new file mode 100644 index 00000000000000..8e15f06804b491 --- /dev/null +++ b/packages/@n8n/api-types/src/scaling.ts @@ -0,0 +1,30 @@ +import type { ExecutionStatus, WorkflowExecuteMode } from 'n8n-workflow'; + +export type RunningJobSummary = { + executionId: string; + workflowId: string; + workflowName: string; + mode: WorkflowExecuteMode; + startedAt: Date; + retryOf: string; + status: ExecutionStatus; +}; + +export type WorkerStatus = { + workerId: string; + runningJobsSummary: RunningJobSummary[]; + freeMem: number; + totalMem: number; + uptime: number; + loadAvg: number[]; + cpus: string; + arch: string; + platform: NodeJS.Platform; + hostname: string; + interfaces: Array<{ + family: 'IPv4' | 'IPv6'; + address: string; + internal: boolean; + }>; + version: string; +}; diff --git a/packages/@n8n/api-types/src/user.ts b/packages/@n8n/api-types/src/user.ts new file mode 100644 index 00000000000000..0002ba1ac9f595 --- /dev/null +++ b/packages/@n8n/api-types/src/user.ts @@ -0,0 +1,6 @@ +export type MinimalUser = { + id: string; + email: string; + firstName: string; + lastName: string; +}; diff --git a/packages/@n8n/api-types/tsconfig.build.json b/packages/@n8n/api-types/tsconfig.build.json new file mode 100644 index 00000000000000..057847e09d6991 --- /dev/null +++ b/packages/@n8n/api-types/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "extends": ["./tsconfig.json", "../../../tsconfig.build.json"], + "compilerOptions": { + "composite": true, + "rootDir": "src", + "outDir": "dist", + "tsBuildInfoFile": "dist/build.tsbuildinfo" + }, + "include": ["src/**/*.ts"], + "exclude": ["test/**", "src/**/__tests__/**"] +} diff --git a/packages/@n8n/api-types/tsconfig.json b/packages/@n8n/api-types/tsconfig.json new file mode 100644 index 00000000000000..9c32bd67a1ec6a --- /dev/null +++ b/packages/@n8n/api-types/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "types": ["node", "jest"], + "baseUrl": "src", + "tsBuildInfoFile": "dist/typecheck.tsbuildinfo" + }, + "include": ["src/**/*.ts", "test/**/*.ts"] +} diff --git a/packages/cli/package.json b/packages/cli/package.json index 23c874837e1d60..3b2d9ceffcb94b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -85,6 +85,7 @@ "@azure/identity": "^4.3.0", "@azure/keyvault-secrets": "^4.8.0", "@google-cloud/secret-manager": "^5.6.0", + "@n8n/api-types": "workspace:*", "@n8n/client-oauth2": "workspace:*", "@n8n/config": "workspace:*", "@n8n/localtunnel": "3.0.0", diff --git a/packages/cli/src/collaboration/collaboration.service.ts b/packages/cli/src/collaboration/collaboration.service.ts index b7066eaf949c7c..cb2ca0d77a905b 100644 --- a/packages/cli/src/collaboration/collaboration.service.ts +++ b/packages/cli/src/collaboration/collaboration.service.ts @@ -1,3 +1,4 @@ +import type { PushPayload } from '@n8n/api-types'; import type { Workflow } from 'n8n-workflow'; import { ApplicationError, ErrorReporterProxy } from 'n8n-workflow'; import { Service } from 'typedi'; @@ -5,7 +6,6 @@ import { Service } from 'typedi'; import { CollaborationState } from '@/collaboration/collaboration.state'; import type { User } from '@/databases/entities/user'; import { UserRepository } from '@/databases/repositories/user.repository'; -import type { ICollaboratorsChanged } from '@/interfaces'; import { Push } from '@/push'; import type { OnPushMessage } from '@/push/types'; import { AccessService } from '@/services/access.service'; @@ -92,7 +92,7 @@ export class CollaborationService { user: user.toIUser(), lastSeen: collaborators.find(({ userId }) => userId === user.id)!.lastSeen, })); - const msgData: ICollaboratorsChanged = { + const msgData: PushPayload<'collaboratorsChanged'> = { workflowId, collaborators: activeCollaborators, }; diff --git a/packages/cli/src/collaboration/collaboration.state.ts b/packages/cli/src/collaboration/collaboration.state.ts index 00508ac11a7531..f8f606a2adc43e 100644 --- a/packages/cli/src/collaboration/collaboration.state.ts +++ b/packages/cli/src/collaboration/collaboration.state.ts @@ -1,9 +1,9 @@ +import type { Iso8601DateTimeString } from '@n8n/api-types'; import type { Workflow } from 'n8n-workflow'; import { Service } from 'typedi'; import { Time } from '@/constants'; import type { User } from '@/databases/entities/user'; -import type { Iso8601DateTimeString } from '@/interfaces'; import { CacheService } from '@/services/cache/cache.service'; type WorkflowCacheHash = Record; diff --git a/packages/cli/src/controllers/e2e.controller.ts b/packages/cli/src/controllers/e2e.controller.ts index 7a132401d1d655..a9e10b15b3d351 100644 --- a/packages/cli/src/controllers/e2e.controller.ts +++ b/packages/cli/src/controllers/e2e.controller.ts @@ -1,3 +1,4 @@ +import type { PushPayload, PushType } from '@n8n/api-types'; import { Request } from 'express'; import Container from 'typedi'; import { v4 as uuid } from 'uuid'; @@ -10,7 +11,7 @@ import { SettingsRepository } from '@/databases/repositories/settings.repository import { UserRepository } from '@/databases/repositories/user.repository'; import { Patch, Post, RestController } from '@/decorators'; import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus'; -import type { BooleanLicenseFeature, IPushDataType, NumericLicenseFeature } from '@/interfaces'; +import type { BooleanLicenseFeature, NumericLicenseFeature } from '@/interfaces'; import { License } from '@/license'; import { Logger } from '@/logger'; import { MfaService } from '@/mfa/mfa.service'; @@ -56,13 +57,13 @@ type ResetRequest = Request< } >; -type PushRequest = Request< +type PushRequest = Request< {}, {}, { - type: IPushDataType; + type: T; pushRef: string; - data: object; + data: PushPayload; } >; @@ -132,7 +133,7 @@ export class E2EController { } @Post('/push', { skipAuth: true }) - async pushSend(req: PushRequest) { + async pushSend(req: PushRequest) { this.push.broadcast(req.body.type, req.body.data); } diff --git a/packages/cli/src/interfaces.ts b/packages/cli/src/interfaces.ts index 7e6eb1584d0448..4d54e185a983a5 100644 --- a/packages/cli/src/interfaces.ts +++ b/packages/cli/src/interfaces.ts @@ -11,7 +11,6 @@ import type { IExecuteResponsePromiseData, IRun, IRunExecutionData, - ITaskData, ITelemetryTrackProperties, IWorkflowBase, CredentialLoadingDetails, @@ -23,7 +22,6 @@ import type { INodeProperties, IUserSettings, IWorkflowExecutionDataProcess, - IUser, } from 'n8n-workflow'; import type PCancelable from 'p-cancelable'; @@ -40,7 +38,6 @@ import type { WorkflowRepository } from '@/databases/repositories/workflow.repos import type { LICENSE_FEATURES, LICENSE_QUOTAS } from './constants'; import type { ExternalHooks } from './external-hooks'; -import type { RunningJobSummary } from './scaling/scaling.types'; import type { WorkflowWithSharingsAndCredentials } from './workflows/workflows.types'; export interface ICredentialsTypeData { @@ -139,11 +136,6 @@ export interface IExecutionDb extends IExecutionBase { */ export type ExecutionPayload = Omit; -export interface IExecutionPushResponse { - executionId?: string; - waitingForWebhook?: boolean; -} - export interface IExecutionResponse extends IExecutionBase { id: string; data: IRunExecutionData; @@ -271,207 +263,6 @@ export interface IPackageVersions { cli: string; } -export type IPushDataType = IPushData['type']; - -export type IPushData = - | PushDataExecutionFinished - | PushDataExecutionStarted - | PushDataExecuteAfter - | PushDataExecuteBefore - | PushDataConsoleMessage - | PushDataReloadNodeType - | PushDataRemoveNodeType - | PushDataTestWebhook - | PushDataNodeDescriptionUpdated - | PushDataExecutionRecovered - | PushDataWorkerStatusMessage - | PushDataWorkflowActivated - | PushDataWorkflowDeactivated - | PushDataWorkflowFailedToActivate - | PushDataCollaboratorsChanged; - -type PushDataCollaboratorsChanged = { - data: ICollaboratorsChanged; - type: 'collaboratorsChanged'; -}; - -type PushDataWorkflowFailedToActivate = { - data: IWorkflowFailedToActivate; - type: 'workflowFailedToActivate'; -}; - -type PushDataWorkflowActivated = { - data: IActiveWorkflowChanged; - type: 'workflowActivated'; -}; - -type PushDataWorkflowDeactivated = { - data: IActiveWorkflowChanged; - type: 'workflowDeactivated'; -}; - -export type PushDataExecutionRecovered = { - data: IPushDataExecutionRecovered; - type: 'executionRecovered'; -}; - -export type PushDataExecutionFinished = { - data: IPushDataExecutionFinished; - type: 'executionFinished'; -}; - -export type PushDataExecutionStarted = { - data: IPushDataExecutionStarted; - type: 'executionStarted'; -}; - -export type PushDataExecuteAfter = { - data: IPushDataNodeExecuteAfter; - type: 'nodeExecuteAfter'; -}; - -export type PushDataExecuteBefore = { - data: IPushDataNodeExecuteBefore; - type: 'nodeExecuteBefore'; -}; - -export type PushDataConsoleMessage = { - data: IPushDataConsoleMessage; - type: 'sendConsoleMessage'; -}; - -type PushDataWorkerStatusMessage = { - data: IPushDataWorkerStatusMessage; - type: 'sendWorkerStatusMessage'; -}; - -type PushDataReloadNodeType = { - data: IPushDataReloadNodeType; - type: 'reloadNodeType'; -}; - -export type PushDataRemoveNodeType = { - data: IPushDataRemoveNodeType; - type: 'removeNodeType'; -}; - -export type PushDataTestWebhook = { - data: IPushDataTestWebhook; - type: 'testWebhookDeleted' | 'testWebhookReceived'; -}; - -export type PushDataNodeDescriptionUpdated = { - data: undefined; - type: 'nodeDescriptionUpdated'; -}; - -/** DateTime in the Iso8601 format, e.g. 2024-10-31T00:00:00.123Z */ -export type Iso8601DateTimeString = string; - -export interface ICollaborator { - user: IUser; - lastSeen: Iso8601DateTimeString; -} - -export interface ICollaboratorsChanged { - workflowId: Workflow['id']; - collaborators: ICollaborator[]; -} - -export interface IActiveWorkflowAdded { - workflowId: Workflow['id']; -} - -interface IActiveWorkflowChanged { - workflowId: Workflow['id']; -} - -interface IWorkflowFailedToActivate { - workflowId: Workflow['id']; - errorMessage: string; -} - -export interface IPushDataExecutionRecovered { - executionId: string; -} - -export interface IPushDataExecutionFinished { - data: IRun; - executionId: string; - retryOf?: string; -} - -export interface IPushDataExecutionStarted { - executionId: string; - mode: WorkflowExecuteMode; - startedAt: Date; - retryOf?: string; - workflowId: string; - workflowName?: string; -} - -export interface IPushDataNodeExecuteAfter { - data: ITaskData; - executionId: string; - nodeName: string; -} - -export interface IPushDataNodeExecuteBefore { - executionId: string; - nodeName: string; -} - -export interface IPushDataReloadNodeType { - name: string; - version: number; -} - -export interface IPushDataRemoveNodeType { - name: string; - version: number; -} - -export interface IPushDataTestWebhook { - executionId: string; - workflowId: string; -} - -export interface IPushDataConsoleMessage { - source: string; - message: string; -} - -export interface IPushDataWorkerStatusMessage { - workerId: string; - status: IPushDataWorkerStatusPayload; -} - -export interface IPushDataWorkerStatusPayload { - workerId: string; - runningJobsSummary: RunningJobSummary[]; - freeMem: number; - totalMem: number; - uptime: number; - loadAvg: number[]; - cpus: string; - arch: string; - platform: NodeJS.Platform; - hostname: string; - interfaces: Array<{ - family: 'IPv4' | 'IPv6'; - address: string; - internal: boolean; - }>; - version: string; -} - -export interface INodesTypeData { - [key: string]: { - className: string; - sourcePath: string; - }; -} - export interface IWorkflowErrorData { [key: string]: any; execution?: { diff --git a/packages/cli/src/load-nodes-and-credentials.ts b/packages/cli/src/load-nodes-and-credentials.ts index 500f5d20289d1c..e2daaa0e76b302 100644 --- a/packages/cli/src/load-nodes-and-credentials.ts +++ b/packages/cli/src/load-nodes-and-credentials.ts @@ -375,7 +375,7 @@ export class LoadNodesAndCredentials { loader.reset(); await loader.loadAll(); await this.postProcessLoaders(); - push.broadcast('nodeDescriptionUpdated'); + push.broadcast('nodeDescriptionUpdated', {}); }, 100); const toWatch = loader.isLazyLoaded diff --git a/packages/cli/src/push/__tests__/websocket.push.test.ts b/packages/cli/src/push/__tests__/websocket.push.test.ts index b7f3fa38a0f567..f62038c6b3fe9d 100644 --- a/packages/cli/src/push/__tests__/websocket.push.test.ts +++ b/packages/cli/src/push/__tests__/websocket.push.test.ts @@ -1,9 +1,9 @@ +import type { PushMessage } from '@n8n/api-types'; import { EventEmitter } from 'events'; import { Container } from 'typedi'; import type WebSocket from 'ws'; import type { User } from '@/databases/entities/user'; -import type { PushDataExecutionRecovered } from '@/interfaces'; import { Logger } from '@/logger'; import { WebSocketPush } from '@/push/websocket.push'; import { mockInstance } from '@test/mocking'; @@ -28,6 +28,18 @@ describe('WebSocketPush', () => { const pushRef1 = 'test-session1'; const pushRef2 = 'test-session2'; const userId: User['id'] = 'test-user'; + const pushMessage: PushMessage = { + type: 'executionRecovered', + data: { + executionId: 'test-execution-id', + }, + }; + const expectedMsg = JSON.stringify({ + type: 'executionRecovered', + data: { + executionId: 'test-execution-id', + }, + }); mockInstance(Logger); const webSocketPush = Container.get(WebSocketPush); @@ -61,50 +73,17 @@ describe('WebSocketPush', () => { it('sends data to one connection', () => { webSocketPush.add(pushRef1, userId, mockWebSocket1); webSocketPush.add(pushRef2, userId, mockWebSocket2); - const data: PushDataExecutionRecovered = { - type: 'executionRecovered', - data: { - executionId: 'test-execution-id', - }, - }; - - webSocketPush.sendToOne('executionRecovered', data, pushRef1); - - expect(mockWebSocket1.send).toHaveBeenCalledWith( - JSON.stringify({ - type: 'executionRecovered', - data: { - type: 'executionRecovered', - data: { - executionId: 'test-execution-id', - }, - }, - }), - ); + webSocketPush.sendToOne(pushMessage.type, pushMessage.data, pushRef1); + + expect(mockWebSocket1.send).toHaveBeenCalledWith(expectedMsg); expect(mockWebSocket2.send).not.toHaveBeenCalled(); }); it('sends data to all connections', () => { webSocketPush.add(pushRef1, userId, mockWebSocket1); webSocketPush.add(pushRef2, userId, mockWebSocket2); - const data: PushDataExecutionRecovered = { - type: 'executionRecovered', - data: { - executionId: 'test-execution-id', - }, - }; - - webSocketPush.sendToAll('executionRecovered', data); - - const expectedMsg = JSON.stringify({ - type: 'executionRecovered', - data: { - type: 'executionRecovered', - data: { - executionId: 'test-execution-id', - }, - }, - }); + webSocketPush.sendToAll(pushMessage.type, pushMessage.data); + expect(mockWebSocket1.send).toHaveBeenCalledWith(expectedMsg); expect(mockWebSocket2.send).toHaveBeenCalledWith(expectedMsg); }); @@ -122,24 +101,8 @@ describe('WebSocketPush', () => { it('sends data to all users connections', () => { webSocketPush.add(pushRef1, userId, mockWebSocket1); webSocketPush.add(pushRef2, userId, mockWebSocket2); - const data: PushDataExecutionRecovered = { - type: 'executionRecovered', - data: { - executionId: 'test-execution-id', - }, - }; - - webSocketPush.sendToUsers('executionRecovered', data, [userId]); - - const expectedMsg = JSON.stringify({ - type: 'executionRecovered', - data: { - type: 'executionRecovered', - data: { - executionId: 'test-execution-id', - }, - }, - }); + webSocketPush.sendToUsers(pushMessage.type, pushMessage.data, [userId]); + expect(mockWebSocket1.send).toHaveBeenCalledWith(expectedMsg); expect(mockWebSocket2.send).toHaveBeenCalledWith(expectedMsg); }); diff --git a/packages/cli/src/push/abstract.push.ts b/packages/cli/src/push/abstract.push.ts index 43febacb5ede1c..f3ae6606ed7a89 100644 --- a/packages/cli/src/push/abstract.push.ts +++ b/packages/cli/src/push/abstract.push.ts @@ -1,7 +1,7 @@ +import type { PushPayload, PushType } from '@n8n/api-types'; import { assert, jsonStringify } from 'n8n-workflow'; import type { User } from '@/databases/entities/user'; -import type { IPushDataType } from '@/interfaces'; import type { Logger } from '@/logger'; import type { OnPushMessage } from '@/push/types'; import { TypedEmitter } from '@/typed-emitter'; @@ -16,19 +16,19 @@ export interface AbstractPushEvents { * * @emits message when a message is received from a client */ -export abstract class AbstractPush extends TypedEmitter { - protected connections: Record = {}; +export abstract class AbstractPush extends TypedEmitter { + protected connections: Record = {}; protected userIdByPushRef: Record = {}; - protected abstract close(connection: T): void; - protected abstract sendToOneConnection(connection: T, data: string): void; + protected abstract close(connection: Connection): void; + protected abstract sendToOneConnection(connection: Connection, data: string): void; constructor(protected readonly logger: Logger) { super(); } - protected add(pushRef: string, userId: User['id'], connection: T) { + protected add(pushRef: string, userId: User['id'], connection: Connection) { const { connections, userIdByPushRef } = this; this.logger.debug('Add editor-UI session', { pushRef }); @@ -60,7 +60,7 @@ export abstract class AbstractPush extends TypedEmitter { delete this.userIdByPushRef[pushRef]; } - private sendTo(type: IPushDataType, data: unknown, pushRefs: string[]) { + private sendTo(type: Type, data: PushPayload, pushRefs: string[]) { this.logger.debug(`Send data of type "${type}" to editor-UI`, { dataType: type, pushRefs: pushRefs.join(', '), @@ -75,11 +75,11 @@ export abstract class AbstractPush extends TypedEmitter { } } - sendToAll(type: IPushDataType, data?: unknown) { + sendToAll(type: Type, data: PushPayload) { this.sendTo(type, data, Object.keys(this.connections)); } - sendToOne(type: IPushDataType, data: unknown, pushRef: string) { + sendToOne(type: Type, data: PushPayload, pushRef: string) { if (this.connections[pushRef] === undefined) { this.logger.error(`The session "${pushRef}" is not registered.`, { pushRef }); return; @@ -88,7 +88,11 @@ export abstract class AbstractPush extends TypedEmitter { this.sendTo(type, data, [pushRef]); } - sendToUsers(type: IPushDataType, data: unknown, userIds: Array) { + sendToUsers( + type: Type, + data: PushPayload, + userIds: Array, + ) { const { connections } = this; const userPushRefs = Object.keys(connections).filter((pushRef) => userIds.includes(this.userIdByPushRef[pushRef]), diff --git a/packages/cli/src/push/index.ts b/packages/cli/src/push/index.ts index 840462d9a6e549..232864968d78d0 100644 --- a/packages/cli/src/push/index.ts +++ b/packages/cli/src/push/index.ts @@ -1,3 +1,4 @@ +import type { PushPayload, PushType } from '@n8n/api-types'; import type { Application } from 'express'; import { ServerResponse } from 'http'; import type { Server } from 'http'; @@ -11,7 +12,6 @@ import config from '@/config'; import type { User } from '@/databases/entities/user'; import { OnShutdown } from '@/decorators/on-shutdown'; import { BadRequestError } from '@/errors/response-errors/bad-request.error'; -import type { IPushDataType } from '@/interfaces'; import { OrchestrationService } from '@/services/orchestration.service'; import { TypedEmitter } from '@/typed-emitter'; @@ -45,6 +45,10 @@ export class Push extends TypedEmitter { if (useWebSockets) this.backend.on('message', (msg) => this.emit('message', msg)); } + getBackend() { + return this.backend; + } + handleRequest(req: SSEPushRequest | WebSocketPushRequest, res: PushResponse) { const { ws, @@ -73,11 +77,11 @@ export class Push extends TypedEmitter { this.emit('editorUiConnected', pushRef); } - broadcast(type: IPushDataType, data?: unknown) { + broadcast(type: Type, data: PushPayload) { this.backend.sendToAll(type, data); } - send(type: IPushDataType, data: unknown, pushRef: string) { + send(type: Type, data: PushPayload, pushRef: string) { /** * Multi-main setup: In a manual webhook execution, the main process that * handles a webhook might not be the same as the main process that created @@ -93,11 +97,11 @@ export class Push extends TypedEmitter { this.backend.sendToOne(type, data, pushRef); } - getBackend() { - return this.backend; - } - - sendToUsers(type: IPushDataType, data: unknown, userIds: Array) { + sendToUsers( + type: Type, + data: PushPayload, + userIds: Array, + ) { this.backend.sendToUsers(type, data, userIds); } diff --git a/packages/cli/src/scaling/job-processor.ts b/packages/cli/src/scaling/job-processor.ts index 317c849e287ea5..3155b0d90f0191 100644 --- a/packages/cli/src/scaling/job-processor.ts +++ b/packages/cli/src/scaling/job-processor.ts @@ -1,3 +1,4 @@ +import type { RunningJobSummary } from '@n8n/api-types'; import { WorkflowExecute } from 'n8n-core'; import { BINARY_ENCODING, ApplicationError, Workflow } from 'n8n-workflow'; import type { ExecutionStatus, IExecuteResponsePromiseData, IRun } from 'n8n-workflow'; @@ -11,7 +12,7 @@ import { Logger } from '@/logger'; import { NodeTypes } from '@/node-types'; import * as WorkflowExecuteAdditionalData from '@/workflow-execute-additional-data'; -import type { Job, JobId, JobResult, RunningJob, RunningJobSummary } from './scaling.types'; +import type { Job, JobId, JobResult, RunningJob } from './scaling.types'; /** * Responsible for processing jobs from the queue, i.e. running enqueued executions. diff --git a/packages/cli/src/scaling/scaling.types.ts b/packages/cli/src/scaling/scaling.types.ts index 9bd6c5d2aefb29..ad5b7b3643b74a 100644 --- a/packages/cli/src/scaling/scaling.types.ts +++ b/packages/cli/src/scaling/scaling.types.ts @@ -1,11 +1,6 @@ +import type { RunningJobSummary } from '@n8n/api-types'; import type Bull from 'bull'; -import type { - ExecutionError, - ExecutionStatus, - IExecuteResponsePromiseData, - IRun, - WorkflowExecuteMode as WorkflowExecutionMode, -} from 'n8n-workflow'; +import type { ExecutionError, IExecuteResponsePromiseData, IRun } from 'n8n-workflow'; import type PCancelable from 'p-cancelable'; export type JobQueue = Bull.Queue; @@ -30,11 +25,11 @@ export type JobOptions = Bull.JobOptions; export type PubSubMessage = MessageToMain | MessageToWorker; -type MessageToMain = RepondToWebhookMessage; +type MessageToMain = RespondToWebhookMessage; type MessageToWorker = AbortJobMessage; -type RepondToWebhookMessage = { +type RespondToWebhookMessage = { kind: 'respond-to-webhook'; executionId: string; response: IExecuteResponsePromiseData; @@ -44,19 +39,10 @@ type AbortJobMessage = { kind: 'abort-job'; }; -export type RunningJob = { - executionId: string; - workflowId: string; - workflowName: string; - mode: WorkflowExecutionMode; - startedAt: Date; - retryOf: string; - status: ExecutionStatus; +export type RunningJob = RunningJobSummary & { run: PCancelable; }; -export type RunningJobSummary = Omit; - export type QueueRecoveryContext = { /** ID of timeout for next scheduled recovery cycle. */ timeout?: NodeJS.Timeout; diff --git a/packages/cli/src/services/orchestration/helpers.ts b/packages/cli/src/services/orchestration/helpers.ts index a6f313ecfff9f3..cfd5bca51a4809 100644 --- a/packages/cli/src/services/orchestration/helpers.ts +++ b/packages/cli/src/services/orchestration/helpers.ts @@ -1,5 +1,5 @@ import { jsonParse } from 'n8n-workflow'; -import * as os from 'os'; +import os from 'node:os'; import { Container } from 'typedi'; import { Logger } from '@/logger'; diff --git a/packages/cli/src/services/orchestration/main/handle-worker-response-message-main.ts b/packages/cli/src/services/orchestration/main/handle-worker-response-message-main.ts index fd1c402aca487d..79e09116d537a6 100644 --- a/packages/cli/src/services/orchestration/main/handle-worker-response-message-main.ts +++ b/packages/cli/src/services/orchestration/main/handle-worker-response-message-main.ts @@ -1,3 +1,4 @@ +import type { WorkerStatus } from '@n8n/api-types'; import { jsonParse } from 'n8n-workflow'; import Container from 'typedi'; @@ -29,7 +30,7 @@ export async function handleWorkerResponseMessageMain( case 'getStatus': Container.get(Push).broadcast('sendWorkerStatusMessage', { workerId: workerResponse.workerId, - status: workerResponse.payload, + status: workerResponse.payload as WorkerStatus, }); break; case 'getId': diff --git a/packages/cli/src/services/orchestration/pubsub/pubsub-message-map.ts b/packages/cli/src/services/orchestration/pubsub/pubsub-message-map.ts index 177b8ad9ac6972..64769cb4e2ae61 100644 --- a/packages/cli/src/services/orchestration/pubsub/pubsub-message-map.ts +++ b/packages/cli/src/services/orchestration/pubsub/pubsub-message-map.ts @@ -1,5 +1,6 @@ -import type { IPushDataType, IWorkflowDb } from '@/interfaces'; -import type { RunningJobSummary } from '@/scaling/scaling.types'; +import type { PushType, WorkerStatus } from '@n8n/api-types'; + +import type { IWorkflowDb } from '@/interfaces'; export type PubSubMessageMap = { // #region Lifecycle @@ -43,24 +44,7 @@ export type PubSubMessageMap = { 'get-worker-id': never; - 'get-worker-status': { - workerId: string; - runningJobsSummary: RunningJobSummary[]; - freeMem: number; - totalMem: number; - uptime: number; - loadAvg: number[]; - cpus: string; - arch: string; - platform: NodeJS.Platform; - hostname: string; - interfaces: Array<{ - family: 'IPv4' | 'IPv6'; - address: string; - internal: boolean; - }>; - version: string; - }; + 'get-worker-status': WorkerStatus; // #endregion @@ -89,7 +73,7 @@ export type PubSubMessageMap = { }; 'relay-execution-lifecycle-event': { - type: IPushDataType; + type: PushType; args: Record; pushRef: string; }; diff --git a/packages/cli/src/services/orchestration/worker/handle-command-message-worker.ts b/packages/cli/src/services/orchestration/worker/handle-command-message-worker.ts index bdeabe78d47121..2bc46745c8f5e2 100644 --- a/packages/cli/src/services/orchestration/worker/handle-command-message-worker.ts +++ b/packages/cli/src/services/orchestration/worker/handle-command-message-worker.ts @@ -1,5 +1,5 @@ import { jsonParse } from 'n8n-workflow'; -import * as os from 'os'; +import os from 'node:os'; import Container from 'typedi'; import { N8N_VERSION } from '@/constants'; diff --git a/packages/cli/src/services/orchestration/worker/types.ts b/packages/cli/src/services/orchestration/worker/types.ts index 5c3db2bbe46159..370f7a1ec36f71 100644 --- a/packages/cli/src/services/orchestration/worker/types.ts +++ b/packages/cli/src/services/orchestration/worker/types.ts @@ -1,7 +1,6 @@ +import type { RunningJobSummary } from '@n8n/api-types'; import type { ExecutionStatus, WorkflowExecuteMode } from 'n8n-workflow'; -import type { RunningJobSummary } from '@/scaling/scaling.types'; - import type { RedisServicePubSubPublisher } from '../../redis/redis-service-pub-sub-publisher'; export interface WorkerCommandReceivedHandlerOptions { diff --git a/packages/cli/src/services/redis/redis-service-commands.ts b/packages/cli/src/services/redis/redis-service-commands.ts index 054cec3b4493af..71ebd3dee5ae8a 100644 --- a/packages/cli/src/services/redis/redis-service-commands.ts +++ b/packages/cli/src/services/redis/redis-service-commands.ts @@ -1,4 +1,6 @@ -import type { IPushDataType, IPushDataWorkerStatusPayload, IWorkflowDb } from '@/interfaces'; +import type { PushType, WorkerStatus } from '@n8n/api-types'; + +import type { IWorkflowDb } from '@/interfaces'; export type RedisServiceCommand = | 'getStatus' @@ -42,7 +44,7 @@ export type RedisServiceBaseCommand = | { senderId: string; command: 'relay-execution-lifecycle-event'; - payload: { type: IPushDataType; args: Record; pushRef: string }; + payload: { type: PushType; args: Record; pushRef: string }; } | { senderId: string; @@ -64,7 +66,7 @@ export type RedisServiceWorkerResponseObject = { | RedisServiceBaseCommand | { command: 'getStatus'; - payload: IPushDataWorkerStatusPayload; + payload: WorkerStatus; } | { command: 'getId'; diff --git a/packages/cli/src/workflow-execute-additional-data.ts b/packages/cli/src/workflow-execute-additional-data.ts index 41409ac1c2631a..040a56b7a32f5c 100644 --- a/packages/cli/src/workflow-execute-additional-data.ts +++ b/packages/cli/src/workflow-execute-additional-data.ts @@ -3,6 +3,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import type { PushType } from '@n8n/api-types'; import { GlobalConfig } from '@n8n/config'; import { WorkflowExecute } from 'n8n-core'; import type { @@ -40,13 +41,7 @@ import config from '@/config'; import { CredentialsHelper } from '@/credentials-helper'; import { ExecutionRepository } from '@/databases/repositories/execution.repository'; import { ExternalHooks } from '@/external-hooks'; -import type { - IPushDataExecutionFinished, - IWorkflowExecuteProcess, - IWorkflowErrorData, - IPushDataType, - ExecutionPayload, -} from '@/interfaces'; +import type { IWorkflowExecuteProcess, IWorkflowErrorData, ExecutionPayload } from '@/interfaces'; import { NodeTypes } from '@/node-types'; import { Push } from '@/push'; import { WorkflowStatisticsService } from '@/services/workflow-statistics.service'; @@ -299,7 +294,6 @@ function hookFunctionsPush(): IWorkflowExecuteHooks { startedAt: new Date(), retryOf: this.retryOf, workflowId, - pushRef, workflowName, }, pushRef, @@ -346,13 +340,15 @@ function hookFunctionsPush(): IWorkflowExecuteHooks { workflowId, }); // TODO: Look at this again - const sendData: IPushDataExecutionFinished = { - executionId, - data: pushRunData, - retryOf, - }; - - pushInstance.send('executionFinished', sendData, pushRef); + pushInstance.send( + 'executionFinished', + { + executionId, + data: pushRunData, + retryOf, + }, + pushRef, + ); }, ], }; @@ -938,7 +934,7 @@ export function setExecutionStatus(status: ExecutionStatus) { Container.get(ActiveExecutions).setStatus(this.executionId, status); } -export function sendDataToUI(type: string, data: IDataObject | IDataObject[]) { +export function sendDataToUI(type: PushType, data: IDataObject | IDataObject[]) { const { pushRef } = this; if (pushRef === undefined) { return; @@ -947,7 +943,7 @@ export function sendDataToUI(type: string, data: IDataObject | IDataObject[]) { // Push data to session which started workflow try { const pushInstance = Container.get(Push); - pushInstance.send(type as IPushDataType, data, pushRef); + pushInstance.send(type, data, pushRef); } catch (error) { const logger = Container.get(Logger); logger.warn(`There was a problem sending message to UI: ${error.message}`); diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 14e93de1b8f42e..d145ba0c636151 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -19,6 +19,7 @@ "references": [ { "path": "../workflow/tsconfig.build.json" }, { "path": "../core/tsconfig.build.json" }, + { "path": "../@n8n/api-types/tsconfig.build.json" }, { "path": "../@n8n/client-oauth2/tsconfig.build.json" }, { "path": "../@n8n/config/tsconfig.build.json" }, { "path": "../@n8n/permissions/tsconfig.build.json" } diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json index b96c856427973c..68c984fe5bc652 100644 --- a/packages/editor-ui/package.json +++ b/packages/editor-ui/package.json @@ -32,6 +32,7 @@ "@jsplumb/core": "^5.13.2", "@jsplumb/util": "^5.13.2", "@lezer/common": "^1.0.4", + "@n8n/api-types": "workspace:*", "@n8n/chat": "workspace:*", "@n8n/codemirror-lang": "workspace:*", "@n8n/codemirror-lang-sql": "^1.0.2", diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index e4d809f98a2742..bcbd8a25f6710b 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -1,13 +1,8 @@ -import type { - AI_NODE_CREATOR_VIEW, - CREDENTIAL_EDIT_MODAL_KEY, - SignInType, - FAKE_DOOR_FEATURES, - TRIGGER_NODE_CREATOR_VIEW, - REGULAR_NODE_CREATOR_VIEW, - AI_OTHERS_NODE_CREATOR_VIEW, - ROLE, -} from '@/constants'; +import type { Component } from 'vue'; +import type { NotificationOptions as ElementNotificationOptions } from 'element-plus'; +import type { Connection } from '@jsplumb/core'; +import type { Iso8601DateTimeString } from '@n8n/api-types'; +import type { Scope } from '@n8n/permissions'; import type { IMenuItem, NodeCreatorTag } from 'n8n-design-system'; import type { GenericValue, @@ -22,9 +17,7 @@ import type { INodeTypeDescription, IPinData, IRunExecutionData, - IRun, IRunData, - ITaskData, IWorkflowSettings as IWorkflowSettingsWorkflow, WorkflowExecuteMode, PublicInstalledPackage, @@ -51,13 +44,21 @@ import type { IPersonalizationSurveyAnswersV4, AnnotationVote, } from 'n8n-workflow'; + +import type { + AI_NODE_CREATOR_VIEW, + CREDENTIAL_EDIT_MODAL_KEY, + SignInType, + FAKE_DOOR_FEATURES, + TRIGGER_NODE_CREATOR_VIEW, + REGULAR_NODE_CREATOR_VIEW, + AI_OTHERS_NODE_CREATOR_VIEW, + ROLE, +} from '@/constants'; import type { BulkCommand, Undoable } from '@/models/history'; import type { PartialBy, TupleToUnion } from '@/utils/typeHelpers'; -import type { Component } from 'vue'; -import type { Scope } from '@n8n/permissions'; -import type { NotificationOptions as ElementNotificationOptions } from 'element-plus'; + import type { ProjectSharingData } from '@/types/projects.types'; -import type { Connection } from '@jsplumb/core'; import type { BaseTextKey } from './plugins/i18n'; export * from 'n8n-design-system/types'; @@ -119,9 +120,6 @@ declare global { } } -/** String that represents a timestamp in the ISO8601 format, i.e. YYYY-MM-DDTHH:MM:SS.sssZ */ -export type Iso8601String = string; - export type EndpointStyle = { width?: number; height?: number; @@ -336,8 +334,8 @@ export interface IShareWorkflowsPayload { export interface ICredentialsResponse extends ICredentialsEncrypted { id: string; - createdAt: Iso8601String; - updatedAt: Iso8601String; + createdAt: Iso8601DateTimeString; + updatedAt: Iso8601DateTimeString; sharedWithProjects?: ProjectSharingData[]; homeProject?: ProjectSharingData; currentUserHasAccess?: boolean; @@ -346,8 +344,8 @@ export interface ICredentialsResponse extends ICredentialsEncrypted { } export interface ICredentialsBase { - createdAt: Iso8601String; - updatedAt: Iso8601String; + createdAt: Iso8601DateTimeString; + updatedAt: Iso8601DateTimeString; } export interface ICredentialsDecryptedResponse extends ICredentialsBase, ICredentialsDecrypted { @@ -422,213 +420,6 @@ export interface IExecutionDeleteFilter { ids?: string[]; } -export interface Collaborator { - user: IUser; - lastSeen: string; -} - -export type PushDataCollaborators = { - workflowId: string; - collaborators: Collaborator[]; -}; - -type PushDataCollaboratorsChanged = { - data: PushDataCollaborators; - type: 'collaboratorsChanged'; -}; - -export type IPushData = - | PushDataExecutionFinished - | PushDataExecutionStarted - | PushDataExecuteAfter - | PushDataExecuteBefore - | PushDataNodeDescriptionUpdated - | PushDataConsoleMessage - | PushDataReloadNodeType - | PushDataRemoveNodeType - | PushDataTestWebhook - | PushDataExecutionRecovered - | PushDataWorkerStatusMessage - | PushDataActiveWorkflowAdded - | PushDataActiveWorkflowRemoved - | PushDataCollaboratorsChanged - | PushDataWorkflowFailedToActivate; - -export type PushDataActiveWorkflowAdded = { - data: IActiveWorkflowAdded; - type: 'workflowActivated'; -}; - -export type PushDataActiveWorkflowRemoved = { - data: IActiveWorkflowRemoved; - type: 'workflowDeactivated'; -}; - -export type PushDataWorkflowFailedToActivate = { - data: IWorkflowFailedToActivate; - type: 'workflowFailedToActivate'; -}; - -export type PushDataExecutionRecovered = { - data: IPushDataExecutionRecovered; - type: 'executionRecovered'; -}; - -export type PushDataExecutionFinished = { - data: IPushDataExecutionFinished; - type: 'executionFinished'; -}; - -export type PushDataExecutionStarted = { - data: IPushDataExecutionStarted; - type: 'executionStarted'; -}; - -export type PushDataExecuteAfter = { - data: IPushDataNodeExecuteAfter; - type: 'nodeExecuteAfter'; -}; - -export type PushDataExecuteBefore = { - data: IPushDataNodeExecuteBefore; - type: 'nodeExecuteBefore'; -}; - -export type PushDataNodeDescriptionUpdated = { - data: {}; - type: 'nodeDescriptionUpdated'; -}; - -export type PushDataConsoleMessage = { - data: IPushDataConsoleMessage; - type: 'sendConsoleMessage'; -}; - -export type PushDataReloadNodeType = { - data: IPushDataReloadNodeType; - type: 'reloadNodeType'; -}; - -export type PushDataRemoveNodeType = { - data: IPushDataRemoveNodeType; - type: 'removeNodeType'; -}; - -export type PushDataTestWebhook = { - data: IPushDataTestWebhook; - type: 'testWebhookDeleted' | 'testWebhookReceived'; -}; - -export type PushDataWorkerStatusMessage = { - data: IPushDataWorkerStatusMessage; - type: 'sendWorkerStatusMessage'; -}; - -export interface IPushDataExecutionStarted { - executionId: string; - mode: WorkflowExecuteMode; - startedAt: Date; - retryOf?: string; - workflowId: string; - workflowName?: string; -} -export interface IPushDataExecutionRecovered { - executionId: string; -} - -export interface IPushDataExecutionFinished { - data: IRun; - executionId: string; - retryOf?: string; -} - -export interface IActiveWorkflowAdded { - workflowId: string; -} - -export interface IActiveWorkflowRemoved { - workflowId: string; -} - -export interface IWorkflowFailedToActivate { - workflowId: string; - errorMessage: string; -} - -export interface IPushDataUnsavedExecutionFinished { - executionId: string; - data: { finished: true; stoppedAt: Date }; -} - -export interface IPushDataExecutionStarted { - executionId: string; -} - -export interface IPushDataNodeExecuteAfter { - data: ITaskData; - executionId: string; - nodeName: string; -} - -export interface IPushDataNodeExecuteBefore { - executionId: string; - nodeName: string; -} - -export interface IPushDataReloadNodeType { - name: string; - version: number; -} -export interface IPushDataRemoveNodeType { - name: string; - version: number; -} - -export interface IPushDataTestWebhook { - executionId: string; - workflowId: string; -} - -export interface IPushDataConsoleMessage { - source: string; - messages: string[]; -} - -export interface WorkerJobStatusSummary { - jobId: string; - executionId: string; - retryOf?: string; - startedAt: Date; - mode: WorkflowExecuteMode; - workflowName: string; - workflowId: string; - status: ExecutionStatus; -} - -export interface IPushDataWorkerStatusPayload { - workerId: string; - runningJobsSummary: WorkerJobStatusSummary[]; - freeMem: number; - totalMem: number; - uptime: number; - loadAvg: number[]; - cpus: string; - arch: string; - platform: NodeJS.Platform; - hostname: string; - interfaces: Array<{ - family: 'IPv4' | 'IPv6'; - address: string; - internal: boolean; - }>; - version: string; -} - -export interface IPushDataWorkerStatusMessage { - workerId: string; - status: IPushDataWorkerStatusPayload; -} - export type IPersonalizationSurveyAnswersV1 = { codingSkill?: string | null; companyIndustry?: string[] | null; diff --git a/packages/editor-ui/src/components/WorkerList.ee.vue b/packages/editor-ui/src/components/WorkerList.ee.vue index bbae452b05020f..45a3d90a3b9b5e 100644 --- a/packages/editor-ui/src/components/WorkerList.ee.vue +++ b/packages/editor-ui/src/components/WorkerList.ee.vue @@ -1,17 +1,18 @@