quantum-framework 0.17.0__tar.gz → 0.18.0__tar.gz

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 (370) hide show
  1. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/PKG-INFO +1 -1
  2. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/pyproject.toml +1 -1
  3. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/check.py +23 -2
  4. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/ast_nodes.py +6 -0
  5. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/ui_engine/src/ast_nodes.py +27 -1
  6. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/ui_engine/src/parser.py +39 -1
  7. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/data/query_parser.py +21 -1
  8. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/forms/action_parser.py +15 -0
  9. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/action_handler.py +82 -22
  10. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/component.py +5 -0
  11. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/data/query_executor.py +38 -4
  12. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/renderer.py +2 -0
  13. quantum_framework-0.18.0/quantum/runtime/table_params.py +163 -0
  14. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_console.py +48 -3
  15. quantum_framework-0.18.0/quantum/runtime/ui_form_rules.py +193 -0
  16. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_html_adapter.py +1 -1
  17. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_page_renderer.py +168 -8
  18. quantum_framework-0.18.0/quantum/runtime/ui_pager.py +73 -0
  19. quantum_framework-0.18.0/quantum/runtime/ui_table_edit.py +139 -0
  20. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_view.py +74 -10
  21. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/web_server.py +85 -0
  22. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_framework.egg-info/PKG-INFO +1 -1
  23. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_framework.egg-info/SOURCES.txt +4 -0
  24. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/LICENSE +0 -0
  25. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/README.md +0 -0
  26. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/__init__.py +0 -0
  27. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/__init__.py +0 -0
  28. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/admin.py +0 -0
  29. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/__init__.py +0 -0
  30. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/build.py +0 -0
  31. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/dev.py +0 -0
  32. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/docs.py +0 -0
  33. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/lint.py +0 -0
  34. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/migrate.py +0 -0
  35. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/new.py +0 -0
  36. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/serve.py +0 -0
  37. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/commands/test.py +0 -0
  38. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/deploy.py +0 -0
  39. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/hot_reload.py +0 -0
  40. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/jobs.py +0 -0
  41. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/mq.py +0 -0
  42. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/pkg.py +0 -0
  43. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/runner.py +0 -0
  44. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/server_process.py +0 -0
  45. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/cli/utils.py +0 -0
  46. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/__init__.py +0 -0
  47. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/base_generator.py +0 -0
  48. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/cli.py +0 -0
  49. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/expression_transformer.py +0 -0
  50. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/javascript/__init__.py +0 -0
  51. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/javascript/generator.py +0 -0
  52. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/optimizer.py +0 -0
  53. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/python/__init__.py +0 -0
  54. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/python/generator.py +0 -0
  55. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/python/runtime.py +0 -0
  56. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/compiler/transpiler.py +0 -0
  57. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/__init__.py +0 -0
  58. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/config_env.py +0 -0
  59. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/docs_links.py +0 -0
  60. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/expression_diagnostics.py +0 -0
  61. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/expression_stdlib.py +0 -0
  62. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/expressions.py +0 -0
  63. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/agents/src/__init__.py +0 -0
  64. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/agents/src/ast_node.py +0 -0
  65. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/conditionals/src/__init__.py +0 -0
  66. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/conditionals/src/ast_node.py +0 -0
  67. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/data_import/src/__init__.py +0 -0
  68. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/data_import/src/ast_node.py +0 -0
  69. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/data_import/src/runtime.py +0 -0
  70. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/dump/src/__init__.py +0 -0
  71. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/dump/src/ast_node.py +0 -0
  72. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/dump/src/parser.py +0 -0
  73. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/dump/src/runtime.py +0 -0
  74. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/functions/src/__init__.py +0 -0
  75. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/functions/src/ast_node.py +0 -0
  76. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/game_engine_2d/src/__init__.py +0 -0
  77. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/game_engine_2d/src/ast_nodes.py +0 -0
  78. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/game_engine_2d/src/parser.py +0 -0
  79. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/invocation/src/__init__.py +0 -0
  80. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/invocation/src/ast_node.py +0 -0
  81. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/invocation/src/runtime.py +0 -0
  82. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/knowledge_base/src/__init__.py +0 -0
  83. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/knowledge_base/src/ast_node.py +0 -0
  84. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/knowledge_base/src/parser.py +0 -0
  85. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/logging/src/__init__.py +0 -0
  86. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/logging/src/ast_node.py +0 -0
  87. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/logging/src/parser.py +0 -0
  88. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/logging/src/runtime.py +0 -0
  89. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/loops/src/__init__.py +0 -0
  90. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/loops/src/ast_node.py +0 -0
  91. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/query/src/__init__.py +0 -0
  92. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/query/src/query_validators.py +0 -0
  93. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/state_management/src/__init__.py +0 -0
  94. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/state_management/src/ast_node.py +0 -0
  95. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/terminal_engine/src/__init__.py +0 -0
  96. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/terminal_engine/src/ast_nodes.py +0 -0
  97. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/terminal_engine/src/parser.py +0 -0
  98. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/testing_engine/src/__init__.py +0 -0
  99. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/testing_engine/src/ast_nodes.py +0 -0
  100. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/testing_engine/src/parser.py +0 -0
  101. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/theming/src/__init__.py +0 -0
  102. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/theming/src/ast_node.py +0 -0
  103. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/theming/src/presets.py +0 -0
  104. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/ui_engine/src/__init__.py +0 -0
  105. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/websocket/src/__init__.py +0 -0
  106. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/features/websocket/src/ast_node.py +0 -0
  107. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/guards.py +0 -0
  108. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/html_compat.py +0 -0
  109. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parser.py +0 -0
  110. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parser_registry.py +0 -0
  111. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/__init__.py +0 -0
  112. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/ai/__init__.py +0 -0
  113. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/ai/agent_parser.py +0 -0
  114. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/ai/knowledge_parser.py +0 -0
  115. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/ai/llm_parser.py +0 -0
  116. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/ai/team_parser.py +0 -0
  117. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/base.py +0 -0
  118. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/composition/__init__.py +0 -0
  119. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/composition/import_parser.py +0 -0
  120. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/composition/slot_parser.py +0 -0
  121. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/control_flow/__init__.py +0 -0
  122. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/control_flow/if_parser.py +0 -0
  123. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/control_flow/loop_parser.py +0 -0
  124. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/control_flow/set_parser.py +0 -0
  125. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/data/__init__.py +0 -0
  126. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/data/data_parser.py +0 -0
  127. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/data/invoke_parser.py +0 -0
  128. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/data/transaction_parser.py +0 -0
  129. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/events/__init__.py +0 -0
  130. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/events/dispatch_event_parser.py +0 -0
  131. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/forms/__init__.py +0 -0
  132. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/forms/flash_parser.py +0 -0
  133. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/forms/redirect_parser.py +0 -0
  134. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/functions/__init__.py +0 -0
  135. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/functions/function_parser.py +0 -0
  136. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/functions/param_parser.py +0 -0
  137. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/functions/return_parser.py +0 -0
  138. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/html/__init__.py +0 -0
  139. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/html/component_call_parser.py +0 -0
  140. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/html/html_parser.py +0 -0
  141. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/jobs/__init__.py +0 -0
  142. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/jobs/job_parser.py +0 -0
  143. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/jobs/schedule_parser.py +0 -0
  144. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/jobs/thread_parser.py +0 -0
  145. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/messaging/__init__.py +0 -0
  146. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/messaging/message_ack_parser.py +0 -0
  147. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/messaging/message_nack_parser.py +0 -0
  148. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/messaging/message_parser.py +0 -0
  149. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/messaging/queue_parser.py +0 -0
  150. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/messaging/websocket_parser.py +0 -0
  151. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/routing/__init__.py +0 -0
  152. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/routing/route_parser.py +0 -0
  153. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/scripting/__init__.py +0 -0
  154. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/scripting/pyclass_parser.py +0 -0
  155. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/scripting/pydecorator_parser.py +0 -0
  156. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/scripting/pyimport_parser.py +0 -0
  157. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/scripting/python_parser.py +0 -0
  158. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/services/__init__.py +0 -0
  159. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/services/dump_parser.py +0 -0
  160. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/services/file_parser.py +0 -0
  161. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/services/log_parser.py +0 -0
  162. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/parsers/services/mail_parser.py +0 -0
  163. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/tiers.py +0 -0
  164. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/core/xml_lines.py +0 -0
  165. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/packages/__init__.py +0 -0
  166. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/packages/manager.py +0 -0
  167. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/packages/manifest.py +0 -0
  168. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/packages/registry.py +0 -0
  169. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/packages/resolver.py +0 -0
  170. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/plugins/__init__.py +0 -0
  171. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/plugins/hooks.py +0 -0
  172. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/plugins/loader.py +0 -0
  173. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/plugins/manifest.py +0 -0
  174. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/plugins/registry.py +0 -0
  175. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/__init__.py +0 -0
  176. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/adapters/__init__.py +0 -0
  177. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/adapters/memory_adapter.py +0 -0
  178. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/adapters/rabbitmq_adapter.py +0 -0
  179. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/adapters/redis_adapter.py +0 -0
  180. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/adapters/sqlite_adapter.py +0 -0
  181. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/agent_service.py +0 -0
  182. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ast_cache.py +0 -0
  183. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/auth_service.py +0 -0
  184. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/component_composer.py +0 -0
  185. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/component_resolver.py +0 -0
  186. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/conditions.py +0 -0
  187. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/database_service.py +0 -0
  188. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/db_schema.py +0 -0
  189. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/dev_panel.py +0 -0
  190. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/email_service.py +0 -0
  191. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/error_handler.py +0 -0
  192. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/execution_context.py +0 -0
  193. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executor_registry.py +0 -0
  194. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/__init__.py +0 -0
  195. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/ai/__init__.py +0 -0
  196. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/ai/agent_executor.py +0 -0
  197. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/ai/knowledge_executor.py +0 -0
  198. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/ai/llm_executor.py +0 -0
  199. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/ai/team_executor.py +0 -0
  200. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/base.py +0 -0
  201. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/control_flow/__init__.py +0 -0
  202. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/control_flow/if_executor.py +0 -0
  203. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/control_flow/loop_executor.py +0 -0
  204. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/control_flow/redirect_executor.py +0 -0
  205. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/control_flow/set_executor.py +0 -0
  206. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/data/__init__.py +0 -0
  207. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/data/data_executor.py +0 -0
  208. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/data/invoke_executor.py +0 -0
  209. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/data/transaction_executor.py +0 -0
  210. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/jobs/__init__.py +0 -0
  211. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/jobs/job_executor.py +0 -0
  212. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/jobs/schedule_executor.py +0 -0
  213. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/jobs/thread_executor.py +0 -0
  214. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/messaging/__init__.py +0 -0
  215. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/messaging/message_ack_executor.py +0 -0
  216. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/messaging/message_executor.py +0 -0
  217. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/messaging/queue_executor.py +0 -0
  218. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/messaging/websocket_executor.py +0 -0
  219. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/scripting/__init__.py +0 -0
  220. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/scripting/pyclass_executor.py +0 -0
  221. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/scripting/pyimport_executor.py +0 -0
  222. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/scripting/python_executor.py +0 -0
  223. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/services/__init__.py +0 -0
  224. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/services/dump_executor.py +0 -0
  225. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/services/file_executor.py +0 -0
  226. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/services/log_executor.py +0 -0
  227. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/executors/services/mail_executor.py +0 -0
  228. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/expression_cache.py +0 -0
  229. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/file_upload_service.py +0 -0
  230. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/function_registry.py +0 -0
  231. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/game_builder.py +0 -0
  232. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/game_code_generator.py +0 -0
  233. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/game_templates.py +0 -0
  234. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/godot_code_generator.py +0 -0
  235. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/godot_templates.py +0 -0
  236. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/job_executor.py +0 -0
  237. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/knowledge_service.py +0 -0
  238. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/llm_cache.py +0 -0
  239. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/llm_providers.py +0 -0
  240. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/llm_service.py +0 -0
  241. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/local_server.py +0 -0
  242. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/logging_setup.py +0 -0
  243. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/message_broker.py +0 -0
  244. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/message_queue_service.py +0 -0
  245. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/param_validation.py +0 -0
  246. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/pypy_compat.py +0 -0
  247. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/python_bridge.py +0 -0
  248. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/query_validators.py +0 -0
  249. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/service_container.py +0 -0
  250. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/terminal_builder.py +0 -0
  251. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/terminal_code_generator.py +0 -0
  252. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/terminal_templates.py +0 -0
  253. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/testing_builder.py +0 -0
  254. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/testing_code_generator.py +0 -0
  255. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/testing_templates.py +0 -0
  256. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_builder.py +0 -0
  257. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_desktop.py +0 -0
  258. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_html_templates.py +0 -0
  259. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_mobile_adapter.py +0 -0
  260. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_mobile_templates.py +0 -0
  261. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_textual_adapter.py +0 -0
  262. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_textual_templates.py +0 -0
  263. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_tokens.py +0 -0
  264. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/ui_validator.py +0 -0
  265. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/validators.py +0 -0
  266. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/websocket_adapter.py +0 -0
  267. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/websocket_service.py +0 -0
  268. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/websocket_transport.py +0 -0
  269. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/runtime/wsgi.py +0 -0
  270. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/services.py +0 -0
  271. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum/utils/__init__.py +0 -0
  272. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/__init__.py +0 -0
  273. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/assets/quantum-admin-connectors.js +0 -0
  274. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/assets/quantum-admin.css +0 -0
  275. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/assets/quantum-source-highlight.js +0 -0
  276. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/__init__.py +0 -0
  277. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/audit_service.py +0 -0
  278. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/auth_service.py +0 -0
  279. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/component_discovery.py +0 -0
  280. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/config_generator.py +0 -0
  281. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/connector_service.py +0 -0
  282. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/crud.py +0 -0
  283. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/database.py +0 -0
  284. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/db_setup_service.py +0 -0
  285. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/deploy_service.py +0 -0
  286. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/docker_service.py +0 -0
  287. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/environment_service.py +0 -0
  288. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/git_service.py +0 -0
  289. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/health_service.py +0 -0
  290. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/job_service.py +0 -0
  291. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/log_service.py +0 -0
  292. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/main.py +0 -0
  293. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/models.py +0 -0
  294. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/pipeline_service.py +0 -0
  295. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/resource_manager.py +0 -0
  296. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/schemas.py +0 -0
  297. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/secret_manager.py +0 -0
  298. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/settings_service.py +0 -0
  299. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/template_service.py +0 -0
  300. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/test_execution_service.py +0 -0
  301. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/test_generator.py +0 -0
  302. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/webhook_service.py +0 -0
  303. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/backend/websocket_manager.py +0 -0
  304. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/_layout/AdminShell.q +0 -0
  305. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/agents.q +0 -0
  306. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/app/[name].q +0 -0
  307. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/applications.q +0 -0
  308. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/component/[...path].q +0 -0
  309. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/components.q +0 -0
  310. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/connectors.q +0 -0
  311. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/dashboard.q +0 -0
  312. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/database.q +0 -0
  313. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/features.q +0 -0
  314. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/index.q +0 -0
  315. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/jobs.q +0 -0
  316. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/login.q +0 -0
  317. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/logout.q +0 -0
  318. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/settings.q +0 -0
  319. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/source.q +0 -0
  320. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/components/admin/tests.q +0 -0
  321. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/run.py +0 -0
  322. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/__init__.py +0 -0
  323. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/_base.py +0 -0
  324. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/_component_test_generator.py +0 -0
  325. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/_yaml_editor.py +0 -0
  326. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/apps.py +0 -0
  327. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/auth.py +0 -0
  328. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/components.py +0 -0
  329. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/connectors.py +0 -0
  330. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/projects.py +0 -0
  331. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/repository.py +0 -0
  332. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/settings.py +0 -0
  333. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_admin/services/yaml_import.py +0 -0
  334. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_framework.egg-info/dependency_links.txt +0 -0
  335. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_framework.egg-info/entry_points.txt +0 -0
  336. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_framework.egg-info/requires.txt +0 -0
  337. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/quantum_framework.egg-info/top_level.txt +0 -0
  338. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/setup.cfg +0 -0
  339. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_agent.py +0 -0
  340. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_animations.py +0 -0
  341. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_ast_cache.py +0 -0
  342. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_cli_commands.py +0 -0
  343. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_component_library.py +0 -0
  344. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_expression_cache.py +0 -0
  345. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_form_validation.py +0 -0
  346. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_game_codegen.py +0 -0
  347. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_game_e2e.py +0 -0
  348. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_game_engine.py +0 -0
  349. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_game_parser.py +0 -0
  350. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_godot_codegen.py +0 -0
  351. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_job_executor.py +0 -0
  352. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_llm_providers.py +0 -0
  353. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_message_broker.py +0 -0
  354. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_message_queue.py +0 -0
  355. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_mobile_target.py +0 -0
  356. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_multi_agent.py +0 -0
  357. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_packages.py +0 -0
  358. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_plugins.py +0 -0
  359. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_pypy_compat.py +0 -0
  360. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_python_scripting.py +0 -0
  361. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_terminal_codegen.py +0 -0
  362. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_terminal_parser.py +0 -0
  363. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_testing_codegen.py +0 -0
  364. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_testing_parser.py +0 -0
  365. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_theming.py +0 -0
  366. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_ui_html_adapter.py +0 -0
  367. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_ui_parity.py +0 -0
  368. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_ui_parser.py +0 -0
  369. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_ui_textual_adapter.py +0 -0
  370. {quantum_framework-0.17.0 → quantum_framework-0.18.0}/tests/test_websocket.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quantum-framework
