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,13 +1,21 @@
"""Workflow plugin: parse JSON string."""
import json
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertParseJson(NodeExecutor):
"""Parse JSON string to object."""
text = inputs.get("text", "")
try:
result = json.loads(text)
return {"result": result}
except json.JSONDecodeError as e:
return {"result": None, "error": str(e)}
node_type = "convert.parseJson"
category = "convert"
description = "Parse JSON string to object"
def execute(self, inputs, runtime=None):
text = inputs.get("text", "")
try:
result = json.loads(text)
return {"result": result}
except json.JSONDecodeError as e:
return {"result": None, "error": str(e)}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertParseJson plugin."""
from .convert_parse_json import ConvertParseJson
def create():
return ConvertParseJson()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_parse_json",
"version": "1.0.0",
"description": "convert_parse_json plugin",
"description": "Parse JSON string to object",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_parse_json.py",
"files": ["convert_parse_json.py", "factory.py"],
"metadata": {
"plugin_type": "convert.parse_json",
"category": "convert"
"plugin_type": "convert.parseJson",
"category": "convert",
"class": "ConvertParseJson",
"entrypoint": "execute"
}
}

View File

@@ -1,11 +1,17 @@
"""Workflow plugin: convert to boolean."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertToBoolean(NodeExecutor):
"""Convert value to boolean."""
value = inputs.get("value")
if isinstance(value, str):
return {"result": value.lower() not in ("false", "0", "", "none", "null")}
node_type = "convert.toBoolean"
category = "convert"
description = "Convert value to boolean"
return {"result": bool(value)}
def execute(self, inputs, runtime=None):
value = inputs.get("value")
if isinstance(value, str):
return {"result": value.lower() not in ("false", "0", "", "none", "null")}
return {"result": bool(value)}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertToBoolean plugin."""
from .convert_to_boolean import ConvertToBoolean
def create():
return ConvertToBoolean()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_to_boolean",
"version": "1.0.0",
"description": "convert_to_boolean plugin",
"description": "Convert value to boolean",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_boolean.py",
"files": ["convert_to_boolean.py", "factory.py"],
"metadata": {
"plugin_type": "convert.to_boolean",
"category": "convert"
"plugin_type": "convert.toBoolean",
"category": "convert",
"class": "ConvertToBoolean",
"entrypoint": "execute"
}
}

View File

@@ -1,17 +1,25 @@
"""Workflow plugin: convert to dictionary."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertToDict(NodeExecutor):
"""Convert value to dictionary."""
value = inputs.get("value")
if isinstance(value, dict):
return {"result": value}
elif isinstance(value, list):
# Convert list of [key, value] pairs to dict
try:
return {"result": dict(value)}
except (TypeError, ValueError):
return {"result": {}, "error": "Cannot convert list to dict"}
else:
return {"result": {}}
node_type = "convert.toDict"
category = "convert"
description = "Convert value to dictionary"
def execute(self, inputs, runtime=None):
value = inputs.get("value")
if isinstance(value, dict):
return {"result": value}
elif isinstance(value, list):
# Convert list of [key, value] pairs to dict
try:
return {"result": dict(value)}
except (TypeError, ValueError):
return {"result": {}, "error": "Cannot convert list to dict"}
else:
return {"result": {}}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertToDict plugin."""
from .convert_to_dict import ConvertToDict
def create():
return ConvertToDict()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_to_dict",
"version": "1.0.0",
"description": "convert_to_dict plugin",
"description": "Convert value to dictionary",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_dict.py",
"files": ["convert_to_dict.py", "factory.py"],
"metadata": {
"plugin_type": "convert.to_dict",
"category": "convert"
"plugin_type": "convert.toDict",
"category": "convert",
"class": "ConvertToDict",
"entrypoint": "execute"
}
}

View File

@@ -1,14 +1,23 @@
"""Workflow plugin: convert to JSON string."""
import json
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertToJson(NodeExecutor):
"""Convert value to JSON string."""
value = inputs.get("value")
indent = inputs.get("indent")
try:
result = json.dumps(value, indent=indent)
return {"result": result}
except (TypeError, ValueError) as e:
return {"result": None, "error": str(e)}
node_type = "convert.toJson"
category = "convert"
description = "Convert value to JSON string"
def execute(self, inputs, runtime=None):
value = inputs.get("value")
indent = inputs.get("indent")
try:
result = json.dumps(value, indent=indent)
return {"result": result}
except (TypeError, ValueError) as e:
return {"result": None, "error": str(e)}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertToJson plugin."""
from .convert_to_json import ConvertToJson
def create():
return ConvertToJson()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_to_json",
"version": "1.0.0",
"description": "convert_to_json plugin",
"description": "Convert value to JSON string",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_json.py",
"files": ["convert_to_json.py", "factory.py"],
"metadata": {
"plugin_type": "convert.to_json",
"category": "convert"
"plugin_type": "convert.toJson",
"category": "convert",
"class": "ConvertToJson",
"entrypoint": "execute"
}
}

