n8n-nodes-cleverflow
Version:
n8n node to integrate with CleverFlow API for creating workflow runs and processing Tally Forms
232 lines • 10.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.processTallyFormFields = exports.processNonCheckboxFieldValue = exports.processCheckboxFields = exports.processFileUploads = exports.findMatchingField = exports.getCheckboxGroupParent = exports.isCheckboxChild = exports.isCheckboxGroupParent = void 0;
const n8n_workflow_1 = require("n8n-workflow");
function isCheckboxGroupParent(field, allFields) {
if (!field || !field.type || !Array.isArray(allFields))
return false;
return field.type === 'CHECKBOXES' &&
Array.isArray(field.options) &&
field.options.length > 0 &&
allFields.some(f => f.key.startsWith(`${field.key}_`));
}
exports.isCheckboxGroupParent = isCheckboxGroupParent;
function isCheckboxChild(field, allFields) {
if (!field || !field.type || !Array.isArray(allFields))
return false;
return field.type === 'CHECKBOXES' &&
typeof field.key === 'string' &&
field.key.includes('_') &&
!field.options;
}
exports.isCheckboxChild = isCheckboxChild;
function getCheckboxGroupParent(field, allFields) {
if (!field || !Array.isArray(allFields) || !isCheckboxChild(field, allFields))
return undefined;
const parentKey = field.key.split('_').slice(0, -1).join('_');
return allFields.find(f => f.key === parentKey);
}
exports.getCheckboxGroupParent = getCheckboxGroupParent;
function findMatchingField(workflowFields, tallyField, isCheckbox = false) {
const cleanLabel = (str) => str.replace(/[^\w\s]|_/g, '')
.replace(/\s+/g, ' ')
.trim()
.toLowerCase();
const fieldLabel = cleanLabel(tallyField.label || '');
let match = workflowFields.find(field => cleanLabel(field.name) === fieldLabel);
if (match)
return match;
if (isCheckbox) {
const parenMatch = tallyField.label.match(/\((.*?)\)/);
if (parenMatch) {
const optionText = cleanLabel(parenMatch[1]);
match = workflowFields.find(field => cleanLabel(field.name) === optionText);
if (match)
return match;
}
}
if (!match) {
match = workflowFields.find(field => {
const fieldName = cleanLabel(field.name);
return fieldName.includes(fieldLabel) || fieldLabel.includes(fieldName);
});
}
return match || null;
}
exports.findMatchingField = findMatchingField;
function processFileUploads(fileField) {
if (!fileField.value || !Array.isArray(fileField.value) || fileField.value.length === 0) {
return [];
}
return fileField.value.filter(file => file && typeof file === 'object' && file.url);
}
exports.processFileUploads = processFileUploads;
function processCheckboxFields(tallyField, workflowFields, allTallyFields) {
var _a, _b, _c;
const results = [];
if (isCheckboxGroupParent(tallyField, allTallyFields)) {
if (Array.isArray(tallyField.value)) {
const selectedOptions = ((_a = tallyField.options) === null || _a === void 0 ? void 0 : _a.filter(opt => tallyField.value.includes(opt.id)).map(opt => opt.text)) || [];
for (const optionText of selectedOptions) {
const matchingField = workflowFields.find(field => field.name.toLowerCase() === optionText.toLowerCase());
if (matchingField) {
results.push({
field: String(matchingField.value),
value: true
});
}
}
}
}
else if (isCheckboxChild(tallyField, allTallyFields)) {
const parent = getCheckboxGroupParent(tallyField, allTallyFields);
const optionId = tallyField.key.split('_').pop();
if (parent && optionId && typeof tallyField.value === 'boolean' && tallyField.value === true) {
const optionText = (_c = (_b = parent.options) === null || _b === void 0 ? void 0 : _b.find(opt => opt.id === optionId)) === null || _c === void 0 ? void 0 : _c.text;
if (optionText) {
const matchingField = findMatchingField(workflowFields, {
...tallyField,
label: optionText
}, true);
if (matchingField) {
results.push({
field: String(matchingField.value),
value: true
});
}
}
}
}
else if (tallyField.type === 'CHECKBOXES' && typeof tallyField.value === 'boolean' && tallyField.value === true) {
const matchingField = findMatchingField(workflowFields, tallyField, true);
if (matchingField) {
results.push({
field: String(matchingField.value),
value: true
});
}
}
return results;
}
exports.processCheckboxFields = processCheckboxFields;
function processNonCheckboxFieldValue(tallyField) {
switch (tallyField.type) {
case 'MULTIPLE_CHOICE':
case 'DROPDOWN':
if (Array.isArray(tallyField.value) && tallyField.value.length > 0 && tallyField.options) {
const selectedOption = tallyField.options.find(opt => opt.id === tallyField.value[0]);
return selectedOption ? selectedOption.text : '';
}
return '';
case 'MULTI_SELECT':
if (Array.isArray(tallyField.value) && tallyField.value.length > 0 && tallyField.options) {
return tallyField.value
.map(id => {
var _a;
const option = (_a = tallyField.options) === null || _a === void 0 ? void 0 : _a.find(opt => opt.id === id);
return option ? option.text : '';
})
.filter(text => text !== '');
}
return [];
case 'FILE_UPLOAD':
return processFileUploads(tallyField);
case 'ATTACHMENTS':
return processFileUploads(tallyField);
case 'LINEAR_SCALE':
return tallyField.value !== undefined ? String(tallyField.value) : '';
case 'INPUT_TEXT':
case 'INPUT_PHONE_NUMBER':
case 'INPUT_EMAIL':
case 'INPUT_NUMBER':
case 'INPUT_DATE':
case 'TEXTAREA':
default:
return tallyField.value !== undefined ? String(tallyField.value) : '';
}
}
exports.processNonCheckboxFieldValue = processNonCheckboxFieldValue;
async function processTallyFormFields(tallyFields, workflowFields, skipEmptyValues, skipInvalidFields, node) {
const fields = [];
const processedFieldKeys = new Set();
const checkboxGroups = {};
const parentKeyMap = {};
tallyFields.forEach(field => {
if (field.type === 'CHECKBOXES') {
if (field.options && field.options.length > 0) {
checkboxGroups[field.key] = [];
}
if (field.label && field.label.includes('(') && field.label.includes(')')) {
const parentLabelMatch = field.label.match(/(.*?)\s*\(/);
if (parentLabelMatch && parentLabelMatch[1]) {
const parentLabel = parentLabelMatch[1].trim();
const parentField = tallyFields.find(f => f.type === 'CHECKBOXES' &&
f.options &&
f.options.length > 0 &&
f.label === parentLabel);
if (parentField) {
if (!checkboxGroups[parentField.key]) {
checkboxGroups[parentField.key] = [];
}
checkboxGroups[parentField.key].push(field);
parentKeyMap[field.key] = parentField.key;
}
}
}
}
});
for (const tallyField of tallyFields) {
if (processedFieldKeys.has(tallyField.key))
continue;
try {
if (skipEmptyValues && (tallyField.value === null ||
tallyField.value === undefined ||
tallyField.value === '' ||
(Array.isArray(tallyField.value) && tallyField.value.length === 0) ||
(typeof tallyField.value === 'boolean' && tallyField.value === false))) {
continue;
}
if (tallyField.type === 'CHECKBOXES') {
const checkboxResults = processCheckboxFields(tallyField, workflowFields, tallyFields);
fields.push(...checkboxResults);
processedFieldKeys.add(tallyField.key);
if (checkboxGroups[tallyField.key]) {
checkboxGroups[tallyField.key].forEach(childField => {
processedFieldKeys.add(childField.key);
});
}
continue;
}
const matchingField = findMatchingField(workflowFields, tallyField);
if (matchingField) {
const processedValue = processNonCheckboxFieldValue(tallyField);
if (!skipEmptyValues || (processedValue !== '' &&
!(Array.isArray(processedValue) && processedValue.length === 0))) {
fields.push({
field: String(matchingField.value),
value: processedValue
});
}
}
else if (!skipInvalidFields) {
throw new n8n_workflow_1.NodeApiError(node, {
message: `Could not find matching field for "${tallyField.label}" in CleverFlow workflow`
});
}
}
catch (error) {
if (skipInvalidFields) {
continue;
}
else {
throw new n8n_workflow_1.NodeApiError(node, {
message: `Error processing field ${tallyField.label}: ${error.message}`
});
}
}
processedFieldKeys.add(tallyField.key);
}
return fields;
}
exports.processTallyFormFields = processTallyFormFields;
//# sourceMappingURL=tallyHelpers.js.map