UNPKG

@rudderstack/workflow-engine

Version:
96 lines 4.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WorkflowOutputsValidator = void 0; const common_1 = require("../common"); const errors_1 = require("../errors"); // Matches: $.outputs.stepName, // Result: [$.outputs.stepName, stepName, stepName]; // Matches: $.outputs.workflow.step, // Result: [$.outputs.workflow.step, workflow.step, workflow, .step, step]; const regexOutputReference = /\$\.?outputs\.((\w+)(\.(\w+))?)/g; class WorkflowOutputsValidator { constructor(workflow) { this.workflow = workflow; this.seenSteps = new Set(); this.stepTypeMap = new Map(); } validateWorkflowOutputReference(match, stepName, parentName) { const workflowName = match[2]; // The name of the workflow step // Access to the child step outputs is restricted to within the same parent workflow step; if (parentName !== workflowName) { throw new errors_1.WorkflowCreationError(`Invalid output reference: ${match[0]}, step is not a child of ${parentName}`, this.workflow.name, parentName, stepName); } } validateExistanceOfOutputReference(match, stepName, parentName) { const fullOutputName = match[1]; // For workflow step const outputStepName = match[2]; // For simple step // Check the referenced step output is already executed. if (!this.seenSteps.has(fullOutputName) && !this.seenSteps.has(outputStepName)) { throw new errors_1.WorkflowCreationError(`Invalid output reference: ${match[0]}, step is not executed yet.`, this.workflow.name, parentName ?? stepName, parentName ? stepName : undefined); } } validateOutputReferences(stepName, template, parentName) { if (!template) { return; } const outputMatches = [...template.matchAll(regexOutputReference)]; // Multiple outputs may exist within the template so we need a loop. // In this case, we are looking for workflow step output references. // Format: $.outputs.workflowStepName.ChildStepName for (const match of outputMatches) { const primaryStepName = match[2]; // The name of the step const childStepName = match[4]; // The name of the child step if (this.stepTypeMap.get(primaryStepName) === common_1.StepType.Workflow && childStepName) { this.validateWorkflowOutputReference(match, stepName, parentName); } this.validateExistanceOfOutputReference(match, stepName, parentName); } } validateCommonStepParams(step, parentName) { this.validateOutputReferences(step.name, step.condition, parentName); this.validateOutputReferences(step.name, step.inputTemplate, parentName); this.validateOutputReferences(step.name, step.loopCondition, parentName); if (step.else) { this.validateSteps([step.else], parentName); } } validateBatchStep(step, parentName) { if (step.batches) { for (const batch of step.batches) { this.validateOutputReferences(step.name, batch.filter, parentName); this.validateOutputReferences(step.name, batch.map, parentName); } } } validateSteps(steps, parentName) { for (const step of steps) { const stepName = step.name; const stepType = step.type; this.stepTypeMap.set(stepName, stepType); let outputName = stepName; this.validateCommonStepParams(step, parentName); if (step.type === common_1.StepType.Workflow) { const workflowStep = step; if (workflowStep.steps) { this.validateSteps(workflowStep.steps, stepName); } } else if (step.type === common_1.StepType.Simple) { this.validateOutputReferences(stepName, step.template, parentName); } else if (step.type === common_1.StepType.Batch) { this.validateBatchStep(step, parentName); } if (parentName) { outputName = `${parentName}.${stepName}`; } this.seenSteps.add(outputName); } } validateOutputs() { const { steps: workflowSteps } = this.workflow; this.validateSteps(workflowSteps); } } exports.WorkflowOutputsValidator = WorkflowOutputsValidator; //# sourceMappingURL=output_validator.js.map