Files

106 lines
2.5 KiB
Go

package executors
import (
"context"
"github.com/lyzrai/flow/pkg/engine"
"github.com/lyzrai/flow/pkg/models"
)
// SetExecutor adds, modifies, or removes fields on each input item.
// Supports n8n v1/v2 (parameters.values.{string,number,boolean}) and v3
// (parameters.assignments.assignments / parameters.fields.values) layouts.
type SetExecutor struct{}
func (e *SetExecutor) Execute(_ context.Context, node models.NodeDef, inputs [][]models.Item, _ *engine.ExecutionContext) (map[int][]models.Item, error) {
var inputItems []models.Item
for _, input := range inputs {
inputItems = append(inputItems, input...)
}
assignments := getAssignments(node.Parameters)
var result []models.Item
for _, item := range inputItems {
newItem := copyItem(item)
for _, a := range assignments {
newItem[a.name] = a.value
}
result = append(result, newItem)
}
return map[int][]models.Item{0: result}, nil
}
type assignment struct {
name string
value any
}
func getAssignments(params map[string]any) []assignment {
var result []assignment
if assignmentsObj, ok := params["assignments"].(map[string]any); ok {
if list, ok := assignmentsObj["assignments"].([]any); ok {
for _, item := range list {
if m, ok := item.(map[string]any); ok {
name, _ := m["name"].(string)
value := m["value"]
if name != "" {
result = append(result, assignment{name: name, value: value})
}
}
}
return result
}
}
if fieldsObj, ok := params["fields"].(map[string]any); ok {
if list, ok := fieldsObj["values"].([]any); ok {
for _, item := range list {
if m, ok := item.(map[string]any); ok {
name, _ := m["name"].(string)
if name == "" {
continue
}
for _, vKey := range []string{"stringValue", "numberValue", "booleanValue", "value"} {
if v, exists := m[vKey]; exists {
result = append(result, assignment{name: name, value: v})
break
}
}
}
}
if len(result) > 0 {
return result
}
}
}
if values, ok := params["values"].(map[string]any); ok {
for _, typeName := range []string{"string", "number", "boolean"} {
if list, ok := values[typeName].([]any); ok {
for _, item := range list {
if m, ok := item.(map[string]any); ok {
name, _ := m["name"].(string)
value := m["value"]
if name != "" {
result = append(result, assignment{name: name, value: value})
}
}
}
}
}
}
return result
}
func copyItem(item models.Item) models.Item {
cp := make(models.Item, len(item))
for k, v := range item {
cp[k] = v
}
return cp
}