UNPKG

@bernierllc/temporal-workflow-ui

Version:

Thin domain-specific wrapper around @bernierllc/generic-workflow-ui for Temporal workflows

168 lines (166 loc) 5.21 kB
"use strict"; /* Copyright (c) 2025 Bernier LLC This file is licensed to the client under a limited-use license. The client may use and modify this code *only within the scope of the project it was delivered for*. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.jsonToTemporalWorkflow = jsonToTemporalWorkflow; /** * Convert JSON definition (n8n-style) to Temporal workflow * * @param json - JSON workflow definition * @returns Temporal workflow */ function jsonToTemporalWorkflow(json) { const stages = json.nodes.map((node, index) => jsonNodeToTemporalStage(node, index)); const transitions = buildTransitionsFromConnections(json.connections); const staticData = json.staticData || {}; return { id: json.meta?.instanceId || generateId(), name: json.name, description: json.nodes[0]?.notes, stages, transitions, metadata: {}, defaultTaskQueue: staticData.defaultTaskQueue, workflowTimeout: staticData.workflowTimeout, searchAttributes: staticData.searchAttributes, }; } /** * Convert JSON node to Temporal stage * * @param node - JSON workflow node * @param index - Node index for order * @returns Temporal workflow stage */ function jsonNodeToTemporalStage(node, index) { const nodeData = node.data || {}; const temporalMetadata = nodeData.temporal; // Validate node type is a valid Temporal node type if (!isValidTemporalNodeType(node.type)) { throw new Error(`Invalid Temporal node type: ${node.type}`); } // If no temporal metadata, create default based on type const metadata = temporalMetadata || createDefaultMetadata(node.type); return { id: node.id, name: node.name, description: node.notes, order: index, type: node.type, metadata, icon: nodeData.icon, color: nodeData.color, }; } /** * Build transitions from connections object * * @param connections - Workflow connections * @returns Array of Temporal transitions */ function buildTransitionsFromConnections(connections) { const transitions = []; for (const [fromId, outputs] of Object.entries(connections)) { for (const [, connectionArrays] of Object.entries(outputs)) { for (const connectionArray of connectionArrays) { for (const connection of connectionArray) { const transitionId = `${fromId}-${connection.node}`; const connectionData = connection.data || {}; transitions.push({ id: transitionId, from: fromId, to: connection.node, name: connectionData.name, description: connectionData.description, condition: connectionData.condition, metadata: connectionData.metadata, }); } } } } return transitions; } /** * Check if a string is a valid Temporal node type * * @param type - Type string to validate * @returns True if valid */ function isValidTemporalNodeType(type) { const validTypes = [ 'activity', 'agent', 'signal', 'trigger', 'child-workflow', 'parallel', 'condition', ]; return validTypes.includes(type); } /** * Create default metadata for a node type * * @param type - Node type * @returns Default metadata */ function createDefaultMetadata(type) { switch (type) { case 'activity': return { nodeType: 'activity', activityName: 'defaultActivity', taskQueue: 'default', }; case 'agent': return { nodeType: 'agent', agentPromptId: 'default-prompt', agentName: 'Default Agent', taskQueue: 'default', }; case 'signal': return { nodeType: 'signal', signalName: 'defaultSignal', }; case 'trigger': return { nodeType: 'trigger', triggerType: 'manual', }; case 'child-workflow': return { nodeType: 'child-workflow', workflowName: 'defaultChildWorkflow', taskQueue: 'default', }; case 'parallel': return { nodeType: 'parallel', branches: [], }; case 'condition': return { nodeType: 'condition', expression: 'true', trueBranch: '', falseBranch: '', }; default: throw new Error(`Unsupported node type: ${type}`); } } /** * Generate a unique ID * * @returns Unique ID string */ function generateId() { return `temporal-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; }