mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix: Remove Request Options from sub nodes (no-changelog) (#9853)
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
@@ -1766,21 +1766,24 @@ export interface INodeInputConfiguration {
|
||||
}
|
||||
|
||||
export interface INodeOutputConfiguration {
|
||||
category?: string;
|
||||
category?: 'error';
|
||||
displayName?: string;
|
||||
maxConnections?: number;
|
||||
required?: boolean;
|
||||
type: ConnectionTypes;
|
||||
}
|
||||
|
||||
export type ExpressionString = `={{${string}}}`;
|
||||
|
||||
export interface INodeTypeDescription extends INodeTypeBaseDescription {
|
||||
version: number | number[];
|
||||
defaults: INodeParameters;
|
||||
eventTriggerDescription?: string;
|
||||
activationMessage?: string;
|
||||
inputs: Array<ConnectionTypes | INodeInputConfiguration> | string;
|
||||
inputs: Array<ConnectionTypes | INodeInputConfiguration> | ExpressionString;
|
||||
requiredInputs?: string | number[] | number; // Ony available with executionOrder => "v1"
|
||||
inputNames?: string[];
|
||||
outputs: Array<ConnectionTypes | INodeInputConfiguration> | string;
|
||||
outputs: Array<ConnectionTypes | INodeOutputConfiguration> | ExpressionString;
|
||||
outputNames?: string[];
|
||||
properties: INodeProperties[];
|
||||
credentials?: INodeCredentialDescription[];
|
||||
|
||||
@@ -10,6 +10,7 @@ import get from 'lodash/get';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
|
||||
import { NodeConnectionType } from './Interfaces';
|
||||
import type {
|
||||
FieldType,
|
||||
IContextObject,
|
||||
@@ -351,8 +352,31 @@ const declarativeNodeOptionParameters: INodeProperties = {
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the provided node type has any output types other than the main connection type.
|
||||
* @param typeDescription The node's type description to check.
|
||||
*/
|
||||
export function isSubNodeType(
|
||||
typeDescription: Pick<INodeTypeDescription, 'outputs'> | null,
|
||||
): boolean {
|
||||
if (!typeDescription || !typeDescription.outputs || typeof typeDescription.outputs === 'string') {
|
||||
return false;
|
||||
}
|
||||
const outputTypes = getConnectionTypes(typeDescription.outputs);
|
||||
return outputTypes
|
||||
? outputTypes.filter((output) => output !== NodeConnectionType.Main).length > 0
|
||||
: false;
|
||||
}
|
||||
|
||||
/** Augments additional `Request Options` property on declarative node-type */
|
||||
export function applyDeclarativeNodeOptionParameters(nodeType: INodeType): void {
|
||||
if (nodeType.execute || nodeType.trigger || nodeType.webhook || nodeType.description.polling) {
|
||||
if (
|
||||
nodeType.execute ||
|
||||
nodeType.trigger ||
|
||||
nodeType.webhook ||
|
||||
nodeType.description.polling ||
|
||||
isSubNodeType(nodeType.description)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
import type { INode, INodeParameters, INodeProperties, INodeTypeDescription } from '@/Interfaces';
|
||||
import type {
|
||||
INode,
|
||||
INodeParameters,
|
||||
INodeProperties,
|
||||
INodeType,
|
||||
INodeTypeDescription,
|
||||
} from '@/Interfaces';
|
||||
import type { Workflow } from '@/Workflow';
|
||||
|
||||
import { getNodeParameters, getNodeHints, isSingleExecution } from '@/NodeHelpers';
|
||||
import {
|
||||
getNodeParameters,
|
||||
getNodeHints,
|
||||
isSingleExecution,
|
||||
isSubNodeType,
|
||||
applyDeclarativeNodeOptionParameters,
|
||||
} from '@/NodeHelpers';
|
||||
|
||||
describe('NodeHelpers', () => {
|
||||
describe('getNodeParameters', () => {
|
||||
@@ -3528,6 +3539,7 @@ describe('NodeHelpers', () => {
|
||||
expect(hints).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSingleExecution', () => {
|
||||
test('should determine based on node parameters if it would be executed once', () => {
|
||||
expect(isSingleExecution('n8n-nodes-base.code', {})).toEqual(true);
|
||||
@@ -3555,4 +3567,72 @@ describe('NodeHelpers', () => {
|
||||
expect(isSingleExecution('n8n-nodes-base.redis', {})).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSubNodeType', () => {
|
||||
const tests: Array<[boolean, Pick<INodeTypeDescription, 'outputs'> | null]> = [
|
||||
[false, null],
|
||||
[false, { outputs: '={{random_expression}}' }],
|
||||
[false, { outputs: [] }],
|
||||
[false, { outputs: ['main'] }],
|
||||
[true, { outputs: ['ai_agent'] }],
|
||||
[true, { outputs: ['main', 'ai_agent'] }],
|
||||
];
|
||||
test.each(tests)('should return %p for %o', (expected, nodeType) => {
|
||||
expect(isSubNodeType(nodeType)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyDeclarativeNodeOptionParameters', () => {
|
||||
test.each([
|
||||
[
|
||||
'node with execute method',
|
||||
{
|
||||
execute: jest.fn(),
|
||||
description: {
|
||||
properties: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'node with trigger method',
|
||||
{
|
||||
trigger: jest.fn(),
|
||||
description: {
|
||||
properties: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'node with webhook method',
|
||||
{
|
||||
webhook: jest.fn(),
|
||||
description: {
|
||||
properties: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'a polling node-type',
|
||||
{
|
||||
description: {
|
||||
polling: true,
|
||||
properties: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
'a node-type with a non-main output',
|
||||
{
|
||||
description: {
|
||||
outputs: ['main', 'ai_agent'],
|
||||
properties: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
])('should not modify properties on node with %s method', (_, nodeTypeName) => {
|
||||
const nodeType = nodeTypeName as unknown as INodeType;
|
||||
applyDeclarativeNodeOptionParameters(nodeType);
|
||||
expect(nodeType.description.properties).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user