3
- Version: 0.17.0
3
+ Version: 0.18.0
4
4
  Summary: Full-stack declarative framework for building web, desktop, and mobile applications
5
5
  Author-email: Daniel Gregorio <danielgregorio2611@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quantum-framework"
7
- version = "0.17.0"
7
+ version = "0.18.0"
8
8
  description = "Full-stack declarative framework for building web, desktop, and mobile applications"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -102,9 +102,30 @@ class ProjectChecker:
102
102
  self._fields(ast, rel, colunas, {nome: nome for nome in colunas}, None)
103
103
 
104
104
  def _queries(self, node, rel: str, colunas: Dict[str, List[str]]) -> None:
105
- from quantum.core.ast_nodes import QueryNode
106
- from quantum.runtime.db_schema import check_sql
105
+ from quantum.core.ast_nodes import ActionNode, QueryNode
106
+ from quantum.runtime.db_schema import check_sql, read_schema
107
107
  for filho in _children(node):
108
+ if isinstance(filho, ActionNode) and getattr(filho, 'table', None):
109
+ # UI-10: the table the action takes its params from exists, with those columns.
110
+ ds = filho.table_datasource
111
+ if ds not in self.datasources:
112
+ self.problems.append(Problem(rel, getattr(filho, 'source_line', None),
113
+ f'<q:action name="{filho.name}">: datasource {ds!r} is not '
114
+ f'declared in quantum.config.yaml'))
115
+ elif self._connection(ds) is not None:
116
+ esquema = read_schema(self._connection(ds))
117
+ tabela = esquema.get(filho.table)
118
+ if tabela is None:
119
+ self.problems.append(Problem(rel, getattr(filho, 'source_line', None),
120
+ f'<q:action name="{filho.name}" table="{filho.table}">: '
121
+ f'no such table (tables: {", ".join(esquema) or "none"})'))
122
+ else:
123
+ for coluna in filho.table_columns or []:
124
+ if coluna not in tabela.columns:
125
+ self.problems.append(Problem(
126
+ rel, getattr(filho, 'source_line', None),
127
+ f'<q:action name="{filho.name}" columns=...>: table "{filho.table}" '
128
+ f'has no column "{coluna}"'))
108
129
  if isinstance(filho, QueryNode):
