refactor(core): Lintfix core and workflow packages (#17096)

This commit is contained in:
Iván Ovejero
2025-07-08 13:04:50 +02:00
committed by GitHub
parent 1a4e4c5e72
commit d6b646d8cf
27 changed files with 47 additions and 86 deletions

View File

@@ -11,13 +11,6 @@ import tseslint from 'typescript-eslint';
import eslintConfigPrettier from 'eslint-config-prettier/flat'; import eslintConfigPrettier from 'eslint-config-prettier/flat';
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript'; import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
// Slowest rules are disabled locally (for lint, not lintfix) to improve performance in development
// They are enabled in CI to ensure code quality
const runAllRules =
process.env.CI === 'true' ||
process.env.INCLUDE_SLOW_RULES === 'true' ||
process.argv.includes('--fix');
export const baseConfig = tseslint.config( export const baseConfig = tseslint.config(
globalIgnores([ globalIgnores([
'node_modules/**', 'node_modules/**',
@@ -110,7 +103,7 @@ export const baseConfig = tseslint.config(
'@typescript-eslint/array-type': ['error', { default: 'array-simple' }], '@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
/** https://typescript-eslint.io/rules/await-thenable/ */ /** https://typescript-eslint.io/rules/await-thenable/ */
'@typescript-eslint/await-thenable': runAllRules ? 'error' : 'off', '@typescript-eslint/await-thenable': 'error',
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-ts-comment.md * https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-ts-comment.md
@@ -230,16 +223,12 @@ export const baseConfig = tseslint.config(
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-misused-promises.md * https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-misused-promises.md
*/ */
'@typescript-eslint/no-misused-promises': runAllRules '@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }],
? ['error', { checksVoidReturn: false }]
: 'off',
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/v4.30.0/packages/eslint-plugin/docs/rules/no-floating-promises.md * https://github.com/typescript-eslint/typescript-eslint/blob/v4.30.0/packages/eslint-plugin/docs/rules/no-floating-promises.md
*/ */
'@typescript-eslint/no-floating-promises': runAllRules '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
? ['error', { ignoreVoid: true }]
: 'off',
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/v4.33.0/packages/eslint-plugin/docs/rules/no-namespace.md * https://github.com/typescript-eslint/typescript-eslint/blob/v4.33.0/packages/eslint-plugin/docs/rules/no-namespace.md
@@ -259,7 +248,7 @@ export const baseConfig = tseslint.config(
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md * https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unnecessary-qualifier.md
*/ */
'@typescript-eslint/no-unnecessary-qualifier': runAllRules ? 'error' : 'off', '@typescript-eslint/no-unnecessary-qualifier': 'error',
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-expressions.md * https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-expressions.md
@@ -279,7 +268,7 @@ export const baseConfig = tseslint.config(
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/promise-function-async.md * https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/promise-function-async.md
*/ */
'@typescript-eslint/promise-function-async': runAllRules ? 'error' : 'off', '@typescript-eslint/promise-function-async': 'error',
/** /**
* https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/triple-slash-reference.md * https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/triple-slash-reference.md
@@ -303,7 +292,7 @@ export const baseConfig = tseslint.config(
/** /**
* https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md * https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md
*/ */
'import-x/no-cycle': runAllRules ? ['error', { ignoreExternal: false, maxDepth: 3 }] : 'off', 'import-x/no-cycle': ['error', { ignoreExternal: false, maxDepth: 3 }],
/** /**
* https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-default-export.md * https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-default-export.md

View File

@@ -34,7 +34,7 @@ describe('NodeExecutionContext', () => {
timezone: 'UTC', timezone: 'UTC',
expression, expression,
}); });
let additionalData = mock<IWorkflowExecuteAdditionalData>({ const additionalData = mock<IWorkflowExecuteAdditionalData>({
credentialsHelper: mock(), credentialsHelper: mock(),
}); });

View File

@@ -14,8 +14,8 @@ import type {
INodeTypes, INodeTypes,
ICredentialDataDecryptedObject, ICredentialDataDecryptedObject,
NodeConnectionType, NodeConnectionType,
IRunData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { IRunData } from 'n8n-workflow';
import { ApplicationError, NodeConnectionTypes } from 'n8n-workflow'; import { ApplicationError, NodeConnectionTypes } from 'n8n-workflow';
import { describeCommonTests } from './shared-tests'; import { describeCommonTests } from './shared-tests';

View File

@@ -12,8 +12,8 @@ import type {
INodeTypes, INodeTypes,
IExecuteFunctions, IExecuteFunctions,
IRunData, IRunData,
ITaskData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import type { ITaskData } from 'n8n-workflow';
import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow'; import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
import { ExecuteContext } from '../../execute-context'; import { ExecuteContext } from '../../execute-context';

View File

@@ -187,7 +187,7 @@ export async function copyBinaryFile(
* Takes a buffer and converts it into the format n8n uses. It encodes the binary data as * Takes a buffer and converts it into the format n8n uses. It encodes the binary data as
* base64 and adds metadata. * base64 and adds metadata.
*/ */
// eslint-disable-next-line complexity
export async function prepareBinaryData( export async function prepareBinaryData(
binaryData: Buffer | Readable, binaryData: Buffer | Readable,
executionId: string, executionId: string,

View File

@@ -5,7 +5,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-shadow */
import { Logger } from '@n8n/backend-common'; import { Logger } from '@n8n/backend-common';
import type { import type {
ClientOAuth2Options, ClientOAuth2Options,
@@ -227,11 +227,10 @@ const getBeforeRedirectFn =
axiosConfig: AxiosRequestConfig, axiosConfig: AxiosRequestConfig,
proxyConfig: IHttpRequestOptions['proxy'] | string | undefined, proxyConfig: IHttpRequestOptions['proxy'] | string | undefined,
) => ) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(redirectedRequest: Record<string, any>) => { (redirectedRequest: Record<string, any>) => {
const redirectAgentOptions = { const redirectAgentOptions = {
...agentOptions, ...agentOptions,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
servername: redirectedRequest.hostname, servername: redirectedRequest.hostname,
}; };
const redirectAgent = getAgentWithProxy({ const redirectAgent = getAgentWithProxy({
@@ -248,7 +247,6 @@ const getBeforeRedirectFn =
} }
if (axiosConfig.headers?.Authorization) { if (axiosConfig.headers?.Authorization) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
redirectedRequest.headers.Authorization = axiosConfig.headers.Authorization; redirectedRequest.headers.Authorization = axiosConfig.headers.Authorization;
} }
if (axiosConfig.auth) { if (axiosConfig.auth) {
@@ -327,11 +325,8 @@ export async function invokeAxios(
} }
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pushFormDataValue = (form: FormData, key: string, value: any) => { const pushFormDataValue = (form: FormData, key: string, value: any) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
if (value?.hasOwnProperty('value') && value.hasOwnProperty('options')) { if (value?.hasOwnProperty('value') && value.hasOwnProperty('options')) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
form.append(key, value.value, value.options); form.append(key, value.value, value.options);
} else { } else {
form.append(key, value); form.append(key, value);
@@ -361,7 +356,6 @@ async function generateContentLengthHeader(config: AxiosRequestConfig) {
} }
try { try {
const length = await new Promise<number>((res, rej) => { const length = await new Promise<number>((res, rej) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
config.data.getLength((error: Error | null, dataLength: number) => { config.data.getLength((error: Error | null, dataLength: number) => {
if (error) rej(error); if (error) rej(error);
else res(dataLength); else res(dataLength);
@@ -372,7 +366,6 @@ async function generateContentLengthHeader(config: AxiosRequestConfig) {
'content-length': length, 'content-length': length,
}; };
} catch (error) { } catch (error) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Container.get(Logger).error('Unable to calculate form data length', { error }); Container.get(Logger).error('Unable to calculate form data length', { error });
} }
} }
@@ -416,7 +409,6 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
if (typeof requestObject.body === 'string') { if (typeof requestObject.body === 'string') {
axiosConfig.data = requestObject.body; axiosConfig.data = requestObject.body;
} else { } else {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const allData = Object.assign(requestObject.body || {}, requestObject.form || {}) as Record< const allData = Object.assign(requestObject.body || {}, requestObject.form || {}) as Record<
string, string,
string string
@@ -441,9 +433,9 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
// replace the existing header with a new one that // replace the existing header with a new one that
// contains the boundary property. // contains the boundary property.
delete axiosConfig.headers?.[contentTypeHeaderKeyName!]; delete axiosConfig.headers?.[contentTypeHeaderKeyName!];
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
const headers = axiosConfig.data.getHeaders(); const headers = axiosConfig.data.getHeaders();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/prefer-nullish-coalescing
axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers); axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers);
await generateContentLengthHeader(axiosConfig); await generateContentLengthHeader(axiosConfig);
} else { } else {
@@ -482,16 +474,16 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
axiosConfig.data = createFormDataObject(requestObject.formData as Record<string, unknown>); axiosConfig.data = createFormDataObject(requestObject.formData as Record<string, unknown>);
} }
// Mix in headers as FormData creates the boundary. // Mix in headers as FormData creates the boundary.
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const headers = axiosConfig.data.getHeaders(); const headers = axiosConfig.data.getHeaders();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/prefer-nullish-coalescing
axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers); axiosConfig.headers = Object.assign(axiosConfig.headers || {}, headers);
await generateContentLengthHeader(axiosConfig); await generateContentLengthHeader(axiosConfig);
} else if (requestObject.body !== undefined) { } else if (requestObject.body !== undefined) {
// If we have body and possibly form // If we have body and possibly form
if (requestObject.form !== undefined && requestObject.body) { if (requestObject.form !== undefined && requestObject.body) {
// merge both objects when exist. // merge both objects when exist.
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
requestObject.body = Object.assign(requestObject.body, requestObject.form); requestObject.body = Object.assign(requestObject.body, requestObject.form);
} }
axiosConfig.data = requestObject.body as FormData | GenericValue | GenericValue[]; axiosConfig.data = requestObject.body as FormData | GenericValue | GenericValue[];
@@ -559,7 +551,6 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
if (requestObject.auth !== undefined) { if (requestObject.auth !== undefined) {
// Check support for sendImmediately // Check support for sendImmediately
if (requestObject.auth.bearer !== undefined) { if (requestObject.auth.bearer !== undefined) {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
Authorization: `Bearer ${requestObject.auth.bearer}`, Authorization: `Bearer ${requestObject.auth.bearer}`,
}); });
@@ -567,9 +558,8 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
const authObj = requestObject.auth; const authObj = requestObject.auth;
// Request accepts both user/username and pass/password // Request accepts both user/username and pass/password
axiosConfig.auth = { axiosConfig.auth = {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
username: (authObj.user || authObj.username) as string, username: (authObj.user || authObj.username) as string,
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
password: (authObj.password || authObj.pass) as string, password: (authObj.password || authObj.pass) as string,
}; };
} }
@@ -586,7 +576,6 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
.map((headerKey) => headerKey.toLowerCase()) .map((headerKey) => headerKey.toLowerCase())
.includes('accept'); .includes('accept');
if (!acceptHeaderExists) { if (!acceptHeaderExists) {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
Accept: 'application/json', Accept: 'application/json',
}); });
@@ -594,7 +583,7 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
} }
if (requestObject.json === false || requestObject.json === undefined) { if (requestObject.json === false || requestObject.json === undefined) {
// Prevent json parsing // Prevent json parsing
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
axiosConfig.transformResponse = (res) => res; axiosConfig.transformResponse = (res) => res;
} }
@@ -647,7 +636,6 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
// as the service returns XML unless requested otherwise. // as the service returns XML unless requested otherwise.
const allHeaders = axiosConfig.headers ? Object.keys(axiosConfig.headers) : []; const allHeaders = axiosConfig.headers ? Object.keys(axiosConfig.headers) : [];
if (!allHeaders.some((headerKey) => headerKey.toLowerCase() === 'accept')) { if (!allHeaders.some((headerKey) => headerKey.toLowerCase() === 'accept')) {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { accept: '*/*' }); axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { accept: '*/*' });
} }
if ( if (
@@ -661,7 +649,7 @@ export async function parseRequestObject(requestObject: IRequestOptions) {
// If we don't specify this here, axios will add // If we don't specify this here, axios will add
// application/json; charset=utf-8 // application/json; charset=utf-8
// and this breaks a lot of stuff // and this breaks a lot of stuff
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
axiosConfig.headers = Object.assign(axiosConfig.headers || {}, { axiosConfig.headers = Object.assign(axiosConfig.headers || {}, {
'content-type': 'application/json', 'content-type': 'application/json',
}); });
@@ -771,7 +759,6 @@ export async function proxyRequestToAxios(
} }
} }
// eslint-disable-next-line complexity
export function convertN8nRequestToAxios(n8nRequest: IHttpRequestOptions): AxiosRequestConfig { export function convertN8nRequestToAxios(n8nRequest: IHttpRequestOptions): AxiosRequestConfig {
// Destructure properties with the same name first. // Destructure properties with the same name first.
const { headers, method, timeout, auth, proxy, url } = n8nRequest; const { headers, method, timeout, auth, proxy, url } = n8nRequest;

View File

@@ -40,7 +40,7 @@ const validateResourceMapperValue = (
for (let i = 0; i < paramValueNames.length; i++) { for (let i = 0; i < paramValueNames.length; i++) {
const key = paramValueNames[i]; const key = paramValueNames[i];
const resolvedValue = paramValues[key]; const resolvedValue = paramValues[key];
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const schemaEntry = schema.find((s) => s.id === key); const schemaEntry = schema.find((s) => s.id === key);
if ( if (

View File

@@ -7,8 +7,8 @@
// 1 means the output has run data // 1 means the output has run data
// PD denotes that the node has pinned data // PD denotes that the node has pinned data
import type { IPinData } from 'n8n-workflow'; import type { IPinData, IRunData } from 'n8n-workflow';
import { NodeConnectionTypes, type IRunData } from 'n8n-workflow'; import { NodeConnectionTypes } from 'n8n-workflow';
import { createNodeData, toITaskData } from './helpers'; import { createNodeData, toITaskData } from './helpers';
import { DirectedGraph } from '../directed-graph'; import { DirectedGraph } from '../directed-graph';

View File

@@ -15,8 +15,10 @@ import type {
ISourceData, ISourceData,
IWaitingForExecution, IWaitingForExecution,
IWaitingForExecutionSource, IWaitingForExecutionSource,
IPinData,
IRunData,
} from 'n8n-workflow'; } from 'n8n-workflow';
import { NodeConnectionTypes, type IPinData, type IRunData } from 'n8n-workflow'; import { NodeConnectionTypes } from 'n8n-workflow';
import { createNodeData, toITaskData } from './helpers'; import { createNodeData, toITaskData } from './helpers';
import { DirectedGraph } from '../directed-graph'; import { DirectedGraph } from '../directed-graph';

View File

@@ -124,12 +124,12 @@ export class DirectedGraph {
const newConnections: GraphConnection[] = []; const newConnections: GraphConnection[] = [];
for (const incomingConnection of incomingConnections) { for (const incomingConnection of incomingConnections) {
if (options.skipConnectionFn && options.skipConnectionFn(incomingConnection)) { if (options.skipConnectionFn?.(incomingConnection)) {
continue; continue;
} }
for (const outgoingConnection of outgoingConnections) { for (const outgoingConnection of outgoingConnections) {
if (options.skipConnectionFn && options.skipConnectionFn(outgoingConnection)) { if (options.skipConnectionFn?.(outgoingConnection)) {
continue; continue;
} }

View File

@@ -123,7 +123,6 @@ export function getSourceDataGroups(
currentInputIndex++; currentInputIndex++;
const connectionWithDataIndex = sortedConnectionsWithData.findIndex( const connectionWithDataIndex = sortedConnectionsWithData.findIndex(
// eslint-disable-next-line @typescript-eslint/no-loop-func
(c) => c.inputIndex === currentInputIndex, (c) => c.inputIndex === currentInputIndex,
); );
@@ -137,7 +136,6 @@ export function getSourceDataGroups(
} }
const connectionWithoutDataIndex = sortedConnectionsWithoutData.findIndex( const connectionWithoutDataIndex = sortedConnectionsWithoutData.findIndex(
// eslint-disable-next-line @typescript-eslint/no-loop-func
(c) => c.inputIndex === currentInputIndex, (c) => c.inputIndex === currentInputIndex,
); );

View File

@@ -1178,7 +1178,6 @@ export class WorkflowExecute {
const newInputData: ITaskDataConnections = {}; const newInputData: ITaskDataConnections = {};
for (const connectionType of Object.keys(inputData)) { for (const connectionType of Object.keys(inputData)) {
newInputData[connectionType] = inputData[connectionType].map((input) => { newInputData[connectionType] = inputData[connectionType].map((input) => {
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
return input && input.slice(0, 1); return input && input.slice(0, 1);
}); });
} }
@@ -1558,7 +1557,7 @@ export class WorkflowExecute {
if (waitBetweenTries !== 0) { if (waitBetweenTries !== 0) {
// TODO: Improve that in the future and check if other nodes can // TODO: Improve that in the future and check if other nodes can
// be executed in the meantime // be executed in the meantime
// eslint-disable-next-line @typescript-eslint/no-shadow
await new Promise((resolve) => { await new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
resolve(undefined); resolve(undefined);
@@ -1767,14 +1766,11 @@ export class WorkflowExecute {
lineResult.json.$error !== undefined && lineResult.json.$error !== undefined &&
lineResult.json.$json !== undefined lineResult.json.$json !== undefined
) { ) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
lineResult.error = lineResult.json.$error as NodeApiError | NodeOperationError; lineResult.error = lineResult.json.$error as NodeApiError | NodeOperationError;
lineResult.json = { lineResult.json = {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
error: (lineResult.json.$error as NodeApiError | NodeOperationError).message, error: (lineResult.json.$error as NodeApiError | NodeOperationError).message,
}; };
} else if (lineResult.error !== undefined) { } else if (lineResult.error !== undefined) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
lineResult.json = { error: lineResult.error.message }; lineResult.json = { error: lineResult.error.message };
} }
} }
@@ -1986,7 +1982,7 @@ export class WorkflowExecute {
const parentNodes = workflow.getParentNodes(nodeName); const parentNodes = workflow.getParentNodes(nodeName);
// Check if input nodes (of same run) got already executed // Check if input nodes (of same run) got already executed
// eslint-disable-next-line @typescript-eslint/no-loop-func
const parentIsWaiting = parentNodes.some((value) => waitingNodes.includes(value)); const parentIsWaiting = parentNodes.some((value) => waitingNodes.includes(value));
if (parentIsWaiting) { if (parentIsWaiting) {
// Execute node later as one of its dependencies is still outstanding // Execute node later as one of its dependencies is still outstanding
@@ -2127,12 +2123,11 @@ export class WorkflowExecute {
this.moveNodeMetadata(); this.moveNodeMetadata();
await hooks.runHook('workflowExecuteAfter', [fullRunData, newStaticData]).catch( await hooks
// eslint-disable-next-line @typescript-eslint/no-shadow .runHook('workflowExecuteAfter', [fullRunData, newStaticData])
(error) => { .catch((error) => {
console.error('There was a problem running hook "workflowExecuteAfter"', error); console.error('There was a problem running hook "workflowExecuteAfter"', error);
}, });
);
if (closeFunction) { if (closeFunction) {
try { try {

View File

@@ -9,7 +9,7 @@ export const loadClassInIsolation = <T>(filePath: string, className: string) =>
// Note: Skip the isolation because it breaks nock mocks in tests // Note: Skip the isolation because it breaks nock mocks in tests
if (inTest) { if (inTest) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
return new (require(filePath)[className])() as T; return new (require(filePath)[className])() as T;
} else { } else {
const script = new Script(`new (require('${filePath}').${className})()`); const script = new Script(`new (require('${filePath}').${className})()`);

View File

@@ -1,4 +1,3 @@
/* eslint-disable complexity */
const check = ( const check = (
val: unknown, val: unknown,
path = 'value', path = 'value',

View File

@@ -12,10 +12,8 @@ function augment<T>(value: T): T {
if (value instanceof Date) return new Date(value.valueOf()) as T; if (value instanceof Date) return new Date(value.valueOf()) as T;
if (value instanceof Uint8Array) return value.slice() as T; if (value instanceof Uint8Array) return value.slice() as T;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
if (Array.isArray(value)) return augmentArray(value) as T; if (Array.isArray(value)) return augmentArray(value) as T;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return augmentObject(value) as T; return augmentObject(value) as T;
} }

View File

@@ -94,7 +94,7 @@ export abstract class NodeError extends ExecutionBaseError {
if (typeof value === 'number') return value.toString(); if (typeof value === 'number') return value.toString();
if (Array.isArray(value)) { if (Array.isArray(value)) {
const resolvedErrors: string[] = value const resolvedErrors: string[] = value
// eslint-disable-next-line @typescript-eslint/no-shadow
.map((jsonError) => { .map((jsonError) => {
if (typeof jsonError === 'string') return jsonError; if (typeof jsonError === 'string') return jsonError;
if (typeof jsonError === 'number') return jsonError.toString(); if (typeof jsonError === 'number') return jsonError.toString();

View File

@@ -1,5 +1,5 @@
import { ExecutionBaseError } from './abstract/execution-base.error';
import type { IDataObject } from '../interfaces'; import type { IDataObject } from '../interfaces';
import { ExecutionBaseError } from './abstract/execution-base.error';
export interface ExpressionErrorOptions { export interface ExpressionErrorOptions {
cause?: Error; cause?: Error;

View File

@@ -1,5 +1,5 @@
import { ExecutionBaseError } from './abstract/execution-base.error';
import type { INode } from '../interfaces'; import type { INode } from '../interfaces';
import { ExecutionBaseError } from './abstract/execution-base.error';
/** /**
* Class for instantiating an operational error, e.g. a timeout error. * Class for instantiating an operational error, e.g. a timeout error.

View File

@@ -14,7 +14,6 @@ export const PrototypeSanitizer: ASTAfterHook = (ast, dataNode) => {
if (!node.computed) { if (!node.computed) {
// This is static, so we're safe to error here // This is static, so we're safe to error here
if (node.property.type !== 'Identifier') { if (node.property.type !== 'Identifier') {
// eslint-disable-next-line n8n-local-rules/no-plain-errors
throw new ExpressionError( throw new ExpressionError(
`Unknown property type ${node.property.type} while sanitising expression`, `Unknown property type ${node.property.type} while sanitising expression`,
); );

View File

@@ -5,6 +5,7 @@ import { ExpressionExtensionError } from './errors/expression-extension.error';
import { ExpressionError } from './errors/expression.error'; import { ExpressionError } from './errors/expression.error';
import { evaluateExpression, setErrorHandler } from './expression-evaluator-proxy'; import { evaluateExpression, setErrorHandler } from './expression-evaluator-proxy';
import { sanitizer, sanitizerName } from './expression-sandboxing'; import { sanitizer, sanitizerName } from './expression-sandboxing';
import { isExpression } from './expressions/expression-helpers';
import { extend, extendOptional } from './extensions'; import { extend, extendOptional } from './extensions';
import { extendSyntax } from './extensions/expression-extension'; import { extendSyntax } from './extensions/expression-extension';
import { extendedFunctions } from './extensions/extended-functions'; import { extendedFunctions } from './extensions/extended-functions';
@@ -25,7 +26,6 @@ import type {
} from './interfaces'; } from './interfaces';
import type { Workflow } from './workflow'; import type { Workflow } from './workflow';
import { WorkflowDataProxy } from './workflow-data-proxy'; import { WorkflowDataProxy } from './workflow-data-proxy';
import { isExpression } from './expressions/expression-helpers';
const IS_FRONTEND_IN_DEV_MODE = const IS_FRONTEND_IN_DEV_MODE =
typeof process === 'object' && typeof process === 'object' &&

View File

@@ -136,7 +136,6 @@ export const extendTransform = (expression: string): { code: string } | undefine
// This is to match behavior in our original expression evaluator (tmpl) // This is to match behavior in our original expression evaluator (tmpl)
const globalIdentifier = types.builders.identifier( const globalIdentifier = types.builders.identifier(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
typeof window !== 'object' ? 'global' : 'window', typeof window !== 'object' ? 'global' : 'window',
); );
// We want to define all of our commonly used identifiers and member // We want to define all of our commonly used identifiers and member

View File

@@ -893,7 +893,7 @@ type BaseExecutionFunctions = FunctionsBaseWithRequiredKeys<'getMode'> & {
getInputSourceData(inputIndex?: number, connectionType?: NodeConnectionType): ISourceData; getInputSourceData(inputIndex?: number, connectionType?: NodeConnectionType): ISourceData;
getExecutionCancelSignal(): AbortSignal | undefined; getExecutionCancelSignal(): AbortSignal | undefined;
onExecutionCancellation(handler: () => unknown): void; onExecutionCancellation(handler: () => unknown): void;
logAiEvent(eventName: AiEvent, msg?: string | undefined): void; logAiEvent(eventName: AiEvent, msg?: string): void;
}; };
// TODO: Create later own type only for Config-Nodes // TODO: Create later own type only for Config-Nodes
@@ -1002,7 +1002,7 @@ export type ISupplyDataFunctions = ExecuteFunctions.GetNodeParameterFn &
getWorkflowDataProxy(itemIndex: number): IWorkflowDataProxyData; getWorkflowDataProxy(itemIndex: number): IWorkflowDataProxyData;
getExecutionCancelSignal(): AbortSignal | undefined; getExecutionCancelSignal(): AbortSignal | undefined;
onExecutionCancellation(handler: () => unknown): void; onExecutionCancellation(handler: () => unknown): void;
logAiEvent(eventName: AiEvent, msg?: string | undefined): void; logAiEvent(eventName: AiEvent, msg?: string): void;
cloneWith(replacements: { cloneWith(replacements: {
runIndex: number; runIndex: number;
inputData: INodeExecutionData[][]; inputData: INodeExecutionData[][];
@@ -1551,7 +1551,7 @@ export interface INodePropertyValueExtractorFunction {
( (
this: IExecuteSingleFunctions, this: IExecuteSingleFunctions,
value: string | NodeParameterValue, value: string | NodeParameterValue,
): Promise<string | NodeParameterValue> | (string | NodeParameterValue); ): Promise<string | NodeParameterValue> | string;
} }
export type INodePropertyValueExtractor = INodePropertyValueExtractorRegex; export type INodePropertyValueExtractor = INodePropertyValueExtractorRegex;

View File

@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
/* eslint-disable prefer-spread */ /* eslint-disable prefer-spread */
@@ -840,7 +840,6 @@ export function getNodeParameters(
itemName itemName
] as INodeParameters[]) { ] as INodeParameters[]) {
nodePropertyOptions = nodeProperties.options!.find( nodePropertyOptions = nodeProperties.options!.find(
// eslint-disable-next-line @typescript-eslint/no-shadow
(nodePropertyOptions) => nodePropertyOptions.name === itemName, (nodePropertyOptions) => nodePropertyOptions.name === itemName,
) as INodePropertyCollection; ) as INodePropertyCollection;
@@ -875,7 +874,7 @@ export function getNodeParameters(
tempNodeParameters = {}; tempNodeParameters = {};
// Get the options of the current item // Get the options of the current item
// eslint-disable-next-line @typescript-eslint/no-shadow
const nodePropertyOptions = nodeProperties.options!.find( const nodePropertyOptions = nodeProperties.options!.find(
(data) => data.name === itemName, (data) => data.name === itemName,
); );

View File

@@ -60,7 +60,6 @@ const withIndefiniteArticle = (noun: string): string => {
return `${article} ${noun}`; return `${article} ${noun}`;
}; };
// eslint-disable-next-line complexity
function parseFilterConditionValues( function parseFilterConditionValues(
condition: FilterConditionValue, condition: FilterConditionValue,
options: FilterOptionsValue, options: FilterOptionsValue,

View File

@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-shadow */
import type { IDataObject, IObservableObject } from './interfaces'; import type { IDataObject, IObservableObject } from './interfaces';

View File

@@ -1030,7 +1030,7 @@ export class WorkflowDataProxy {
const placeholdersDataInputData = const placeholdersDataInputData =
inputData?.[NodeConnectionTypes.AiTool]?.[0]?.[itemIndex].json; inputData?.[NodeConnectionTypes.AiTool]?.[0]?.[itemIndex].json;
if (Boolean(!placeholdersDataInputData)) { if (!placeholdersDataInputData) {
throw new ExpressionError('No execution data available', { throw new ExpressionError('No execution data available', {
runIndex, runIndex,
itemIndex, itemIndex,

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-for-in-array */ /* eslint-disable @typescript-eslint/no-for-in-array */
@@ -534,7 +533,7 @@ export class Workflow {
} }
connectionsByIndex = connectionsByIndex =
this.connectionsByDestinationNode[nodeName][NodeConnectionTypes.Main][connectionIndex]; this.connectionsByDestinationNode[nodeName][NodeConnectionTypes.Main][connectionIndex];
// eslint-disable-next-line @typescript-eslint/no-loop-func
connectionsByIndex?.forEach((connection) => { connectionsByIndex?.forEach((connection) => {
if (checkedNodes.includes(connection.node)) { if (checkedNodes.includes(connection.node)) {
// Node got checked already before // Node got checked already before
@@ -730,7 +729,6 @@ export class Workflow {
const toAdd = [...queue]; const toAdd = [...queue];
queue = []; queue = [];
// eslint-disable-next-line @typescript-eslint/no-loop-func
toAdd.forEach((curr) => { toAdd.forEach((curr) => {
if (visited[curr.name]) { if (visited[curr.name]) {
visited[curr.name].indicies = dedupe(visited[curr.name].indicies.concat(curr.indicies)); visited[curr.name].indicies = dedupe(visited[curr.name].indicies.concat(curr.indicies));
@@ -770,7 +768,7 @@ export class Workflow {
const outputs = NodeHelpers.getNodeOutputs(this, node, nodeType.description); const outputs = NodeHelpers.getNodeOutputs(this, node, nodeType.description);
if ( if (
!!outputs.find( outputs.find(
(output) => (output) =>
((output as INodeOutputConfiguration)?.type ?? output) !== NodeConnectionTypes.Main, ((output as INodeOutputConfiguration)?.type ?? output) !== NodeConnectionTypes.Main,
) )