code0-hercules 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- code0_hercules-1.3.0.dist-info/METADATA +79 -0
- code0_hercules-1.3.0.dist-info/RECORD +258 -0
- code0_hercules-1.3.0.dist-info/WHEEL +5 -0
- code0_hercules-1.3.0.dist-info/entry_points.txt +2 -0
- code0_hercules-1.3.0.dist-info/top_level.txt +1 -0
- hercules/__init__.py +81 -0
- hercules/_metadata.py +38 -0
- hercules/_tsgen/convert.mjs +96 -0
- hercules/_tsgen/package-lock.json +366 -0
- hercules/_tsgen/package.json +11 -0
- hercules/_tucana/__init__.py +29 -0
- hercules/_tucana/helpers.py +73 -0
- hercules/action.py +345 -0
- hercules/actions/__init__.py +21 -0
- hercules/actions/execution.py +121 -0
- hercules/actions/flow_execution.py +11 -0
- hercules/actions/flow_update.py +18 -0
- hercules/actions/module_configurations.py +14 -0
- hercules/actions/sub_flow_execution.py +14 -0
- hercules/cli.py +137 -0
- hercules/decorators/__init__.py +0 -0
- hercules/decorators/datatype.py +39 -0
- hercules/decorators/event.py +35 -0
- hercules/decorators/function.py +59 -0
- hercules/decorators/meta.py +82 -0
- hercules/decorators/runtime_event.py +15 -0
- hercules/decorators/runtime_function.py +18 -0
- hercules/definitions/__init__.py +162 -0
- hercules/definitions/cron_action/__init__.py +0 -0
- hercules/definitions/cron_action/data_types/__init__.py +0 -0
- hercules/definitions/cron_action/data_types/cron_day_of_month.py +11 -0
- hercules/definitions/cron_action/data_types/cron_day_of_week.py +11 -0
- hercules/definitions/cron_action/data_types/cron_hour.py +11 -0
- hercules/definitions/cron_action/data_types/cron_minute.py +11 -0
- hercules/definitions/cron_action/data_types/cron_month.py +11 -0
- hercules/definitions/cron_action/runtime_flow_types/__init__.py +0 -0
- hercules/definitions/cron_action/runtime_flow_types/cron.py +19 -0
- hercules/definitions/rest_action/__init__.py +0 -0
- hercules/definitions/rest_action/data_types/__init__.py +0 -0
- hercules/definitions/rest_action/data_types/rest_adapter_input.py +19 -0
- hercules/definitions/rest_action/data_types/rest_auth_type.py +19 -0
- hercules/definitions/rest_action/data_types/rest_auth_value.py +11 -0
- hercules/definitions/rest_action/runtime_flow_types/__init__.py +0 -0
- hercules/definitions/rest_action/runtime_flow_types/rest.py +20 -0
- hercules/definitions/rest_action/runtime_functions/__init__.py +0 -0
- hercules/definitions/rest_action/runtime_functions/rest_control_respond.py +21 -0
- hercules/definitions/taurus_boolean/__init__.py +0 -0
- hercules/definitions/taurus_boolean/data_types/__init__.py +0 -0
- hercules/definitions/taurus_boolean/data_types/boolean.py +11 -0
- hercules/definitions/taurus_boolean/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_boolean/runtime_functions/std_boolean_as_number.py +18 -0
- hercules/definitions/taurus_boolean/runtime_functions/std_boolean_as_text.py +18 -0
- hercules/definitions/taurus_boolean/runtime_functions/std_boolean_from_number.py +18 -0
- hercules/definitions/taurus_boolean/runtime_functions/std_boolean_from_text.py +18 -0
- hercules/definitions/taurus_boolean/runtime_functions/std_boolean_is_equal.py +19 -0
- hercules/definitions/taurus_boolean/runtime_functions/std_boolean_negate.py +18 -0
- hercules/definitions/taurus_color/__init__.py +0 -0
- hercules/definitions/taurus_color/data_types/__init__.py +0 -0
- hercules/definitions/taurus_color/data_types/color.py +17 -0
- hercules/definitions/taurus_color/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_color/runtime_functions/std_color_as_hex.py +18 -0
- hercules/definitions/taurus_color/runtime_functions/std_color_as_hsl.py +18 -0
- hercules/definitions/taurus_color/runtime_functions/std_color_as_rgb.py +18 -0
- hercules/definitions/taurus_color/runtime_functions/std_color_from_hex.py +18 -0
- hercules/definitions/taurus_color/runtime_functions/std_color_from_hsl.py +21 -0
- hercules/definitions/taurus_color/runtime_functions/std_color_from_rgb.py +21 -0
- hercules/definitions/taurus_control/__init__.py +0 -0
- hercules/definitions/taurus_control/data_types/__init__.py +0 -0
- hercules/definitions/taurus_control/data_types/comparator.py +21 -0
- hercules/definitions/taurus_control/data_types/consumer.py +20 -0
- hercules/definitions/taurus_control/data_types/predicate.py +20 -0
- hercules/definitions/taurus_control/data_types/runnable.py +13 -0
- hercules/definitions/taurus_control/data_types/transform.py +20 -0
- hercules/definitions/taurus_control/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_control/runtime_functions/std_control_if.py +19 -0
- hercules/definitions/taurus_control/runtime_functions/std_control_if_else.py +21 -0
- hercules/definitions/taurus_control/runtime_functions/std_control_return.py +18 -0
- hercules/definitions/taurus_control/runtime_functions/std_control_stop.py +16 -0
- hercules/definitions/taurus_control/runtime_functions/std_control_value.py +18 -0
- hercules/definitions/taurus_date/__init__.py +0 -0
- hercules/definitions/taurus_date/data_types/__init__.py +0 -0
- hercules/definitions/taurus_date/data_types/date.py +11 -0
- hercules/definitions/taurus_date/data_types/hour.py +11 -0
- hercules/definitions/taurus_date/data_types/minute.py +11 -0
- hercules/definitions/taurus_date/data_types/month.py +22 -0
- hercules/definitions/taurus_date/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_date/runtime_functions/std_date_format.py +20 -0
- hercules/definitions/taurus_date/runtime_functions/std_date_from.py +24 -0
- hercules/definitions/taurus_date/runtime_functions/std_date_from_text.py +19 -0
- hercules/definitions/taurus_date/runtime_functions/std_date_from_unix.py +18 -0
- hercules/definitions/taurus_date/runtime_functions/std_date_now.py +16 -0
- hercules/definitions/taurus_file/__init__.py +0 -0
- hercules/definitions/taurus_file/data_types/__init__.py +0 -0
- hercules/definitions/taurus_file/data_types/file.py +19 -0
- hercules/definitions/taurus_file/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_file/runtime_functions/std_file_size.py +18 -0
- hercules/definitions/taurus_http/__init__.py +0 -0
- hercules/definitions/taurus_http/data_types/__init__.py +0 -0
- hercules/definitions/taurus_http/data_types/http_auth_place.py +12 -0
- hercules/definitions/taurus_http/data_types/http_auth_type.py +17 -0
- hercules/definitions/taurus_http/data_types/http_auth_value.py +11 -0
- hercules/definitions/taurus_http/data_types/http_method.py +16 -0
- hercules/definitions/taurus_http/data_types/http_payload.py +11 -0
- hercules/definitions/taurus_http/data_types/http_request.py +19 -0
- hercules/definitions/taurus_http/data_types/http_response.py +18 -0
- hercules/definitions/taurus_http/data_types/http_schema.py +31 -0
- hercules/definitions/taurus_http/data_types/http_status_code.py +13 -0
- hercules/definitions/taurus_http/data_types/http_url.py +13 -0
- hercules/definitions/taurus_http/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_http/runtime_functions/http_request_send.py +26 -0
- hercules/definitions/taurus_list/__init__.py +0 -0
- hercules/definitions/taurus_list/data_types/__init__.py +0 -0
- hercules/definitions/taurus_list/data_types/list.py +13 -0
- hercules/definitions/taurus_list/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_at.py +20 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_concat.py +20 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_filter.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_find.py +20 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_find_index.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_find_last.py +20 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_first.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_flat.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_for_each.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_index_of.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_is_empty.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_join.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_last.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_map.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_max.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_min.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_pop.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_push.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_remove.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_reverse.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_size.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_sort.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_sort_reverse.py +19 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_sum.py +18 -0
- hercules/definitions/taurus_list/runtime_functions/std_list_to_unique.py +18 -0
- hercules/definitions/taurus_number/__init__.py +0 -0
- hercules/definitions/taurus_number/data_types/__init__.py +0 -0
- hercules/definitions/taurus_number/data_types/number.py +11 -0
- hercules/definitions/taurus_number/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_abs.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_add.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_arccos.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_arcsin.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_arctan.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_as_text.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_clamp.py +20 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_cos.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_cosh.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_divide.py +20 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_euler.py +16 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_exponential.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_from_text.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_has_digits.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_is_equal.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_is_greater.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_is_less.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_is_positive.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_is_zero.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_ln.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_log.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_max.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_min.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_modulo.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_multiply.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_negate.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_pi.py +16 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_random_number.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_remove_digits.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_root.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_round.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_round_down.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_round_up.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_sin.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_sinh.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_square.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_square_root.py +18 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_subtract.py +19 -0
- hercules/definitions/taurus_number/runtime_functions/std_number_tan.py +18 -0
- hercules/definitions/taurus_object/__init__.py +0 -0
- hercules/definitions/taurus_object/data_types/__init__.py +0 -0
- hercules/definitions/taurus_object/data_types/object.py +13 -0
- hercules/definitions/taurus_object/data_types/type.py +13 -0
- hercules/definitions/taurus_object/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_object/runtime_functions/std_object_contains_key.py +19 -0
- hercules/definitions/taurus_object/runtime_functions/std_object_get.py +19 -0
- hercules/definitions/taurus_object/runtime_functions/std_object_keys.py +18 -0
- hercules/definitions/taurus_object/runtime_functions/std_object_set.py +20 -0
- hercules/definitions/taurus_object/runtime_functions/std_object_size.py +18 -0
- hercules/definitions/taurus_text/__init__.py +0 -0
- hercules/definitions/taurus_text/data_types/__init__.py +0 -0
- hercules/definitions/taurus_text/data_types/text.py +11 -0
- hercules/definitions/taurus_text/data_types/text_encoding.py +13 -0
- hercules/definitions/taurus_text/runtime_functions/__init__.py +0 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_append.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_as_bytes.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_at.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_byte_size.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_capitalize.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_chars.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_contains.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_decode.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_encode.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_ends_with.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_from_ascii.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_hex.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_index_of.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_insert.py +20 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_is_equal.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_length.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_lowercase.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_octal.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_prepend.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_remove.py +20 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_replace.py +20 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_replace_first.py +21 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_replace_last.py +20 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_reverse.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_split.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_starts_with.py +19 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_swapcase.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_to_ascii.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_trim.py +18 -0
- hercules/definitions/taurus_text/runtime_functions/std_text_uppercase.py +18 -0
- hercules/events.py +23 -0
- hercules/internal/__init__.py +0 -0
- hercules/internal/connection.py +37 -0
- hercules/internal/literal.py +113 -0
- hercules/internal/module_builder.py +261 -0
- hercules/internal/pydantic_codegen.py +82 -0
- hercules/internal/schema.py +158 -0
- hercules/internal/tsgen.py +93 -0
- hercules/manager/__init__.py +0 -0
- hercules/manager/base.py +73 -0
- hercules/manager/config.py +45 -0
- hercules/manager/datatype.py +8 -0
- hercules/manager/event.py +8 -0
- hercules/manager/flow.py +12 -0
- hercules/manager/function.py +8 -0
- hercules/manager/runtime_event.py +8 -0
- hercules/manager/runtime_function.py +8 -0
- hercules/map/__init__.py +0 -0
- hercules/map/datatype.py +41 -0
- hercules/map/event.py +74 -0
- hercules/map/function.py +76 -0
- hercules/map/runtime_event.py +43 -0
- hercules/map/runtime_function.py +64 -0
- hercules/models/__init__.py +0 -0
- hercules/models/datatype.py +49 -0
- hercules/models/event.py +35 -0
- hercules/models/function.py +37 -0
- hercules/models/runtime_event.py +29 -0
- hercules/models/runtime_function.py +33 -0
- hercules/schema.py +38 -0
- hercules/types.py +88 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Schema registry plus TypeScript type-string and rule generation.
|
|
2
|
+
|
|
3
|
+
Data types are described with Pydantic models. Registered models are keyed by
|
|
4
|
+
class; when a registered model appears nested inside another type it is rendered
|
|
5
|
+
as its identifier instead of being inlined, which lets recursive and
|
|
6
|
+
mutually-recursive data types resolve by reference (mirroring the TypeScript SDK's
|
|
7
|
+
``zod-schema`` behaviour).
|
|
8
|
+
|
|
9
|
+
The Pydantic ``model_json_schema()`` output is pre-processed here (references to
|
|
10
|
+
registered models become ``tsType`` identifier hints, non-registered nested models
|
|
11
|
+
are inlined, titles are stripped) and then handed to the Node helper, which turns
|
|
12
|
+
it into an inline TypeScript type expression.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import Any, Dict, List, Optional, Type
|
|
17
|
+
|
|
18
|
+
from pydantic import BaseModel
|
|
19
|
+
|
|
20
|
+
from tucana.generated.shared import data_type_pb2
|
|
21
|
+
from hercules.internal.tsgen import json_schema_to_ts
|
|
22
|
+
|
|
23
|
+
SchemaModel = Type[BaseModel]
|
|
24
|
+
|
|
25
|
+
# Maps a registered Pydantic model class -> its data-type identifier.
|
|
26
|
+
_registry: Dict[SchemaModel, str] = {}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def register_schema(model: SchemaModel, identifier: str) -> None:
|
|
30
|
+
_registry[model] = identifier
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_registered_identifier(model: SchemaModel) -> Optional[str]:
|
|
34
|
+
return _registry.get(model)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _registered_names() -> Dict[str, str]:
|
|
38
|
+
"""Map each registered model's JSON-schema definition name to its identifier."""
|
|
39
|
+
return {model.__name__: identifier for model, identifier in _registry.items()}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# JSON-schema annotation keywords that describe rather than shape a type. They
|
|
43
|
+
# would otherwise surface as JSDoc comments / noise in the emitted type string.
|
|
44
|
+
_ANNOTATION_KEYS = ("title", "description", "default", "examples", "$comment")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _strip_annotations(node: Any) -> None:
|
|
48
|
+
if isinstance(node, dict):
|
|
49
|
+
for key in _ANNOTATION_KEYS:
|
|
50
|
+
node.pop(key, None)
|
|
51
|
+
for value in node.values():
|
|
52
|
+
_strip_annotations(value)
|
|
53
|
+
elif isinstance(node, list):
|
|
54
|
+
for item in node:
|
|
55
|
+
_strip_annotations(item)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _resolve(
|
|
59
|
+
node: Any,
|
|
60
|
+
defs: Dict[str, Any],
|
|
61
|
+
names: Dict[str, str],
|
|
62
|
+
self_name: str,
|
|
63
|
+
self_identifier: Optional[str],
|
|
64
|
+
stack: List[str],
|
|
65
|
+
) -> Any:
|
|
66
|
+
"""Recursively rewrite ``$ref`` nodes.
|
|
67
|
+
|
|
68
|
+
References to registered models (and self-references) become ``tsType``
|
|
69
|
+
identifier hints; references to non-registered nested models are inlined so
|
|
70
|
+
the whole type collapses into a single expression. A non-registered recursive
|
|
71
|
+
reference cannot be inlined and raises.
|
|
72
|
+
"""
|
|
73
|
+
if isinstance(node, list):
|
|
74
|
+
return [
|
|
75
|
+
_resolve(item, defs, names, self_name, self_identifier, stack)
|
|
76
|
+
for item in node
|
|
77
|
+
]
|
|
78
|
+
if not isinstance(node, dict):
|
|
79
|
+
return node
|
|
80
|
+
|
|
81
|
+
ref = node.get("$ref")
|
|
82
|
+
if isinstance(ref, str) and ref.startswith("#/$defs/"):
|
|
83
|
+
ref_name = ref.split("/")[-1]
|
|
84
|
+
if ref_name in names:
|
|
85
|
+
return {"tsType": names[ref_name]}
|
|
86
|
+
if ref_name == self_name and self_identifier is not None:
|
|
87
|
+
return {"tsType": self_identifier}
|
|
88
|
+
if ref_name in stack:
|
|
89
|
+
subject = (
|
|
90
|
+
f'data type "{self_identifier}"' if self_identifier else "the schema"
|
|
91
|
+
)
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f"Cannot generate a type string for {subject}: it contains "
|
|
94
|
+
f"recursive schemas that cannot be inlined. Register each "
|
|
95
|
+
f"recursive schema as its own data type so it can be referenced "
|
|
96
|
+
f"by identifier."
|
|
97
|
+
)
|
|
98
|
+
target = defs.get(ref_name, {})
|
|
99
|
+
return _resolve(
|
|
100
|
+
target, defs, names, self_name, self_identifier, stack + [ref_name]
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
result: Dict[str, Any] = {}
|
|
104
|
+
for key, value in node.items():
|
|
105
|
+
if key in _ANNOTATION_KEYS:
|
|
106
|
+
continue
|
|
107
|
+
result[key] = _resolve(
|
|
108
|
+
value, defs, names, self_name, self_identifier, stack
|
|
109
|
+
)
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def pydantic_to_type_string(model: SchemaModel) -> str:
|
|
114
|
+
schema = model.model_json_schema()
|
|
115
|
+
defs = schema.pop("$defs", {})
|
|
116
|
+
|
|
117
|
+
self_identifier = _registry.get(model)
|
|
118
|
+
names = _registered_names()
|
|
119
|
+
|
|
120
|
+
ref = schema.get("$ref")
|
|
121
|
+
if isinstance(ref, str) and ref.startswith("#/$defs/"):
|
|
122
|
+
# Self-recursive models put the body under ``$defs`` and make the root a ref.
|
|
123
|
+
self_name = ref.split("/")[-1]
|
|
124
|
+
body: Any = defs.get(self_name, {})
|
|
125
|
+
else:
|
|
126
|
+
self_name = schema.get("title") or model.__name__
|
|
127
|
+
body = schema
|
|
128
|
+
|
|
129
|
+
resolved = _resolve(body, defs, names, self_name, self_identifier, [self_name])
|
|
130
|
+
_strip_annotations(resolved)
|
|
131
|
+
|
|
132
|
+
name = self_identifier or model.__name__
|
|
133
|
+
return json_schema_to_ts(resolved, name)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def pydantic_to_rules(model: SchemaModel) -> List[data_type_pb2.DefinitionDataTypeRule]:
|
|
137
|
+
schema = model.model_json_schema()
|
|
138
|
+
rules: List[data_type_pb2.DefinitionDataTypeRule] = []
|
|
139
|
+
|
|
140
|
+
pattern = schema.get("pattern")
|
|
141
|
+
if pattern:
|
|
142
|
+
rules.append(
|
|
143
|
+
data_type_pb2.DefinitionDataTypeRule(
|
|
144
|
+
regex=data_type_pb2.DataTypeRegexRuleConfig(pattern=pattern)
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
minimum = schema.get("minimum")
|
|
149
|
+
maximum = schema.get("maximum")
|
|
150
|
+
if minimum is not None and maximum is not None:
|
|
151
|
+
rules.append(
|
|
152
|
+
data_type_pb2.DefinitionDataTypeRule(
|
|
153
|
+
number_range=data_type_pb2.DataTypeNumberRangeRuleConfig(
|
|
154
|
+
**{"from": int(minimum), "to": int(maximum)}
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
return rules
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Bridge to the bundled Node schema-conversion helper (``hercules/_tsgen``).
|
|
2
|
+
|
|
3
|
+
The helper handles the two directions that have no good pure-Python equivalent:
|
|
4
|
+
|
|
5
|
+
* a Pydantic JSON schema -> an inline TypeScript type expression
|
|
6
|
+
(via ``json-schema-to-typescript``)
|
|
7
|
+
* a TypeScript type expression -> a JSON schema
|
|
8
|
+
(via ``ts-json-schema-generator``)
|
|
9
|
+
|
|
10
|
+
Node must be installed. The helper's own npm dependencies are installed lazily on
|
|
11
|
+
first use if ``node_modules`` is missing.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import shutil
|
|
17
|
+
import subprocess
|
|
18
|
+
from functools import lru_cache
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, Dict, Optional
|
|
21
|
+
|
|
22
|
+
_TSGEN_DIR = Path(__file__).resolve().parent.parent / "_tsgen"
|
|
23
|
+
_CONVERT = _TSGEN_DIR / "convert.mjs"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TsGenError(RuntimeError):
|
|
27
|
+
"""Raised when the Node schema-conversion helper cannot run or fails."""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@lru_cache(maxsize=1)
|
|
31
|
+
def _node() -> str:
|
|
32
|
+
node = shutil.which("node")
|
|
33
|
+
if node is None:
|
|
34
|
+
raise TsGenError(
|
|
35
|
+
"Node.js is required for TypeScript <-> Pydantic schema conversion "
|
|
36
|
+
"but 'node' was not found on PATH. Install Node.js to continue."
|
|
37
|
+
)
|
|
38
|
+
return node
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@lru_cache(maxsize=1)
|
|
42
|
+
def _ensure_dependencies() -> None:
|
|
43
|
+
if (_TSGEN_DIR / "node_modules").is_dir():
|
|
44
|
+
return
|
|
45
|
+
npm = shutil.which("npm")
|
|
46
|
+
if npm is None:
|
|
47
|
+
raise TsGenError(
|
|
48
|
+
f"The Node helper dependencies are not installed and 'npm' was not "
|
|
49
|
+
f"found on PATH. Run 'npm install' in {_TSGEN_DIR} manually."
|
|
50
|
+
)
|
|
51
|
+
result = subprocess.run(
|
|
52
|
+
[npm, "install"],
|
|
53
|
+
cwd=_TSGEN_DIR,
|
|
54
|
+
capture_output=True,
|
|
55
|
+
text=True,
|
|
56
|
+
)
|
|
57
|
+
if result.returncode != 0:
|
|
58
|
+
raise TsGenError(
|
|
59
|
+
f"Failed to install Node helper dependencies in {_TSGEN_DIR}:\n"
|
|
60
|
+
f"{result.stderr.strip()}"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _run(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
65
|
+
_ensure_dependencies()
|
|
66
|
+
result = subprocess.run(
|
|
67
|
+
[_node(), str(_CONVERT)],
|
|
68
|
+
input=json.dumps(request),
|
|
69
|
+
capture_output=True,
|
|
70
|
+
text=True,
|
|
71
|
+
)
|
|
72
|
+
if result.returncode != 0:
|
|
73
|
+
raise TsGenError(result.stderr.strip() or "Node helper failed.")
|
|
74
|
+
return json.loads(result.stdout)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def json_schema_to_ts(schema: Dict[str, Any], name: str) -> str:
|
|
78
|
+
"""Compile a (pre-processed) JSON schema into an inline TypeScript type string."""
|
|
79
|
+
return _run({"mode": "json_schema_to_ts", "schema": schema, "name": name})["type"]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def ts_to_json_schema(
|
|
83
|
+
ts_type: str, name: str, preamble: Optional[str] = None
|
|
84
|
+
) -> Dict[str, Any]:
|
|
85
|
+
"""Convert a TypeScript type expression into a JSON schema."""
|
|
86
|
+
request: Dict[str, Any] = {
|
|
87
|
+
"mode": "ts_to_json_schema",
|
|
88
|
+
"ts": ts_type,
|
|
89
|
+
"name": name,
|
|
90
|
+
}
|
|
91
|
+
if preamble:
|
|
92
|
+
request["preamble"] = preamble
|
|
93
|
+
return _run(request)["schema"]
|
|
File without changes
|
hercules/manager/base.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Base manager (port of ``src/manager/BaseManager.ts``)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Callable, Dict, Generic, Iterator, List, Optional, Tuple, TypeVar
|
|
5
|
+
|
|
6
|
+
K = TypeVar("K")
|
|
7
|
+
V = TypeVar("V")
|
|
8
|
+
T = TypeVar("T")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class BaseManager(Generic[K, V]):
|
|
12
|
+
def __init__(self) -> None:
|
|
13
|
+
self.cache: Dict[K, V] = {}
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def size(self) -> int:
|
|
17
|
+
return len(self.cache)
|
|
18
|
+
|
|
19
|
+
def get(self, key: K) -> Optional[V]:
|
|
20
|
+
return self.cache.get(key)
|
|
21
|
+
|
|
22
|
+
def has(self, key: K) -> bool:
|
|
23
|
+
return key in self.cache
|
|
24
|
+
|
|
25
|
+
def set(self, key: K, value: V) -> "BaseManager[K, V]":
|
|
26
|
+
self.cache[key] = value
|
|
27
|
+
return self
|
|
28
|
+
|
|
29
|
+
def delete(self, key: K) -> bool:
|
|
30
|
+
if key in self.cache:
|
|
31
|
+
del self.cache[key]
|
|
32
|
+
return True
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
def clear(self) -> None:
|
|
36
|
+
self.cache.clear()
|
|
37
|
+
|
|
38
|
+
def values(self) -> List[V]:
|
|
39
|
+
return list(self.cache.values())
|
|
40
|
+
|
|
41
|
+
def keys(self) -> List[K]:
|
|
42
|
+
return list(self.cache.keys())
|
|
43
|
+
|
|
44
|
+
def entries(self) -> List[Tuple[K, V]]:
|
|
45
|
+
return list(self.cache.items())
|
|
46
|
+
|
|
47
|
+
def find(self, predicate: Callable[[V, K], bool]) -> Optional[V]:
|
|
48
|
+
for key, value in self.cache.items():
|
|
49
|
+
if predicate(value, key):
|
|
50
|
+
return value
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
def filter(self, predicate: Callable[[V, K], bool]) -> List[V]:
|
|
54
|
+
return [value for key, value in self.cache.items() if predicate(value, key)]
|
|
55
|
+
|
|
56
|
+
def map(self, fn: Callable[[V, K], T]) -> List[T]:
|
|
57
|
+
return [fn(value, key) for key, value in self.cache.items()]
|
|
58
|
+
|
|
59
|
+
def some(self, predicate: Callable[[V, K], bool]) -> bool:
|
|
60
|
+
return any(predicate(value, key) for key, value in self.cache.items())
|
|
61
|
+
|
|
62
|
+
def every(self, predicate: Callable[[V, K], bool]) -> bool:
|
|
63
|
+
return all(predicate(value, key) for key, value in self.cache.items())
|
|
64
|
+
|
|
65
|
+
def for_each(self, fn: Callable[[V, K], None]) -> None:
|
|
66
|
+
for key, value in self.cache.items():
|
|
67
|
+
fn(value, key)
|
|
68
|
+
|
|
69
|
+
def __iter__(self) -> Iterator[Tuple[K, V]]:
|
|
70
|
+
return iter(self.cache.items())
|
|
71
|
+
|
|
72
|
+
def __len__(self) -> int:
|
|
73
|
+
return len(self.cache)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Config manager (port of ``src/manager/config-manager.ts``)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
from hercules._tucana.helpers import construct_value, to_allowed_value
|
|
7
|
+
from hercules.manager.base import BaseManager
|
|
8
|
+
from hercules.types import ProjectConfiguration
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ConfigManager(BaseManager):
|
|
12
|
+
def update(self, configs: List) -> None:
|
|
13
|
+
self.clear()
|
|
14
|
+
for config in configs:
|
|
15
|
+
module_configurations = list(config.module_configurations)
|
|
16
|
+
|
|
17
|
+
def make_find_config(mcs):
|
|
18
|
+
def find_config(identifier):
|
|
19
|
+
mc = next(
|
|
20
|
+
(c for c in mcs if c.identifier == identifier), None
|
|
21
|
+
)
|
|
22
|
+
if mc is None:
|
|
23
|
+
return None
|
|
24
|
+
return to_allowed_value(
|
|
25
|
+
mc.value if mc.HasField("value") else construct_value(None)
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return find_config
|
|
29
|
+
|
|
30
|
+
self.set(
|
|
31
|
+
config.project_id,
|
|
32
|
+
ProjectConfiguration(
|
|
33
|
+
project_id=config.project_id,
|
|
34
|
+
config_values=[
|
|
35
|
+
{
|
|
36
|
+
"identifier": mc.identifier,
|
|
37
|
+
"value": to_allowed_value(
|
|
38
|
+
mc.value if mc.HasField("value") else construct_value(None)
|
|
39
|
+
),
|
|
40
|
+
}
|
|
41
|
+
for mc in module_configurations
|
|
42
|
+
],
|
|
43
|
+
find_config=make_find_config(module_configurations),
|
|
44
|
+
),
|
|
45
|
+
)
|
hercules/manager/flow.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Flow manager (port of ``src/manager/FlowManager.ts``).
|
|
2
|
+
|
|
3
|
+
Registry of the action's own flows, kept in sync via ActionFlowUpdate messages.
|
|
4
|
+
Keyed by flow id.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from hercules.manager.base import BaseManager
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FlowManager(BaseManager):
|
|
12
|
+
pass
|
hercules/map/__init__.py
ADDED
|
File without changes
|
hercules/map/datatype.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Data type mapping (port of ``src/map/datatype.map.ts``)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from hercules._metadata import get_metadata
|
|
5
|
+
from hercules.internal.schema import register_schema
|
|
6
|
+
from hercules.models.datatype import DataTypeProps
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def data_type_map(klass: type) -> DataTypeProps:
|
|
10
|
+
identifier = get_metadata("hercules:identifier", klass)
|
|
11
|
+
name = get_metadata("hercules:name", klass) or []
|
|
12
|
+
display_message = get_metadata("hercules:display_message", klass) or []
|
|
13
|
+
alias = get_metadata("hercules:alias", klass) or []
|
|
14
|
+
generic_keys = get_metadata("hercules:generic_keys", klass) or []
|
|
15
|
+
|
|
16
|
+
if not identifier:
|
|
17
|
+
raise ValueError(
|
|
18
|
+
f"Data type class {klass.__name__} is missing an identifier. "
|
|
19
|
+
f'Add @Identifier("your_identifier") to the class.'
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
schema = get_metadata("hercules:schema", klass)
|
|
23
|
+
if schema is None:
|
|
24
|
+
raise ValueError(
|
|
25
|
+
f"Data type class {klass.__name__} is missing a schema. "
|
|
26
|
+
f"Add @Schema(MyModel) with a Pydantic model to the class."
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
register_schema(schema, identifier)
|
|
30
|
+
|
|
31
|
+
type_string = get_metadata("hercules:type_string", klass)
|
|
32
|
+
|
|
33
|
+
return DataTypeProps(
|
|
34
|
+
identifier=identifier,
|
|
35
|
+
schema=schema,
|
|
36
|
+
name=name,
|
|
37
|
+
display_message=display_message,
|
|
38
|
+
alias=alias,
|
|
39
|
+
generic_keys=generic_keys,
|
|
40
|
+
type_string=type_string,
|
|
41
|
+
)
|
hercules/map/event.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Event mapping (port of ``src/map/event.map.ts``)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import fields, replace
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
from hercules._metadata import get_metadata, get_own_metadata
|
|
8
|
+
from hercules.map.runtime_event import runtime_event_map
|
|
9
|
+
from hercules.models.event import EventModel, EventSettingProps
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _merge_setting(base: EventSettingProps, override: EventSettingProps) -> EventSettingProps:
|
|
13
|
+
# Mirror `{...rs, ...override}`: only the properties the override actually set
|
|
14
|
+
# (non-None) replace the runtime event's setting.
|
|
15
|
+
changes = {
|
|
16
|
+
f.name: getattr(override, f.name)
|
|
17
|
+
for f in fields(override)
|
|
18
|
+
if f.name != "identifier" and getattr(override, f.name) is not None
|
|
19
|
+
}
|
|
20
|
+
return replace(base, **changes)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def event_map(klass: type) -> EventModel:
|
|
24
|
+
parent_class = klass.__bases__[0]
|
|
25
|
+
runtime_event = runtime_event_map(parent_class)
|
|
26
|
+
|
|
27
|
+
identifier = get_metadata("hercules:identifier", klass)
|
|
28
|
+
signature = get_metadata("hercules:signature", klass)
|
|
29
|
+
settings: List[EventSettingProps] = (
|
|
30
|
+
get_own_metadata("hercules:flow_settings", klass) or []
|
|
31
|
+
)
|
|
32
|
+
name = get_metadata("hercules:name", klass)
|
|
33
|
+
description = get_metadata("hercules:description", klass)
|
|
34
|
+
documentation = get_metadata("hercules:documentation", klass)
|
|
35
|
+
display_message = get_metadata("hercules:display_message", klass)
|
|
36
|
+
alias = get_metadata("hercules:alias", klass)
|
|
37
|
+
display_icon = get_metadata("hercules:display_icon", klass)
|
|
38
|
+
editable = get_metadata("hercules:editable", klass)
|
|
39
|
+
editable = editable if editable is not None else False
|
|
40
|
+
|
|
41
|
+
if not identifier:
|
|
42
|
+
raise ValueError(
|
|
43
|
+
f"Event class {klass.__name__} is missing an identifier. "
|
|
44
|
+
f'Add @Identifier("your_identifier") to the class.'
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
runtime_settings = runtime_event.settings or []
|
|
48
|
+
for es in settings:
|
|
49
|
+
if not any(s.identifier == es.identifier for s in runtime_settings):
|
|
50
|
+
raise ValueError(
|
|
51
|
+
f'Event class {klass.__name__} has a setting "{es.identifier}" '
|
|
52
|
+
f"that does not exist in its runtime event."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Settings come from the runtime event (in its order); the event class only
|
|
56
|
+
# overrides individual properties per identifier.
|
|
57
|
+
merged_settings: List[EventSettingProps] = []
|
|
58
|
+
for rs in runtime_settings:
|
|
59
|
+
override = next((s for s in settings if s.identifier == rs.identifier), None)
|
|
60
|
+
merged_settings.append(_merge_setting(rs, override) if override else replace(rs))
|
|
61
|
+
|
|
62
|
+
return EventModel(
|
|
63
|
+
runtime_identifier=runtime_event.identifier,
|
|
64
|
+
identifier=identifier,
|
|
65
|
+
signature=signature or runtime_event.signature,
|
|
66
|
+
settings=merged_settings,
|
|
67
|
+
name=name or runtime_event.name,
|
|
68
|
+
description=description or runtime_event.description,
|
|
69
|
+
documentation=documentation or runtime_event.documentation,
|
|
70
|
+
display_message=display_message or runtime_event.display_message,
|
|
71
|
+
alias=alias or runtime_event.alias,
|
|
72
|
+
display_icon=display_icon or runtime_event.display_icon,
|
|
73
|
+
editable=editable,
|
|
74
|
+
)
|
hercules/map/function.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Function mapping (port of ``src/map/function.map.ts``)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from dataclasses import replace
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
from hercules._metadata import get_metadata
|
|
8
|
+
from hercules.map.runtime_function import runtime_function_map
|
|
9
|
+
from hercules.models.function import FunctionParameterProps, FunctionProps
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def function_map(klass: type) -> FunctionProps:
|
|
13
|
+
parent_class = klass.__bases__[0]
|
|
14
|
+
runtime_function = runtime_function_map(parent_class)
|
|
15
|
+
|
|
16
|
+
identifier = get_metadata("hercules:identifier", klass)
|
|
17
|
+
function_parameters: List[FunctionParameterProps] = (
|
|
18
|
+
get_metadata("hercules:function_parameters", klass) or []
|
|
19
|
+
)
|
|
20
|
+
name = get_metadata("hercules:name", klass)
|
|
21
|
+
display_message = get_metadata("hercules:display_message", klass)
|
|
22
|
+
description = get_metadata("hercules:description", klass)
|
|
23
|
+
deprecation_message = get_metadata("hercules:deprecation_message", klass)
|
|
24
|
+
alias = get_metadata("hercules:alias", klass)
|
|
25
|
+
documentation = get_metadata("hercules:documentation", klass)
|
|
26
|
+
signature = get_metadata("hercules:signature", klass)
|
|
27
|
+
display_icon = get_metadata("hercules:display_icon", klass)
|
|
28
|
+
throws_error = get_metadata("hercules:throws_error", klass)
|
|
29
|
+
design = get_metadata("hercules:design", klass)
|
|
30
|
+
|
|
31
|
+
runtime_params = runtime_function.parameters or []
|
|
32
|
+
if len(function_parameters) > len(runtime_params):
|
|
33
|
+
raise ValueError(
|
|
34
|
+
f"Function definition class {klass.__name__} has more function "
|
|
35
|
+
f"parameters than its runtime function."
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
for fp in function_parameters:
|
|
39
|
+
if not any(p.runtime_name == fp.runtime_name for p in runtime_params):
|
|
40
|
+
raise ValueError(
|
|
41
|
+
f"Function definition class {klass.__name__} has a function "
|
|
42
|
+
f'parameter "{fp.runtime_name}" that does not exist in its '
|
|
43
|
+
f"runtime function."
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
merged: List[FunctionParameterProps] = list(function_parameters)
|
|
47
|
+
for rp in runtime_params:
|
|
48
|
+
if not any(p.runtime_name == rp.runtime_name for p in merged):
|
|
49
|
+
merged.append(replace(rp, runtime_definition_name=rp.runtime_name))
|
|
50
|
+
|
|
51
|
+
return FunctionProps(
|
|
52
|
+
runtime_definition_name=runtime_function.runtime_name,
|
|
53
|
+
runtime_name=identifier or runtime_function.runtime_name,
|
|
54
|
+
signature=signature or runtime_function.signature,
|
|
55
|
+
throws_error=throws_error if throws_error is not None else runtime_function.throws_error,
|
|
56
|
+
alias=alias or runtime_function.alias,
|
|
57
|
+
description=description or runtime_function.description,
|
|
58
|
+
name=name or runtime_function.name,
|
|
59
|
+
documentation=documentation or runtime_function.documentation,
|
|
60
|
+
deprecation_message=deprecation_message or runtime_function.deprecation_message,
|
|
61
|
+
display_message=display_message or runtime_function.display_message,
|
|
62
|
+
display_icon=display_icon or runtime_function.display_icon,
|
|
63
|
+
design=design or runtime_function.design,
|
|
64
|
+
parameters=[
|
|
65
|
+
replace(
|
|
66
|
+
p,
|
|
67
|
+
runtime_definition_name=p.runtime_definition_name or p.runtime_name,
|
|
68
|
+
name=p.name or [],
|
|
69
|
+
description=p.description or [],
|
|
70
|
+
documentation=p.documentation or [],
|
|
71
|
+
hidden=p.hidden or False,
|
|
72
|
+
optional=p.optional or False,
|
|
73
|
+
)
|
|
74
|
+
for p in merged
|
|
75
|
+
],
|
|
76
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Runtime event mapping (port of ``src/map/runtime_event.map.ts``)."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from hercules._metadata import get_metadata
|
|
5
|
+
from hercules.models.runtime_event import RuntimeEventProps
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def runtime_event_map(klass: type) -> RuntimeEventProps:
|
|
9
|
+
identifier = get_metadata("hercules:identifier", klass)
|
|
10
|
+
signature = get_metadata("hercules:signature", klass)
|
|
11
|
+
settings = get_metadata("hercules:flow_settings", klass) or []
|
|
12
|
+
name = get_metadata("hercules:name", klass) or []
|
|
13
|
+
description = get_metadata("hercules:description", klass) or []
|
|
14
|
+
documentation = get_metadata("hercules:documentation", klass) or []
|
|
15
|
+
display_message = get_metadata("hercules:display_message", klass) or []
|
|
16
|
+
alias = get_metadata("hercules:alias", klass) or []
|
|
17
|
+
display_icon = get_metadata("hercules:display_icon", klass)
|
|
18
|
+
editable = get_metadata("hercules:editable", klass)
|
|
19
|
+
editable = editable if editable is not None else False
|
|
20
|
+
|
|
21
|
+
if not identifier:
|
|
22
|
+
raise ValueError(
|
|
23
|
+
f"Runtime event class {klass.__name__} is missing an identifier. "
|
|
24
|
+
f'Add @Identifier("your_identifier") to the class.'
|
|
25
|
+
)
|
|
26
|
+
if not signature:
|
|
27
|
+
raise ValueError(
|
|
28
|
+
f"Runtime event class {klass.__name__} is missing a signature. "
|
|
29
|
+
f'Add @Signature("(): RETURN_TYPE") to the class.'
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return RuntimeEventProps(
|
|
33
|
+
identifier=identifier,
|
|
34
|
+
signature=signature,
|
|
35
|
+
settings=settings,
|
|
36
|
+
name=name,
|
|
37
|
+
description=description,
|
|
38
|
+
documentation=documentation,
|
|
39
|
+
display_message=display_message,
|
|
40
|
+
alias=alias,
|
|
41
|
+
display_icon=display_icon,
|
|
42
|
+
editable=editable,
|
|
43
|
+
)
|