109
130
  ds = filho.datasource
110
131
  if not ds or ds.startswith('knowledge:') or getattr(filho, 'source', None):
@@ -698,6 +698,8 @@ class QueryNode(QuantumNode):
698
698
  self.interval = None
699
699
  self.paginate = False # Enable automatic pagination
700
700
  self.page = None
701
+ self.page_expr = None # DB-9: page as an expression (default {query.page})
702
+ self.sortable = False # UI-13: ORDER BY the URL's ?sort=/&dir=
701
703
  self.page_size = 20
702
704
  self.timeout = None
703
705
  self.maxrows = None
@@ -1137,6 +1139,10 @@ class ActionNode(QuantumNode):
1137
1139
  self.method = method.upper()
1138
1140
  self.params: List[QuantumParam] = []
1139
1141
  self.body: List[QuantumNode] = []
1142
+ # UI-10 (M17): params from a table's schema — see quantum/runtime/table_params.py
1143
+ self.table: Optional[str] = None
1144
+ self.table_datasource: Optional[str] = None
1145
+ self.table_columns: Optional[List[str]] = None
1140
1146
 
1141
1147
  # Action configuration
1142
1148
  self.validate_csrf = True # Auto CSRF protection
@@ -319,6 +319,9 @@ class UIFormNode(QuantumNode, UILayoutMixin):
319
319
 
