From 5eb1eb88e4f5aab7321c9545292a434d6affd250 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: Fri, 21 Oct 2022 11:38:56 +0200 Subject: [PATCH] fix(core): delete some of the redundant code in core (#4359) --- packages/core/src/Interfaces.ts | 64 ++++----- packages/core/src/LoadNodeDetails.ts | 82 +++++++++++ packages/core/src/LoadNodeListSearch.ts | 117 ++-------------- packages/core/src/LoadNodeParameterOptions.ts | 127 +++--------------- 4 files changed, 131 insertions(+), 259 deletions(-) create mode 100644 packages/core/src/LoadNodeDetails.ts diff --git a/packages/core/src/Interfaces.ts b/packages/core/src/Interfaces.ts index 783f1068fa..d0ec2f024a 100644 --- a/packages/core/src/Interfaces.ts +++ b/packages/core/src/Interfaces.ts @@ -4,7 +4,6 @@ import { IAllExecuteFunctions, IBinaryData, ICredentialTestFunctions as ICredentialTestFunctionsBase, - ICredentialType, IDataObject, IExecuteFunctions as IExecuteFunctionsBase, IExecuteSingleFunctions as IExecuteSingleFunctionsBase, @@ -12,7 +11,6 @@ import { IHttpRequestOptions, ILoadOptionsFunctions as ILoadOptionsFunctionsBase, INodeExecutionData, - INodeType, IOAuth2Options, IPairedItemData, IPollFunctions as IPollFunctionsBase, @@ -24,12 +22,8 @@ import { NodeExecutionWithMetadata, } from 'n8n-workflow'; -import { OptionsWithUri, OptionsWithUrl } from 'request'; -import requestPromise from 'request-promise-native'; - -interface Constructable { - new (): T; -} +import type { OptionsWithUri, OptionsWithUrl } from 'request'; +import type { RequestPromiseAPI, RequestPromiseOptions } from 'request-promise-native'; export interface IProcessMessage { data?: any; @@ -50,19 +44,19 @@ export interface IExecuteFunctions extends IExecuteFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ): Promise; // tslint:disable-line:no-any requestOAuth1( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[]; normalizeItems(items: INodeExecutionData | INodeExecutionData[]): INodeExecutionData[]; @@ -92,19 +86,19 @@ export interface IExecuteSingleFunctions extends IExecuteSingleFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ): Promise; // tslint:disable-line:no-any requestOAuth1( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any httpRequestWithAuthentication( this: IAllExecuteFunctions, @@ -126,19 +120,19 @@ export interface IPollFunctions extends IPollFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ): Promise; // tslint:disable-line:no-any requestOAuth1( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[]; httpRequestWithAuthentication( @@ -165,19 +159,19 @@ export interface ITriggerFunctions extends ITriggerFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ): Promise; // tslint:disable-line:no-any requestOAuth1( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[]; httpRequestWithAuthentication( @@ -201,19 +195,19 @@ export interface ILoadOptionsFunctions extends ILoadOptionsFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2?: ( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ) => Promise; // tslint:disable-line:no-any requestOAuth1?( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any httpRequestWithAuthentication( this: IAllExecuteFunctions, @@ -225,7 +219,7 @@ export interface ILoadOptionsFunctions extends ILoadOptionsFunctionsBase { export interface ICredentialTestFunctions extends ICredentialTestFunctionsBase { helpers: { - request: requestPromise.RequestPromiseAPI; + request: RequestPromiseAPI; }; } @@ -236,19 +230,19 @@ export interface IHookFunctions extends IHookFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ): Promise; // tslint:disable-line:no-any requestOAuth1( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any httpRequestWithAuthentication( this: IAllExecuteFunctions, @@ -270,19 +264,19 @@ export interface IWebhookFunctions extends IWebhookFunctionsBase { requestWithAuthentication( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, additionalCredentialOptions?: IAdditionalCredentialOptions, ): Promise; requestOAuth2( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUri | RequestPromiseOptions, oAuth2Options?: IOAuth2Options, ): Promise; // tslint:disable-line:no-any requestOAuth1( this: IAllExecuteFunctions, credentialsType: string, - requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions, + requestOptions: OptionsWithUrl | RequestPromiseOptions, ): Promise; // tslint:disable-line:no-any returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[]; httpRequestWithAuthentication( @@ -299,16 +293,6 @@ export interface IWorkflowSettings extends IWorkflowSettingsWorkflow { saveManualRuns?: boolean; } -// New node definition in file -export interface INodeDefinitionFile { - [key: string]: Constructable; -} - -// Is identical to TaskDataConnections but does not allow null value to be used as input for nodes -export interface INodeInputDataConnections { - [key: string]: INodeExecutionData[][]; -} - export interface IWorkflowData { pollResponses?: IPollResponse[]; triggerResponses?: ITriggerResponse[]; diff --git a/packages/core/src/LoadNodeDetails.ts b/packages/core/src/LoadNodeDetails.ts new file mode 100644 index 0000000000..582183b987 --- /dev/null +++ b/packages/core/src/LoadNodeDetails.ts @@ -0,0 +1,82 @@ +import type { + INode, + INodeCredentials, + INodeParameters, + INodeTypeNameVersion, + INodeTypes, +} from 'n8n-workflow'; +import { Workflow } from 'n8n-workflow'; + +const TEMP_NODE_NAME = 'Temp-Node'; +const TEMP_WORKFLOW_NAME = 'Temp-Workflow'; + +export abstract class LoadNodeDetails { + path: string; + + workflow: Workflow; + + constructor( + nodeTypeNameAndVersion: INodeTypeNameVersion, + nodeTypes: INodeTypes, + path: string, + currentNodeParameters: INodeParameters, + credentials?: INodeCredentials, + ) { + const nodeType = nodeTypes.getByNameAndVersion( + nodeTypeNameAndVersion.name, + nodeTypeNameAndVersion.version, + ); + + this.path = path; + + if (nodeType === undefined) { + throw new Error( + `The node-type "${nodeTypeNameAndVersion.name} v${nodeTypeNameAndVersion.version}" is not known!`, + ); + } + + const nodeData: INode = { + parameters: currentNodeParameters, + id: 'uuid-1234', + name: TEMP_NODE_NAME, + type: nodeTypeNameAndVersion.name, + typeVersion: nodeTypeNameAndVersion.version, + position: [0, 0], + }; + + if (credentials) { + nodeData.credentials = credentials; + } + + const workflowData = { + nodes: [nodeData], + connections: {}, + }; + + this.workflow = new Workflow({ + nodes: workflowData.nodes, + connections: workflowData.connections, + active: false, + nodeTypes, + }); + } + + /** + * Returns data of a fake workflow + */ + getWorkflowData() { + return { + name: TEMP_WORKFLOW_NAME, + active: false, + connections: {}, + nodes: Object.values(this.workflow.nodes), + createdAt: new Date(), + updatedAt: new Date(), + }; + } + + protected getTempNode() { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this.workflow.getNode(TEMP_NODE_NAME)!; + } +} diff --git a/packages/core/src/LoadNodeListSearch.ts b/packages/core/src/LoadNodeListSearch.ts index f1f0313dcc..6676aa814f 100644 --- a/packages/core/src/LoadNodeListSearch.ts +++ b/packages/core/src/LoadNodeListSearch.ts @@ -1,104 +1,11 @@ -/* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import type { INodeListSearchResult, IWorkflowExecuteAdditionalData } from 'n8n-workflow'; -import { - INode, - INodeCredentials, - INodeListSearchResult, - INodeParameters, - INodeTypeNameVersion, - INodeTypes, - IWorkflowExecuteAdditionalData, - Workflow, -} from 'n8n-workflow'; - -// eslint-disable-next-line import/no-cycle import { NodeExecuteFunctions } from '.'; +import { LoadNodeDetails } from './LoadNodeDetails'; -const TEMP_NODE_NAME = 'Temp-Node'; -const TEMP_WORKFLOW_NAME = 'Temp-Workflow'; - -export class LoadNodeListSearch { - currentNodeParameters: INodeParameters; - - path: string; - - workflow: Workflow; - - constructor( - nodeTypeNameAndVersion: INodeTypeNameVersion, - nodeTypes: INodeTypes, - path: string, - currentNodeParameters: INodeParameters, - credentials?: INodeCredentials, - ) { - const nodeType = nodeTypes.getByNameAndVersion( - nodeTypeNameAndVersion.name, - nodeTypeNameAndVersion.version, - ); - this.currentNodeParameters = currentNodeParameters; - this.path = path; - if (nodeType === undefined) { - throw new Error( - `The node-type "${nodeTypeNameAndVersion.name} v${nodeTypeNameAndVersion.version}" is not known!`, - ); - } - - const nodeData: INode = { - parameters: currentNodeParameters, - id: 'uuid-1234', - name: TEMP_NODE_NAME, - type: nodeTypeNameAndVersion.name, - typeVersion: nodeTypeNameAndVersion.version, - position: [0, 0], - }; - if (credentials) { - nodeData.credentials = credentials; - } - - const workflowData = { - nodes: [nodeData], - connections: {}, - }; - - this.workflow = new Workflow({ - nodes: workflowData.nodes, - connections: workflowData.connections, - active: false, - nodeTypes, - }); - } - - /** - * Returns data of a fake workflow - * - * @returns - * @memberof LoadNodeParameterOptions - */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - getWorkflowData() { - return { - name: TEMP_WORKFLOW_NAME, - active: false, - connections: {}, - nodes: Object.values(this.workflow.nodes), - createdAt: new Date(), - updatedAt: new Date(), - }; - } - +export class LoadNodeListSearch extends LoadNodeDetails { /** * Returns the available options via a predefined method - * - * @param {string} methodName The name of the method of which to get the data from - * @param {IWorkflowExecuteAdditionalData} additionalData - * @returns {Promise} - * @memberof LoadNodeParameterOptions */ async getOptionsViaMethodName( methodName: string, @@ -106,28 +13,24 @@ export class LoadNodeListSearch { filter?: string, paginationToken?: string, ): Promise { - const node = this.workflow.getNode(TEMP_NODE_NAME); + const node = this.getTempNode(); - const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node!.type, node?.typeVersion); + const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion); + const method = nodeType?.methods?.listSearch?.[methodName]; - if ( - !nodeType || - nodeType.methods === undefined || - nodeType.methods.listSearch === undefined || - nodeType.methods.listSearch[methodName] === undefined - ) { + if (typeof method !== 'function') { throw new Error( - `The node-type "${node!.type}" does not have the method "${methodName}" defined!`, + `The node-type "${node.type}" does not have the method "${methodName}" defined!`, ); } const thisArgs = NodeExecuteFunctions.getLoadOptionsFunctions( this.workflow, - node!, + node, this.path, additionalData, ); - return nodeType.methods.listSearch[methodName].call(thisArgs, filter, paginationToken); + return method.call(thisArgs, filter, paginationToken); } } diff --git a/packages/core/src/LoadNodeParameterOptions.ts b/packages/core/src/LoadNodeParameterOptions.ts index e2ab207b9c..37781faff6 100644 --- a/packages/core/src/LoadNodeParameterOptions.ts +++ b/packages/core/src/LoadNodeParameterOptions.ts @@ -1,154 +1,59 @@ -/* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/restrict-template-expressions */ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ - import { ILoadOptions, - INode, - INodeCredentials, INodeExecutionData, - INodeParameters, INodeProperties, INodePropertyOptions, INodeType, - INodeTypeNameVersion, - INodeTypes, IRunExecutionData, ITaskDataConnections, IWorkflowExecuteAdditionalData, RoutingNode, - Workflow, } from 'n8n-workflow'; -// eslint-disable-next-line import/no-cycle import { NodeExecuteFunctions } from '.'; +import { LoadNodeDetails } from './LoadNodeDetails'; -const TEMP_NODE_NAME = 'Temp-Node'; -const TEMP_WORKFLOW_NAME = 'Temp-Workflow'; - -export class LoadNodeParameterOptions { - currentNodeParameters: INodeParameters; - - path: string; - - workflow: Workflow; - - constructor( - nodeTypeNameAndVersion: INodeTypeNameVersion, - nodeTypes: INodeTypes, - path: string, - currentNodeParameters: INodeParameters, - credentials?: INodeCredentials, - ) { - const nodeType = nodeTypes.getByNameAndVersion( - nodeTypeNameAndVersion.name, - nodeTypeNameAndVersion.version, - ); - this.currentNodeParameters = currentNodeParameters; - this.path = path; - if (nodeType === undefined) { - throw new Error( - `The node-type "${nodeTypeNameAndVersion.name} v${nodeTypeNameAndVersion.version}" is not known!`, - ); - } - - const nodeData: INode = { - parameters: currentNodeParameters, - id: 'uuid-1234', - name: TEMP_NODE_NAME, - type: nodeTypeNameAndVersion.name, - typeVersion: nodeTypeNameAndVersion.version, - position: [0, 0], - }; - if (credentials) { - nodeData.credentials = credentials; - } - - const workflowData = { - nodes: [nodeData], - connections: {}, - }; - - this.workflow = new Workflow({ - nodes: workflowData.nodes, - connections: workflowData.connections, - active: false, - nodeTypes, - }); - } - - /** - * Returns data of a fake workflow - * - */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - getWorkflowData() { - return { - name: TEMP_WORKFLOW_NAME, - active: false, - connections: {}, - nodes: Object.values(this.workflow.nodes), - createdAt: new Date(), - updatedAt: new Date(), - }; - } - +export class LoadNodeParameterOptions extends LoadNodeDetails { /** * Returns the available options via a predefined method - * - * @param {string} methodName The name of the method of which to get the data from */ async getOptionsViaMethodName( methodName: string, additionalData: IWorkflowExecuteAdditionalData, ): Promise { - const node = this.workflow.getNode(TEMP_NODE_NAME); + const node = this.getTempNode(); - const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node!.type, node?.typeVersion); + const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion); + const method = nodeType?.methods?.loadOptions?.[methodName]; - if ( - !nodeType || - nodeType.methods === undefined || - nodeType.methods.loadOptions === undefined || - nodeType.methods.loadOptions[methodName] === undefined - ) { + if (typeof method !== 'function') { throw new Error( - `The node-type "${node!.type}" does not have the method "${methodName}" defined!`, + `The node-type "${node.type}" does not have the method "${methodName}" defined!`, ); } const thisArgs = NodeExecuteFunctions.getLoadOptionsFunctions( this.workflow, - node!, + node, this.path, additionalData, ); - return nodeType.methods.loadOptions[methodName].call(thisArgs); + return method.call(thisArgs); } /** * Returns the available options via a load request information - * - * @param {ILoadOptions} loadOptions The load options which also contain the request information */ async getOptionsViaRequestProperty( loadOptions: ILoadOptions, additionalData: IWorkflowExecuteAdditionalData, ): Promise { - const node = this.workflow.getNode(TEMP_NODE_NAME); + const node = this.getTempNode(); - const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node!.type, node?.typeVersion); + const nodeType = this.workflow.nodeTypes.getByNameAndVersion(node.type, node?.typeVersion); - if ( - nodeType === undefined || - !nodeType.description.requestDefaults || - !nodeType.description.requestDefaults.baseURL - ) { + if (!nodeType?.description?.requestDefaults?.baseURL) { // This in in here for now for security reasons. // Background: As the full data for the request to make does get send, and the auth data // will then be applied, would it be possible to retrieve that data like that. By at least @@ -156,9 +61,7 @@ export class LoadNodeParameterOptions { // In the future this code has to get improved that it does not use the request information from // the request rather resolves it via the parameter-path and nodeType data. throw new Error( - `The node-type "${ - node!.type - }" does not exist or does not have "requestDefaults.baseURL" defined!`, + `The node-type "${node.type}" does not exist or does not have "requestDefaults.baseURL" defined!`, ); } @@ -169,7 +72,7 @@ export class LoadNodeParameterOptions { const routingNode = new RoutingNode( this.workflow, - node!, + node, connectionInputData, runExecutionData ?? null, additionalData, @@ -203,7 +106,7 @@ export class LoadNodeParameterOptions { inputData, runIndex, tempNode, - { node: node!, source: null, data: {} }, + { node, source: null, data: {} }, NodeExecuteFunctions, );