refactor(workflow): convert all plugins to class/struct + factory pattern

- Python: class extending NodeExecutor + factory.py (80+ plugins)
- TypeScript: class implements NodeExecutor + factory.ts (7 groups, 116 classes)
- Go: struct with methods + factory.go (36 plugins)
- Rust: struct impl NodeExecutor trait + factory.rs (54 plugins)
- Mojo: struct + factory.mojo (11 plugins)

All package.json files now include:
- files array listing source files
- metadata.class/struct field
- metadata.entrypoint field

This enables a unified plugin loading system across all languages
with no import side effects (Spring-style DI pattern).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-22 14:53:04 +00:00
parent 2562c2f55b
commit 7ce8b4ae8a
653 changed files with 13243 additions and 3034 deletions

View File

@@ -1,23 +1,37 @@
// Package convert_parse_json provides the parse JSON plugin.
// Package convert_parse_json provides a workflow plugin for parsing JSON strings.
package convert_parse_json
import (
"encoding/json"
plugin "metabuilder/workflow/plugins/go"
)
// Run parses a JSON string to object.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// ConvertParseJson implements the NodeExecutor interface for parsing JSON strings.
type ConvertParseJson struct {
NodeType string
Category string
Description string
}
// NewConvertParseJson creates a new ConvertParseJson instance.
func NewConvertParseJson() *ConvertParseJson {
return &ConvertParseJson{
NodeType: "convert.parse_json",
Category: "convert",
Description: "Parse a JSON string to object",
}
}
// Execute runs the plugin logic.
func (p *ConvertParseJson) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
str, ok := inputs["string"].(string)
if !ok {
return map[string]interface{}{"result": nil, "error": "string is required"}, nil
return map[string]interface{}{"result": nil, "error": "string is required"}
}
var result interface{}
if err := json.Unmarshal([]byte(str), &result); err != nil {
return map[string]interface{}{"result": nil, "error": err.Error()}, nil
return map[string]interface{}{"result": nil, "error": err.Error()}
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -0,0 +1,7 @@
// Package convert_parse_json provides factory for ConvertParseJson plugin.
package convert_parse_json
// Create returns a new ConvertParseJson instance.
func Create() *ConvertParseJson {
return NewConvertParseJson()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_parse_json.go",
"files": ["convert_parse_json.go", "factory.go"],
"metadata": {
"plugin_type": "convert.parse_json",
"category": "convert"
"category": "convert",
"struct": "ConvertParseJson",
"entrypoint": "Execute"
}
}

View File

@@ -1,14 +1,28 @@
// Package convert_to_boolean provides the convert to boolean plugin.
// Package convert_to_boolean provides a workflow plugin for converting values to booleans.
package convert_to_boolean
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run converts a value to boolean.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// ConvertToBoolean implements the NodeExecutor interface for converting values to booleans.
type ConvertToBoolean struct {
NodeType string
Category string
Description string
}
// NewConvertToBoolean creates a new ConvertToBoolean instance.
func NewConvertToBoolean() *ConvertToBoolean {
return &ConvertToBoolean{
NodeType: "convert.to_boolean",
Category: "convert",
Description: "Convert a value to boolean",
}
}
// Execute runs the plugin logic.
func (p *ConvertToBoolean) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
value := inputs["value"]
var result bool
@@ -31,5 +45,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
result = true // Non-nil values are truthy
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -0,0 +1,7 @@
// Package convert_to_boolean provides factory for ConvertToBoolean plugin.
package convert_to_boolean
// Create returns a new ConvertToBoolean instance.
func Create() *ConvertToBoolean {
return NewConvertToBoolean()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_boolean.go",
"files": ["convert_to_boolean.go", "factory.go"],
"metadata": {
"plugin_type": "convert.to_boolean",
"category": "convert"
"category": "convert",
"struct": "ConvertToBoolean",
"entrypoint": "Execute"
}
}

View File

@@ -1,14 +1,28 @@
// Package convert_to_json provides the convert to JSON plugin.
// Package convert_to_json provides a workflow plugin for converting values to JSON.
package convert_to_json
import (
"encoding/json"
plugin "metabuilder/workflow/plugins/go"
)
// Run converts a value to JSON string.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// ConvertToJson implements the NodeExecutor interface for converting values to JSON.
type ConvertToJson struct {
NodeType string
Category string
Description string
}
// NewConvertToJson creates a new ConvertToJson instance.
func NewConvertToJson() *ConvertToJson {
return &ConvertToJson{
NodeType: "convert.to_json",
Category: "convert",
Description: "Convert a value to JSON string",
}
}
// Execute runs the plugin logic.
func (p *ConvertToJson) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
value := inputs["value"]
pretty := false
if p, ok := inputs["pretty"].(bool); ok {
@@ -25,8 +39,8 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
if err != nil {
return map[string]interface{}{"result": "", "error": err.Error()}, nil
return map[string]interface{}{"result": "", "error": err.Error()}
}
return map[string]interface{}{"result": string(bytes)}, nil
return map[string]interface{}{"result": string(bytes)}
}

View File

@@ -0,0 +1,7 @@
// Package convert_to_json provides factory for ConvertToJson plugin.
package convert_to_json
// Create returns a new ConvertToJson instance.
func Create() *ConvertToJson {
return NewConvertToJson()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_json.go",
"files": ["convert_to_json.go", "factory.go"],
"metadata": {
"plugin_type": "convert.to_json",
"category": "convert"
"category": "convert",
"struct": "ConvertToJson",
"entrypoint": "Execute"
}
}

View File

@@ -1,14 +1,28 @@
// Package convert_to_number provides the convert to number plugin.
// Package convert_to_number provides a workflow plugin for converting values to numbers.
package convert_to_number
import (
"strconv"
plugin "metabuilder/workflow/plugins/go"
)
// Run converts a value to number.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// ConvertToNumber implements the NodeExecutor interface for converting values to numbers.
type ConvertToNumber struct {
NodeType string
Category string
Description string
}
// NewConvertToNumber creates a new ConvertToNumber instance.
func NewConvertToNumber() *ConvertToNumber {
return &ConvertToNumber{
NodeType: "convert.to_number",
Category: "convert",
Description: "Convert a value to number",
}
}
// Execute runs the plugin logic.
func (p *ConvertToNumber) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
value := inputs["value"]
var result float64
@@ -24,7 +38,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
case string:
result, err = strconv.ParseFloat(v, 64)
if err != nil {
return map[string]interface{}{"result": 0, "error": "invalid number string"}, nil
return map[string]interface{}{"result": 0, "error": "invalid number string"}
}
case bool:
if v {
@@ -33,8 +47,8 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
result = 0
}
default:
return map[string]interface{}{"result": 0, "error": "cannot convert to number"}, nil
return map[string]interface{}{"result": 0, "error": "cannot convert to number"}
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -0,0 +1,7 @@
// Package convert_to_number provides factory for ConvertToNumber plugin.
package convert_to_number
// Create returns a new ConvertToNumber instance.
func Create() *ConvertToNumber {
return NewConvertToNumber()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_number.go",
"files": ["convert_to_number.go", "factory.go"],
"metadata": {
"plugin_type": "convert.to_number",
"category": "convert"
"category": "convert",
"struct": "ConvertToNumber",
"entrypoint": "Execute"
}
}

View File

@@ -1,15 +1,29 @@
// Package convert_to_string provides the convert to string plugin.
// Package convert_to_string provides a workflow plugin for converting values to strings.
package convert_to_string
import (
"encoding/json"
"fmt"
plugin "metabuilder/workflow/plugins/go"
)
// Run converts a value to string.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// ConvertToString implements the NodeExecutor interface for converting values to strings.
type ConvertToString struct {
NodeType string
Category string
Description string
}
// NewConvertToString creates a new ConvertToString instance.
func NewConvertToString() *ConvertToString {
return &ConvertToString{
NodeType: "convert.to_string",
Category: "convert",
Description: "Convert a value to string",
}
}
// Execute runs the plugin logic.
func (p *ConvertToString) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
value := inputs["value"]
var result string
@@ -29,5 +43,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -0,0 +1,7 @@
// Package convert_to_string provides factory for ConvertToString plugin.
package convert_to_string
// Create returns a new ConvertToString instance.
func Create() *ConvertToString {
return NewConvertToString()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_string.go",
"files": ["convert_to_string.go", "factory.go"],
"metadata": {
"plugin_type": "convert.to_string",
"category": "convert"
"category": "convert",
"struct": "ConvertToString",
"entrypoint": "Execute"
}
}

View File

@@ -1,13 +1,28 @@
// Package dict_delete provides the dictionary delete plugin.
// Package dict_delete provides a workflow plugin for deleting dictionary keys.
package dict_delete
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run removes a key from a dictionary.
// DictDelete implements the NodeExecutor interface for deleting dictionary keys.
type DictDelete struct {
NodeType string
Category string
Description string
}
// NewDictDelete creates a new DictDelete instance.
func NewDictDelete() *DictDelete {
return &DictDelete{
NodeType: "dict.delete",
Category: "dict",
Description: "Delete a key from a dictionary",
}
}
// Execute runs the plugin logic.
// Removes a key from a dictionary.
// Supports dot notation for nested keys (e.g., "user.name").
// Inputs:
// - dict: the dictionary to modify
@@ -16,10 +31,10 @@ import (
// Returns:
// - result: the modified dictionary
// - deleted: whether the key was found and deleted
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *DictDelete) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
dict, ok := inputs["dict"].(map[string]interface{})
if !ok {
return map[string]interface{}{"result": map[string]interface{}{}, "deleted": false}, nil
return map[string]interface{}{"result": map[string]interface{}{}, "deleted": false}
}
// Make a shallow copy to avoid mutating the original
@@ -27,7 +42,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
key, ok := inputs["key"].(string)
if !ok {
return map[string]interface{}{"result": dict, "deleted": false}, nil
return map[string]interface{}{"result": dict, "deleted": false}
}
// Handle dot notation for nested keys
@@ -37,9 +52,9 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
// Simple key
if _, exists := dict[key]; exists {
delete(dict, key)
return map[string]interface{}{"result": dict, "deleted": true}, nil
return map[string]interface{}{"result": dict, "deleted": true}
}
return map[string]interface{}{"result": dict, "deleted": false}, nil
return map[string]interface{}{"result": dict, "deleted": false}
}
// Nested key - navigate to parent and delete
@@ -54,11 +69,11 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
current = copied
} else {
// Cannot descend further
return map[string]interface{}{"result": dict, "deleted": false}, nil
return map[string]interface{}{"result": dict, "deleted": false}
}
} else {
// Path does not exist
return map[string]interface{}{"result": dict, "deleted": false}, nil
return map[string]interface{}{"result": dict, "deleted": false}
}
}
@@ -66,10 +81,10 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
finalKey := parts[len(parts)-1]
if _, exists := current[finalKey]; exists {
delete(current, finalKey)
return map[string]interface{}{"result": dict, "deleted": true}, nil
return map[string]interface{}{"result": dict, "deleted": true}
}
return map[string]interface{}{"result": dict, "deleted": false}, nil
return map[string]interface{}{"result": dict, "deleted": false}
}
// copyDict creates a shallow copy of a dictionary.