320
320
  def __init__(self):
321
321
  self.on_submit: Optional[str] = None
322
+ self.rules: Optional[str] = None # UI-9: 'off' = no rules from the action
323
+ self.values: Optional[str] = None # UI-10: {row} whose fields fill the form
324
+ self.submit: Optional[str] = None # UI-10: text of the generated button
322
325
  self.children: List[QuantumNode] = []
323
326
 
324
327
  # Validation mode: 'client', 'server', or 'both' (default)
@@ -550,6 +553,8 @@ class UIInputNode(QuantumNode, UILayoutMixin):
550
553
  def __init__(self):
551
554
  self.bind: Optional[str] = None
552
555
  self.value: Optional[str] = None # initial value (UI-6)
556
+ self.search: Optional[str] = None # UI-12: id of the region it refreshes as you type
557
+ self.delay: Optional[int] = None # UI-12: ms after the last key (300 with search=)
553
558
  self.placeholder: Optional[str] = None
554
559
  self.input_type: str = "text" # text, password, email, number
555
560
  self.on_change: Optional[str] = None
@@ -673,6 +678,9 @@ class UITableNode(QuantumNode, UILayoutMixin):
673
678
  def __init__(self):
674
679
  self.source: Optional[str] = None
675
680
  self.as_var: Optional[str] = None # row variable for column content (UI-5)
