mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-27 07:14:56 +00:00
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:
7
workflow/plugins/python/list/list_concat/factory.py
Normal file
7
workflow/plugins/python/list/list_concat/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListConcat plugin."""
|
||||
|
||||
from .list_concat import ListConcat
|
||||
|
||||
|
||||
def create():
|
||||
return ListConcat()
|
||||
@@ -1,11 +1,20 @@
|
||||
"""Workflow plugin: concatenate lists."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
|
||||
class ListConcat(NodeExecutor):
|
||||
"""Concatenate multiple lists."""
|
||||
lists = inputs.get("lists", [])
|
||||
result = []
|
||||
for lst in lists:
|
||||
if isinstance(lst, list):
|
||||
result.extend(lst)
|
||||
return {"result": result}
|
||||
|
||||
node_type = "list.concat"
|
||||
category = "list"
|
||||
description = "Concatenate multiple lists"
|
||||
|
||||
def execute(self, inputs, runtime=None):
|
||||
array = inputs.get("array", inputs.get("list", []))
|
||||
lists = inputs.get("lists", inputs.get("arrays", [array]))
|
||||
result = []
|
||||
for lst in lists:
|
||||
if isinstance(lst, list):
|
||||
result.extend(lst)
|
||||
return {"result": result}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_concat",
|
||||
"version": "1.0.0",
|
||||
"description": "list_concat plugin",
|
||||
"description": "Concatenate multiple lists",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_concat.py",
|
||||
"files": ["list_concat.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.concat",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListConcat",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
7
workflow/plugins/python/list/list_every/factory.py
Normal file
7
workflow/plugins/python/list/list_every/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListEvery plugin."""
|
||||
|
||||
from .list_every import ListEvery
|
||||
|
||||
|
||||
def create():
|
||||
return ListEvery()
|
||||
@@ -1,18 +1,26 @@
|
||||
"""Workflow plugin: check if all items match condition."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
|
||||
class ListEvery(NodeExecutor):
|
||||
"""Check if all items match condition."""
|
||||
items = inputs.get("items", [])
|
||||
key = inputs.get("key")
|
||||
value = inputs.get("value")
|
||||
|
||||
if not items:
|
||||
return {"result": True}
|
||||
node_type = "list.every"
|
||||
category = "list"
|
||||
description = "Check if all items match condition"
|
||||
|
||||
if key is not None and value is not None:
|
||||
result = all(isinstance(item, dict) and item.get(key) == value for item in items)
|
||||
else:
|
||||
result = all(items)
|
||||
def execute(self, inputs, runtime=None):
|
||||
items = inputs.get("items", inputs.get("array", []))
|
||||
key = inputs.get("key")
|
||||
value = inputs.get("value")
|
||||
|
||||
return {"result": result}
|
||||
if not items:
|
||||
return {"result": True}
|
||||
|
||||
if key is not None and value is not None:
|
||||
result = all(isinstance(item, dict) and item.get(key) == value for item in items)
|
||||
else:
|
||||
result = all(items)
|
||||
|
||||
return {"result": result}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_every",
|
||||
"version": "1.0.0",
|
||||
"description": "list_every plugin",
|
||||
"description": "Check if all items match condition",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_every.py",
|
||||
"files": ["list_every.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.every",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListEvery",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
7
workflow/plugins/python/list/list_find/factory.py
Normal file
7
workflow/plugins/python/list/list_find/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListFind plugin."""
|
||||
|
||||
from .list_find import ListFind
|
||||
|
||||
|
||||
def create():
|
||||
return ListFind()
|
||||
@@ -1,14 +1,22 @@
|
||||
"""Workflow plugin: find item in list."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
|
||||
class ListFind(NodeExecutor):
|
||||
"""Find first item matching condition."""
|
||||
items = inputs.get("items", [])
|
||||
key = inputs.get("key")
|
||||
value = inputs.get("value")
|
||||
|
||||
for item in items:
|
||||
if isinstance(item, dict) and item.get(key) == value:
|
||||
return {"result": item, "found": True}
|
||||
node_type = "list.find"
|
||||
category = "list"
|
||||
description = "Find first item matching condition"
|
||||
|
||||
return {"result": None, "found": False}
|
||||
def execute(self, inputs, runtime=None):
|
||||
items = inputs.get("items", inputs.get("array", []))
|
||||
key = inputs.get("key")
|
||||
value = inputs.get("value")
|
||||
|
||||
for item in items:
|
||||
if isinstance(item, dict) and item.get(key) == value:
|
||||
return {"result": item, "found": True}
|
||||
|
||||
return {"result": None, "found": False}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_find",
|
||||
"version": "1.0.0",
|
||||
"description": "list_find plugin",
|
||||
"description": "Find first item matching condition",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_find.py",
|
||||
"files": ["list_find.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.find",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListFind",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
7
workflow/plugins/python/list/list_length/factory.py
Normal file
7
workflow/plugins/python/list/list_length/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListLength plugin."""
|
||||
|
||||
from .list_length import ListLength
|
||||
|
||||
|
||||
def create():
|
||||
return ListLength()
|
||||
@@ -1,7 +1,15 @@
|
||||
"""Workflow plugin: get list length."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
"""Get length of a list or string."""
|
||||
items = inputs.get("items", [])
|
||||
return {"result": len(items) if items is not None else 0}
|
||||
|
||||
class ListLength(NodeExecutor):
|
||||
"""Get list length."""
|
||||
|
||||
node_type = "list.length"
|
||||
category = "list"
|
||||
description = "Get list length"
|
||||
|
||||
def execute(self, inputs, runtime=None):
|
||||
array = inputs.get("array", inputs.get("list", []))
|
||||
return {"result": len(array) if array is not None else 0}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_length",
|
||||
"version": "1.0.0",
|
||||
"description": "list_length plugin",
|
||||
"description": "Get length of list",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_length.py",
|
||||
"files": ["list_length.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.length",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListLength",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
7
workflow/plugins/python/list/list_slice/factory.py
Normal file
7
workflow/plugins/python/list/list_slice/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListSlice plugin."""
|
||||
|
||||
from .list_slice import ListSlice
|
||||
|
||||
|
||||
def create():
|
||||
return ListSlice()
|
||||
@@ -1,15 +1,19 @@
|
||||
"""Workflow plugin: slice a list."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
|
||||
class ListSlice(NodeExecutor):
|
||||
"""Extract slice from list."""
|
||||
items = inputs.get("items", [])
|
||||
start = inputs.get("start", 0)
|
||||
end = inputs.get("end")
|
||||
|
||||
if end is None:
|
||||
result = items[start:]
|
||||
else:
|
||||
result = items[start:end]
|
||||
node_type = "list.slice"
|
||||
category = "list"
|
||||
description = "Extract slice from list"
|
||||
|
||||
return {"result": result}
|
||||
def execute(self, inputs, runtime=None):
|
||||
array = inputs.get("array", inputs.get("items", inputs.get("list", [])))
|
||||
start = inputs.get("start", 0)
|
||||
end = inputs.get("end")
|
||||
|
||||
result = array[start:end] if end is not None else array[start:]
|
||||
return {"result": result}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_slice",
|
||||
"version": "1.0.0",
|
||||
"description": "list_slice plugin",
|
||||
"description": "Extract slice from list",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_slice.py",
|
||||
"files": ["list_slice.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.slice",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListSlice",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
7
workflow/plugins/python/list/list_some/factory.py
Normal file
7
workflow/plugins/python/list/list_some/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListSome plugin."""
|
||||
|
||||
from .list_some import ListSome
|
||||
|
||||
|
||||
def create():
|
||||
return ListSome()
|
||||
@@ -1,15 +1,23 @@
|
||||
"""Workflow plugin: check if some items match condition."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
"""Check if at least one item matches condition."""
|
||||
items = inputs.get("items", [])
|
||||
key = inputs.get("key")
|
||||
value = inputs.get("value")
|
||||
|
||||
if key is not None and value is not None:
|
||||
result = any(isinstance(item, dict) and item.get(key) == value for item in items)
|
||||
else:
|
||||
result = any(items)
|
||||
class ListSome(NodeExecutor):
|
||||
"""Check if some items match condition."""
|
||||
|
||||
return {"result": result}
|
||||
node_type = "list.some"
|
||||
category = "list"
|
||||
description = "Check if some items match condition"
|
||||
|
||||
def execute(self, inputs, runtime=None):
|
||||
items = inputs.get("items", inputs.get("array", []))
|
||||
key = inputs.get("key")
|
||||
value = inputs.get("value")
|
||||
|
||||
if key is not None and value is not None:
|
||||
result = any(isinstance(item, dict) and item.get(key) == value for item in items)
|
||||
else:
|
||||
result = any(items)
|
||||
|
||||
return {"result": result}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_some",
|
||||
"version": "1.0.0",
|
||||
"description": "list_some plugin",
|
||||
"description": "Check if some items match condition",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_some.py",
|
||||
"files": ["list_some.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.some",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListSome",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
7
workflow/plugins/python/list/list_sort/factory.py
Normal file
7
workflow/plugins/python/list/list_sort/factory.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Factory for ListSort plugin."""
|
||||
|
||||
from .list_sort import ListSort
|
||||
|
||||
|
||||
def create():
|
||||
return ListSort()
|
||||
@@ -1,17 +1,29 @@
|
||||
"""Workflow plugin: sort a list."""
|
||||
|
||||
from ...base import NodeExecutor
|
||||
|
||||
def run(_runtime, inputs):
|
||||
|
||||
class ListSort(NodeExecutor):
|
||||
"""Sort list by key or naturally."""
|
||||
items = inputs.get("items", [])
|
||||
key = inputs.get("key")
|
||||
reverse = inputs.get("reverse", False)
|
||||
|
||||
try:
|
||||
if key:
|
||||
result = sorted(items, key=lambda x: x.get(key) if isinstance(x, dict) else x, reverse=reverse)
|
||||
else:
|
||||
result = sorted(items, reverse=reverse)
|
||||
return {"result": result}
|
||||
except (TypeError, AttributeError):
|
||||
return {"result": items, "error": "Cannot sort items"}
|
||||
node_type = "list.sort"
|
||||
category = "list"
|
||||
description = "Sort list by key or naturally"
|
||||
|
||||
def execute(self, inputs, runtime=None):
|
||||
items = inputs.get("items", inputs.get("array", []))
|
||||
key = inputs.get("key")
|
||||
reverse = inputs.get("reverse", inputs.get("order") == "desc")
|
||||
|
||||
try:
|
||||
if key:
|
||||
result = sorted(
|
||||
items,
|
||||
key=lambda x: x.get(key) if isinstance(x, dict) else x,
|
||||
reverse=reverse,
|
||||
)
|
||||
else:
|
||||
result = sorted(items, reverse=reverse)
|
||||
return {"result": result}
|
||||
except (TypeError, AttributeError):
|
||||
return {"result": items, "error": "Cannot sort items"}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "@metabuilder/list_sort",
|
||||
"version": "1.0.0",
|
||||
"description": "list_sort plugin",
|
||||
"description": "Sort list by key or naturally",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"keywords": ["list", "workflow", "plugin"],
|
||||
"main": "list_sort.py",
|
||||
"files": ["list_sort.py", "factory.py"],
|
||||
"metadata": {
|
||||
"plugin_type": "list.sort",
|
||||
"category": "list"
|
||||
"category": "list",
|
||||
"class": "ListSort",
|
||||
"entrypoint": "execute"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user