View File

@@ -0,0 +1,7 @@
// Package dict_delete provides factory for DictDelete plugin.
package dict_delete
// Create returns a new DictDelete instance.
func Create() *DictDelete {
return NewDictDelete()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["dict", "workflow", "plugin"],
"main": "dict_delete.go",
"files": ["dict_delete.go", "factory.go"],
"metadata": {
"plugin_type": "dict.delete",
"category": "dict"
"category": "dict",
"struct": "DictDelete",
"entrypoint": "Execute"
}
}

View File

@@ -1,13 +1,28 @@
// Package dict_get provides the dictionary get plugin.
// Package dict_get provides a workflow plugin for getting dictionary values.
package dict_get
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run retrieves a value from a dictionary by key.
// DictGet implements the NodeExecutor interface for getting dictionary values.
type DictGet struct {
NodeType string
Category string
Description string
}
// NewDictGet creates a new DictGet instance.
func NewDictGet() *DictGet {
return &DictGet{
NodeType: "dict.get",
Category: "dict",
Description: "Get a value from a dictionary by key",
}
}
// Execute runs the plugin logic.
// Retrieves a value from a dictionary by key.
// Supports dot notation for nested keys (e.g., "user.name").
// Inputs:
// - dict: the dictionary to read from
@@ -17,17 +32,17 @@ import (
// Returns:
// - result: the value at the key or default
// - found: whether the key was found
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *DictGet) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
dict, ok := inputs["dict"].(map[string]interface{})
if !ok {
defaultVal := inputs["default"]
return map[string]interface{}{"result": defaultVal, "found": false}, nil
return map[string]interface{}{"result": defaultVal, "found": false}
}
key, ok := inputs["key"].(string)
if !ok {
defaultVal := inputs["default"]
return map[string]interface{}{"result": defaultVal, "found": false}, nil
return map[string]interface{}{"result": defaultVal, "found": false}
}
// Handle dot notation for nested keys
@@ -38,7 +53,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
if val, exists := current[part]; exists {
if i == len(parts)-1 {
// Final key, return the value
return map[string]interface{}{"result": val, "found": true}, nil
return map[string]interface{}{"result": val, "found": true}
}
// Not the final key, try to descend
if nested, ok := val.(map[string]interface{}); ok {
@@ -46,15 +61,15 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
} else {
// Cannot descend further
defaultVal := inputs["default"]
return map[string]interface{}{"result": defaultVal, "found": false}, nil
return map[string]interface{}{"result": defaultVal, "found": false}
}
} else {
// Key not found
defaultVal := inputs["default"]
return map[string]interface{}{"result": defaultVal, "found": false}, nil
return map[string]interface{}{"result": defaultVal, "found": false}
}
}
defaultVal := inputs["default"]
return map[string]interface{}{"result": defaultVal, "found": false}, nil
return map[string]interface{}{"result": defaultVal, "found": false}
}