681
+ self.sort: bool = False # UI-13: headers sort the query
682
+ self.edit: Optional[str] = None # UI-13: table whose cells are edited in place
683
+ self.edit_datasource: Optional[str] = None
676
684
  self.children: List[QuantumNode] = [] # UIColumnNode children
677
685
  self._init_layout_attrs()
678
686
 
@@ -697,6 +705,7 @@ class UIColumnNode(QuantumNode):
697
705
  self.label: Optional[str] = None
698
706
  self.column_width: Optional[str] = None
699
707
  self.align: Optional[str] = None # left, center, right
708
+ self.edit: bool = True # UI-13: edit="false" keeps it read-only
700
709
  # UI-5: a column with content draws it once per row (buttons, links).
701
710
  self.children: List[QuantumNode] = []
702
711
 
@@ -1870,6 +1879,23 @@ class UIDatePickerNode(QuantumNode, UILayoutMixin):
1870
1879
  return self._validate_layout()
1871
1880
 
1872
1881
 
1882
+ class UIPagerNode(QuantumNode, UILayoutMixin):
1883
+ """<ui:pager for="query"> — previous, page numbers and next over a paginated query (UI-11)."""
1884
+
1885
+ def __init__(self):
1886
+ self.for_query: Optional[str] = None
1887
+ self.param: str = 'page'
1888
+ self.window: int = 2
1889
+ self.children: List[QuantumNode] = []
1890
+ self._init_layout_attrs()
1891
+
1892
+ def to_dict(self) -> Dict[str, Any]:
1893
+ return {"type": "ui_pager", "for": self.for_query, "param": self.param}
1894
+
1895
+ def validate(self) -> List[str]:
1896
+ return [] if self.for_query else ["ui:pager needs for="]
1897
+
1898
+
1873
1899
  def is_ui_node(node) -> bool:
1874
1900
  """A ui:* element (UI-1): markup, drawn by a renderer, never executed."""
1875
1901
  return type(node).__module__ == __name__
@@ -1882,6 +1908,6 @@ CORE_TAGS = frozenset({
1882
1908
  'window', 'hbox', 'vbox', 'grid', 'panel', 'section', 'scrollbox', 'spacer', 'rule',
1883
1909
  'header', 'footer', 'card', 'card-header', 'card-body', 'card-footer', 'tabpanel', 'tab',
1884
1910
  'text', 'badge', 'alert', 'link', 'image', 'progress',
1885
- 'table', 'column', 'list', 'item',
1911
+ 'table', 'column', 'list', 'item', 'pager',
1886
1912
  'form', 'formitem', 'input', 'checkbox', 'switch', 'radio', 'select', 'option', 'button',
1887
1913
  })
@@ -28,7 +28,7 @@ from .ast_nodes import (
28
28
  UIToastNode, UIToastContainerNode,
29
29
  UICarouselNode, UISlideNode,
30
30
  UIStepperNode, UIStepNode,
31
- UICalendarNode, UIDatePickerNode,
31
+ UICalendarNode, UIDatePickerNode, UIPagerNode,
32
32
  )
33
33
  from quantum.core.features.theming.src import UIThemeNode, UIColorNode
34
34
  from quantum.core.ast_nodes import TextNode
@@ -81,6 +81,7 @@ class UIParser:
81
81
  'select': '_parse_ui_select',
82
82
  'table': '_parse_ui_table',
83
83
  'column': '_parse_ui_column',
84
+ 'pager': '_parse_ui_pager',
84
85
  'list': '_parse_ui_list',
85
86
  'item': '_parse_ui_item',
86
87
  'image': '_parse_ui_image',
@@ -359,6 +360,13 @@ class UIParser:
359
360
  node = UIFormNode()
360
361
  node.on_submit = element.get('on-submit')
361
362
  node.send = element.get('with')
363
+ # UI-9: rules="off" stops the form from taking its fields' rules from the action.
364
+ node.rules = element.get('rules')
365
+ # UI-10: an edit form opens with a row's values; the generated button's text.
366
+ node.values = element.get('values')
367
+ node.submit = element.get('submit')
368
+ if node.rules not in (None, 'on', 'off'):
369
+ raise UIParseError(f'<ui:form rules="{node.rules}">: use on (the default) or off')
362
370
 
363
371
  # Validation attributes
364
372
  node.validation_mode = element.get('validation', 'both')
@@ -430,6 +438,14 @@ class UIParser:
430
438
  node = UIInputNode()
431
439
  node.bind = element.get('bind')
432
440
  node.value = element.get('value')
