quantum-framework 0.9.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 (262) hide show
  1. quantum/__init__.py +1 -0
  2. quantum/cli/__init__.py +2 -0
  3. quantum/cli/commands/__init__.py +15 -0
  4. quantum/cli/commands/build.py +417 -0
  5. quantum/cli/commands/dev.py +185 -0
  6. quantum/cli/commands/docs.py +329 -0
  7. quantum/cli/commands/lint.py +523 -0
  8. quantum/cli/commands/migrate.py +527 -0
  9. quantum/cli/commands/new.py +622 -0
  10. quantum/cli/commands/serve.py +190 -0
  11. quantum/cli/commands/test.py +193 -0
  12. quantum/cli/deploy.py +810 -0
  13. quantum/cli/hot_reload.py +951 -0
  14. quantum/cli/jobs.py +356 -0
  15. quantum/cli/mq.py +582 -0
  16. quantum/cli/pkg.py +390 -0
  17. quantum/cli/runner.py +547 -0
  18. quantum/cli/server_process.py +159 -0
  19. quantum/cli/utils.py +334 -0
  20. quantum/compiler/__init__.py +30 -0
  21. quantum/compiler/base_generator.py +367 -0
  22. quantum/compiler/cli.py +295 -0
  23. quantum/compiler/expression_transformer.py +444 -0
  24. quantum/compiler/javascript/__init__.py +10 -0
  25. quantum/compiler/javascript/generator.py +659 -0
  26. quantum/compiler/optimizer.py +270 -0
  27. quantum/compiler/python/__init__.py +10 -0
  28. quantum/compiler/python/generator.py +883 -0
  29. quantum/compiler/python/runtime.py +863 -0
  30. quantum/compiler/transpiler.py +330 -0
  31. quantum/core/__init__.py +3 -0
  32. quantum/core/ast_nodes.py +2611 -0
  33. quantum/core/expression_diagnostics.py +87 -0
  34. quantum/core/expression_stdlib.py +148 -0
  35. quantum/core/expressions.py +591 -0
  36. quantum/core/features/agents/src/__init__.py +30 -0
  37. quantum/core/features/agents/src/ast_node.py +540 -0
  38. quantum/core/features/conditionals/src/__init__.py +8 -0
  39. quantum/core/features/conditionals/src/ast_node.py +68 -0
  40. quantum/core/features/data_fetching/src/__init__.py +21 -0
  41. quantum/core/features/data_fetching/src/ast_node.py +312 -0
  42. quantum/core/features/data_fetching/src/desktop_adapter.py +351 -0
  43. quantum/core/features/data_fetching/src/html_adapter.py +474 -0
  44. quantum/core/features/data_fetching/src/parser.py +225 -0
  45. quantum/core/features/data_import/src/__init__.py +0 -0
  46. quantum/core/features/data_import/src/ast_node.py +291 -0
  47. quantum/core/features/data_import/src/runtime.py +538 -0
  48. quantum/core/features/dump/src/__init__.py +12 -0
  49. quantum/core/features/dump/src/ast_node.py +106 -0
  50. quantum/core/features/dump/src/parser.py +61 -0
  51. quantum/core/features/dump/src/runtime.py +246 -0
  52. quantum/core/features/functions/src/__init__.py +8 -0
  53. quantum/core/features/functions/src/ast_node.py +149 -0
  54. quantum/core/features/game_engine_2d/src/__init__.py +19 -0
  55. quantum/core/features/game_engine_2d/src/ast_nodes.py +1719 -0
  56. quantum/core/features/game_engine_2d/src/parser.py +983 -0
  57. quantum/core/features/invocation/src/__init__.py +0 -0
  58. quantum/core/features/invocation/src/ast_node.py +146 -0
  59. quantum/core/features/invocation/src/runtime.py +327 -0
  60. quantum/core/features/knowledge_base/src/__init__.py +6 -0
  61. quantum/core/features/knowledge_base/src/ast_node.py +113 -0
  62. quantum/core/features/knowledge_base/src/parser.py +82 -0
  63. quantum/core/features/logging/src/__init__.py +12 -0
  64. quantum/core/features/logging/src/ast_node.py +111 -0
  65. quantum/core/features/logging/src/parser.py +50 -0
  66. quantum/core/features/logging/src/runtime.py +190 -0
  67. quantum/core/features/loops/src/__init__.py +8 -0
  68. quantum/core/features/loops/src/ast_node.py +60 -0
  69. quantum/core/features/query/src/__init__.py +0 -0
  70. quantum/core/features/query/src/database_service.py +322 -0
  71. quantum/core/features/query/src/query_validators.py +20 -0
  72. quantum/core/features/state_management/src/__init__.py +11 -0
  73. quantum/core/features/state_management/src/ast_node.py +228 -0
  74. quantum/core/features/terminal_engine/src/__init__.py +21 -0
  75. quantum/core/features/terminal_engine/src/ast_nodes.py +560 -0
  76. quantum/core/features/terminal_engine/src/parser.py +361 -0
  77. quantum/core/features/testing_engine/src/__init__.py +41 -0
  78. quantum/core/features/testing_engine/src/ast_nodes.py +1212 -0
  79. quantum/core/features/testing_engine/src/parser.py +604 -0
  80. quantum/core/features/theming/src/__init__.py +48 -0
  81. quantum/core/features/theming/src/ast_node.py +137 -0
  82. quantum/core/features/theming/src/presets.py +405 -0
  83. quantum/core/features/ui_engine/src/__init__.py +20 -0
  84. quantum/core/features/ui_engine/src/ast_nodes.py +1854 -0
  85. quantum/core/features/ui_engine/src/parser.py +1106 -0
  86. quantum/core/features/websocket/src/__init__.py +24 -0
  87. quantum/core/features/websocket/src/ast_node.py +247 -0
  88. quantum/core/html_compat.py +299 -0
  89. quantum/core/parser.py +1235 -0
  90. quantum/core/parser_registry.py +213 -0
  91. quantum/core/parsers/__init__.py +76 -0
  92. quantum/core/parsers/ai/__init__.py +12 -0
  93. quantum/core/parsers/ai/agent_parser.py +106 -0
  94. quantum/core/parsers/ai/knowledge_parser.py +86 -0
  95. quantum/core/parsers/ai/llm_parser.py +78 -0
  96. quantum/core/parsers/ai/team_parser.py +88 -0
  97. quantum/core/parsers/base.py +322 -0
  98. quantum/core/parsers/composition/__init__.py +10 -0
  99. quantum/core/parsers/composition/import_parser.py +50 -0
  100. quantum/core/parsers/composition/slot_parser.py +48 -0
  101. quantum/core/parsers/control_flow/__init__.py +11 -0
  102. quantum/core/parsers/control_flow/if_parser.py +68 -0
  103. quantum/core/parsers/control_flow/loop_parser.py +105 -0
  104. quantum/core/parsers/control_flow/set_parser.py +89 -0
  105. quantum/core/parsers/data/__init__.py +12 -0
  106. quantum/core/parsers/data/data_parser.py +217 -0
  107. quantum/core/parsers/data/invoke_parser.py +116 -0
  108. quantum/core/parsers/data/query_parser.py +188 -0
  109. quantum/core/parsers/data/transaction_parser.py +77 -0
  110. quantum/core/parsers/events/__init__.py +9 -0
  111. quantum/core/parsers/events/dispatch_event_parser.py +44 -0
  112. quantum/core/parsers/forms/__init__.py +11 -0
  113. quantum/core/parsers/forms/action_parser.py +54 -0
  114. quantum/core/parsers/forms/flash_parser.py +34 -0
  115. quantum/core/parsers/forms/redirect_parser.py +33 -0
  116. quantum/core/parsers/functions/__init__.py +11 -0
  117. quantum/core/parsers/functions/function_parser.py +137 -0
  118. quantum/core/parsers/functions/param_parser.py +66 -0
  119. quantum/core/parsers/functions/return_parser.py +31 -0
  120. quantum/core/parsers/html/__init__.py +10 -0
  121. quantum/core/parsers/html/component_call_parser.py +130 -0
  122. quantum/core/parsers/html/html_parser.py +115 -0
  123. quantum/core/parsers/jobs/__init__.py +11 -0
  124. quantum/core/parsers/jobs/job_parser.py +71 -0
  125. quantum/core/parsers/jobs/schedule_parser.py +62 -0
  126. quantum/core/parsers/jobs/thread_parser.py +57 -0
  127. quantum/core/parsers/messaging/__init__.py +17 -0
  128. quantum/core/parsers/messaging/message_ack_parser.py +30 -0
  129. quantum/core/parsers/messaging/message_nack_parser.py +30 -0
  130. quantum/core/parsers/messaging/message_parser.py +114 -0
  131. quantum/core/parsers/messaging/queue_parser.py +61 -0
  132. quantum/core/parsers/messaging/websocket_parser.py +121 -0
  133. quantum/core/parsers/persistence/__init__.py +9 -0
  134. quantum/core/parsers/persistence/persist_parser.py +64 -0
  135. quantum/core/parsers/routing/__init__.py +9 -0
  136. quantum/core/parsers/routing/route_parser.py +41 -0
  137. quantum/core/parsers/scripting/__init__.py +12 -0
  138. quantum/core/parsers/scripting/pyclass_parser.py +62 -0
  139. quantum/core/parsers/scripting/pydecorator_parser.py +68 -0
  140. quantum/core/parsers/scripting/pyimport_parser.py +52 -0
  141. quantum/core/parsers/scripting/python_parser.py +49 -0
  142. quantum/core/parsers/services/__init__.py +12 -0
  143. quantum/core/parsers/services/dump_parser.py +52 -0
  144. quantum/core/parsers/services/file_parser.py +48 -0
  145. quantum/core/parsers/services/log_parser.py +46 -0
  146. quantum/core/parsers/services/mail_parser.py +65 -0
  147. quantum/core/tiers.py +82 -0
  148. quantum/packages/__init__.py +28 -0
  149. quantum/packages/manager.py +413 -0
  150. quantum/packages/manifest.py +351 -0
  151. quantum/packages/registry.py +399 -0
  152. quantum/packages/resolver.py +336 -0
  153. quantum/plugins/__init__.py +33 -0
  154. quantum/plugins/hooks.py +329 -0
  155. quantum/plugins/loader.py +479 -0
  156. quantum/plugins/manifest.py +336 -0
  157. quantum/plugins/registry.py +371 -0
  158. quantum/runtime/__init__.py +28 -0
  159. quantum/runtime/action_handler.py +443 -0
  160. quantum/runtime/adapters/__init__.py +88 -0
  161. quantum/runtime/adapters/memory_adapter.py +690 -0
  162. quantum/runtime/adapters/rabbitmq_adapter.py +715 -0
  163. quantum/runtime/adapters/redis_adapter.py +582 -0
  164. quantum/runtime/adapters/sqlite_adapter.py +414 -0
  165. quantum/runtime/agent_service.py +1133 -0
  166. quantum/runtime/api_server.py +86 -0
  167. quantum/runtime/ast_cache.py +506 -0
  168. quantum/runtime/auth_service.py +267 -0
  169. quantum/runtime/component.py +990 -0
  170. quantum/runtime/component_composer.py +319 -0
  171. quantum/runtime/component_resolver.py +174 -0
  172. quantum/runtime/database_service.py +598 -0
  173. quantum/runtime/email_service.py +162 -0
  174. quantum/runtime/error_handler.py +295 -0
  175. quantum/runtime/execution_context.py +286 -0
  176. quantum/runtime/executor_registry.py +171 -0
  177. quantum/runtime/executors/__init__.py +71 -0
  178. quantum/runtime/executors/ai/__init__.py +12 -0
  179. quantum/runtime/executors/ai/agent_executor.py +217 -0
  180. quantum/runtime/executors/ai/knowledge_executor.py +114 -0
  181. quantum/runtime/executors/ai/llm_executor.py +153 -0
  182. quantum/runtime/executors/ai/team_executor.py +171 -0
  183. quantum/runtime/executors/base.py +262 -0
  184. quantum/runtime/executors/control_flow/__init__.py +11 -0
  185. quantum/runtime/executors/control_flow/if_executor.py +93 -0
  186. quantum/runtime/executors/control_flow/loop_executor.py +307 -0
  187. quantum/runtime/executors/control_flow/set_executor.py +412 -0
  188. quantum/runtime/executors/data/__init__.py +12 -0
  189. quantum/runtime/executors/data/data_executor.py +145 -0
  190. quantum/runtime/executors/data/invoke_executor.py +176 -0
  191. quantum/runtime/executors/data/query_executor.py +256 -0
  192. quantum/runtime/executors/data/transaction_executor.py +91 -0
  193. quantum/runtime/executors/jobs/__init__.py +11 -0
  194. quantum/runtime/executors/jobs/job_executor.py +190 -0
  195. quantum/runtime/executors/jobs/schedule_executor.py +132 -0
  196. quantum/runtime/executors/jobs/thread_executor.py +127 -0
  197. quantum/runtime/executors/messaging/__init__.py +17 -0
  198. quantum/runtime/executors/messaging/message_ack_executor.py +51 -0
  199. quantum/runtime/executors/messaging/message_executor.py +174 -0
  200. quantum/runtime/executors/messaging/queue_executor.py +103 -0
  201. quantum/runtime/executors/messaging/websocket_executor.py +197 -0
  202. quantum/runtime/executors/scripting/__init__.py +11 -0
  203. quantum/runtime/executors/scripting/pyclass_executor.py +90 -0
  204. quantum/runtime/executors/scripting/pyimport_executor.py +81 -0
  205. quantum/runtime/executors/scripting/python_executor.py +249 -0
  206. quantum/runtime/executors/services/__init__.py +12 -0
  207. quantum/runtime/executors/services/dump_executor.py +72 -0
  208. quantum/runtime/executors/services/file_executor.py +89 -0
  209. quantum/runtime/executors/services/log_executor.py +77 -0
  210. quantum/runtime/executors/services/mail_executor.py +81 -0
  211. quantum/runtime/expression_cache.py +498 -0
  212. quantum/runtime/file_upload_service.py +326 -0
  213. quantum/runtime/function_registry.py +118 -0
  214. quantum/runtime/game_builder.py +166 -0
  215. quantum/runtime/game_code_generator.py +2371 -0
  216. quantum/runtime/game_templates.py +2006 -0
  217. quantum/runtime/godot_code_generator.py +4681 -0
  218. quantum/runtime/godot_templates.py +1449 -0
  219. quantum/runtime/job_executor.py +1599 -0
  220. quantum/runtime/knowledge_service.py +500 -0
  221. quantum/runtime/llm_cache.py +100 -0
  222. quantum/runtime/llm_providers.py +704 -0
  223. quantum/runtime/llm_service.py +287 -0
  224. quantum/runtime/logging_setup.py +140 -0
  225. quantum/runtime/message_broker.py +364 -0
  226. quantum/runtime/message_queue_service.py +571 -0
  227. quantum/runtime/param_validation.py +184 -0
  228. quantum/runtime/pypy_compat.py +315 -0
  229. quantum/runtime/python_bridge.py +698 -0
  230. quantum/runtime/query_validators.py +304 -0
  231. quantum/runtime/renderer.py +733 -0
  232. quantum/runtime/service_container.py +444 -0
  233. quantum/runtime/terminal_builder.py +76 -0
  234. quantum/runtime/terminal_code_generator.py +607 -0
  235. quantum/runtime/terminal_templates.py +243 -0
  236. quantum/runtime/testing_builder.py +77 -0
  237. quantum/runtime/testing_code_generator.py +833 -0
  238. quantum/runtime/testing_templates.py +85 -0
  239. quantum/runtime/ui_builder.py +188 -0
  240. quantum/runtime/ui_desktop_adapter.py +1730 -0
  241. quantum/runtime/ui_desktop_templates.py +307 -0
  242. quantum/runtime/ui_html_adapter.py +2691 -0
  243. quantum/runtime/ui_html_templates.py +2297 -0
  244. quantum/runtime/ui_mobile_adapter.py +1832 -0
  245. quantum/runtime/ui_mobile_templates.py +1003 -0
  246. quantum/runtime/ui_textual_adapter.py +1866 -0
  247. quantum/runtime/ui_textual_templates.py +45 -0
  248. quantum/runtime/ui_tokens.py +465 -0
  249. quantum/runtime/ui_validator.py +365 -0
  250. quantum/runtime/validators.py +256 -0
  251. quantum/runtime/web_server.py +1766 -0
  252. quantum/runtime/websocket_adapter.py +501 -0
  253. quantum/runtime/websocket_service.py +585 -0
  254. quantum/runtime/websocket_transport.py +289 -0
  255. quantum/runtime/wsgi.py +101 -0
  256. quantum/utils/__init__.py +1 -0
  257. quantum_framework-0.9.0.dist-info/METADATA +244 -0
  258. quantum_framework-0.9.0.dist-info/RECORD +262 -0
  259. quantum_framework-0.9.0.dist-info/WHEEL +5 -0
  260. quantum_framework-0.9.0.dist-info/entry_points.txt +2 -0
  261. quantum_framework-0.9.0.dist-info/licenses/LICENSE +21 -0
  262. quantum_framework-0.9.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,291 @@