View File

@@ -0,0 +1,7 @@
// Package dict_get provides factory for DictGet plugin.
package dict_get
// Create returns a new DictGet instance.
func Create() *DictGet {
return NewDictGet()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["dict", "workflow", "plugin"],
"main": "dict_get.go",
"files": ["dict_get.go", "factory.go"],
"metadata": {
"plugin_type": "dict.get",
"category": "dict"
"category": "dict",
"struct": "DictGet",
"entrypoint": "Execute"
}
}

View File

@@ -1,23 +1,38 @@
// Package dict_keys provides the dictionary keys plugin.
// Package dict_keys provides a workflow plugin for getting dictionary keys.
package dict_keys
import (
"sort"
plugin "metabuilder/workflow/plugins/go"
)
// Run returns all keys from a dictionary.
// DictKeys implements the NodeExecutor interface for getting dictionary keys.
type DictKeys struct {
NodeType string
Category string
Description string
}
// NewDictKeys creates a new DictKeys instance.
func NewDictKeys() *DictKeys {
return &DictKeys{
NodeType: "dict.keys",
Category: "dict",
Description: "Get all keys from a dictionary",
}
}
// Execute runs the plugin logic.
// Returns all keys from a dictionary.
// Inputs:
// - dict: the dictionary to get keys from
// - sorted: (optional) whether to sort keys alphabetically (default: false)
//
// Returns:
// - result: list of keys
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *DictKeys) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
dict, ok := inputs["dict"].(map[string]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
keys := make([]interface{}, 0, len(dict))
@@ -34,5 +49,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
})
}
return map[string]interface{}{"result": keys}, nil
return map[string]interface{}{"result": keys}
}

View File

@@ -0,0 +1,7 @@
// Package dict_keys provides factory for DictKeys plugin.
package dict_keys
// Create returns a new DictKeys instance.
func Create() *DictKeys {
return NewDictKeys()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["dict", "workflow", "plugin"],
"main": "dict_keys.go",
"files": ["dict_keys.go", "factory.go"],
"metadata": {
"plugin_type": "dict.keys",
"category": "dict"
"category": "dict",
"struct": "DictKeys",
"entrypoint": "Execute"
}
}

View File

@@ -1,11 +1,24 @@
// Package dict_merge provides the dictionary merge plugin.
// Package dict_merge provides a workflow plugin for merging dictionaries.
package dict_merge
import (
plugin "metabuilder/workflow/plugins/go"
)
// DictMerge implements the NodeExecutor interface for merging dictionaries.
type DictMerge struct {
NodeType string
Category string
Description string
}
// Run combines multiple dictionaries into one.
// NewDictMerge creates a new DictMerge instance.
func NewDictMerge() *DictMerge {
return &DictMerge{
NodeType: "dict.merge",
Category: "dict",
Description: "Merge multiple dictionaries into one",
}
}
// Execute runs the plugin logic.
// Combines multiple dictionaries into one.
// Later dictionaries override earlier ones for duplicate keys.
// Inputs:
// - dicts: list of dictionaries to merge
@@ -13,10 +26,10 @@ import (
//
// Returns:
// - result: the merged dictionary
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *DictMerge) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
dicts, ok := inputs["dicts"].([]interface{})
if !ok {
return map[string]interface{}{"result": map[string]interface{}{}}, nil
return map[string]interface{}{"result": map[string]interface{}{}}
}
deep := false
@@ -39,7 +52,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}
// shallowMerge copies all keys from src to dst, overwriting existing keys.

View File

@@ -0,0 +1,7 @@
// Package dict_merge provides factory for DictMerge plugin.
package dict_merge
// Create returns a new DictMerge instance.
func Create() *DictMerge {
return NewDictMerge()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["dict", "workflow", "plugin"],
"main": "dict_merge.go",
"files": ["dict_merge.go", "factory.go"],
"metadata": {
"plugin_type": "dict.merge",
"category": "dict"
"category": "dict",
"struct": "DictMerge",
"entrypoint": "Execute"
}
}

View File

@@ -1,13 +1,28 @@
// Package dict_set provides the dictionary set plugin.
// Package dict_set provides a workflow plugin for setting dictionary values.
package dict_set
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run sets a value in a dictionary by key.
// DictSet implements the NodeExecutor interface for setting dictionary values.
type DictSet struct {
NodeType string
Category string
Description string
}
// NewDictSet creates a new DictSet instance.
func NewDictSet() *DictSet {
return &DictSet{
NodeType: "dict.set",
Category: "dict",
Description: "Set a value in a dictionary by key",
}
}
// Execute runs the plugin logic.
// Sets a value in a dictionary by key.
// Supports dot notation for nested keys (e.g., "user.name").
// Creates intermediate objects as needed.
// Inputs:
@@ -17,7 +32,7 @@ import (
//
// Returns:
// - result: the modified dictionary
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *DictSet) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
dict, ok := inputs["dict"].(map[string]interface{})
if !ok {
dict = make(map[string]interface{})
@@ -28,7 +43,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
key, ok := inputs["key"].(string)
if !ok {
return map[string]interface{}{"result": dict}, nil
return map[string]interface{}{"result": dict}
}
value := inputs["value"]
@@ -39,7 +54,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
if len(parts) == 1 {
// Simple key
dict[key] = value
return map[string]interface{}{"result": dict}, nil
return map[string]interface{}{"result": dict}
}
// Nested key - navigate/create intermediate objects
@@ -69,7 +84,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
// Set the final value
current[parts[len(parts)-1]] = value
return map[string]interface{}{"result": dict}, nil
return map[string]interface{}{"result": dict}
}
// copyDict creates a shallow copy of a dictionary.

View File

@@ -0,0 +1,7 @@
// Package dict_set provides factory for DictSet plugin.
package dict_set
// Create returns a new DictSet instance.
func Create() *DictSet {
return NewDictSet()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["dict", "workflow", "plugin"],
"main": "dict_set.go",
"files": ["dict_set.go", "factory.go"],
"metadata": {
"plugin_type": "dict.set",
"category": "dict"
"category": "dict",
"struct": "DictSet",
"entrypoint": "Execute"
}
}

View File