441
+ # UI-12: search as you type — refresh the element with this id.
442
+ node.search = element.get('search')
443
+ espera = element.get('delay')
444
+ if espera is not None and not espera.isdigit():
445
+ raise UIParseError(f'<ui:input delay="{espera}">: milliseconds, e.g. delay="300"')
446
+ node.delay = int(espera) if espera is not None else (300 if node.search else None)
447
+ if node.search is not None and not node.bind:
448
+ raise UIParseError('<ui:input search=...> needs bind= (the URL parameter it sets)')
433
449
  node.placeholder = element.get('placeholder')
434
450
  node.input_type = element.get('type', 'text')
435
451
  node.on_change = element.get('on-change')
@@ -498,6 +514,14 @@ class UIParser:
498
514
  node = UITableNode()
499
515
  node.source = element.get('source')
500
516
  node.as_var = element.get('as')
517
+ # UI-13: sortable headers and cells edited in place.
518
+ node.sort = self._parse_bool(element.get('sort'))
519
+ node.edit = element.get('edit')
520
+ node.edit_datasource = element.get('datasource')
521
+ if node.edit and not node.edit_datasource:
522
+ raise UIParseError(f'<ui:table edit="{node.edit}"> needs datasource= (where the table is)')
523
+ if (node.sort or node.edit) and not node.source:
524
+ raise UIParseError('<ui:table sort/edit> needs source="{query}"')
501
525
  self._apply_layout_attrs(node, element)
502
526
  # Parse child <ui:column> elements
503
527
  self._parse_children(element, node)
@@ -509,9 +533,23 @@ class UIParser:
509
533
  node.label = element.get('label')
510
534
  node.column_width = element.get('width')
511
535
  node.align = element.get('align')
536
+ node.edit = element.get('edit', 'true') != 'false'
512
537
  self._parse_children(element, node)
513
538
  return node
514
539
 
540
+ def _parse_ui_pager(self, element: ET.Element) -> UIPagerNode:
541
+ node = UIPagerNode()
542
+ node.for_query = element.get('for')
543
+ if not node.for_query:
544
+ raise UIParseError('<ui:pager> needs for="<the paginated q:query>"')
545
+ node.param = element.get('param') or 'page'
546
+ janela = element.get('window')
547
+ if janela is not None and not janela.isdigit():
548
+ raise UIParseError(f'<ui:pager window="{janela}">: the number of pages shown each side of the current one')
549
+ node.window = int(janela) if janela is not None else 2
550
+ self._apply_layout_attrs(node, element)
551
+ return node
552
+
515
553
  def _parse_ui_list(self, element: ET.Element) -> UIListNode:
516
554
  node = UIListNode()
517
555
  node.source = element.get('source')
@@ -77,7 +77,27 @@ class QueryParser(BaseTagParser):
77
77
  # Parse attributes
78
78
  query_node.source = source
79
79
  query_node.paginate = self.get_bool_attr(element, 'paginate', False)
80
- query_node.page = self.get_int_attr(element, 'page', 0) or None
80
+ # UI-13: ordered by the URL's ?sort=/&dir= (a <ui:table sort="true"> writes them)
81
+ query_node.sortable = self.get_bool_attr(element, 'sortable', False)
82
+ # DB-9: page= is an expression, resolved when the query runs; it was
83
+ # read as an int at parse time, so page="{query.page}" was always
84
+ # page 1. With paginate="true" and no page=, the page is the URL's
85
+ # `page` parameter — the one <ui:pager> writes.
86
+ pagina = element.get('page')
87
+ query_node.page = None
88
+ query_node.page_expr = None
89
+ if pagina is not None:
90
+ if '{' in pagina:
91
+ query_node.page_expr = pagina
92
+ elif pagina.strip().isdigit():
93
+ query_node.page = int(pagina)
94
+ else:
95
+ from quantum.core.parser import QuantumParseError
96
+ raise QuantumParseError(
97
+ f'<q:query name="{name}" page="{pagina}">: a page number or an expression, '
98
+ f'e.g. page="{{query.pagina}}"')
99
+ elif query_node.paginate:
100
+ query_node.page_expr = '{query.page}'
81
101
  # Accept both spellings: the codebase convention is camelCase, but
82
102
  # snake_case reads naturally in XML and the examples used it —
83
103
  # the mismatch made page_size None and crashed pagination with
@@ -48,6 +48,21 @@ class ActionParser(BaseTagParser):
48
48
  f'<q:action name="{name}"> {attr}= is not supported: it was accepted '
49
49
  f'and never enforced. {porque}')
50
50
 
51
+ # UI-10 (M17): the action's params come from a table's schema, read
52
+ # from the database when the action is used; a q:param written wins.
53
+ action_node.table = element.get('table')
54
+ action_node.table_datasource = element.get('datasource')
55
+ colunas = element.get('columns')
56
+ action_node.table_columns = [c.strip() for c in colunas.split(',') if c.strip()] if colunas else None
57
+ if (action_node.table_datasource or colunas) and not action_node.table:
58
+ from quantum.core.parser import QuantumParseError
59
+ raise QuantumParseError(
60
+ f'<q:action name="{name}"> datasource= and columns= describe table=, which is missing')
61
+ if action_node.table and not action_node.table_datasource:
62
+ from quantum.core.parser import QuantumParseError
63
+ raise QuantumParseError(
64
+ f'<q:action name="{name}" table="{action_node.table}"> needs datasource= (where the table is)')
65
+
51
66
  # Parse children (params, statements)
52
67
  for child in element:
53
68
  child_type = self._get_element_name(child)
