@onlineapps/conn-orch-orchestrator 1.0.27 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-orch-orchestrator",
3
- "version": "1.0.27",
3
+ "version": "1.0.28",
4
4
  "description": "Workflow orchestration connector for OA Drive - handles message routing and workflow execution",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -89,10 +89,10 @@ class WorkflowOrchestrator {
89
89
  delivery: context?.delivery || cookbookDef?.delivery || { handler: 'none' }
90
90
  };
91
91
 
92
- // Find current step (V2: step_id only)
93
- const step = cookbookDef.steps.find(s => s.step_id === current_step);
92
+ // Find current step (V2: steps is an object keyed by step_id)
93
+ const step = cookbookDef.steps[current_step];
94
94
  if (!step) {
95
- throw new Error(`Step not found: ${current_step}. Available steps: ${cookbookDef.steps.map(s => s.step_id).join(', ')}`);
95
+ throw new Error(`Step not found: ${current_step}. Available steps: ${Object.keys(cookbookDef.steps).join(', ')}`);
96
96
  }
97
97
 
98
98
  // Get step_id (V2)
@@ -131,19 +131,16 @@ class WorkflowOrchestrator {
131
131
 
132
132
  // Update context with result - steps as OBJECT (V2 format, keyed by step_id)
133
133
  // Each step preserves its definition (step_id, type, service, operation, input) and adds output
134
- const currentIndex = cookbookDef.steps.findIndex(s => s.step_id === current_step);
135
- const stepDefinition = cookbookDef.steps[currentIndex];
134
+ const stepDefinition = cookbookDef.steps[current_step];
136
135
 
137
136
  // Initialize steps object from cookbook if not present
138
- // V2: steps is an object keyed by step_id, not an array
137
+ // V2: steps is an object keyed by step_id
139
138
  let existingSteps = enrichedContext.steps || {};
140
139
 
141
140
  // Initialize from cookbook if empty
142
141
  if (Object.keys(existingSteps).length === 0) {
143
- cookbookDef.steps.forEach(s => {
144
- if (s.step_id) {
145
- existingSteps[s.step_id] = { ...s };
146
- }
142
+ Object.entries(cookbookDef.steps).forEach(([key, s]) => {
143
+ existingSteps[key] = { ...s };
147
144
  });
148
145
  }
149
146
 
@@ -175,6 +172,12 @@ class WorkflowOrchestrator {
175
172
  steps: existingSteps // Object keyed by step_id
176
173
  };
177
174
 
175
+ // V2: Get step order from object keys (JavaScript preserves insertion order for string keys)
176
+ const stepKeys = Object.keys(cookbookDef.steps);
177
+ const currentIndex = stepKeys.indexOf(current_step);
178
+ const nextStepKey = stepKeys[currentIndex + 1];
179
+ const nextStep = nextStepKey ? cookbookDef.steps[nextStepKey] : null;
180
+
178
181
  // Publish workflow.progress AFTER execution (so we have step output)
179
182
  const { publishToMonitoringWorkflow } = require('@onlineapps/mq-client-core').monitoring;
180
183
  try {
@@ -201,9 +204,6 @@ class WorkflowOrchestrator {
201
204
  });
202
205
  }
203
206
 
204
- // Find next step (currentIndex already defined above)
205
- const nextStep = cookbookDef.steps[currentIndex + 1];
206
-
207
207
  if (nextStep) {
208
208
  // Route to next step
209
209
  const nextStepId = nextStep.step_id;
@@ -752,22 +752,36 @@ class WorkflowOrchestrator {
752
752
  throw new Error(`FAIL-FAST: Invalid version format '${version}'. Must be 2.x.x (e.g., 2.0.0)`);
753
753
  }
754
754
 
755
- // Check steps
756
- if (!cookbook.steps || !Array.isArray(cookbook.steps) || cookbook.steps.length === 0) {
755
+ // Check steps - V2 FORMAT: steps MUST be an OBJECT (keyed by step_id), NOT an array!
756
+ if (!cookbook.steps || typeof cookbook.steps !== 'object') {
757
+ throw new Error('FAIL-FAST: Cookbook must have steps object');
758
+ }
759
+
760
+ // V1 format (array) is BANNED!
761
+ if (Array.isArray(cookbook.steps)) {
762
+ throw new Error('FAIL-FAST: V1 FORMAT BANNED! Cookbook steps must be an OBJECT (keyed by step_id), NOT an array!');
763
+ }
764
+
765
+ const stepKeys = Object.keys(cookbook.steps);
766
+ if (stepKeys.length === 0) {
757
767
  throw new Error('FAIL-FAST: Cookbook must have at least one step');
758
768
  }
759
769
 
760
770
  // Validate each step has step_id (V2) not id (V1)
761
771
  const invalidSteps = [];
762
- cookbook.steps.forEach((step, index) => {
772
+ stepKeys.forEach((stepKey) => {
773
+ const step = cookbook.steps[stepKey];
763
774
  if (step.id && !step.step_id) {
764
- invalidSteps.push(`Step ${index}: has 'id' (V1) but missing 'step_id' (V2)`);
775
+ invalidSteps.push(`Step '${stepKey}': has 'id' (V1) but missing 'step_id' (V2)`);
765
776
  }
766
777
  if (!step.step_id) {
767
- invalidSteps.push(`Step ${index}: missing required 'step_id'`);
778
+ invalidSteps.push(`Step '${stepKey}': missing required 'step_id'`);
779
+ }
780
+ if (step.step_id !== stepKey) {
781
+ invalidSteps.push(`Step '${stepKey}': step_id '${step.step_id}' does not match key '${stepKey}'`);
768
782
  }
769
783
  if (!step.type) {
770
- invalidSteps.push(`Step ${index} (${step.step_id || 'unknown'}): missing required 'type'`);
784
+ invalidSteps.push(`Step '${stepKey}': missing required 'type'`);
771
785
  }
772
786
  });
773
787
 
@@ -777,7 +791,7 @@ class WorkflowOrchestrator {
777
791
 
778
792
  this.logger.info('[WorkflowOrchestrator] V2 format validation passed', {
779
793
  version: cookbook.version,
780
- steps: cookbook.steps.map(s => s.step_id)
794
+ steps: Object.keys(cookbook.steps)
781
795
  });
782
796
  }
783
797
  }