n8n-nodes-base
Version:
Base nodes of n8n
239 lines • 10.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SplitOut = void 0;
const get_1 = __importDefault(require("lodash/get"));
const unset_1 = __importDefault(require("lodash/unset"));
const n8n_workflow_1 = require("n8n-workflow");
const utils_1 = require("../utils/utils");
const utils_2 = require("./utils");
class SplitOut {
description = {
displayName: 'Split Out',
name: 'splitOut',
icon: 'file:splitOut.svg',
group: ['transform'],
subtitle: '',
version: 1,
description: 'Turn a list inside item(s) into separate items',
defaults: {
name: 'Split Out',
},
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
builderHint: {
relatedNodes: [
{
nodeType: 'n8n-nodes-base.aggregate',
relationHint: 'Reverse operation - combine items back',
},
],
},
properties: [
{
displayName: 'Fields To Split Out',
name: 'fieldToSplitOut',
type: 'string',
default: '',
required: true,
placeholder: 'Drag fields from the left or type their names',
description: 'The name of the input fields to break out into separate items. Separate multiple field names by commas. For binary data, use $binary.',
requiresDataPath: 'multiple',
hint: 'Use $binary to split out the input item by binary data',
},
{
displayName: 'Include',
name: 'include',
type: 'options',
options: [
{
name: 'No Other Fields',
value: 'noOtherFields',
},
{
name: 'All Other Fields',
value: 'allOtherFields',
},
{
name: 'Selected Other Fields',
value: 'selectedOtherFields',
},
],
default: 'noOtherFields',
description: 'Whether to copy any other fields into the new items',
},
{
displayName: 'Fields To Include',
name: 'fieldsToInclude',
type: 'string',
placeholder: 'e.g. email, name',
requiresDataPath: 'multiple',
description: 'Fields in the input items to aggregate together',
default: '',
displayOptions: {
show: {
include: ['selectedOtherFields'],
},
},
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add Field',
default: {},
options: [
{
displayName: 'Disable Dot Notation',
name: 'disableDotNotation',
type: 'boolean',
default: false,
description: 'Whether to disallow referencing child fields using `parent.child` in the field name',
},
{
displayName: 'Destination Field Name',
name: 'destinationFieldName',
type: 'string',
requiresDataPath: 'multiple',
default: '',
description: 'The field in the output under which to put the split field contents',
},
{
displayName: 'Include Binary',
name: 'includeBinary',
type: 'boolean',
default: false,
description: 'Whether to include the binary data in the new items',
},
],
},
],
};
async execute() {
const returnData = [];
const items = this.getInputData();
const fieldsTracker = new utils_2.FieldsTracker();
for (let i = 0; i < items.length; i++) {
const fieldsToSplitOut = this.getNodeParameter('fieldToSplitOut', i)
.split(',')
.map((field) => field.trim().replace(/^\$json\./, ''));
const options = this.getNodeParameter('options', i, {});
const disableDotNotation = options.disableDotNotation;
const destinationFields = (options.destinationFieldName || '')
.split(',')
.filter((field) => field.trim() !== '')
.map((field) => field.trim());
if (destinationFields.length && destinationFields.length !== fieldsToSplitOut.length) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'If multiple fields to split out are given, the same number of destination fields must be given');
}
const include = this.getNodeParameter('include', i);
const multiSplit = fieldsToSplitOut.length > 1;
const item = { ...items[i].json };
const splited = [];
for (const [entryIndex, fieldToSplitOut] of fieldsToSplitOut.entries()) {
const destinationFieldName = destinationFields[entryIndex] || '';
let entityToSplit = [];
if (fieldToSplitOut === '$binary') {
entityToSplit = Object.entries(items[i].binary || {}).map(([key, value]) => ({
[key]: value,
}));
}
else {
if (!disableDotNotation) {
entityToSplit = (0, get_1.default)(item, fieldToSplitOut);
}
else {
entityToSplit = item[fieldToSplitOut];
}
fieldsTracker.add(fieldToSplitOut);
const entryExists = entityToSplit !== undefined;
if (!entryExists) {
entityToSplit = [];
}
fieldsTracker.update(fieldToSplitOut, entryExists);
if (typeof entityToSplit !== 'object' || entityToSplit === null) {
entityToSplit = [entityToSplit];
}
if (!Array.isArray(entityToSplit)) {
entityToSplit = Object.values(entityToSplit);
}
}
for (const [elementIndex, element] of entityToSplit.entries()) {
if (splited[elementIndex] === undefined) {
splited[elementIndex] = { json: {}, pairedItem: { item: i } };
}
const fieldName = destinationFieldName || fieldToSplitOut;
if (fieldToSplitOut === '$binary') {
if (splited[elementIndex].binary === undefined) {
splited[elementIndex].binary = {};
}
splited[elementIndex].binary[Object.keys(element)[0]] = Object.values(element)[0];
continue;
}
if (typeof element === 'object' && element !== null && include === 'noOtherFields') {
if (destinationFieldName === '' && !multiSplit) {
splited[elementIndex] = {
json: { ...splited[elementIndex].json, ...element },
pairedItem: { item: i },
};
}
else {
splited[elementIndex].json[fieldName] = element;
}
}
else {
splited[elementIndex].json[fieldName] = element;
}
}
}
for (const splitEntry of splited) {
let newItem = splitEntry;
if (include === 'allOtherFields') {
const itemCopy = (0, n8n_workflow_1.deepCopy)(item);
for (const fieldToSplitOut of fieldsToSplitOut) {
if (!disableDotNotation) {
(0, unset_1.default)(itemCopy, fieldToSplitOut);
}
else {
delete itemCopy[fieldToSplitOut];
}
}
newItem.json = { ...itemCopy, ...splitEntry.json };
}
if (include === 'selectedOtherFields') {
const fieldsToInclude = (0, utils_1.prepareFieldsArray)(this.getNodeParameter('fieldsToInclude', i, ''), 'Fields To Include');
if (!fieldsToInclude.length) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No fields specified', {
description: 'Please add a field to include',
});
}
for (const field of fieldsToInclude) {
if (!disableDotNotation) {
splitEntry.json[field] = (0, get_1.default)(item, field);
}
else {
splitEntry.json[field] = item[field];
}
}
newItem = splitEntry;
}
const includeBinary = options.includeBinary;
if (includeBinary) {
if (items[i].binary && !newItem.binary) {
newItem.binary = items[i].binary;
}
}
returnData.push(newItem);
}
}
const hints = fieldsTracker.getHints();
if (hints.length) {
this.addExecutionHints(...hints);
}
return [returnData];
}
}
exports.SplitOut = SplitOut;
//# sourceMappingURL=SplitOut.node.js.map