bring back yahoo pipes!
at main 104 lines 2.7 kB view raw
1package transforms 2 3import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/kierank/pipes/nodes" 9) 10 11type MapNode struct{} 12 13func (n *MapNode) Type() string { return "map" } 14func (n *MapNode) Label() string { return "Map Fields" } 15func (n *MapNode) Description() string { return "Rename, extract, or create new fields" } 16func (n *MapNode) Category() string { return "transform" } 17func (n *MapNode) Inputs() int { return 1 } 18func (n *MapNode) Outputs() int { return 1 } 19 20func (n *MapNode) Execute(ctx context.Context, config map[string]interface{}, inputs [][]interface{}, execCtx *nodes.Context) ([]interface{}, error) { 21 if len(inputs) == 0 || len(inputs[0]) == 0 { 22 return []interface{}{}, nil 23 } 24 25 items := inputs[0] 26 mappings, _ := config["mappings"].(string) 27 keepOriginal, _ := config["keep_original"].(bool) 28 29 if mappings == "" { 30 return items, nil 31 } 32 33 // Parse mappings: "newField:sourceField, title:name" 34 fieldMap := parseMappings(mappings) 35 36 var result []interface{} 37 for _, item := range items { 38 itemMap, ok := item.(map[string]interface{}) 39 if !ok { 40 result = append(result, item) 41 continue 42 } 43 44 var newItem map[string]interface{} 45 if keepOriginal { 46 newItem = make(map[string]interface{}) 47 for k, v := range itemMap { 48 newItem[k] = v 49 } 50 } else { 51 newItem = make(map[string]interface{}) 52 } 53 54 for newField, sourceField := range fieldMap { 55 if val := getNestedValue(itemMap, sourceField); val != nil { 56 newItem[newField] = val 57 } 58 } 59 60 result = append(result, newItem) 61 } 62 63 execCtx.Log("map", "info", fmt.Sprintf("Mapped %d items", len(result))) 64 return result, nil 65} 66 67func parseMappings(s string) map[string]string { 68 result := make(map[string]string) 69 parts := strings.Split(s, ",") 70 for _, part := range parts { 71 part = strings.TrimSpace(part) 72 if kv := strings.SplitN(part, ":", 2); len(kv) == 2 { 73 result[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1]) 74 } 75 } 76 return result 77} 78 79func (n *MapNode) ValidateConfig(config map[string]interface{}) error { 80 return nil 81} 82 83func (n *MapNode) GetConfigSchema() *nodes.ConfigSchema { 84 return &nodes.ConfigSchema{ 85 Fields: []nodes.ConfigField{ 86 { 87 Name: "mappings", 88 Label: "Field Mappings", 89 Type: "textarea", 90 Required: true, 91 Placeholder: "title:name, url:link, summary:description", 92 HelpText: "Map fields as newField:sourceField, separated by commas. Use dot notation for nested fields.", 93 }, 94 { 95 Name: "keep_original", 96 Label: "Keep Original Fields", 97 Type: "checkbox", 98 Required: false, 99 DefaultValue: true, 100 HelpText: "Keep all original fields in addition to mapped ones", 101 }, 102 }, 103 } 104}