@@ -24,8 +24,23 @@ logger = logging.getLogger('quantum.action')
24
24
 
25
25
 
26
26
  class ValidationError(Exception):
27
- """Parameter validation error"""
28
- pass
27
+ """Parameter validation error.
28
+
29
+ `fields` maps each field that failed to its own message (UI-9): the form
30
+ shows each one next to its field. The exception's text is the first one,
31
+ the flash message it always was."""
32
+
33
+ def __init__(self, message: str, fields: Optional[Dict[str, str]] = None):
34
+ super().__init__(message)
35
+ self.fields = fields or {}
36
+
37
+
38
+ def _field_message(nome: str, mensagem: str) -> str:
39
+ """"Parameter 'titulo' must be at least 3 characters" -> "Must be at least 3 characters"."""
40
+ texto = re.sub(rf"^Parameter '{re.escape(nome)}' ", '', mensagem)
41
+ if texto == 'is required':
42
+ return 'Required'
43
+ return texto[:1].upper() + texto[1:]
29
44
 
30
45
 
31
46
  class ActionHandler:
@@ -70,7 +85,7 @@ class ActionHandler:
70
85
  form_data = self._extract_form_data()
71
86
 
72
87
  # 2. Validate parameters
73
- validated_params = self._validate_parameters(action.params, form_data)
88
+ validated_params = self._validate_parameters(self._params_of(action), form_data, action)
74
89
 
75
90
  # 3. Add validated params to context
76
91
  for key, value in validated_params.items():
@@ -129,6 +144,15 @@ class ActionHandler:
129
144
  except ValidationError as e:
130
145
  # Validation failed - set error flash and redirect back
131
146
  self._set_flash_message(str(e), 'error')
147
+ # UI-9: the next render of the form shows each error by its field
148
+ # and the values that were sent (never a password, never a file).
149
+ session['form_state'] = {
150
+ 'action': getattr(action, 'name', None),
151
+ 'errors': e.fields,
152
+ 'values': {n: v for n, v in request.form.items()
153
+ if n != 'action' and n not in self._secret_fields(action)},
154
+ }
155
+ session.modified = True
132
156
  # Redirect to referer or home
133
157
  referer = request.referrer or '/'
134
158
  return referer, 302
@@ -206,10 +230,16 @@ class ActionHandler:
206
230
 
207
231
  return data
208
232
 
233
+ def _params_of(self, action) -> List[QuantumParam]:
234
+ """The action's q:params, plus its table's when it declares one (UI-10)."""
235
+ from quantum.runtime.table_params import params_of
236
+ return params_of(action, getattr(self.component_runtime, 'config', None) or {})
237
+
209
238
  def _validate_parameters(
210
239
  self,
211
240
  params: List[QuantumParam],
212
- form_data: Dict[str, Any]
241
+ form_data: Dict[str, Any],
242
+ action=None,
213
243
  ) -> Dict[str, Any]:
214
244
  """
215
245
  Validate form data against q:param definitions.
@@ -218,30 +248,60 @@ class ActionHandler:
218
248
  """
219
249
 
220
250
  validated = {}
251
+ primeira = None
252
+ por_campo: Dict[str, str] = {}
221
253
 
222
254
  for param in params:
223
255
  value = form_data.get(param.name)
256
+ try:
257
+ # Check required
258
+ if param.required and (value is None or value == ''):
259
+ raise ValidationError(f"Parameter '{param.name}' is required")
260
+
261
+ # Skip validation if optional and not provided
262
+ if value is None or value == '':
263
+ if param.default is not None:
264
+ validated[param.name] = param.default
265
+ elif getattr(param, 'nullable', False):
266
+ validated[param.name] = None # UI-10: a NULL column left blank
267
+ continue
224
268
 
225
- # Check required
226
- if param.required and (value is None or value == ''):
227
- raise ValidationError(f"Parameter '{param.name}' is required")
228
-
229
- # Skip validation if optional and not provided
230
- if value is None or value == '':
231
- if param.default is not None:
232
- validated[param.name] = param.default
233
- continue
234
-
235
- # Type validation and conversion
236
- validated_value = self._validate_type(param, value)
237
-
238
- # Additional validation rules
239
- self._validate_rules(param, validated_value)
240
-
241
- validated[param.name] = validated_value
242
-
269
+ # Type validation and conversion
270
+ validated_value = self._validate_type(param, value)
271
+
272
+ # Additional validation rules
273
+ self._validate_rules(param, validated_value)
274
+
275
+ # UI-10: a foreign key names a row that exists.
276
+ referencia = getattr(param, 'references', None)
277
+ if referencia and action is not None and getattr(action, 'table_datasource', None):
278
+ from quantum.runtime.table_params import reference_exists
279
+ if not reference_exists(getattr(self.component_runtime, 'config', None) or {},
280
+ action.table_datasource, referencia, validated_value):
281
+ raise ValidationError(
282
+ f"Parameter '{param.name}' must name an existing row of {referencia[0]} "
283
+ f"(no {referencia[1]} = {validated_value})")
284
+
285
+ validated[param.name] = validated_value
286
+ except ValidationError as erro:
287
+ # UI-9: every field is checked, so the form can mark each one.
288
+ primeira = primeira or str(erro)
289
+ por_campo[param.name] = _field_message(param.name, str(erro))
290
+
291
+ if primeira:
292
+ raise ValidationError(primeira, por_campo)
243
293
  return validated
244
294
 
