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.
Files changed (258) hide show
  1. code0_hercules-1.3.0.dist-info/METADATA +79 -0
  2. code0_hercules-1.3.0.dist-info/RECORD +258 -0
  3. code0_hercules-1.3.0.dist-info/WHEEL +5 -0
  4. code0_hercules-1.3.0.dist-info/entry_points.txt +2 -0
  5. code0_hercules-1.3.0.dist-info/top_level.txt +1 -0
  6. hercules/__init__.py +81 -0
  7. hercules/_metadata.py +38 -0
  8. hercules/_tsgen/convert.mjs +96 -0
  9. hercules/_tsgen/package-lock.json +366 -0
  10. hercules/_tsgen/package.json +11 -0
  11. hercules/_tucana/__init__.py +29 -0
  12. hercules/_tucana/helpers.py +73 -0
  13. hercules/action.py +345 -0
  14. hercules/actions/__init__.py +21 -0
  15. hercules/actions/execution.py +121 -0
  16. hercules/actions/flow_execution.py +11 -0
  17. hercules/actions/flow_update.py +18 -0
  18. hercules/actions/module_configurations.py +14 -0
  19. hercules/actions/sub_flow_execution.py +14 -0
  20. hercules/cli.py +137 -0
  21. hercules/decorators/__init__.py +0 -0
  22. hercules/decorators/datatype.py +39 -0
  23. hercules/decorators/event.py +35 -0
  24. hercules/decorators/function.py +59 -0
  25. hercules/decorators/meta.py +82 -0
  26. hercules/decorators/runtime_event.py +15 -0
  27. hercules/decorators/runtime_function.py +18 -0
  28. hercules/definitions/__init__.py +162 -0
  29. hercules/definitions/cron_action/__init__.py +0 -0
  30. hercules/definitions/cron_action/data_types/__init__.py +0 -0
  31. hercules/definitions/cron_action/data_types/cron_day_of_month.py +11 -0
  32. hercules/definitions/cron_action/data_types/cron_day_of_week.py +11 -0
  33. hercules/definitions/cron_action/data_types/cron_hour.py +11 -0
  34. hercules/definitions/cron_action/data_types/cron_minute.py +11 -0
  35. hercules/definitions/cron_action/data_types/cron_month.py +11 -0
  36. hercules/definitions/cron_action/runtime_flow_types/__init__.py +0 -0
  37. hercules/definitions/cron_action/runtime_flow_types/cron.py +19 -0
  38. hercules/definitions/rest_action/__init__.py +0 -0
  39. hercules/definitions/rest_action/data_types/__init__.py +0 -0
  40. hercules/definitions/rest_action/data_types/rest_adapter_input.py +19 -0
  41. hercules/definitions/rest_action/data_types/rest_auth_type.py +19 -0
  42. hercules/definitions/rest_action/data_types/rest_auth_value.py +11 -0
  43. hercules/definitions/rest_action/runtime_flow_types/__init__.py +0 -0
  44. hercules/definitions/rest_action/runtime_flow_types/rest.py +20 -0
  45. hercules/definitions/rest_action/runtime_functions/__init__.py +0 -0
  46. hercules/definitions/rest_action/runtime_functions/rest_control_respond.py +21 -0
  47. hercules/definitions/taurus_boolean/__init__.py +0 -0
  48. hercules/definitions/taurus_boolean/data_types/__init__.py +0 -0
  49. hercules/definitions/taurus_boolean/data_types/boolean.py +11 -0
  50. hercules/definitions/taurus_boolean/runtime_functions/__init__.py +0 -0
  51. hercules/definitions/taurus_boolean/runtime_functions/std_boolean_as_number.py +18 -0
  52. hercules/definitions/taurus_boolean/runtime_functions/std_boolean_as_text.py +18 -0
  53. hercules/definitions/taurus_boolean/runtime_functions/std_boolean_from_number.py +18 -0
  54. hercules/definitions/taurus_boolean/runtime_functions/std_boolean_from_text.py +18 -0
  55. hercules/definitions/taurus_boolean/runtime_functions/std_boolean_is_equal.py +19 -0
  56. hercules/definitions/taurus_boolean/runtime_functions/std_boolean_negate.py +18 -0
  57. hercules/definitions/taurus_color/__init__.py +0 -0
  58. hercules/definitions/taurus_color/data_types/__init__.py +0 -0
  59. hercules/definitions/taurus_color/data_types/color.py +17 -0
  60. hercules/definitions/taurus_color/runtime_functions/__init__.py +0 -0
  61. hercules/definitions/taurus_color/runtime_functions/std_color_as_hex.py +18 -0
  62. hercules/definitions/taurus_color/runtime_functions/std_color_as_hsl.py +18 -0
  63. hercules/definitions/taurus_color/runtime_functions/std_color_as_rgb.py +18 -0
  64. hercules/definitions/taurus_color/runtime_functions/std_color_from_hex.py +18 -0
  65. hercules/definitions/taurus_color/runtime_functions/std_color_from_hsl.py +21 -0
  66. hercules/definitions/taurus_color/runtime_functions/std_color_from_rgb.py +21 -0
  67. hercules/definitions/taurus_control/__init__.py +0 -0
  68. hercules/definitions/taurus_control/data_types/__init__.py +0 -0
  69. hercules/definitions/taurus_control/data_types/comparator.py +21 -0
  70. hercules/definitions/taurus_control/data_types/consumer.py +20 -0
  71. hercules/definitions/taurus_control/data_types/predicate.py +20 -0
  72. hercules/definitions/taurus_control/data_types/runnable.py +13 -0
  73. hercules/definitions/taurus_control/data_types/transform.py +20 -0
  74. hercules/definitions/taurus_control/runtime_functions/__init__.py +0 -0
  75. hercules/definitions/taurus_control/runtime_functions/std_control_if.py +19 -0
  76. hercules/definitions/taurus_control/runtime_functions/std_control_if_else.py +21 -0
  77. hercules/definitions/taurus_control/runtime_functions/std_control_return.py +18 -0
  78. hercules/definitions/taurus_control/runtime_functions/std_control_stop.py +16 -0
  79. hercules/definitions/taurus_control/runtime_functions/std_control_value.py +18 -0
  80. hercules/definitions/taurus_date/__init__.py +0 -0
  81. hercules/definitions/taurus_date/data_types/__init__.py +0 -0
  82. hercules/definitions/taurus_date/data_types/date.py +11 -0
  83. hercules/definitions/taurus_date/data_types/hour.py +11 -0
  84. hercules/definitions/taurus_date/data_types/minute.py +11 -0
  85. hercules/definitions/taurus_date/data_types/month.py +22 -0
  86. hercules/definitions/taurus_date/runtime_functions/__init__.py +0 -0
  87. hercules/definitions/taurus_date/runtime_functions/std_date_format.py +20 -0
  88. hercules/definitions/taurus_date/runtime_functions/std_date_from.py +24 -0
  89. hercules/definitions/taurus_date/runtime_functions/std_date_from_text.py +19 -0
  90. hercules/definitions/taurus_date/runtime_functions/std_date_from_unix.py +18 -0
  91. hercules/definitions/taurus_date/runtime_functions/std_date_now.py +16 -0
  92. hercules/definitions/taurus_file/__init__.py +0 -0
  93. hercules/definitions/taurus_file/data_types/__init__.py +0 -0
  94. hercules/definitions/taurus_file/data_types/file.py +19 -0
  95. hercules/definitions/taurus_file/runtime_functions/__init__.py +0 -0
  96. hercules/definitions/taurus_file/runtime_functions/std_file_size.py +18 -0
  97. hercules/definitions/taurus_http/__init__.py +0 -0
  98. hercules/definitions/taurus_http/data_types/__init__.py +0 -0
  99. hercules/definitions/taurus_http/data_types/http_auth_place.py +12 -0
  100. hercules/definitions/taurus_http/data_types/http_auth_type.py +17 -0
  101. hercules/definitions/taurus_http/data_types/http_auth_value.py +11 -0
  102. hercules/definitions/taurus_http/data_types/http_method.py +16 -0
  103. hercules/definitions/taurus_http/data_types/http_payload.py +11 -0
  104. hercules/definitions/taurus_http/data_types/http_request.py +19 -0
  105. hercules/definitions/taurus_http/data_types/http_response.py +18 -0
  106. hercules/definitions/taurus_http/data_types/http_schema.py +31 -0
  107. hercules/definitions/taurus_http/data_types/http_status_code.py +13 -0
  108. hercules/definitions/taurus_http/data_types/http_url.py +13 -0
  109. hercules/definitions/taurus_http/runtime_functions/__init__.py +0 -0
  110. hercules/definitions/taurus_http/runtime_functions/http_request_send.py +26 -0
  111. hercules/definitions/taurus_list/__init__.py +0 -0
  112. hercules/definitions/taurus_list/data_types/__init__.py +0 -0
  113. hercules/definitions/taurus_list/data_types/list.py +13 -0
  114. hercules/definitions/taurus_list/runtime_functions/__init__.py +0 -0
  115. hercules/definitions/taurus_list/runtime_functions/std_list_at.py +20 -0
  116. hercules/definitions/taurus_list/runtime_functions/std_list_concat.py +20 -0
  117. hercules/definitions/taurus_list/runtime_functions/std_list_filter.py +19 -0
  118. hercules/definitions/taurus_list/runtime_functions/std_list_find.py +20 -0
  119. hercules/definitions/taurus_list/runtime_functions/std_list_find_index.py +19 -0
  120. hercules/definitions/taurus_list/runtime_functions/std_list_find_last.py +20 -0
  121. hercules/definitions/taurus_list/runtime_functions/std_list_first.py +18 -0
  122. hercules/definitions/taurus_list/runtime_functions/std_list_flat.py +18 -0
  123. hercules/definitions/taurus_list/runtime_functions/std_list_for_each.py +19 -0
  124. hercules/definitions/taurus_list/runtime_functions/std_list_index_of.py +19 -0
  125. hercules/definitions/taurus_list/runtime_functions/std_list_is_empty.py +18 -0
  126. hercules/definitions/taurus_list/runtime_functions/std_list_join.py +19 -0
  127. hercules/definitions/taurus_list/runtime_functions/std_list_last.py +18 -0
  128. hercules/definitions/taurus_list/runtime_functions/std_list_map.py +19 -0
  129. hercules/definitions/taurus_list/runtime_functions/std_list_max.py +18 -0
  130. hercules/definitions/taurus_list/runtime_functions/std_list_min.py +18 -0
  131. hercules/definitions/taurus_list/runtime_functions/std_list_pop.py +18 -0
  132. hercules/definitions/taurus_list/runtime_functions/std_list_push.py +19 -0
  133. hercules/definitions/taurus_list/runtime_functions/std_list_remove.py +19 -0
  134. hercules/definitions/taurus_list/runtime_functions/std_list_reverse.py +18 -0
  135. hercules/definitions/taurus_list/runtime_functions/std_list_size.py +18 -0
  136. hercules/definitions/taurus_list/runtime_functions/std_list_sort.py +19 -0
  137. hercules/definitions/taurus_list/runtime_functions/std_list_sort_reverse.py +19 -0
  138. hercules/definitions/taurus_list/runtime_functions/std_list_sum.py +18 -0
  139. hercules/definitions/taurus_list/runtime_functions/std_list_to_unique.py +18 -0
  140. hercules/definitions/taurus_number/__init__.py +0 -0
  141. hercules/definitions/taurus_number/data_types/__init__.py +0 -0
  142. hercules/definitions/taurus_number/data_types/number.py +11 -0
  143. hercules/definitions/taurus_number/runtime_functions/__init__.py +0 -0
  144. hercules/definitions/taurus_number/runtime_functions/std_number_abs.py +18 -0
  145. hercules/definitions/taurus_number/runtime_functions/std_number_add.py +19 -0
  146. hercules/definitions/taurus_number/runtime_functions/std_number_arccos.py +18 -0
  147. hercules/definitions/taurus_number/runtime_functions/std_number_arcsin.py +18 -0
  148. hercules/definitions/taurus_number/runtime_functions/std_number_arctan.py +18 -0
  149. hercules/definitions/taurus_number/runtime_functions/std_number_as_text.py +18 -0
  150. hercules/definitions/taurus_number/runtime_functions/std_number_clamp.py +20 -0
  151. hercules/definitions/taurus_number/runtime_functions/std_number_cos.py +18 -0
  152. hercules/definitions/taurus_number/runtime_functions/std_number_cosh.py +18 -0
  153. hercules/definitions/taurus_number/runtime_functions/std_number_divide.py +20 -0
  154. hercules/definitions/taurus_number/runtime_functions/std_number_euler.py +16 -0
  155. hercules/definitions/taurus_number/runtime_functions/std_number_exponential.py +19 -0
  156. hercules/definitions/taurus_number/runtime_functions/std_number_from_text.py +18 -0
  157. hercules/definitions/taurus_number/runtime_functions/std_number_has_digits.py +18 -0
  158. hercules/definitions/taurus_number/runtime_functions/std_number_is_equal.py +19 -0
  159. hercules/definitions/taurus_number/runtime_functions/std_number_is_greater.py +19 -0
  160. hercules/definitions/taurus_number/runtime_functions/std_number_is_less.py +19 -0
  161. hercules/definitions/taurus_number/runtime_functions/std_number_is_positive.py +18 -0
  162. hercules/definitions/taurus_number/runtime_functions/std_number_is_zero.py +18 -0
  163. hercules/definitions/taurus_number/runtime_functions/std_number_ln.py +18 -0
  164. hercules/definitions/taurus_number/runtime_functions/std_number_log.py +19 -0
  165. hercules/definitions/taurus_number/runtime_functions/std_number_max.py +19 -0
  166. hercules/definitions/taurus_number/runtime_functions/std_number_min.py +19 -0
  167. hercules/definitions/taurus_number/runtime_functions/std_number_modulo.py +19 -0
  168. hercules/definitions/taurus_number/runtime_functions/std_number_multiply.py +19 -0
  169. hercules/definitions/taurus_number/runtime_functions/std_number_negate.py +18 -0
  170. hercules/definitions/taurus_number/runtime_functions/std_number_pi.py +16 -0
  171. hercules/definitions/taurus_number/runtime_functions/std_number_random_number.py +19 -0
  172. hercules/definitions/taurus_number/runtime_functions/std_number_remove_digits.py +18 -0
  173. hercules/definitions/taurus_number/runtime_functions/std_number_root.py +19 -0
  174. hercules/definitions/taurus_number/runtime_functions/std_number_round.py +19 -0
  175. hercules/definitions/taurus_number/runtime_functions/std_number_round_down.py +19 -0
  176. hercules/definitions/taurus_number/runtime_functions/std_number_round_up.py +19 -0
  177. hercules/definitions/taurus_number/runtime_functions/std_number_sin.py +18 -0
  178. hercules/definitions/taurus_number/runtime_functions/std_number_sinh.py +18 -0
  179. hercules/definitions/taurus_number/runtime_functions/std_number_square.py +18 -0
  180. hercules/definitions/taurus_number/runtime_functions/std_number_square_root.py +18 -0
  181. hercules/definitions/taurus_number/runtime_functions/std_number_subtract.py +19 -0
  182. hercules/definitions/taurus_number/runtime_functions/std_number_tan.py +18 -0
  183. hercules/definitions/taurus_object/__init__.py +0 -0
  184. hercules/definitions/taurus_object/data_types/__init__.py +0 -0
  185. hercules/definitions/taurus_object/data_types/object.py +13 -0
  186. hercules/definitions/taurus_object/data_types/type.py +13 -0
  187. hercules/definitions/taurus_object/runtime_functions/__init__.py +0 -0
  188. hercules/definitions/taurus_object/runtime_functions/std_object_contains_key.py +19 -0
  189. hercules/definitions/taurus_object/runtime_functions/std_object_get.py +19 -0
  190. hercules/definitions/taurus_object/runtime_functions/std_object_keys.py +18 -0
  191. hercules/definitions/taurus_object/runtime_functions/std_object_set.py +20 -0
  192. hercules/definitions/taurus_object/runtime_functions/std_object_size.py +18 -0
  193. hercules/definitions/taurus_text/__init__.py +0 -0
  194. hercules/definitions/taurus_text/data_types/__init__.py +0 -0
  195. hercules/definitions/taurus_text/data_types/text.py +11 -0
  196. hercules/definitions/taurus_text/data_types/text_encoding.py +13 -0
  197. hercules/definitions/taurus_text/runtime_functions/__init__.py +0 -0
  198. hercules/definitions/taurus_text/runtime_functions/std_text_append.py +19 -0
  199. hercules/definitions/taurus_text/runtime_functions/std_text_as_bytes.py +18 -0
  200. hercules/definitions/taurus_text/runtime_functions/std_text_at.py +19 -0
  201. hercules/definitions/taurus_text/runtime_functions/std_text_byte_size.py +18 -0
  202. hercules/definitions/taurus_text/runtime_functions/std_text_capitalize.py +18 -0
  203. hercules/definitions/taurus_text/runtime_functions/std_text_chars.py +18 -0
  204. hercules/definitions/taurus_text/runtime_functions/std_text_contains.py +19 -0
  205. hercules/definitions/taurus_text/runtime_functions/std_text_decode.py +19 -0
  206. hercules/definitions/taurus_text/runtime_functions/std_text_encode.py +19 -0
  207. hercules/definitions/taurus_text/runtime_functions/std_text_ends_with.py +19 -0
  208. hercules/definitions/taurus_text/runtime_functions/std_text_from_ascii.py +18 -0
  209. hercules/definitions/taurus_text/runtime_functions/std_text_hex.py +18 -0
  210. hercules/definitions/taurus_text/runtime_functions/std_text_index_of.py +19 -0
  211. hercules/definitions/taurus_text/runtime_functions/std_text_insert.py +20 -0
  212. hercules/definitions/taurus_text/runtime_functions/std_text_is_equal.py +19 -0
  213. hercules/definitions/taurus_text/runtime_functions/std_text_length.py +18 -0
  214. hercules/definitions/taurus_text/runtime_functions/std_text_lowercase.py +18 -0
  215. hercules/definitions/taurus_text/runtime_functions/std_text_octal.py +18 -0
  216. hercules/definitions/taurus_text/runtime_functions/std_text_prepend.py +19 -0
  217. hercules/definitions/taurus_text/runtime_functions/std_text_remove.py +20 -0
  218. hercules/definitions/taurus_text/runtime_functions/std_text_replace.py +20 -0
  219. hercules/definitions/taurus_text/runtime_functions/std_text_replace_first.py +21 -0
  220. hercules/definitions/taurus_text/runtime_functions/std_text_replace_last.py +20 -0
  221. hercules/definitions/taurus_text/runtime_functions/std_text_reverse.py +18 -0
  222. hercules/definitions/taurus_text/runtime_functions/std_text_split.py +19 -0
  223. hercules/definitions/taurus_text/runtime_functions/std_text_starts_with.py +19 -0
  224. hercules/definitions/taurus_text/runtime_functions/std_text_swapcase.py +18 -0
  225. hercules/definitions/taurus_text/runtime_functions/std_text_to_ascii.py +18 -0
  226. hercules/definitions/taurus_text/runtime_functions/std_text_trim.py +18 -0
  227. hercules/definitions/taurus_text/runtime_functions/std_text_uppercase.py +18 -0
  228. hercules/events.py +23 -0
  229. hercules/internal/__init__.py +0 -0
  230. hercules/internal/connection.py +37 -0
  231. hercules/internal/literal.py +113 -0
  232. hercules/internal/module_builder.py +261 -0
  233. hercules/internal/pydantic_codegen.py +82 -0
  234. hercules/internal/schema.py +158 -0
  235. hercules/internal/tsgen.py +93 -0
  236. hercules/manager/__init__.py +0 -0
  237. hercules/manager/base.py +73 -0
  238. hercules/manager/config.py +45 -0
  239. hercules/manager/datatype.py +8 -0
  240. hercules/manager/event.py +8 -0
  241. hercules/manager/flow.py +12 -0
  242. hercules/manager/function.py +8 -0
  243. hercules/manager/runtime_event.py +8 -0
  244. hercules/manager/runtime_function.py +8 -0
  245. hercules/map/__init__.py +0 -0
  246. hercules/map/datatype.py +41 -0
  247. hercules/map/event.py +74 -0
  248. hercules/map/function.py +76 -0
  249. hercules/map/runtime_event.py +43 -0
  250. hercules/map/runtime_function.py +64 -0
  251. hercules/models/__init__.py +0 -0
  252. hercules/models/datatype.py +49 -0
  253. hercules/models/event.py +35 -0
  254. hercules/models/function.py +37 -0
  255. hercules/models/runtime_event.py +29 -0
  256. hercules/models/runtime_function.py +33 -0
  257. hercules/schema.py +38 -0
  258. hercules/types.py +88 -0
