@teleporthq/teleport-plugin-next-workflows 0.43.30 → 0.43.31

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.
@@ -23,6 +23,27 @@ export const getEdgesTo = (nodeId: string, edges: UIDLWorkflowEdge[]): UIDLWorkf
23
23
  return edges.filter((e) => e.target === nodeId)
24
24
  }
25
25
 
26
+ /**
27
+ * Recursively collect every workflow-context node id a config references, i.e.
28
+ * the ids inside `{ type: 'workflowContext', nodeId: '<id>', path: [...] }`
29
+ * objects embedded anywhere in a node's config (filter values, column mappings,
30
+ * loop collections, custom-js params, …).
31
+ */
32
+ export const collectWorkflowContextNodeIds = (value: unknown, out: Set<string>): void => {
33
+ if (!value || typeof value !== 'object') {
34
+ return
35
+ }
36
+ if (Array.isArray(value)) {
37
+ value.forEach((item) => collectWorkflowContextNodeIds(item, out))
38
+ return
39
+ }
40
+ const record = value as Record<string, unknown>
41
+ if (record.type === 'workflowContext' && typeof record.nodeId === 'string') {
42
+ out.add(record.nodeId)
43
+ }
44
+ Object.values(record).forEach((child) => collectWorkflowContextNodeIds(child, out))
45
+ }
46
+
26
47
  export const getTopologicalOrder = (
27
48
  nodes: UIDLWorkflowNode[],
28
49
  edges: UIDLWorkflowEdge[]
@@ -44,6 +65,37 @@ export const getTopologicalOrder = (
44
65
  }
45
66
  })
46
67
 
68
+ // Virtual dependency edges from IMPLICIT data dependencies: a node that
69
+ // consumes another node's output via a `workflowContext` reference in its
70
+ // config MUST run after that node, even when no explicit edge wires them.
71
+ // Without this, a `data-create-item` that reads a `state-get-local-state`
72
+ // result only through its columnMappings is treated as in-degree 0 and can be
73
+ // ordered (and segmented) BEFORE the state read — so on the server it writes
74
+ // null for that column (run 0a5f554e: `titles.type_field` NOT-NULL violation;
75
+ // the "Add Asset" draft rows came through as "N/A" for the same reason).
76
+ // Control-flow nodes (loop/if/switch/parallel) are skipped — their outputs
77
+ // (e.g. a loop's `currentItem`) are scoped by dedicated edge handles, not a
78
+ // linear data dependency. Edges are added to this LOCAL graph only (never to
79
+ // `workflow.edges`), so loop/branch extraction elsewhere is unaffected.
80
+ const nodeTypeById = new Map(nodes.map((n) => [n.id, n.type]))
81
+ nodes.forEach((node) => {
82
+ const referencedIds = new Set<string>()
83
+ collectWorkflowContextNodeIds(node.config, referencedIds)
84
+ referencedIds.forEach((refId) => {
85
+ if (refId === node.id || !nodeIds.has(refId)) {
86
+ return
87
+ }
88
+ if (isControlFlowNode(nodeTypeById.get(refId) || '')) {
89
+ return
90
+ }
91
+ if (adjacency[refId].includes(node.id)) {
92
+ return
93
+ }
94
+ adjacency[refId].push(node.id)
95
+ inDegree[node.id]++
96
+ })
97
+ })
98
+
47
99
  const queue: string[] = []
48
100
  nodeIdArr.forEach((id) => {
49
101
  if (inDegree[id] === 0) {