295
+ @staticmethod
296
+ def _secret_fields(action) -> set:
297
+ """Fields never sent back to a form: passwords and uploads (UI-9)."""
298
+ nomes = set()
299
+ for param in getattr(action, 'params', None) or []: # table columns are never secrets
300
+ tipo = str(getattr(param, 'type', '') or '').lower()
301
+ if tipo in ('password', 'file') or 'senha' in param.name.lower() or 'password' in param.name.lower():
302
+ nomes.add(param.name)
303
+ return nomes
304
+
245
305
  def _validate_type(self, param: QuantumParam, value: Any) -> Any:
246
306
  """Converte o valor para o tipo declarado, ou levanta ValidationError.
247
307
 
@@ -232,6 +232,11 @@ class ComponentRuntime:
232
232
  """Access to service container"""
233
233
  return self._services
234
234
 
235
+ @property
236
+ def config(self) -> Dict[str, Any]:
237
+ """The project configuration this runtime runs with."""
238
+ return self._services._config or {}
239
+
235
240
  @property
236
241
  def executor_registry(self) -> ExecutorRegistry:
237
242
  """Access to executor registry (may be None if not using modular executors)"""
@@ -93,10 +93,11 @@ class QueryExecutor(BaseExecutor):
93
93
 
94
94
  # Handle pagination
95
95
  pagination_metadata = None
96
- sql_to_execute = node.sql
96
+ sql_to_execute = self._sorted_sql(node, params, exec_context) # UI-13
97
97
 
98
98
  if node.paginate:
99
- pagination_metadata, sql_to_execute = self._handle_pagination(node, params)
99
+ pagination_metadata, sql_to_execute = self._handle_pagination(
100
+ node, params, exec_context, base_sql=sql_to_execute)
100
101
 
101
102
  # Execute query
102
103
  result = self.services.database.execute_query(
@@ -110,7 +111,32 @@ class QueryExecutor(BaseExecutor):
110
111
 
111
112
  return result
112
113
 
113
- def _handle_pagination(self, node: QueryNode, params: Dict[str, Any]):
114
+ def _sorted_sql(self, node: QueryNode, params: Dict[str, Any], exec_context) -> str:
115
+ """UI-13: a sortable query orders by the URL's ?sort= (and ?dir=asc|desc).
116
+
117
+ The column must be one the query returns — found with LIMIT 0, never
118
+ taken from the URL otherwise; an unknown one leaves the order as
119
+ written (a URL is not an error)."""
120
+ if not getattr(node, 'sortable', False):
121
+ return node.sql
122
+ try:
123
+ consulta = exec_context.get_variable('query') if exec_context is not None else None
124
+ except Exception:
125
+ consulta = None
126
+ consulta = consulta if isinstance(consulta, dict) else {}
127
+ coluna = str(consulta.get('sort') or '').strip()
128
+ direcao = 'DESC' if str(consulta.get('dir') or '').lower() == 'desc' else 'ASC'
129
+ if not coluna:
130
+ return node.sql
131
+ base = node.sql.strip().rstrip(';')
132
+ sonda = self.services.database.execute_query(
133
+ node.datasource, f'SELECT * FROM ({base}) AS quantum_ordenada LIMIT 0', params)
134
+ if coluna not in (sonda.column_list or []):
135
+ return node.sql
136
+ return f'SELECT * FROM ({base}) AS quantum_ordenada ORDER BY "{coluna}" {direcao}'
137
+
138
+ def _handle_pagination(self, node: QueryNode, params: Dict[str, Any], exec_context=None,
139
+ base_sql: str = None):
114
140
  """Handle query pagination"""
115
141
  count_sql = self._generate_count_query(node.sql)
116
142
  count_result = self.services.database.execute_query(
@@ -122,13 +148,21 @@ class QueryExecutor(BaseExecutor):
122
148
  total_records = count_result.data[0]['count'] if count_result.data else 0
123
149
 
124
150
  page = node.page if node.page is not None else 1
151
+ if getattr(node, 'page_expr', None):
152
+ # DB-9: from the URL, so never an error — ?page=abc or ?page=-3 is page 1.
153
+ variaveis = exec_context.get_all_variables() if exec_context is not None else None
154
+ bruto = self.apply_databinding(node.page_expr, variaveis)
155
+ try:
156
+ page = max(1, int(str(bruto).strip()))
157
+ except (TypeError, ValueError):
158
+ page = 1
125
159
  # paginate="true" without a page size is a config error, not a
126
160
  # reason to crash on None arithmetic further down.
127
161
  page_size = node.page_size or 10
128
162
  total_pages = (total_records + page_size - 1) // page_size
129
163
 
130
164
  offset = (page - 1) * page_size
131
- sql_to_execute = f"{node.sql}\nLIMIT {page_size} OFFSET {offset}"
165
+ sql_to_execute = f"{base_sql or node.sql}\nLIMIT {page_size} OFFSET {offset}"
132
166
 
133
167
  pagination_metadata = {
134
168
  'totalRecords': total_records,
@@ -121,6 +121,8 @@ class HTMLRenderer:
121
121
  # component rendered is the page; a called component posts to it.
122
122
  if not hasattr(self, '_ui_actions'):
123
123
  self._ui_actions = [s.name for s in node.statements if isinstance(s, ActionNode)]
124
+ # UI-9: a ui:form takes its fields' rules from the action it posts to.
125
+ self._ui_action_nodes = {s.name: s for s in node.statements if isinstance(s, ActionNode)}
124
126
  self.imports = {
125
127
  imp.alias or imp.component: (imp.component, imp.from_path)
126
128
  for imp in node.statements