@@ -0,0 +1,18 @@
1
+ from hercules.models.runtime_function import RuntimeFunctionRunnable
2
+ from hercules.decorators.meta import Alias, Description, DisplayIcon, DisplayMessage, Identifier, Name, Signature
3
+ from hercules.decorators.runtime_function import OmitRuntimeFunction
4
+ from hercules.decorators.function import Parameter
5
+
6
+
7
+ @OmitRuntimeFunction()
8
+ @Identifier("std::text::uppercase")
9
+ @Signature("(value: TEXT): TEXT")
10
+ @Name({"code": "en-US", "content": "Uppercase"})
11
+ @Description({"code": "en-US", "content": "Transforms all letters in the text to their uppercase equivalents."})
12
+ @DisplayMessage({"code": "en-US", "content": "Uppercase ${value}"})
13
+ @Alias({"code": "en-US", "content": "uppercase;text;string;std"})
14
+ @DisplayIcon("tabler:abc")
15
+ @Parameter({"runtime_name": "value", "name": [{"code": "en-US", "content": "Text Value"}], "description": [{"code": "en-US", "content": "Converts all characters in the input text to uppercase."}]})
16
+ class StdTextUppercase(RuntimeFunctionRunnable):
17
+ def run(self, *args):
18
+ raise NotImplementedError("StdTextUppercase.run() is not implemented")
hercules/events.py ADDED
@@ -0,0 +1,23 @@
1
+ """Event names (port of ``src/events.ts``)."""
2
+ from __future__ import annotations
3
+
4
+ from enum import Enum
5
+
6
+
7
+ class CodeZeroEvent(str, Enum):
8
+ error = "error"
9
+ connected = "connected"
10
+ stream_message_received = "streamMessageReceived"
11
+ stream_message_sent = "streamMessageSent"
12
+ module_updated = "moduleUpdated"
13
+ execution_request_received = "executionRequestReceived"
14
+ sub_flow_execution_response_received = "subFlowExecutionResponseReceived"
15
+ flow_execution_response_received = "flowExecutionResponseReceived"
16
+ flow_updated = "flowUpdated"
17
+ flow_deleted = "flowDeleted"
18
+
19
+ def __str__(self) -> str: # so it can be used interchangeably with the value
20
+ return self.value
21
+
22
+
23
+ __all__ = ["CodeZeroEvent"]
File without changes
@@ -0,0 +1,37 @@
1
+ """gRPC connection (port of ``src/internal/connection.ts``).
2
+
3
+ Opens the bi-directional ``ActionTransferService.Transfer`` stream and sends the
4
+ initial ``ActionLogon`` request. Uses ``grpc.aio`` for an async streaming client.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Optional, Tuple
9
+
10
+ import grpc
11
+
12
+ from tucana.generated.aquila import action_pb2, action_pb2_grpc
13
+ from tucana.generated.shared import module_pb2
14
+
15
+
16
+ async def create_connection(
17
+ module: module_pb2.Module,
18
+ auth_token: str,
19
+ aquila_url: str,
20
+ grpc_options: Optional[list] = None,
21
+ ) -> Tuple[grpc.aio.Channel, "grpc.aio.StreamStreamCall"]:
22
+ channel = grpc.aio.insecure_channel(aquila_url, options=grpc_options)
23
+ stub = action_pb2_grpc.ActionTransferServiceStub(channel)
24
+
25
+ # Bi-directional stream. Authorization is passed as call metadata.
26
+ stream = stub.Transfer(metadata=(("authorization", auth_token),))
27
+
28
+ await stream.write(
29
+ action_pb2.ActionTransferRequest(
30
+ logon=action_pb2.ActionLogon(
31
+ module=module,
32
+ scaling_option=action_pb2.ActionLogon.ScalingOption.SPLIT,
33
+ )
34
+ )
35
+ )
36
+
37
+ return channel, stream
@@ -0,0 +1,113 @@
1
+ """Inline ``${signature}`` reference resolution (port of ``src/internal/literal.ts``).
2
+
3
+ Resolves an ``aquila.ActionLiteralValue`` into a plain Python value, substituting
4
+ every ``${signature}`` placeholder inside a (possibly nested) string leaf with the
5
+ value of the matching inline reference.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import re
11
+ from typing import Optional
12
+
13
+ from hercules._tucana.helpers import PlainValue, to_allowed_value
14
+ from hercules.types import RuntimeError
15
+ from tucana.generated.shared import struct_pb2
16
+
17
+ __all__ = ["resolve_literal", "resolve_node_value", "to_sub_flow_caller"]
18
+
19
+ # Matches every ``${signature}`` placeholder inside a string.
20
+ _REFERENCE_PATTERN = re.compile(r"\$\{([^}]+)\}")
21
+ # Matches a string that consists of exactly one ``${signature}`` placeholder.
22
+ # ``\A``/``\Z`` (not ``^``/``$``) so a trailing newline is not treated as a sole match,
23
+ # mirroring JavaScript's ``$`` anchor.
24
+ _SOLE_REFERENCE_PATTERN = re.compile(r"\A\$\{([^}]+)\}\Z")
25
+
26
+
27
+ def to_sub_flow_caller(action, sub_flow):
28
+ """Wrap a sub flow value in an awaitable caller exposing its declared I/O schema."""
29
+
30
+ async def caller(*args):
31
+ return await action.execute_sub_flow(sub_flow, *args)
32
+
33
+ # Expose the sub flow's declared I/O so the handler can inspect it.
34
+ caller.input_schema = sub_flow.input_schema
35
+ caller.output_schema = sub_flow.output_schema
36
+ return caller
37
+
38
+
39
+ def resolve_node_value(action, node):
40
+ """Resolve a single parameter node into a concrete value.
41
+
42
+ Literal values have their inline ``${signature}`` references substituted; sub
43
+ flows become awaitable callers. A missing node resolves to ``None``.
44
+ """
45
+ which = node.WhichOneof("value") if node is not None else None
46
+ if which == "literal_value":
47
+ return resolve_literal(action, node.literal_value)
48
+ if which == "sub_flow":
49
+ return to_sub_flow_caller(action, node.sub_flow)
50
+ return None
51
+
52
+
53
+ def resolve_literal(action, literal):
54
+ """Resolve an ``ActionLiteralValue`` into a plain value.
55
+
56
+ A string that is exactly ``${signature}`` adopts the referenced value verbatim
57
+ (preserving its type); mixed strings interpolate the referenced value as text.
58
+ Unknown signatures are left untouched.
59
+ """
60
+ references = {}
61
+ for reference in literal.references:
62
+ references[reference.signature] = resolve_node_value(action, reference.value)
63
+ if literal.HasField("value"):
64
+ return _resolve_value(literal.value, references)
65
+ return None
66
+
67
+
68
+ def _resolve_value(value: struct_pb2.Value, references: dict):
69
+ kind = value.WhichOneof("kind")
70
+ if kind == "string_value":
71
+ return _resolve_string(value.string_value, references)
72
+ if kind == "struct_value":
73
+ return {k: _resolve_value(v, references) for k, v in value.struct_value.fields.items()}
74
+ if kind == "list_value":
75
+ return [_resolve_value(v, references) for v in value.list_value.values]
76
+ # Numbers, booleans and null cannot carry placeholders.
77
+ return to_allowed_value(value)
78
+
79
+
80
+ def _resolve_string(raw: str, references: dict):
81
+ sole = _SOLE_REFERENCE_PATTERN.match(raw)
82
+ if sole is not None:
83
+ signature = sole.group(1)
84
+ # Adopt the referenced value verbatim so its type (number, dict, sub flow, ...) is preserved.
85
+ return references[signature] if signature in references else raw
86
+
87
+ def replace(match: "re.Match[str]") -> str:
88
+ signature = match.group(1)
89
+ if signature in references:
90
+ return _stringify_reference(signature, references[signature])
91
+ return match.group(0)
92
+
93
+ return _REFERENCE_PATTERN.sub(replace, raw)
94
+
95
+
96
+ def _stringify_reference(signature: str, value: Optional[PlainValue]) -> str:
97
+ if value is None:
98
+ return ""
99
+ if isinstance(value, str):
100
+ return value
101
+ if callable(value):
102
+ # A sub flow has no textual form, so it cannot be interpolated into a string.
103
+ raise RuntimeError(
104
+ "INLINE_REFERENCE_NOT_STRINGIFIABLE",
105
+ f"Inline reference ${{{signature}}} resolves to a sub flow and cannot be interpolated into a string",
106
+ )
107
+ if isinstance(value, bool):
108
+ # Match the cross-SDK textual form ("true"/"false"), not Python's "True"/"False".
109
+ return "true" if value else "false"
110
+ if isinstance(value, (int, float)):
111
+ return str(value)
112
+ # dict / list -> compact JSON, matching the TS ``JSON.stringify`` output.
113
+ return json.dumps(value, separators=(",", ":"))
@@ -0,0 +1,261 @@
1
+ """Module builder (port of ``src/internal/module-builder.ts``).
2
+
3
+ Assembles the tucana ``shared.Module`` protobuf message from the registered
4
+ definitions.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from dataclasses import dataclass
9
+ from typing import List, Optional, Union
10
+
11
+ from hercules._tucana.helpers import construct_value
12
+ from tucana.generated.shared import (
13
+ data_type_pb2,
14
+ flow_type_pb2,
15
+ function_pb2,
16
+ module_pb2,
17
+ runtime_flow_type_pb2,
18
+ runtime_function_pb2,
19
+ translation_pb2,
20
+ )
21
+ from hercules.models.datatype import DataTypeProps
22
+ from hercules.models.event import EventModel
23
+ from hercules.models.function import FunctionProps
24
+ from hercules.models.runtime_event import RuntimeEventProps
25
+ from hercules.models.runtime_function import RuntimeFunctionProps
26
+ from hercules.types import ConfigurationDefinition, Translation
27
+
28
+ _NONE = flow_type_pb2.FlowTypeSetting.UniquenessScope.NONE
29
+
30
+
31
+ @dataclass
32
+ class ModuleBuildData:
33
+ identifier: str
34
+ version: str
35
+ author: str
36
+ icon: str
37
+ documentation: str
38
+ name: List[Translation]
39
+ configuration_definitions: List[ConfigurationDefinition]
40
+ data_types: List[DataTypeProps]
41
+ events: List[EventModel]
42
+ runtime_events: List[RuntimeEventProps]
43
+ functions: List[FunctionProps]
44
+ runtime_functions: List[RuntimeFunctionProps]
45
+
46
+
47
+ def _translations(items) -> List[translation_pb2.Translation]:
48
+ result = []
49
+ for item in items or []:
50
+ if isinstance(item, Translation):
51
+ result.append(translation_pb2.Translation(code=item.code, content=item.content))
52
+ elif isinstance(item, dict):
53
+ result.append(
54
+ translation_pb2.Translation(code=item["code"], content=item["content"])
55
+ )
56
+ else:
57
+ result.append(translation_pb2.Translation(code=item.code, content=item.content))
58
+ return result
59
+
60
+
61
+ def _to_uniqueness_scope(unique: Optional[Union[int, str]]) -> int:
62
+ if unique is None:
63
+ return _NONE
64
+ if isinstance(unique, str):
65
+ scope = flow_type_pb2.FlowTypeSetting.UniquenessScope.Value(unique)
66
+ return scope
67
+ return unique
68
+
69
+
70
+ def _config_def(def_: ConfigurationDefinition, version: str) -> module_pb2.ModuleConfigurationDefinition:
71
+ kwargs = dict(
72
+ identifier=def_.identifier,
73
+ name=_translations(def_.name),
74
+ description=_translations(def_.description),
75
+ type=def_.type,
76
+ linked_data_type_identifiers=def_.linked_data_types or [],
77
+ optional=def_.optional or False,
78
+ hidden=def_.hidden or False,
79
+ )
80
+ if def_.default_value is not None:
81
+ kwargs["default_value"] = construct_value(def_.default_value)
82
+ return module_pb2.ModuleConfigurationDefinition(**kwargs)
83
+
84
+
85
+ def _data_type(dt: DataTypeProps, version: str) -> data_type_pb2.DefinitionDataType:
86
+ return data_type_pb2.DefinitionDataType(
87
+ identifier=dt.identifier,
88
+ name=_translations(dt.name),
89
+ alias=_translations(dt.alias),
90
+ rules=list(dt.rules or []),
91
+ generic_keys=list(dt.generic_keys or []),
92
+ type=dt.type,
93
+ linked_data_type_identifiers=[],
94
+ display_message=_translations(dt.display_message),
95
+ version=version,
96
+ definition_source="action",
97
+ )
98
+
99
+
100
+ def _flow_type_setting(s, version: str) -> flow_type_pb2.FlowTypeSetting:
101
+ kwargs = dict(
102
+ identifier=s.identifier,
103
+ unique=_to_uniqueness_scope(s.unique),
104
+ name=_translations(s.name),
105
+ description=_translations(s.description),
106
+ optional=s.optional or False,
107
+ hidden=s.hidden or False,
108
+ )
109
+ if s.default_value is not None:
110
+ kwargs["default_value"] = construct_value(s.default_value)
111
+ return flow_type_pb2.FlowTypeSetting(**kwargs)
112
+
113
+
114
+ def _flow_type(ft: EventModel, version: str) -> flow_type_pb2.FlowType:
115
+ return flow_type_pb2.FlowType(
116
+ identifier=ft.identifier,
117
+ settings=[_flow_type_setting(s, version) for s in (ft.settings or [])],
118
+ editable=ft.editable or False,
119
+ name=_translations(ft.name),
120
+ description=_translations(ft.description),
121
+ documentation=_translations(ft.documentation),
122
+ display_message=_translations(ft.display_message),
123
+ alias=_translations(ft.alias),
124
+ version=version,
125
+ display_icon=ft.display_icon or "tabler:note",
126
+ definition_source="action",
127
+ linked_data_type_identifiers=[],
128
+ signature=ft.signature,
129
+ runtime_identifier=ft.runtime_identifier or ft.identifier,
130
+ )
131
+
132
+
133
+ def _runtime_flow_type_setting(s, version: str) -> runtime_flow_type_pb2.RuntimeFlowTypeSetting:
134
+ kwargs = dict(
135
+ identifier=s.identifier,
136
+ unique=_to_uniqueness_scope(s.unique),
137
+ name=_translations(s.name),
138
+ description=_translations(s.description),
139
+ optional=s.optional or False,
140
+ hidden=s.hidden or False,
141
+ )
142
+ if s.default_value is not None:
143
+ kwargs["default_value"] = construct_value(s.default_value)
144
+ return runtime_flow_type_pb2.RuntimeFlowTypeSetting(**kwargs)
145
+
146
+
147
+ def _runtime_flow_type(rft: RuntimeEventProps, version: str) -> runtime_flow_type_pb2.RuntimeFlowType:
148
+ return runtime_flow_type_pb2.RuntimeFlowType(
149
+ identifier=rft.identifier,
150
+ runtime_settings=[_runtime_flow_type_setting(s, version) for s in (rft.settings or [])],
151
+ editable=rft.editable or False,
152
+ name=_translations(rft.name),
153
+ description=_translations(rft.description),
154
+ documentation=_translations(rft.documentation),
155
+ display_message=_translations(rft.display_message),
156
+ alias=_translations(rft.alias),
157
+ version=version,
158
+ display_icon=rft.display_icon or "tabler:note",
159
+ definition_source="action",
160
+ linked_data_type_identifiers=[],
161
+ signature=rft.signature,
162
+ )
163
+
164
+
165
+ def _parameter_definition(p, version: str) -> function_pb2.ParameterDefinition:
166
+ kwargs = dict(
167
+ runtime_name=p.runtime_name,
168
+ runtime_definition_name=p.runtime_definition_name or p.runtime_name,
169
+ name=_translations(p.name),
170
+ description=_translations(p.description),
171
+ documentation=_translations(p.documentation),
172
+ hidden=p.hidden or False,
173
+ optional=p.optional or False,
174
+ )
175
+ if p.default_value is not None:
176
+ kwargs["default_value"] = construct_value(p.default_value)
177
+ return function_pb2.ParameterDefinition(**kwargs)
178
+
179
+
180
+ def _function_definition(f: FunctionProps, version: str) -> function_pb2.FunctionDefinition:
181
+ kwargs = dict(
182
+ runtime_name=f.runtime_name,
183
+ runtime_definition_name=f.runtime_definition_name,
184
+ signature=f.signature,
185
+ throws_error=f.throws_error or False,
186
+ name=_translations(f.name),
187
+ description=_translations(f.description),
188
+ documentation=_translations(f.documentation),
189
+ deprecation_message=_translations(f.deprecation_message),
190
+ display_message=_translations(f.display_message),
191
+ alias=_translations(f.alias),
192
+ linked_data_type_identifiers=[],
193
+ display_icon=f.display_icon or "tabler:note",
194
+ version=version,
195
+ definition_source="action",
196
+ parameter_definitions=[_parameter_definition(p, version) for p in (f.parameters or [])],
197
+ )
198
+ if f.design is not None:
199
+ kwargs["design"] = f.design
200
+ return function_pb2.FunctionDefinition(**kwargs)
201
+
202
+
203
+ def _runtime_parameter_definition(p, version: str) -> runtime_function_pb2.RuntimeParameterDefinition:
204
+ kwargs = dict(
205
+ runtime_name=p.runtime_name,
206
+ name=_translations(p.name),
207
+ description=_translations(p.description),
208
+ documentation=_translations(p.documentation),
209
+ hidden=p.hidden or False,
210
+ optional=p.optional or False,
211
+ )
212
+ if p.default_value is not None:
213
+ kwargs["default_value"] = construct_value(p.default_value)
214
+ return runtime_function_pb2.RuntimeParameterDefinition(**kwargs)
215
+
216
+
217
+ def _runtime_function_definition(f: RuntimeFunctionProps, version: str) -> runtime_function_pb2.RuntimeFunctionDefinition:
218
+ kwargs = dict(
219
+ runtime_name=f.runtime_name,
220
+ signature=f.signature,
221
+ throws_error=f.throws_error or False,
222
+ name=_translations(f.name),
223
+ description=_translations(f.description),
224
+ documentation=_translations(f.documentation),
225
+ deprecation_message=_translations(f.deprecation_message),
226
+ display_message=_translations(f.display_message),
227
+ alias=_translations(f.alias),
228
+ linked_data_type_identifiers=[],
229
+ display_icon=f.display_icon or "tabler:note",
230
+ version=version,
231
+ definition_source="action",
232
+ runtime_parameter_definitions=[
233
+ _runtime_parameter_definition(p, version) for p in (f.parameters or [])
234
+ ],
235
+ )
236
+ if f.design is not None:
237
+ kwargs["design"] = f.design
238
+ return runtime_function_pb2.RuntimeFunctionDefinition(**kwargs)
239
+
240
+
241
+ def build_module(data: ModuleBuildData) -> module_pb2.Module:
242
+ version = data.version
243
+ return module_pb2.Module(
244
+ identifier=data.identifier,
245
+ version=version,
246
+ author=data.author,
247
+ icon=data.icon,
248
+ documentation=data.documentation,
249
+ name=_translations(data.name),
250
+ description=[],
251
+ definition_source="action",
252
+ configurations=[_config_def(c, version) for c in data.configuration_definitions],
253
+ definition_data_types=[_data_type(dt, version) for dt in data.data_types],
254
+ flow_types=[_flow_type(ft, version) for ft in data.events],
255
+ runtime_flow_types=[_runtime_flow_type(rft, version) for rft in data.runtime_events],
256
+ function_definitions=[_function_definition(f, version) for f in data.functions],
257
+ runtime_function_definitions=[
258
+ _runtime_function_definition(f, version) for f in data.runtime_functions
259
+ ],
260
+ definitions=[],
261
+ )
@@ -0,0 +1,82 @@
1
+ """TypeScript type string -> Pydantic v2 model code.
2
+
3
+ Pipeline:
4
+
5
+ TS type expression --(Node: ts-json-schema-generator)--> JSON schema
6
+ --(datamodel-code-generator)--------> Pydantic v2 code
7
+
8
+ ``datamodel-code-generator`` does not parse TypeScript itself, so the TypeScript
9
+ is first turned into a JSON schema by the bundled Node helper
10
+ (:mod:`hercules.internal.tsgen`).
11
+
12
+ Custom/referenced types that appear in the TypeScript (other data types) can be
13
+ declared up front via ``preamble`` so the generator resolves them, e.g.
14
+ ``preamble="type CustomType = unknown;"``.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import shutil
20
+ import subprocess
21
+ import tempfile
22
+ from pathlib import Path
23
+ from typing import Optional
24
+
25
+ from hercules.internal.tsgen import ts_to_json_schema
26
+
27
+
28
+ class PydanticCodegenError(RuntimeError):
29
+ """Raised when Pydantic code generation fails."""
30
+
31
+
32
+ def _datamodel_codegen() -> str:
33
+ exe = shutil.which("datamodel-codegen")
34
+ if exe is None:
35
+ raise PydanticCodegenError(
36
+ "datamodel-code-generator is not installed. Install it with "
37
+ "'pip install datamodel-code-generator' (or the 'codegen' extra)."
38
+ )
39
+ return exe
40
+
41
+
42
+ def ts_to_pydantic(
43
+ ts_type: str,
44
+ name: str,
45
+ *,
46
+ preamble: Optional[str] = None,
47
+ snake_case_fields: bool = False,
48
+ ) -> str:
49
+ """Convert a TypeScript type expression into Pydantic v2 model source code.
50
+
51
+ ``name`` becomes the root model's class name. Nested object types become
52
+ their own models; unions and custom references are preserved.
53
+ """
54
+ schema = ts_to_json_schema(ts_type, name, preamble)
55
+
56
+ with tempfile.TemporaryDirectory() as tmp:
57
+ tmp_path = Path(tmp)
58
+ in_file = tmp_path / "schema.json"
59
+ out_file = tmp_path / "model.py"
60
+ in_file.write_text(json.dumps(schema))
61
+
62
+ cmd = [
63
+ _datamodel_codegen(),
64
+ "--input", str(in_file),
65
+ "--input-file-type", "jsonschema",
66
+ "--output", str(out_file),
67
+ "--output-model-type", "pydantic_v2.BaseModel",
68
+ "--class-name", name,
69
+ "--use-standard-collections",
70
+ "--use-union-operator",
71
+ "--disable-timestamp",
72
+ "--formatters", "black", "isort",
73
+ ]
74
+ if snake_case_fields:
75
+ cmd.append("--snake-case-field")
76
+
77
+ result = subprocess.run(cmd, capture_output=True, text=True)
78
+ if result.returncode != 0:
79
+ raise PydanticCodegenError(
80
+ result.stderr.strip() or "datamodel-code-generator failed."
81
+ )
82
+ return out_file.read_text()