@@ -1,23 +1,38 @@
// Package dict_values provides the dictionary values plugin.
// Package dict_values provides a workflow plugin for getting dictionary values.
package dict_values
import (
"sort"
plugin "metabuilder/workflow/plugins/go"
)
// Run returns all values from a dictionary.
// DictValues implements the NodeExecutor interface for getting dictionary values.
type DictValues struct {
NodeType string
Category string
Description string
}
// NewDictValues creates a new DictValues instance.
func NewDictValues() *DictValues {
return &DictValues{
NodeType: "dict.values",
Category: "dict",
Description: "Get all values from a dictionary",
}
}
// Execute runs the plugin logic.
// Returns all values from a dictionary.
// Inputs:
// - dict: the dictionary to get values from
// - sorted_by_key: (optional) return values sorted by their keys (default: false)
//
// Returns:
// - result: list of values
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *DictValues) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
dict, ok := inputs["dict"].(map[string]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
sortedByKey := false
@@ -38,7 +53,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
for _, k := range keys {
values = append(values, dict[k])
}
return map[string]interface{}{"result": values}, nil
return map[string]interface{}{"result": values}
}
// Return values in arbitrary order
@@ -47,5 +62,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
values = append(values, v)
}
return map[string]interface{}{"result": values}, nil
return map[string]interface{}{"result": values}
}

View File

