feat(Split Out Node): Incorrect warning fix (#20468)

This commit is contained in:
Michael Kret 2025-10-08 20:10:04 +03:00 committed by GitHub
parent 09589d501b
commit fb501d6ded
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 112 additions and 25 deletions

View File

@ -8,10 +8,10 @@ import type {
INodeExecutionData,
INodeType,
INodeTypeDescription,
NodeExecutionHint,
} from 'n8n-workflow';
import { prepareFieldsArray } from '../utils/utils';
import { FieldsTracker } from './utils';
export class SplitOut implements INodeType {
description: INodeTypeDescription = {
@ -113,7 +113,7 @@ export class SplitOut implements INodeType {
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const returnData: INodeExecutionData[] = [];
const items = this.getInputData();
const notFoundedFields: { [key: string]: boolean[] } = {};
const fieldsTracker = new FieldsTracker();
for (let i = 0; i < items.length; i++) {
const fieldsToSplitOut = (this.getNodeParameter('fieldToSplitOut', i) as string)
@ -161,18 +161,16 @@ export class SplitOut implements INodeType {
entityToSplit = item[fieldToSplitOut] as IDataObject[];
}
if (entityToSplit === undefined) {
fieldsTracker.add(fieldToSplitOut);
const entryExists = entityToSplit !== undefined;
if (!entryExists) {
entityToSplit = [];
if (!notFoundedFields[fieldToSplitOut]) {
notFoundedFields[fieldToSplitOut] = [];
}
notFoundedFields[fieldToSplitOut].push(false);
} else {
if (notFoundedFields[fieldToSplitOut]) {
notFoundedFields[fieldToSplitOut].push(true);
}
}
fieldsTracker.update(fieldToSplitOut, entryExists);
if (typeof entityToSplit !== 'object' || entityToSplit === null) {
entityToSplit = [entityToSplit] as unknown as IDataObject[];
}
@ -265,21 +263,10 @@ export class SplitOut implements INodeType {
}
}
if (Object.keys(notFoundedFields).length) {
const hints: NodeExecutionHint[] = [];
const hints = fieldsTracker.getHints();
for (const [field, values] of Object.entries(notFoundedFields)) {
if (values.every((value) => !value)) {
hints.push({
message: `The field '${field}' wasn't found in any input item`,
location: 'outputPane',
});
}
}
if (hints.length) {
this.addExecutionHints(...hints);
}
if (hints.length) {
this.addExecutionHints(...hints);
}
return [returnData];

View File

@ -0,0 +1,68 @@
import { FieldsTracker } from '../utils';
describe('FieldsTracker', () => {
let fieldsTracker: FieldsTracker;
beforeEach(() => {
fieldsTracker = new FieldsTracker();
});
describe('add', () => {
it('should add field with false value', () => {
fieldsTracker.add('testField');
expect(fieldsTracker.fields.testField).toBe(false);
});
it('should not overwrite existing field', () => {
fieldsTracker.add('testField');
fieldsTracker.fields.testField = true;
fieldsTracker.add('testField');
expect(fieldsTracker.fields.testField).toBe(true);
});
});
describe('update', () => {
it('should update field from false to true', () => {
fieldsTracker.add('testField');
fieldsTracker.update('testField', true);
expect(fieldsTracker.fields.testField).toBe(true);
});
it('should not update field from true to false', () => {
fieldsTracker.add('testField');
fieldsTracker.fields.testField = true;
fieldsTracker.update('testField', false);
expect(fieldsTracker.fields.testField).toBe(true);
});
});
describe('getHints', () => {
it('should return empty array when no fields tracked', () => {
expect(fieldsTracker.getHints()).toEqual([]);
});
it('should return hint for missing field', () => {
fieldsTracker.add('missingField');
const hints = fieldsTracker.getHints();
expect(hints).toEqual([
{
message: "The field 'missingField' wasn't found in any input item",
location: 'outputPane',
},
]);
});
it('should not return hint for found field', () => {
fieldsTracker.add('foundField');
fieldsTracker.update('foundField', true);
expect(fieldsTracker.getHints()).toEqual([]);
});
});
});

View File

@ -0,0 +1,32 @@
import type { NodeExecutionHint } from 'n8n-workflow';
export class FieldsTracker {
fields: { [key: string]: boolean } = {};
add(key: string) {
if (this.fields[key] === undefined) {
this.fields[key] = false;
}
}
update(key: string, value: boolean) {
if (!this.fields[key] && value) {
this.fields[key] = true;
}
}
getHints() {
const hints: NodeExecutionHint[] = [];
for (const [field, value] of Object.entries(this.fields)) {
if (!value) {
hints.push({
message: `The field '${field}' wasn't found in any input item`,
location: 'outputPane',
});
}
}
return hints;
}
}