View File

@@ -1,17 +1,25 @@
"""Workflow plugin: convert to list."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertToList(NodeExecutor):
"""Convert value to list."""
value = inputs.get("value")
if isinstance(value, list):
return {"result": value}
elif isinstance(value, (tuple, set)):
return {"result": list(value)}
elif isinstance(value, dict):
return {"result": list(value.items())}
elif value is None:
return {"result": []}
else:
return {"result": [value]}
node_type = "convert.toList"
category = "convert"
description = "Convert value to list"
def execute(self, inputs, runtime=None):
value = inputs.get("value")
if isinstance(value, list):
return {"result": value}
elif isinstance(value, (tuple, set)):
return {"result": list(value)}
elif isinstance(value, dict):
return {"result": list(value.items())}
elif value is None:
return {"result": []}
else:
return {"result": [value]}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertToList plugin."""
from .convert_to_list import ConvertToList
def create():
return ConvertToList()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_to_list",
"version": "1.0.0",
"description": "convert_to_list plugin",
"description": "Convert value to list",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_list.py",
"files": ["convert_to_list.py", "factory.py"],
"metadata": {
"plugin_type": "convert.to_list",
"category": "convert"
"plugin_type": "convert.toList",
"category": "convert",
"class": "ConvertToList",
"entrypoint": "execute"
}
}

View File

@@ -1,14 +1,21 @@
"""Workflow plugin: convert to number."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertToNumber(NodeExecutor):
"""Convert value to number."""
value = inputs.get("value")
default = inputs.get("default", 0)
try:
if isinstance(value, str) and "." in value:
return {"result": float(value)}
return {"result": int(value)}
except (ValueError, TypeError):
return {"result": default, "error": "Cannot convert to number"}
node_type = "convert.toNumber"
category = "convert"
description = "Convert value to number"
def execute(self, inputs, runtime=None):
value = inputs.get("value")
default = inputs.get("default", 0)
try:
if isinstance(value, str) and "." in value:
return {"result": float(value)}
return {"result": int(value)}
except (ValueError, TypeError):
return {"result": default, "error": "Cannot convert to number"}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertToNumber plugin."""
from .convert_to_number import ConvertToNumber
def create():
return ConvertToNumber()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_to_number",
"version": "1.0.0",
"description": "convert_to_number plugin",
"description": "Convert value to number",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_number.py",
"files": ["convert_to_number.py", "factory.py"],
"metadata": {
"plugin_type": "convert.to_number",
"category": "convert"
"plugin_type": "convert.toNumber",
"category": "convert",
"class": "ConvertToNumber",
"entrypoint": "execute"
}
}

View File

@@ -1,7 +1,15 @@
"""Workflow plugin: convert to string."""
from ...base import NodeExecutor
def run(_runtime, inputs):
class ConvertToString(NodeExecutor):
"""Convert value to string."""
value = inputs.get("value")
return {"result": str(value) if value is not None else ""}
node_type = "convert.toString"
category = "convert"
description = "Convert value to string"
def execute(self, inputs, runtime=None):
value = inputs.get("value")
return {"result": str(value) if value is not None else ""}

View File

@@ -0,0 +1,7 @@
"""Factory for ConvertToString plugin."""
from .convert_to_string import ConvertToString
def create():
return ConvertToString()

View File

@@ -1,13 +1,16 @@
{
"name": "@metabuilder/convert_to_string",
"version": "1.0.0",
"description": "convert_to_string plugin",
"description": "Convert value to string",
"author": "MetaBuilder",
"license": "MIT",
"keywords": ["convert", "workflow", "plugin"],
"main": "convert_to_string.py",
"files": ["convert_to_string.py", "factory.py"],
"metadata": {
"plugin_type": "convert.to_string",
"category": "convert"
"plugin_type": "convert.toString",
"category": "convert",
"class": "ConvertToString",
"entrypoint": "execute"
}
}