@@ -0,0 +1,7 @@
// Package dict_values provides factory for DictValues plugin.
package dict_values
// Create returns a new DictValues instance.
func Create() *DictValues {
return NewDictValues()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["dict", "workflow", "plugin"],
"main": "dict_values.go",
"files": ["dict_values.go", "factory.go"],
"metadata": {
"plugin_type": "dict.values",
"category": "dict"
"category": "dict",
"struct": "DictValues",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_concat provides factory for ListConcat plugin.
package list_concat
// Create returns a new ListConcat instance.
func Create() *ListConcat {
return NewListConcat()
}

View File

@@ -1,15 +1,27 @@
// Package list_concat provides the concatenate lists plugin.
// Package list_concat provides a workflow plugin for concatenating lists.
package list_concat
import (
plugin "metabuilder/workflow/plugins/go"
)
// ListConcat implements the NodeExecutor interface for concatenating lists.
type ListConcat struct {
NodeType string
Category string
Description string
}
// Run concatenates multiple lists.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewListConcat creates a new ListConcat instance.
func NewListConcat() *ListConcat {
return &ListConcat{
NodeType: "list.concat",
Category: "list",
Description: "Concatenate multiple lists",
}
}
// Execute runs the plugin logic.
func (p *ListConcat) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
lists, ok := inputs["lists"].([]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
var result []interface{}
@@ -19,5 +31,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_concat.go",
"files": ["list_concat.go", "factory.go"],
"metadata": {
"plugin_type": "list.concat",
"category": "list"
"category": "list",
"struct": "ListConcat",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_find provides factory for ListFind plugin.
package list_find
// Create returns a new ListFind instance.
func Create() *ListFind {
return NewListFind()
}

View File

@@ -1,11 +1,23 @@
// Package list_find provides the list find plugin.
// Package list_find provides a workflow plugin for finding elements in lists.
package list_find
import (
plugin "metabuilder/workflow/plugins/go"
)
// ListFind implements the NodeExecutor interface for finding elements in lists.
type ListFind struct {
NodeType string
Category string
Description string
}
// Run returns the first element matching a condition or key/value pair.
// NewListFind creates a new ListFind instance.
func NewListFind() *ListFind {
return &ListFind{
NodeType: "list.find",
Category: "list",
Description: "Find first element matching a condition",
}
}
// Execute runs the plugin logic.
// Inputs:
// - list: the list to search
// - key: (optional) the key to match in objects
@@ -14,10 +26,10 @@ import (
// Returns:
// - result: the first matching element or nil
// - index: the index of the match or -1
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *ListFind) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
list, ok := inputs["list"].([]interface{})
if !ok {
return map[string]interface{}{"result": nil, "index": -1}, nil
return map[string]interface{}{"result": nil, "index": -1}
}
value := inputs["value"]
@@ -28,16 +40,16 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
// Search by key/value in objects
if obj, ok := item.(map[string]interface{}); ok {
if objVal, exists := obj[key]; exists && objVal == value {
return map[string]interface{}{"result": item, "index": i}, nil
return map[string]interface{}{"result": item, "index": i}
}
}
} else {
// Direct value comparison
if item == value {
return map[string]interface{}{"result": item, "index": i}, nil
return map[string]interface{}{"result": item, "index": i}
}
}
}
return map[string]interface{}{"result": nil, "index": -1}, nil
return map[string]interface{}{"result": nil, "index": -1}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_find.go",
"files": ["list_find.go", "factory.go"],
"metadata": {
"plugin_type": "list.find",
"category": "list"
"category": "list",
"struct": "ListFind",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_length provides factory for ListLength plugin.
package list_length
// Create returns a new ListLength instance.
func Create() *ListLength {
return NewListLength()
}

View File

@@ -1,16 +1,28 @@
// Package list_length provides the list length plugin.
// Package list_length provides a workflow plugin for getting list length.
package list_length
import (
plugin "metabuilder/workflow/plugins/go"
)
// ListLength implements the NodeExecutor interface for getting list length.
type ListLength struct {
NodeType string
Category string
Description string
}
// Run returns the length of a list.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewListLength creates a new ListLength instance.
func NewListLength() *ListLength {
return &ListLength{
NodeType: "list.length",
Category: "list",
Description: "Get the length of a list",
}
}
// Execute runs the plugin logic.
func (p *ListLength) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
list, ok := inputs["list"].([]interface{})
if !ok {
return map[string]interface{}{"result": 0}, nil
return map[string]interface{}{"result": 0}
}
return map[string]interface{}{"result": len(list)}, nil
return map[string]interface{}{"result": len(list)}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_length.go",
"files": ["list_length.go", "factory.go"],
"metadata": {
"plugin_type": "list.length",
"category": "list"
"category": "list",
"struct": "ListLength",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_reverse provides factory for ListReverse plugin.
package list_reverse
// Create returns a new ListReverse instance.
func Create() *ListReverse {
return NewListReverse()
}

View File

@@ -1,15 +1,27 @@
// Package list_reverse provides the list reverse plugin.
// Package list_reverse provides a workflow plugin for reversing lists.
package list_reverse
import (
plugin "metabuilder/workflow/plugins/go"
)
// ListReverse implements the NodeExecutor interface for reversing lists.
type ListReverse struct {
NodeType string
Category string
Description string
}
// Run reverses a list.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewListReverse creates a new ListReverse instance.
func NewListReverse() *ListReverse {
return &ListReverse{
NodeType: "list.reverse",
Category: "list",
Description: "Reverse a list",
}
}
// Execute runs the plugin logic.
func (p *ListReverse) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
list, ok := inputs["list"].([]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
result := make([]interface{}, len(list))
@@ -17,5 +29,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
result[len(list)-1-i] = v
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_reverse.go",
"files": ["list_reverse.go", "factory.go"],
"metadata": {
"plugin_type": "list.reverse",
"category": "list"
"category": "list",
"struct": "ListReverse",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_slice provides factory for ListSlice plugin.
package list_slice
// Create returns a new ListSlice instance.
func Create() *ListSlice {
return NewListSlice()
}

View File

@@ -1,15 +1,27 @@
// Package list_slice provides the list slice plugin.
// Package list_slice provides a workflow plugin for slicing lists.
package list_slice
import (
plugin "metabuilder/workflow/plugins/go"
)
// ListSlice implements the NodeExecutor interface for slicing lists.
type ListSlice struct {
NodeType string
Category string
Description string
}
// Run extracts a portion of a list.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewListSlice creates a new ListSlice instance.
func NewListSlice() *ListSlice {
return &ListSlice{
NodeType: "list.slice",
Category: "list",
Description: "Extract a portion of a list",
}
}
// Execute runs the plugin logic.
func (p *ListSlice) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
list, ok := inputs["list"].([]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
start := 0
@@ -41,5 +53,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
start = end
}
return map[string]interface{}{"result": list[start:end]}, nil
return map[string]interface{}{"result": list[start:end]}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_slice.go",
"files": ["list_slice.go", "factory.go"],
"metadata": {
"plugin_type": "list.slice",
"category": "list"
"category": "list",
"struct": "ListSlice",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_sort provides factory for ListSort plugin.
package list_sort
// Create returns a new ListSort instance.
func Create() *ListSort {
return NewListSort()
}

View File

@@ -1,13 +1,27 @@
// Package list_sort provides the list sort plugin.
// Package list_sort provides a workflow plugin for sorting lists.
package list_sort
import (
"sort"
plugin "metabuilder/workflow/plugins/go"
)
// Run sorts a list of values.
// ListSort implements the NodeExecutor interface for sorting lists.
type ListSort struct {
NodeType string
Category string
Description string
}
// NewListSort creates a new ListSort instance.
func NewListSort() *ListSort {
return &ListSort{
NodeType: "list.sort",
Category: "list",
Description: "Sort a list of values",
}
}
// Execute runs the plugin logic.
// Inputs:
// - list: the list to sort
// - key: (optional) the key to sort by for objects
@@ -15,10 +29,10 @@ import (
//
// Returns:
// - result: the sorted list
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *ListSort) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
list, ok := inputs["list"].([]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
// Make a copy to avoid mutating the original
@@ -55,7 +69,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
return less
})
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}
// compareLess compares two values and returns true if a < b.

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_sort.go",
"files": ["list_sort.go", "factory.go"],
"metadata": {
"plugin_type": "list.sort",
"category": "list"
"category": "list",
"struct": "ListSort",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package list_unique provides factory for ListUnique plugin.
package list_unique
// Create returns a new ListUnique instance.
func Create() *ListUnique {
return NewListUnique()
}

View File

@@ -1,23 +1,37 @@
// Package list_unique provides the list unique plugin.
// Package list_unique provides a workflow plugin for removing duplicates from lists.
package list_unique
import (
"encoding/json"
plugin "metabuilder/workflow/plugins/go"
)
// Run removes duplicate elements from a list.
// ListUnique implements the NodeExecutor interface for removing duplicates from lists.
type ListUnique struct {
NodeType string
Category string
Description string
}
// NewListUnique creates a new ListUnique instance.
func NewListUnique() *ListUnique {
return &ListUnique{
NodeType: "list.unique",
Category: "list",
Description: "Remove duplicate elements from a list",
}
}
// Execute runs the plugin logic.
// Inputs:
// - list: the list to deduplicate
// - key: (optional) the key to use for uniqueness in objects
//
// Returns:
// - result: the list with duplicates removed
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
func (p *ListUnique) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
list, ok := inputs["list"].([]interface{})
if !ok {
return map[string]interface{}{"result": []interface{}{}}, nil
return map[string]interface{}{"result": []interface{}{}}
}
key, hasKey := inputs["key"].(string)
@@ -48,7 +62,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}
// toHashKey converts a value to a string suitable for use as a map key.

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["list", "workflow", "plugin"],
"main": "list_unique.go",
"files": ["list_unique.go", "factory.go"],
"metadata": {
"plugin_type": "list.unique",
"category": "list"
"category": "list",
"struct": "ListUnique",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package logic_and provides factory for LogicAnd plugin.
package logic_and
// Create returns a new LogicAnd instance.
func Create() *LogicAnd {
return NewLogicAnd()
}

View File

@@ -1,24 +1,36 @@
// Package logic_and provides the logical AND plugin.
// Package logic_and provides a workflow plugin for logical AND operations.
package logic_and
import (
plugin "metabuilder/workflow/plugins/go"
)
// LogicAnd implements the NodeExecutor interface for logical AND operations.
type LogicAnd struct {
NodeType string
Category string
Description string
}
// Run performs logical AND on boolean values.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewLogicAnd creates a new LogicAnd instance.
func NewLogicAnd() *LogicAnd {
return &LogicAnd{
NodeType: "logic.and",
Category: "logic",
Description: "Perform logical AND on boolean values",
}
}
// Execute runs the plugin logic.
func (p *LogicAnd) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
values, ok := inputs["values"].([]interface{})
if !ok || len(values) == 0 {
return map[string]interface{}{"result": false}, nil
return map[string]interface{}{"result": false}
}
for _, v := range values {
if !toBool(v) {
return map[string]interface{}{"result": false}, nil
return map[string]interface{}{"result": false}
}
}
return map[string]interface{}{"result": true}, nil
return map[string]interface{}{"result": true}
}
func toBool(v interface{}) bool {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["logic", "workflow", "plugin"],
"main": "logic_and.go",
"files": ["logic_and.go", "factory.go"],
"metadata": {
"plugin_type": "logic.and",
"category": "logic"
"category": "logic",
"struct": "LogicAnd",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package logic_equals provides factory for LogicEquals plugin.
package logic_equals
// Create returns a new LogicEquals instance.
func Create() *LogicEquals {
return NewLogicEquals()
}

View File

@@ -1,17 +1,31 @@
// Package logic_equals provides the equality check plugin.
// Package logic_equals provides a workflow plugin for equality checks.
package logic_equals
import (
"reflect"
plugin "metabuilder/workflow/plugins/go"
)
// Run checks if two values are equal.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// LogicEquals implements the NodeExecutor interface for equality checks.
type LogicEquals struct {
NodeType string
Category string
Description string
}
// NewLogicEquals creates a new LogicEquals instance.
func NewLogicEquals() *LogicEquals {
return &LogicEquals{
NodeType: "logic.equals",
Category: "logic",
Description: "Check if two values are equal",
}
}
// Execute runs the plugin logic.
func (p *LogicEquals) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
a := inputs["a"]
b := inputs["b"]
result := reflect.DeepEqual(a, b)
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["logic", "workflow", "plugin"],
"main": "logic_equals.go",
"files": ["logic_equals.go", "factory.go"],
"metadata": {
"plugin_type": "logic.equals",
"category": "logic"
"category": "logic",
"struct": "LogicEquals",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package logic_gt provides factory for LogicGt plugin.
package logic_gt
// Create returns a new LogicGt instance.
func Create() *LogicGt {
return NewLogicGt()
}

View File

@@ -1,16 +1,28 @@
// Package logic_gt provides the greater than comparison plugin.
// Package logic_gt provides a workflow plugin for greater than comparisons.
package logic_gt
import (
plugin "metabuilder/workflow/plugins/go"
)
// LogicGt implements the NodeExecutor interface for greater than comparisons.
type LogicGt struct {
NodeType string
Category string
Description string
}
// Run checks if a > b.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewLogicGt creates a new LogicGt instance.
func NewLogicGt() *LogicGt {
return &LogicGt{
NodeType: "logic.gt",
Category: "logic",
Description: "Check if a is greater than b",
}
}
// Execute runs the plugin logic.
func (p *LogicGt) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
a := toFloat(inputs["a"])
b := toFloat(inputs["b"])
return map[string]interface{}{"result": a > b}, nil
return map[string]interface{}{"result": a > b}
}
func toFloat(v interface{}) float64 {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["logic", "workflow", "plugin"],
"main": "logic_gt.go",
"files": ["logic_gt.go", "factory.go"],
"metadata": {
"plugin_type": "logic.gt",
"category": "logic"
"category": "logic",
"struct": "LogicGt",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package logic_lt provides factory for LogicLt plugin.
package logic_lt
// Create returns a new LogicLt instance.
func Create() *LogicLt {
return NewLogicLt()
}

View File

@@ -1,16 +1,28 @@
// Package logic_lt provides the less than comparison plugin.
// Package logic_lt provides a workflow plugin for less than comparisons.
package logic_lt
import (
plugin "metabuilder/workflow/plugins/go"
)
// LogicLt implements the NodeExecutor interface for less than comparisons.
type LogicLt struct {
NodeType string
Category string
Description string
}
// Run checks if a < b.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewLogicLt creates a new LogicLt instance.
func NewLogicLt() *LogicLt {
return &LogicLt{
NodeType: "logic.lt",
Category: "logic",
Description: "Check if a is less than b",
}
}
// Execute runs the plugin logic.
func (p *LogicLt) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
a := toFloat(inputs["a"])
b := toFloat(inputs["b"])
return map[string]interface{}{"result": a < b}, nil
return map[string]interface{}{"result": a < b}
}
func toFloat(v interface{}) float64 {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["logic", "workflow", "plugin"],
"main": "logic_lt.go",
"files": ["logic_lt.go", "factory.go"],
"metadata": {
"plugin_type": "logic.lt",
"category": "logic"
"category": "logic",
"struct": "LogicLt",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package logic_not provides factory for LogicNot plugin.
package logic_not
// Create returns a new LogicNot instance.
func Create() *LogicNot {
return NewLogicNot()
}

View File

@@ -1,14 +1,26 @@
// Package logic_not provides the logical NOT plugin.
// Package logic_not provides a workflow plugin for logical NOT operations.
package logic_not
import (
plugin "metabuilder/workflow/plugins/go"
)
// LogicNot implements the NodeExecutor interface for logical NOT operations.
type LogicNot struct {
NodeType string
Category string
Description string
}
// Run performs logical NOT on a boolean value.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewLogicNot creates a new LogicNot instance.
func NewLogicNot() *LogicNot {
return &LogicNot{
NodeType: "logic.not",
Category: "logic",
Description: "Perform logical NOT on a boolean value",
}
}
// Execute runs the plugin logic.
func (p *LogicNot) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
value := inputs["value"]
return map[string]interface{}{"result": !toBool(value)}, nil
return map[string]interface{}{"result": !toBool(value)}
}
func toBool(v interface{}) bool {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["logic", "workflow", "plugin"],
"main": "logic_not.go",
"files": ["logic_not.go", "factory.go"],
"metadata": {
"plugin_type": "logic.not",
"category": "logic"
"category": "logic",
"struct": "LogicNot",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package logic_or provides factory for LogicOr plugin.
package logic_or
// Create returns a new LogicOr instance.
func Create() *LogicOr {
return NewLogicOr()
}

View File

@@ -1,24 +1,36 @@
// Package logic_or provides the logical OR plugin.
// Package logic_or provides a workflow plugin for logical OR operations.
package logic_or
import (
plugin "metabuilder/workflow/plugins/go"
)
// LogicOr implements the NodeExecutor interface for logical OR operations.
type LogicOr struct {
NodeType string
Category string
Description string
}
// Run performs logical OR on boolean values.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewLogicOr creates a new LogicOr instance.
func NewLogicOr() *LogicOr {
return &LogicOr{
NodeType: "logic.or",
Category: "logic",
Description: "Perform logical OR on boolean values",
}
}
// Execute runs the plugin logic.
func (p *LogicOr) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
values, ok := inputs["values"].([]interface{})
if !ok || len(values) == 0 {
return map[string]interface{}{"result": false}, nil
return map[string]interface{}{"result": false}
}
for _, v := range values {
if toBool(v) {
return map[string]interface{}{"result": true}, nil
return map[string]interface{}{"result": true}
}
}
return map[string]interface{}{"result": false}, nil
return map[string]interface{}{"result": false}
}
func toBool(v interface{}) bool {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["logic", "workflow", "plugin"],
"main": "logic_or.go",
"files": ["logic_or.go", "factory.go"],
"metadata": {
"plugin_type": "logic.or",
"category": "logic"
"category": "logic",
"struct": "LogicOr",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package math_add provides factory for MathAdd plugin.
package math_add
// Create returns a new MathAdd instance.
func Create() *MathAdd {
return NewMathAdd()
}

View File

@@ -1,15 +1,27 @@
// Package math_add provides the add numbers plugin.
// Package math_add provides a workflow plugin for adding numbers.
package math_add
import (
plugin "metabuilder/workflow/plugins/go"
)
// MathAdd implements the NodeExecutor interface for adding numbers.
type MathAdd struct {
NodeType string
Category string
Description string
}
// Run adds two or more numbers.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewMathAdd creates a new MathAdd instance.
func NewMathAdd() *MathAdd {
return &MathAdd{
NodeType: "math.add",
Category: "math",
Description: "Add two or more numbers",
}
}
// Execute runs the plugin logic.
func (p *MathAdd) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
numbers, ok := inputs["numbers"].([]interface{})
if !ok {
return map[string]interface{}{"result": 0, "error": "numbers must be an array"}, nil
return map[string]interface{}{"result": 0, "error": "numbers must be an array"}
}
var sum float64
@@ -24,5 +36,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
}
return map[string]interface{}{"result": sum}, nil
return map[string]interface{}{"result": sum}
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["math", "workflow", "plugin"],
"main": "math_add.go",
"files": ["math_add.go", "factory.go"],
"metadata": {
"plugin_type": "math.add",
"category": "math"
"category": "math",
"struct": "MathAdd",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package math_divide provides factory for MathDivide plugin.
package math_divide
// Create returns a new MathDivide instance.
func Create() *MathDivide {
return NewMathDivide()
}

View File

@@ -1,29 +1,43 @@
// Package math_divide provides the divide numbers plugin.
// Package math_divide provides a workflow plugin for dividing numbers.
package math_divide
import (
"errors"
plugin "metabuilder/workflow/plugins/go"
)
// Run divides the first number by subsequent numbers.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// MathDivide implements the NodeExecutor interface for dividing numbers.
type MathDivide struct {
NodeType string
Category string
Description string
}
// NewMathDivide creates a new MathDivide instance.
func NewMathDivide() *MathDivide {
return &MathDivide{
NodeType: "math.divide",
Category: "math",
Description: "Divide the first number by subsequent numbers",
}
}
// Execute runs the plugin logic.
func (p *MathDivide) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
numbers, ok := inputs["numbers"].([]interface{})
if !ok || len(numbers) < 2 {
return map[string]interface{}{"result": 0, "error": "numbers must have at least 2 elements"}, nil
return map[string]interface{}{"result": 0, "error": "numbers must have at least 2 elements"}
}
result := toFloat64(numbers[0])
for i := 1; i < len(numbers); i++ {
divisor := toFloat64(numbers[i])
if divisor == 0 {
return nil, errors.New("division by zero")
return map[string]interface{}{"result": 0, "error": errors.New("division by zero").Error()}
}
result /= divisor
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}
func toFloat64(v interface{}) float64 {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["math", "workflow", "plugin"],
"main": "math_divide.go",
"files": ["math_divide.go", "factory.go"],
"metadata": {
"plugin_type": "math.divide",
"category": "math"
"category": "math",
"struct": "MathDivide",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package math_multiply provides factory for MathMultiply plugin.
package math_multiply
// Create returns a new MathMultiply instance.
func Create() *MathMultiply {
return NewMathMultiply()
}

View File

@@ -1,15 +1,27 @@
// Package math_multiply provides the multiply numbers plugin.
// Package math_multiply provides a workflow plugin for multiplying numbers.
package math_multiply
import (
plugin "metabuilder/workflow/plugins/go"
)
// MathMultiply implements the NodeExecutor interface for multiplying numbers.
type MathMultiply struct {
NodeType string
Category string
Description string
}
// Run multiplies two or more numbers.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewMathMultiply creates a new MathMultiply instance.
func NewMathMultiply() *MathMultiply {
return &MathMultiply{
NodeType: "math.multiply",
Category: "math",
Description: "Multiply two or more numbers",
}
}
// Execute runs the plugin logic.
func (p *MathMultiply) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
numbers, ok := inputs["numbers"].([]interface{})
if !ok || len(numbers) == 0 {
return map[string]interface{}{"result": 0, "error": "numbers must be a non-empty array"}, nil
return map[string]interface{}{"result": 0, "error": "numbers must be a non-empty array"}
}
result := 1.0
@@ -17,7 +29,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
result *= toFloat64(n)
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}
func toFloat64(v interface{}) float64 {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["math", "workflow", "plugin"],
"main": "math_multiply.go",
"files": ["math_multiply.go", "factory.go"],
"metadata": {
"plugin_type": "math.multiply",
"category": "math"
"category": "math",
"struct": "MathMultiply",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package math_subtract provides factory for MathSubtract plugin.
package math_subtract
// Create returns a new MathSubtract instance.
func Create() *MathSubtract {
return NewMathSubtract()
}

View File

@@ -1,15 +1,27 @@
// Package math_subtract provides the subtract numbers plugin.
// Package math_subtract provides a workflow plugin for subtracting numbers.
package math_subtract
import (
plugin "metabuilder/workflow/plugins/go"
)
// MathSubtract implements the NodeExecutor interface for subtracting numbers.
type MathSubtract struct {
NodeType string
Category string
Description string
}
// Run subtracts numbers from the first number.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// NewMathSubtract creates a new MathSubtract instance.
func NewMathSubtract() *MathSubtract {
return &MathSubtract{
NodeType: "math.subtract",
Category: "math",
Description: "Subtract numbers from the first number",
}
}
// Execute runs the plugin logic.
func (p *MathSubtract) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
numbers, ok := inputs["numbers"].([]interface{})
if !ok || len(numbers) == 0 {
return map[string]interface{}{"result": 0, "error": "numbers must be a non-empty array"}, nil
return map[string]interface{}{"result": 0, "error": "numbers must be a non-empty array"}
}
result := toFloat64(numbers[0])
@@ -17,7 +29,7 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
result -= toFloat64(numbers[i])
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}
func toFloat64(v interface{}) float64 {

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["math", "workflow", "plugin"],
"main": "math_subtract.go",
"files": ["math_subtract.go", "factory.go"],
"metadata": {
"plugin_type": "math.subtract",
"category": "math"
"category": "math",
"struct": "MathSubtract",
"entrypoint": "Execute"
}
}

View File

@@ -0,0 +1,7 @@
// Package string_concat provides factory for StringConcat plugin.
package string_concat
// Create returns a new StringConcat instance.
func Create() *StringConcat {
return NewStringConcat()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["string", "workflow", "plugin"],
"main": "string_concat.go",
"files": ["string_concat.go", "factory.go"],
"metadata": {
"plugin_type": "string.concat",
"category": "string"
"category": "string",
"struct": "StringConcat",
"entrypoint": "Execute"
}
}

View File

@@ -1,18 +1,32 @@
// Package string_concat provides the concatenate strings plugin.
// Package string_concat provides a workflow plugin for concatenating strings.
package string_concat
import (
"fmt"
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run concatenates multiple strings with optional separator.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// StringConcat implements the NodeExecutor interface for concatenating strings.
type StringConcat struct {
NodeType string
Category string
Description string
}
// NewStringConcat creates a new StringConcat instance.
func NewStringConcat() *StringConcat {
return &StringConcat{
NodeType: "string.concat",
Category: "string",
Description: "Concatenate multiple strings with optional separator",
}
}
// Execute runs the plugin logic.
func (p *StringConcat) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
strs, ok := inputs["strings"].([]interface{})
if !ok {
return map[string]interface{}{"result": "", "error": "strings must be an array"}, nil
return map[string]interface{}{"result": "", "error": "strings must be an array"}
}
separator := ""
@@ -25,5 +39,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
strList[i] = fmt.Sprintf("%v", s)
}
return map[string]interface{}{"result": strings.Join(strList, separator)}, nil
return map[string]interface{}{"result": strings.Join(strList, separator)}
}

View File

@@ -0,0 +1,7 @@
// Package string_lower provides factory for StringLower plugin.
package string_lower
// Create returns a new StringLower instance.
func Create() *StringLower {
return NewStringLower()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["string", "workflow", "plugin"],
"main": "string_lower.go",
"files": ["string_lower.go", "factory.go"],
"metadata": {
"plugin_type": "string.lower",
"category": "string"
"category": "string",
"struct": "StringLower",
"entrypoint": "Execute"
}
}

View File

@@ -1,18 +1,32 @@
// Package string_lower provides the lowercase string plugin.
// Package string_lower provides a workflow plugin for lowercasing strings.
package string_lower
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run converts string to lowercase.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// StringLower implements the NodeExecutor interface for lowercasing strings.
type StringLower struct {
NodeType string
Category string
Description string
}
// NewStringLower creates a new StringLower instance.
func NewStringLower() *StringLower {
return &StringLower{
NodeType: "string.lower",
Category: "string",
Description: "Convert string to lowercase",
}
}
// Execute runs the plugin logic.
func (p *StringLower) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
str, ok := inputs["string"].(string)
if !ok {
return map[string]interface{}{"result": "", "error": "string is required"}, nil
return map[string]interface{}{"result": "", "error": "string is required"}
}
return map[string]interface{}{"result": strings.ToLower(str)}, nil
return map[string]interface{}{"result": strings.ToLower(str)}
}

View File

@@ -0,0 +1,7 @@
// Package string_replace provides factory for StringReplace plugin.
package string_replace
// Create returns a new StringReplace instance.
func Create() *StringReplace {
return NewStringReplace()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["string", "workflow", "plugin"],
"main": "string_replace.go",
"files": ["string_replace.go", "factory.go"],
"metadata": {
"plugin_type": "string.replace",
"category": "string"
"category": "string",
"struct": "StringReplace",
"entrypoint": "Execute"
}
}

View File

@@ -1,17 +1,31 @@
// Package string_replace provides the replace string plugin.
// Package string_replace provides a workflow plugin for replacing strings.
package string_replace
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run replaces occurrences in a string.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// StringReplace implements the NodeExecutor interface for replacing strings.
type StringReplace struct {
NodeType string
Category string
Description string
}
// NewStringReplace creates a new StringReplace instance.
func NewStringReplace() *StringReplace {
return &StringReplace{
NodeType: "string.replace",
Category: "string",
Description: "Replace occurrences in a string",
}
}
// Execute runs the plugin logic.
func (p *StringReplace) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
str, ok := inputs["string"].(string)
if !ok {
return map[string]interface{}{"result": "", "error": "string is required"}, nil
return map[string]interface{}{"result": "", "error": "string is required"}
}
old, _ := inputs["old"].(string)
@@ -24,5 +38,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
}
result := strings.Replace(str, old, new, count)
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -0,0 +1,7 @@
// Package string_split provides factory for StringSplit plugin.
package string_split
// Create returns a new StringSplit instance.
func Create() *StringSplit {
return NewStringSplit()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["string", "workflow", "plugin"],
"main": "string_split.go",
"files": ["string_split.go", "factory.go"],
"metadata": {
"plugin_type": "string.split",
"category": "string"
"category": "string",
"struct": "StringSplit",
"entrypoint": "Execute"
}
}

View File

@@ -1,17 +1,31 @@
// Package string_split provides the split string plugin.
// Package string_split provides a workflow plugin for splitting strings.
package string_split
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run splits a string by separator.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// StringSplit implements the NodeExecutor interface for splitting strings.
type StringSplit struct {
NodeType string
Category string
Description string
}
// NewStringSplit creates a new StringSplit instance.
func NewStringSplit() *StringSplit {
return &StringSplit{
NodeType: "string.split",
Category: "string",
Description: "Split a string by separator",
}
}
// Execute runs the plugin logic.
func (p *StringSplit) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
str, ok := inputs["string"].(string)
if !ok {
return map[string]interface{}{"result": []string{}, "error": "string is required"}, nil
return map[string]interface{}{"result": []string{}, "error": "string is required"}
}
separator := ""
@@ -29,5 +43,5 @@ func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]int
result = strings.Split(str, separator)
}
return map[string]interface{}{"result": result}, nil
return map[string]interface{}{"result": result}
}

View File

@@ -0,0 +1,7 @@
// Package string_upper provides factory for StringUpper plugin.
package string_upper
// Create returns a new StringUpper instance.
func Create() *StringUpper {
return NewStringUpper()
}

View File

@@ -6,8 +6,11 @@
"license": "MIT",
"keywords": ["string", "workflow", "plugin"],
"main": "string_upper.go",
"files": ["string_upper.go", "factory.go"],
"metadata": {
"plugin_type": "string.upper",
"category": "string"
"category": "string",
"struct": "StringUpper",
"entrypoint": "Execute"
}
}

View File

@@ -1,18 +1,32 @@
// Package string_upper provides the uppercase string plugin.
// Package string_upper provides a workflow plugin for uppercasing strings.
package string_upper
import (
"strings"
plugin "metabuilder/workflow/plugins/go"
)
// Run converts string to uppercase.
func Run(runtime *plugin.Runtime, inputs map[string]interface{}) (map[string]interface{}, error) {
// StringUpper implements the NodeExecutor interface for uppercasing strings.
type StringUpper struct {
NodeType string
Category string
Description string
}
// NewStringUpper creates a new StringUpper instance.
func NewStringUpper() *StringUpper {
return &StringUpper{
NodeType: "string.upper",
Category: "string",
Description: "Convert string to uppercase",
}
}
// Execute runs the plugin logic.
func (p *StringUpper) Execute(inputs map[string]interface{}, runtime interface{}) map[string]interface{} {
str, ok := inputs["string"].(string)
if !ok {
return map[string]interface{}{"result": "", "error": "string is required"}, nil
return map[string]interface{}{"result": "", "error": "string is required"}
}
return map[string]interface{}{"result": strings.ToUpper(str)}, nil
return map[string]interface{}{"result": strings.ToUpper(str)}
}

View File

@@ -0,0 +1,7 @@
// Package var_delete provides factory for VarDelete plugin.
package var_delete
// Create returns a new VarDelete instance.
func Create() *VarDelete {
return NewVarDelete()
}

Some files were not shown because too many files have changed in this diff Show More