UNPKG

n8n-nodes-variables

Version:

n8n community node for managing typed global variables accessible from any workflow stage - like programming language variables with strong typing support

544 lines 24.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkflowVariables = void 0; const n8n_workflow_1 = require("n8n-workflow"); const WORKFLOW_VARIABLES_KEY = '__workflow_variables__'; function getWorkflowVariables(context) { const staticData = context.getWorkflowStaticData('global'); if (!staticData[WORKFLOW_VARIABLES_KEY]) { staticData[WORKFLOW_VARIABLES_KEY] = {}; } return staticData[WORKFLOW_VARIABLES_KEY]; } function setWorkflowVariable(context, name, value) { const variables = getWorkflowVariables(context); variables[name] = value; } function getWorkflowVariable(context, name) { const variables = getWorkflowVariables(context); return variables[name]; } class WorkflowVariables { constructor() { this.description = { displayName: 'Variables', name: 'variables', icon: 'fa:code-branch', group: ['utility'], version: 1, description: 'Manage typed global variables accessible from any workflow stage - like programming language variables', defaults: { name: 'Variables', }, inputs: ["main"], outputs: ["main"], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', options: [ { name: 'Clear All Variables', value: 'clear', description: 'Reset all workflow variables', action: 'Reset all workflow variables', }, { name: 'Get Variable', value: 'get', description: 'Retrieve a variable value', action: 'Retrieve a variable value', }, { name: 'Initialize Variables', value: 'initialize', description: 'Set up initial variables for the workflow', action: 'Set up initial variables for the workflow', }, { name: 'Set Variable', value: 'set', description: 'Update a variable value (can be used at any stage)', action: 'Update a variable value can be used at any stage', }, { name: 'View All Variables', value: 'viewAll', description: 'Display all current variables and their values', action: 'Display all current variables and their values', }, ], default: 'set', noDataExpression: true, }, { displayName: 'Variable Name', name: 'variableName', type: 'string', default: '', displayOptions: { show: { operation: ['set', 'get'], }, }, required: true, placeholder: 'e.g., URL, pageNumber, maxRetries', description: 'Name of the variable to set or get', }, { displayName: 'Variable Type', name: 'variableType', type: 'options', options: [ { name: 'Boolean', value: 'boolean', description: 'True/False value', }, { name: 'Date', value: 'date', description: 'Date value', }, { name: 'JSON', value: 'json', description: 'Complex object or array', }, { name: 'Number', value: 'number', description: 'Numeric value', }, { name: 'String', value: 'string', description: 'Text value', }, ], default: 'string', displayOptions: { show: { operation: ['set'], }, }, description: 'Type of the variable value', }, { displayName: 'Variable Value', name: 'variableValue', type: 'string', default: '', displayOptions: { show: { operation: ['set'], variableType: ['string'], }, }, placeholder: 'Enter text value', description: 'Text value to store in the variable. Supports expressions.', }, { displayName: 'Variable Value', name: 'variableValue', type: 'number', default: 0, displayOptions: { show: { operation: ['set'], variableType: ['number'], }, }, placeholder: 'Enter numeric value', description: 'Numeric value to store in the variable. Supports expressions.', }, { displayName: 'Variable Value', name: 'variableValue', type: 'boolean', default: false, displayOptions: { show: { operation: ['set'], variableType: ['boolean'], }, }, description: 'Whether to store true or false in the variable', }, { displayName: 'Variable Value', name: 'variableValue', type: 'json', default: '', displayOptions: { show: { operation: ['set'], variableType: ['json'], }, }, placeholder: 'Enter JSON object or array', description: 'JSON object or array to store in the variable. Supports expressions.', }, { displayName: 'Variable Value', name: 'variableValue', type: 'dateTime', default: '', displayOptions: { show: { operation: ['set'], variableType: ['date'], }, }, placeholder: 'Select or enter date', description: 'Date value to store in the variable. Supports expressions.', }, { displayName: 'Initial Variables', name: 'initialVariables', type: 'fixedCollection', default: { variables: [] }, displayOptions: { show: { operation: ['initialize'], }, }, placeholder: 'Add Variable', typeOptions: { multipleValues: true, sortable: true, }, options: [ { name: 'variables', displayName: 'Variable', values: [ { displayName: 'Name', name: 'name', type: 'string', default: '', placeholder: 'variableName', description: 'Variable name (e.g., URL, counter, maxPages)', required: true, }, { displayName: 'Type', name: 'type', type: 'options', options: [ { name: 'Boolean', value: 'boolean', }, { name: 'Date', value: 'date', }, { name: 'JSON', value: 'json', }, { name: 'Number', value: 'number', }, { name: 'String', value: 'string', }, ], default: 'string', description: 'Type of the variable', }, { displayName: 'Value', name: 'value', type: 'string', default: '', displayOptions: { show: { type: ['string'], }, }, placeholder: 'Initial text value', description: 'Initial text value for the variable', }, { displayName: 'Value', name: 'value', type: 'number', default: 0, displayOptions: { show: { type: ['number'], }, }, placeholder: 'Initial numeric value', description: 'Initial numeric value for the variable', }, { displayName: 'Value', name: 'value', type: 'boolean', default: false, displayOptions: { show: { type: ['boolean'], }, }, description: 'Whether the initial variable value should be true or false', }, { displayName: 'Value', name: 'value', type: 'json', default: '', displayOptions: { show: { type: ['json'], }, }, placeholder: 'Initial JSON value', description: 'Initial JSON object or array for the variable', }, { displayName: 'Value', name: 'value', type: 'dateTime', default: '', displayOptions: { show: { type: ['date'], }, }, placeholder: 'Initial date value', description: 'Initial date value for the variable', }, ], }, ], description: 'Set up initial variables for your workflow', }, { displayName: 'Usage Guide', name: 'usageGuide', type: 'collection', default: {}, displayOptions: { show: { operation: ['initialize'], }, }, placeholder: 'Expression Access', description: 'After initialization, access variables in ANY node using: $workflow.variables.VARIABLE_NAME (e.g., $workflow.variables.URL in HTTP Request)', options: [], }, ], }; } async execute() { const items = this.getInputData(); const operation = this.getNodeParameter('operation', 0); let returnData = []; const staticData = this.getWorkflowStaticData('global'); if (!staticData.variables) { staticData.variables = {}; } for (let i = 0; i < items.length; i++) { try { if (operation === 'initialize') { const initialVariables = this.getNodeParameter('initialVariables', i, { variables: [] }); const variables = getWorkflowVariables(this); const resultVariables = {}; Object.keys(variables).forEach(key => delete variables[key]); if (staticData.variables) { Object.keys(staticData.variables).forEach(key => delete staticData.variables[key]); } for (const variable of initialVariables.variables) { if (variable.name) { let processedValue; const varType = variable.type || 'string'; switch (varType) { case 'string': processedValue = String(variable.value || ''); break; case 'number': processedValue = Number(variable.value || 0); if (isNaN(processedValue)) { processedValue = 0; } break; case 'boolean': processedValue = Boolean(variable.value); break; case 'date': if (variable.value) { processedValue = new Date(variable.value); if (isNaN(processedValue.getTime())) { processedValue = new Date(); } } else { processedValue = new Date(); } break; case 'json': default: if (typeof variable.value === 'string') { try { processedValue = JSON.parse(variable.value); } catch (e) { processedValue = variable.value; } } else { processedValue = variable.value; } break; } variables[variable.name] = processedValue; staticData.variables[variable.name] = processedValue; resultVariables[variable.name] = processedValue; } } returnData.push({ json: { ...items[i].json, ...resultVariables, }, pairedItem: items[i].pairedItem, }); } else if (operation === 'set') { const variableName = this.getNodeParameter('variableName', i); const variableType = this.getNodeParameter('variableType', i); const variableValue = this.getNodeParameter('variableValue', i); if (!variableName) { throw new n8n_workflow_1.ApplicationError('Variable name is required'); } let processedValue; switch (variableType) { case 'string': processedValue = String(variableValue); break; case 'number': processedValue = Number(variableValue); if (isNaN(processedValue)) { throw new n8n_workflow_1.ApplicationError(`Invalid number value: ${variableValue}`); } break; case 'boolean': processedValue = Boolean(variableValue); break; case 'date': if (variableValue) { processedValue = new Date(variableValue); if (isNaN(processedValue.getTime())) { throw new n8n_workflow_1.ApplicationError(`Invalid date value: ${variableValue}`); } } else { processedValue = null; } break; case 'json': default: if (typeof variableValue === 'string') { try { processedValue = JSON.parse(variableValue); } catch (e) { throw new n8n_workflow_1.ApplicationError(`Invalid JSON value: ${variableValue}`); } } else { processedValue = variableValue; } break; } setWorkflowVariable(this, variableName, processedValue); staticData.variables[variableName] = processedValue; const allVariables = getWorkflowVariables(this); returnData.push({ json: { ...items[i].json, ...allVariables, }, pairedItem: items[i].pairedItem, }); } else if (operation === 'get') { const variableName = this.getNodeParameter('variableName', i); if (!variableName) { throw new n8n_workflow_1.ApplicationError('Variable name is required'); } const value = getWorkflowVariable(this, variableName); returnData.push({ json: { ...items[i].json, operation: 'get', variableName: variableName, variableValue: value, [variableName]: value, status: value !== undefined ? 'found' : 'not_found', message: value !== undefined ? `Retrieved variable '${variableName}'` : `Variable '${variableName}' not found`, }, pairedItem: items[i].pairedItem, }); } else if (operation === 'viewAll') { const variables = getWorkflowVariables(this); returnData.push({ json: { ...items[i].json, ...variables, }, pairedItem: items[i].pairedItem, }); } else if (operation === 'clear') { const variables = getWorkflowVariables(this); const clearedVariables = Object.keys(variables); Object.keys(variables).forEach(key => delete variables[key]); if (staticData.variables) { Object.keys(staticData.variables).forEach(key => delete staticData.variables[key]); } returnData.push({ json: { ...items[i].json, operation: 'clear', clearedVariables: clearedVariables, clearedCount: clearedVariables.length, message: `Cleared ${clearedVariables.length} workflow variables`, }, pairedItem: items[i].pairedItem, }); } } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: error.message, operation: operation, status: 'error', }, pairedItem: items[i].pairedItem, }); } else { throw error; } } } return [returnData]; } } exports.WorkflowVariables = WorkflowVariables; //# sourceMappingURL=WorkflowVariables.node.js.map