1
+ """
2
+ Data Import Feature - AST Nodes
3
+ Defines DataNode and related nodes for q:data
4
+ """
5
+
6
+ from typing import List, Dict, Any, Optional
7
+ from quantum.core.ast_nodes import QuantumNode
8
+
9
+
10
+ class DataNode(QuantumNode):
11
+ """Represents a <q:data> - Data import and transformation component"""
12
+
13
+ def __init__(self, name: str, source: str, data_type: str):
14
+ self.name = name # Variable name for result
15
+ self.source = source # File path, URL, or variable reference
16
+ self.data_type = data_type # csv, json, xml, transform
17
+
18
+ # Caching
19
+ self.cache = True # Cache by default
20
+ self.ttl = None # Cache TTL in seconds
21
+
22
+ # CSV-specific attributes
23
+ self.delimiter = ","
24
+ self.quote = '"'
25
+ self.header = True # First row contains headers
26
+ self.encoding = "utf-8"
27
+ self.skip_rows = 0
28
+
29
+ # XML-specific attributes
30
+ self.xpath = None # XPath expression to select nodes
31
+ self.namespace = None # XML namespace URI
32
+
33
+ # Child elements
34
+ self.columns: List['ColumnNode'] = [] # For CSV
35
+ self.fields: List['FieldNode'] = [] # For XML
36
+ self.transforms: List['TransformNode'] = [] # For transformations
37
+ self.headers: List['HeaderNode'] = [] # For HTTP headers (URL sources)
38
+
39
+ # Result metadata
40
+ self.result = None # Variable name for metadata
41
+
42
+ def add_column(self, column: 'ColumnNode'):
43
+ """Add CSV column definition"""
44
+ self.columns.append(column)
45
+
46
+ def add_field(self, field: 'FieldNode'):
47
+ """Add XML field mapping"""
48
+ self.fields.append(field)
49
+
50
+ def add_transform(self, transform: 'TransformNode'):
51
+ """Add transformation operation"""
52
+ self.transforms.append(transform)
53
+
54
+ def add_header(self, header: 'HeaderNode'):
55
+ """Add HTTP header"""
56
+ self.headers.append(header)
57
+
58
+ def to_dict(self) -> Dict[str, Any]:
59
+ return {
60
+ "type": "data",
61
+ "name": self.name,
62
+ "source": self.source,
63
+ "data_type": self.data_type,
64
+ "cache": self.cache,
65
+ "ttl": self.ttl,
66
+ "columns": [c.to_dict() for c in self.columns],
67
+ "fields": [f.to_dict() for f in self.fields],
68
+ "transforms": [t.to_dict() for t in self.transforms],
69
+ "headers": [h.to_dict() for h in self.headers]
70
+ }
71
+
72
+ def validate(self) -> List[str]:
73
+ errors = []
74
+ if not self.name:
75
+ errors.append("Data name is required")
76
+ if not self.source:
77
+ errors.append("Data source is required")
78
+ if self.data_type not in ['csv', 'json', 'xml', 'transform']:
79
+ errors.append(f"Invalid data type: {self.data_type}. Must be csv, json, xml, or transform")
80
+
81
+ # Validate child elements
82
+ for column in self.columns:
83
+ errors.extend(column.validate())
84
+ for field in self.fields:
85
+ errors.extend(field.validate())
86
+ for transform in self.transforms:
87
+ errors.extend(transform.validate())
88
+ for header in self.headers:
89
+ errors.extend(header.validate())
90
+
91
+ return errors
92
+
93
+
94
+ class ColumnNode(QuantumNode):
95
+ """Represents a <q:column> - CSV column definition"""
96
+
97
+ def __init__(self, name: str, col_type: str = "string"):
98
+ self.name = name
99
+ self.col_type = col_type # string, integer, decimal, boolean, date, datetime
100
+
101
+ # Validation (same as QuantumParam)
102
+ self.required = False
103
+ self.default = None
104
+ self.validate_rule = None
105
+ self.pattern = None
106
+ self.min = None
107
+ self.max = None
108
+ self.minlength = None
109
+ self.maxlength = None
110
+ self.range = None
111
+ self.enum = None
112
+
113
+ def to_dict(self) -> Dict[str, Any]:
114
+ return {
115
+ "type": "column",
116
+ "name": self.name,
117
+ "col_type": self.col_type,
118
+ "required": self.required,
119
+ "default": self.default
120
+ }
121
+
122
+ def validate(self) -> List[str]:
123
+ errors = []
124
+ if not self.name:
125
+ errors.append("Column name is required")
126
+ valid_types = ['string', 'integer', 'decimal', 'boolean', 'date', 'datetime', 'json', 'array']
127
+ if self.col_type not in valid_types:
128
+ errors.append(f"Invalid column type: {self.col_type}. Must be one of {valid_types}")
129
+ return errors
130
+
131
+
132
+ class FieldNode(QuantumNode):
133
+ """Represents a <q:field> - XML field mapping"""
134
+
135
+ def __init__(self, name: str, xpath: str, field_type: str = "string"):
136
+ self.name = name
137
+ self.xpath = xpath # XPath expression to extract value
138
+ self.field_type = field_type # string, integer, decimal, boolean, date, datetime
139
+
140
+ def to_dict(self) -> Dict[str, Any]:
141
+ return {
142
+ "type": "field",
143
+ "name": self.name,
144
+ "xpath": self.xpath,
145
+ "field_type": self.field_type
146
+ }
147
+
148
+ def validate(self) -> List[str]:
149
+ errors = []
150
+ if not self.name:
151
+ errors.append("Field name is required")
152
+ if not self.xpath:
153
+ errors.append("Field xpath is required")
154
+ valid_types = ['string', 'integer', 'decimal', 'boolean', 'date', 'datetime', 'json', 'array']
155
+ if self.field_type not in valid_types:
156
+ errors.append(f"Invalid field type: {self.field_type}. Must be one of {valid_types}")
157
+ return errors
158
+
159
+
160
+ class TransformNode(QuantumNode):
161
+ """Represents a <q:transform> - Container for transformation operations"""
162
+
163
+ def __init__(self):
164
+ self.operations: List[QuantumNode] = [] # Filter, Sort, Limit, Compute, etc.
165
+
166
+ def add_operation(self, operation: QuantumNode):
167
+ """Add transformation operation"""
168
+ self.operations.append(operation)
169
+
170
+ def to_dict(self) -> Dict[str, Any]:
171
+ return {
172
+ "type": "transform",
173
+ "operations": [op.to_dict() for op in self.operations]
174
+ }
175
+
176
+ def validate(self) -> List[str]:
177
+ errors = []
178
+ for operation in self.operations:
179
+ errors.extend(operation.validate())
180
+ return errors
181
+
182
+
183
+ class FilterNode(QuantumNode):
184
+ """Represents a <q:filter> - Filter operation"""
185
+
186
+ def __init__(self, condition: str):
187
+ self.condition = condition # Filter expression
188
+
189
+ def to_dict(self) -> Dict[str, Any]:
190
+ return {
191
+ "type": "filter",
192
+ "condition": self.condition
193
+ }
194
+
195
+ def validate(self) -> List[str]:
196
+ errors = []
197
+ if not self.condition:
198
+ errors.append("Filter condition is required")
199
+ return errors
200
+
201
+
202
+ class SortNode(QuantumNode):
203
+ """Represents a <q:sort> - Sort operation"""
204
+
205
+ def __init__(self, by: str, order: str = "asc"):
206
+ self.by = by # Field name to sort by
207
+ self.order = order # asc or desc
208
+
209
+ def to_dict(self) -> Dict[str, Any]:
210
+ return {
211
+ "type": "sort",
212
+ "by": self.by,
213
+ "order": self.order
214
+ }
215
+
216
+ def validate(self) -> List[str]:
217
+ errors = []
218
+ if not self.by:
219
+ errors.append("Sort 'by' field is required")
220
+ if self.order not in ['asc', 'desc']:
221
+ errors.append(f"Invalid sort order: {self.order}. Must be 'asc' or 'desc'")
222
+ return errors
223
+
224
+
225
+ class LimitNode(QuantumNode):
226
+ """Represents a <q:limit> - Limit operation"""
227
+
228
+ def __init__(self, value: int):
229
+ self.value = value # Maximum number of records
230
+
231
+ def to_dict(self) -> Dict[str, Any]:
232
+ return {
233
+ "type": "limit",
234
+ "value": self.value
235
+ }
236
+
237
+ def validate(self) -> List[str]:
238
+ errors = []
239
+ if self.value is None:
240
+ errors.append("Limit value is required")
241
+ if isinstance(self.value, int) and self.value < 0:
242
+ errors.append("Limit value must be >= 0")
243
+ return errors
244
+
245
+
246
+ class ComputeNode(QuantumNode):
247
+ """Represents a <q:compute> - Compute derived field"""
248
+
249
+ def __init__(self, field: str, expression: str, comp_type: str = "string"):
250
+ self.field = field # New field name
251
+ self.expression = expression # Expression to compute value
252
+ self.comp_type = comp_type # Result type
253
+
254
+ def to_dict(self) -> Dict[str, Any]:
255
+ return {
256
+ "type": "compute",
257
+ "field": self.field,
258
+ "expression": self.expression,
259
+ "comp_type": self.comp_type
260
+ }
261
+
262
+ def validate(self) -> List[str]:
263
+ errors = []
264
+ if not self.field:
265
+ errors.append("Compute field name is required")
266
+ if not self.expression:
267
+ errors.append("Compute expression is required")
268
+ return errors
269
+
270
+
271
+ class HeaderNode(QuantumNode):
272
+ """Represents a <q:header> - HTTP header for URL sources"""
273
+
274
+ def __init__(self, name: str, value: str):
275
+ self.name = name
276
+ self.value = value
277
+
278
+ def to_dict(self) -> Dict[str, Any]:
279
+ return {
280
+ "type": "header",
281
+ "name": self.name,
282
+ "value": self.value[:50] + "..." if len(str(self.value)) > 50 else self.value
283
+ }
284
+
285
+ def validate(self) -> List[str]:
286
+ errors = []
287
+ if not self.name:
288
+ errors.append("Header name is required")
289
+ if self.value is None:
290
+ errors.append(f"Header '{self.name}' value is required")
291
+ return errors