mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-30 16:26:59 +02:00
feat(Split Out Node): Incorrect warning fix (#20468)
This commit is contained in:
parent
09589d501b
commit
fb501d6ded
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
32
packages/nodes-base/nodes/Transform/SplitOut/utils.ts
Normal file
32
packages/nodes-base/nodes/Transform/SplitOut/utils.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user