amsdal 0.2.5__cp312-cp312-win_amd64.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.

Potentially problematic release.


This version of amsdal might be problematic. Click here for more details.

Files changed (254) hide show
  1. amsdal/Third-Party Materials - AMSDAL Dependencies - License Notices.md +1308 -0
  2. amsdal/__about__.py +4 -0
  3. amsdal/__about__.pyi +1 -0
  4. amsdal/__init__.py +3 -0
  5. amsdal/__init__.pyi +0 -0
  6. amsdal/__migrations__/0000_initial.py +203 -0
  7. amsdal/__migrations__/0001_datetime_type.py +18 -0
  8. amsdal/__migrations__/0002_fixture_order.py +40 -0
  9. amsdal/cloud/__init__.cp312-win_amd64.pyd +0 -0
  10. amsdal/cloud/__init__.pyi +0 -0
  11. amsdal/cloud/client.cp312-win_amd64.pyd +0 -0
  12. amsdal/cloud/client.pyi +57 -0
  13. amsdal/cloud/constants.cp312-win_amd64.pyd +0 -0
  14. amsdal/cloud/constants.pyi +13 -0
  15. amsdal/cloud/enums.cp312-win_amd64.pyd +0 -0
  16. amsdal/cloud/enums.pyi +68 -0
  17. amsdal/cloud/models/__init__.cp312-win_amd64.pyd +0 -0
  18. amsdal/cloud/models/__init__.pyi +0 -0
  19. amsdal/cloud/models/base.cp312-win_amd64.pyd +0 -0
  20. amsdal/cloud/models/base.pyi +247 -0
  21. amsdal/cloud/services/__init__.cp312-win_amd64.pyd +0 -0
  22. amsdal/cloud/services/__init__.pyi +0 -0
  23. amsdal/cloud/services/actions/__init__.cp312-win_amd64.pyd +0 -0
  24. amsdal/cloud/services/actions/__init__.pyi +0 -0
  25. amsdal/cloud/services/actions/add_allowlist_ip.cp312-win_amd64.pyd +0 -0
  26. amsdal/cloud/services/actions/add_allowlist_ip.pyi +19 -0
  27. amsdal/cloud/services/actions/add_basic_auth.cp312-win_amd64.pyd +0 -0
  28. amsdal/cloud/services/actions/add_basic_auth.pyi +21 -0
  29. amsdal/cloud/services/actions/add_dependency.cp312-win_amd64.pyd +0 -0
  30. amsdal/cloud/services/actions/add_dependency.pyi +19 -0
  31. amsdal/cloud/services/actions/add_secret.cp312-win_amd64.pyd +0 -0
  32. amsdal/cloud/services/actions/add_secret.pyi +20 -0
  33. amsdal/cloud/services/actions/base.cp312-win_amd64.pyd +0 -0
  34. amsdal/cloud/services/actions/base.pyi +122 -0
  35. amsdal/cloud/services/actions/create_deploy.cp312-win_amd64.pyd +0 -0
  36. amsdal/cloud/services/actions/create_deploy.pyi +41 -0
  37. amsdal/cloud/services/actions/create_env.cp312-win_amd64.pyd +0 -0
  38. amsdal/cloud/services/actions/create_env.pyi +19 -0
  39. amsdal/cloud/services/actions/create_session.cp312-win_amd64.pyd +0 -0
  40. amsdal/cloud/services/actions/create_session.pyi +17 -0
  41. amsdal/cloud/services/actions/delete_allowlist_ip.cp312-win_amd64.pyd +0 -0
  42. amsdal/cloud/services/actions/delete_allowlist_ip.pyi +19 -0
  43. amsdal/cloud/services/actions/delete_basic_auth.cp312-win_amd64.pyd +0 -0
  44. amsdal/cloud/services/actions/delete_basic_auth.pyi +20 -0
  45. amsdal/cloud/services/actions/delete_dependency.cp312-win_amd64.pyd +0 -0
  46. amsdal/cloud/services/actions/delete_dependency.pyi +21 -0
  47. amsdal/cloud/services/actions/delete_env.cp312-win_amd64.pyd +0 -0
  48. amsdal/cloud/services/actions/delete_env.pyi +21 -0
  49. amsdal/cloud/services/actions/delete_secret.cp312-win_amd64.pyd +0 -0
  50. amsdal/cloud/services/actions/delete_secret.pyi +21 -0
  51. amsdal/cloud/services/actions/destroy_deploy.cp312-win_amd64.pyd +0 -0
  52. amsdal/cloud/services/actions/destroy_deploy.pyi +18 -0
  53. amsdal/cloud/services/actions/expose_db.cp312-win_amd64.pyd +0 -0
  54. amsdal/cloud/services/actions/expose_db.pyi +22 -0
  55. amsdal/cloud/services/actions/get_basic_auth_credentials.cp312-win_amd64.pyd +0 -0
  56. amsdal/cloud/services/actions/get_basic_auth_credentials.pyi +21 -0
  57. amsdal/cloud/services/actions/get_monitoring_info.cp312-win_amd64.pyd +0 -0
  58. amsdal/cloud/services/actions/get_monitoring_info.pyi +21 -0
  59. amsdal/cloud/services/actions/list_dependencies.cp312-win_amd64.pyd +0 -0
  60. amsdal/cloud/services/actions/list_dependencies.pyi +21 -0
  61. amsdal/cloud/services/actions/list_deploys.cp312-win_amd64.pyd +0 -0
  62. amsdal/cloud/services/actions/list_deploys.pyi +19 -0
  63. amsdal/cloud/services/actions/list_envs.cp312-win_amd64.pyd +0 -0
  64. amsdal/cloud/services/actions/list_envs.pyi +20 -0
  65. amsdal/cloud/services/actions/list_secrets.cp312-win_amd64.pyd +0 -0
  66. amsdal/cloud/services/actions/list_secrets.pyi +22 -0
  67. amsdal/cloud/services/actions/manager.cp312-win_amd64.pyd +0 -0
  68. amsdal/cloud/services/actions/manager.pyi +278 -0
  69. amsdal/cloud/services/actions/signup_action.cp312-win_amd64.pyd +0 -0
  70. amsdal/cloud/services/actions/signup_action.pyi +20 -0
  71. amsdal/cloud/services/actions/update_deploy.cp312-win_amd64.pyd +0 -0
  72. amsdal/cloud/services/actions/update_deploy.pyi +19 -0
  73. amsdal/cloud/services/auth/__init__.cp312-win_amd64.pyd +0 -0
  74. amsdal/cloud/services/auth/__init__.pyi +0 -0
  75. amsdal/cloud/services/auth/base.cp312-win_amd64.pyd +0 -0
  76. amsdal/cloud/services/auth/base.pyi +6 -0
  77. amsdal/cloud/services/auth/credentials.cp312-win_amd64.pyd +0 -0
  78. amsdal/cloud/services/auth/credentials.pyi +31 -0
  79. amsdal/cloud/services/auth/manager.cp312-win_amd64.pyd +0 -0
  80. amsdal/cloud/services/auth/manager.pyi +26 -0
  81. amsdal/cloud/services/auth/signup_service.cp312-win_amd64.pyd +0 -0
  82. amsdal/cloud/services/auth/signup_service.pyi +32 -0
  83. amsdal/cloud/services/auth/token.cp312-win_amd64.pyd +0 -0
  84. amsdal/cloud/services/auth/token.pyi +28 -0
  85. amsdal/configs/__init__.py +0 -0
  86. amsdal/configs/__init__.pyi +0 -0
  87. amsdal/configs/constants.py +33 -0
  88. amsdal/configs/constants.pyi +22 -0
  89. amsdal/configs/main.py +254 -0
  90. amsdal/configs/main.pyi +177 -0
  91. amsdal/context/__init__.py +0 -0
  92. amsdal/context/__init__.pyi +0 -0
  93. amsdal/context/manager.py +69 -0
  94. amsdal/context/manager.pyi +50 -0
  95. amsdal/contrib/__init__.cp312-win_amd64.pyd +0 -0
  96. amsdal/contrib/__init__.pyi +0 -0
  97. amsdal/contrib/app_config.py +7 -0
  98. amsdal/contrib/app_config.pyi +6 -0
  99. amsdal/contrib/auth/__init__.py +0 -0
  100. amsdal/contrib/auth/__init__.pyi +0 -0
  101. amsdal/contrib/auth/app.py +27 -0
  102. amsdal/contrib/auth/app.pyi +15 -0
  103. amsdal/contrib/auth/decorators/__init__.py +20 -0
  104. amsdal/contrib/auth/decorators/__init__.pyi +6 -0
  105. amsdal/contrib/auth/errors.py +7 -0
  106. amsdal/contrib/auth/errors.pyi +4 -0
  107. amsdal/contrib/auth/lifecycle/__init__.py +0 -0
  108. amsdal/contrib/auth/lifecycle/__init__.pyi +0 -0
  109. amsdal/contrib/auth/lifecycle/consumer.py +222 -0
  110. amsdal/contrib/auth/lifecycle/consumer.pyi +69 -0
  111. amsdal/contrib/auth/migrations/0000_initial.py +49 -0
  112. amsdal/contrib/auth/models/login_session/hooks/pre_init.py +64 -0
  113. amsdal/contrib/auth/models/login_session/model.json +23 -0
  114. amsdal/contrib/auth/models/login_session/modifiers/display_name.py +11 -0
  115. amsdal/contrib/auth/models/permission/fixtures/basic_permissions.json +62 -0
  116. amsdal/contrib/auth/models/permission/model.json +18 -0
  117. amsdal/contrib/auth/models/permission/modifiers/display_name.py +11 -0
  118. amsdal/contrib/auth/models/user/hooks/post_init.py +58 -0
  119. amsdal/contrib/auth/models/user/hooks/pre_create.py +8 -0
  120. amsdal/contrib/auth/models/user/model.json +25 -0
  121. amsdal/contrib/auth/models/user/modifiers/display_name.py +19 -0
  122. amsdal/contrib/auth/settings.py +36 -0
  123. amsdal/contrib/auth/settings.pyi +26 -0
  124. amsdal/contrib/frontend_configs/__init__.py +0 -0
  125. amsdal/contrib/frontend_configs/__init__.pyi +0 -0
  126. amsdal/contrib/frontend_configs/app.py +24 -0
  127. amsdal/contrib/frontend_configs/app.pyi +19 -0
  128. amsdal/contrib/frontend_configs/constants.py +1 -0
  129. amsdal/contrib/frontend_configs/constants.pyi +1 -0
  130. amsdal/contrib/frontend_configs/conversion/__init__.py +5 -0
  131. amsdal/contrib/frontend_configs/conversion/__init__.pyi +3 -0
  132. amsdal/contrib/frontend_configs/conversion/convert.py +250 -0
  133. amsdal/contrib/frontend_configs/conversion/convert.pyi +23 -0
  134. amsdal/contrib/frontend_configs/lifecycle/__init__.py +0 -0
  135. amsdal/contrib/frontend_configs/lifecycle/__init__.pyi +0 -0
  136. amsdal/contrib/frontend_configs/lifecycle/consumer.py +242 -0
  137. amsdal/contrib/frontend_configs/lifecycle/consumer.pyi +86 -0
  138. amsdal/contrib/frontend_configs/migrations/0000_initial.py +255 -0
  139. amsdal/contrib/frontend_configs/models/frontend_activator_config/model.json +11 -0
  140. amsdal/contrib/frontend_configs/models/frontend_config_async_validator/model.json +11 -0
  141. amsdal/contrib/frontend_configs/models/frontend_config_group_validator/model.json +52 -0
  142. amsdal/contrib/frontend_configs/models/frontend_config_option/model.json +15 -0
  143. amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base/model.json +6 -0
  144. amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base/properties/model_dump.py +13 -0
  145. amsdal/contrib/frontend_configs/models/frontend_config_slider_option/model.json +19 -0
  146. amsdal/contrib/frontend_configs/models/frontend_config_text_mask/model.json +26 -0
  147. amsdal/contrib/frontend_configs/models/frontend_config_validator/model.json +41 -0
  148. amsdal/contrib/frontend_configs/models/frontend_control_config/model.json +250 -0
  149. amsdal/contrib/frontend_configs/models/frontend_model_config/fixtures/permissions.json +24 -0
  150. amsdal/contrib/frontend_configs/models/frontend_model_config/model.json +17 -0
  151. amsdal/contrib/frontend_configs/models/frontent_config_control_action/model.json +54 -0
  152. amsdal/contrib/frontend_configs/models/frontent_config_control_action/properties/action_validate.py +33 -0
  153. amsdal/contrib/frontend_configs/utils.py +29 -0
  154. amsdal/contrib/frontend_configs/utils.pyi +17 -0
  155. amsdal/errors.py +31 -0
  156. amsdal/errors.pyi +12 -0
  157. amsdal/fixtures/__init__.cp312-win_amd64.pyd +0 -0
  158. amsdal/fixtures/__init__.pyi +0 -0
  159. amsdal/fixtures/manager.cp312-win_amd64.pyd +0 -0
  160. amsdal/fixtures/manager.pyi +118 -0
  161. amsdal/manager.cp312-win_amd64.pyd +0 -0
  162. amsdal/manager.pyi +183 -0
  163. amsdal/migration/__init__.cp312-win_amd64.pyd +0 -0
  164. amsdal/migration/__init__.pyi +0 -0
  165. amsdal/migration/base_migration_schemas.cp312-win_amd64.pyd +0 -0
  166. amsdal/migration/base_migration_schemas.pyi +120 -0
  167. amsdal/migration/data_classes.cp312-win_amd64.pyd +0 -0
  168. amsdal/migration/data_classes.pyi +178 -0
  169. amsdal/migration/executors/__init__.cp312-win_amd64.pyd +0 -0
  170. amsdal/migration/executors/__init__.pyi +0 -0
  171. amsdal/migration/executors/base.cp312-win_amd64.pyd +0 -0
  172. amsdal/migration/executors/base.pyi +106 -0
  173. amsdal/migration/executors/default_executor.cp312-win_amd64.pyd +0 -0
  174. amsdal/migration/executors/default_executor.pyi +96 -0
  175. amsdal/migration/executors/state_executor.cp312-win_amd64.pyd +0 -0
  176. amsdal/migration/executors/state_executor.pyi +78 -0
  177. amsdal/migration/file_migration_executor.cp312-win_amd64.pyd +0 -0
  178. amsdal/migration/file_migration_executor.pyi +68 -0
  179. amsdal/migration/file_migration_generator.cp312-win_amd64.pyd +0 -0
  180. amsdal/migration/file_migration_generator.pyi +139 -0
  181. amsdal/migration/file_migration_store.cp312-win_amd64.pyd +0 -0
  182. amsdal/migration/file_migration_store.pyi +61 -0
  183. amsdal/migration/file_migration_writer.cp312-win_amd64.pyd +0 -0
  184. amsdal/migration/file_migration_writer.pyi +73 -0
  185. amsdal/migration/migrations.cp312-win_amd64.pyd +0 -0
  186. amsdal/migration/migrations.pyi +166 -0
  187. amsdal/migration/migrations_loader.cp312-win_amd64.pyd +0 -0
  188. amsdal/migration/migrations_loader.pyi +32 -0
  189. amsdal/migration/schemas_loaders.cp312-win_amd64.pyd +0 -0
  190. amsdal/migration/schemas_loaders.pyi +37 -0
  191. amsdal/migration/templates/data_migration.tmpl +18 -0
  192. amsdal/migration/templates/dict_validator.tmpl +4 -0
  193. amsdal/migration/templates/migration.tmpl +6 -0
  194. amsdal/migration/templates/model_class.tmpl +8 -0
  195. amsdal/migration/templates/model_class_layout.tmpl +24 -0
  196. amsdal/migration/templates/options_validator.tmpl +4 -0
  197. amsdal/migration/utils.cp312-win_amd64.pyd +0 -0
  198. amsdal/migration/utils.pyi +58 -0
  199. amsdal/mixins/__init__.cp312-win_amd64.pyd +0 -0
  200. amsdal/mixins/__init__.pyi +0 -0
  201. amsdal/mixins/build_mixin.cp312-win_amd64.pyd +0 -0
  202. amsdal/mixins/build_mixin.pyi +78 -0
  203. amsdal/mixins/class_versions_mixin.cp312-win_amd64.pyd +0 -0
  204. amsdal/mixins/class_versions_mixin.pyi +6 -0
  205. amsdal/py.typed +0 -0
  206. amsdal/schemas/__init__.py +0 -0
  207. amsdal/schemas/__init__.pyi +0 -0
  208. amsdal/schemas/core/class_object/model.json +31 -0
  209. amsdal/schemas/core/class_object/properties/display_name.py +9 -0
  210. amsdal/schemas/core/class_object_meta/model.json +55 -0
  211. amsdal/schemas/core/class_property/model.json +22 -0
  212. amsdal/schemas/core/class_property_meta/model.json +23 -0
  213. amsdal/schemas/core/file/hooks/pre_create.py +11 -0
  214. amsdal/schemas/core/file/hooks/pre_update.py +11 -0
  215. amsdal/schemas/core/file/model.json +23 -0
  216. amsdal/schemas/core/file/properties/from_file.py +34 -0
  217. amsdal/schemas/core/file/properties/mimetype.py +13 -0
  218. amsdal/schemas/core/file/properties/str.py +6 -0
  219. amsdal/schemas/core/file/properties/to_file.py +24 -0
  220. amsdal/schemas/core/file/properties/validate_data.py +32 -0
  221. amsdal/schemas/core/fixture/model.json +35 -0
  222. amsdal/schemas/core/option/model.json +19 -0
  223. amsdal/schemas/core/validator/model.json +19 -0
  224. amsdal/schemas/manager.cp312-win_amd64.pyd +0 -0
  225. amsdal/schemas/manager.py +116 -0
  226. amsdal/schemas/manager.pyi +65 -0
  227. amsdal/schemas/types/anything/model.json +7 -0
  228. amsdal/schemas/types/array/model.json +7 -0
  229. amsdal/schemas/types/binary/model.json +7 -0
  230. amsdal/schemas/types/boolean/model.json +17 -0
  231. amsdal/schemas/types/date/model.json +7 -0
  232. amsdal/schemas/types/datetime/model.json +7 -0
  233. amsdal/schemas/types/dictionary/model.json +8 -0
  234. amsdal/schemas/types/number/model.json +8 -0
  235. amsdal/schemas/types/object/model.json +53 -0
  236. amsdal/schemas/types/string/model.json +8 -0
  237. amsdal/services/__init__.cp312-win_amd64.pyd +0 -0
  238. amsdal/services/__init__.pyi +0 -0
  239. amsdal/services/transaction_execution.cp312-win_amd64.pyd +0 -0
  240. amsdal/services/transaction_execution.pyi +76 -0
  241. amsdal/utils/__init__.py +0 -0
  242. amsdal/utils/__init__.pyi +0 -0
  243. amsdal/utils/contrib_paths.py +23 -0
  244. amsdal/utils/contrib_paths.pyi +14 -0
  245. amsdal/utils/tests/__init__.py +0 -0
  246. amsdal/utils/tests/enums.py +18 -0
  247. amsdal/utils/tests/factories.py +49 -0
  248. amsdal/utils/tests/helpers.py +309 -0
  249. amsdal-0.2.5.dist-info/LICENSE.txt +107 -0
  250. amsdal-0.2.5.dist-info/METADATA +366 -0
  251. amsdal-0.2.5.dist-info/RECORD +254 -0
  252. amsdal-0.2.5.dist-info/WHEEL +5 -0
  253. amsdal-0.2.5.dist-info/license_check.py +35 -0
  254. amsdal-0.2.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,242 @@
1
+ import contextlib
2
+ import logging
3
+ from typing import Any
4
+
5
+ from amsdal_models.classes.errors import AmsdalClassNotFoundError
6
+ from amsdal_utils.lifecycle.consumer import LifecycleConsumer
7
+ from amsdal_utils.models.data_models.address import Address
8
+ from amsdal_utils.models.data_models.core import LegacyDictSchema
9
+ from amsdal_utils.models.data_models.enums import CoreTypes
10
+ from amsdal_utils.models.data_models.schema import PropertyData
11
+ from amsdal_utils.models.enums import SchemaTypes
12
+ from amsdal_utils.models.enums import Versions
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ core_to_frontend_types = {
17
+ CoreTypes.NUMBER.value: 'number',
18
+ CoreTypes.BOOLEAN.value: 'checkbox',
19
+ CoreTypes.STRING.value: 'text',
20
+ CoreTypes.ANYTHING.value: 'text',
21
+ CoreTypes.BINARY.value: 'text',
22
+ CoreTypes.DATE.value: 'date',
23
+ CoreTypes.DATETIME.value: 'datetime',
24
+ }
25
+
26
+
27
+ def process_property(field_name: str, property_data: PropertyData) -> dict[str, Any]:
28
+ """
29
+ Processes a property and converts it to a frontend configuration dictionary.
30
+
31
+ This function takes a field name and property data, and converts them into a dictionary
32
+ that represents the configuration for a frontend form control. It handles various types
33
+ such as core types, arrays, dictionaries, and files.
34
+
35
+ Args:
36
+ field_name (str): The name of the field to be processed.
37
+ property_data (PropertyData): The property data to be processed.
38
+
39
+ Returns:
40
+ dict[str, Any]: A dictionary representing the frontend configuration for the given property.
41
+ """
42
+ type_definition: dict[str, Any]
43
+ if property_data.type in core_to_frontend_types:
44
+ type_definition = {
45
+ 'type': core_to_frontend_types[property_data.type],
46
+ }
47
+ elif property_data.type == CoreTypes.ARRAY.value:
48
+ type_definition = {
49
+ 'type': 'array',
50
+ 'control': process_property(f'{field_name}_items', property_data.items), # type: ignore[arg-type]
51
+ }
52
+ elif property_data.type == CoreTypes.DICTIONARY.value:
53
+ if isinstance(property_data.items, LegacyDictSchema):
54
+ type_definition = {
55
+ 'type': 'dict',
56
+ 'control': process_property(
57
+ f'{field_name}_items',
58
+ PropertyData(
59
+ type=property_data.items.key_type,
60
+ items=None,
61
+ title=None,
62
+ read_only=False,
63
+ options=None,
64
+ default=None,
65
+ field_name=field_name,
66
+ field_id=None,
67
+ is_deleted=False,
68
+ ),
69
+ ),
70
+ }
71
+ else:
72
+ type_definition = {
73
+ 'type': 'dict',
74
+ 'control': process_property(
75
+ f'{field_name}_items',
76
+ property_data.items.key, # type: ignore[union-attr, arg-type]
77
+ ),
78
+ }
79
+ elif property_data.type == 'File':
80
+ type_definition = {
81
+ 'type': 'file',
82
+ }
83
+ else:
84
+ type_definition = {
85
+ 'type': 'object_latest',
86
+ 'entityType': property_data.type,
87
+ }
88
+
89
+ if getattr(property_data, 'default', None) is not None:
90
+ type_definition['value'] = property_data.default
91
+
92
+ if getattr(property_data, 'options', None) is not None:
93
+ type_definition['options'] = [
94
+ {
95
+ 'label': option.key,
96
+ 'value': option.value,
97
+ }
98
+ for option in property_data.options # type: ignore[union-attr]
99
+ ]
100
+
101
+ return {
102
+ 'name': field_name,
103
+ 'label': property_data.title if hasattr(property_data, 'title') and property_data.title else field_name,
104
+ **type_definition,
105
+ }
106
+
107
+
108
+ def populate_frontend_config_with_values(config: dict[str, Any], values: dict[str, Any]) -> dict[str, Any]:
109
+ """
110
+ Populates a frontend configuration dictionary with values.
111
+
112
+ This function takes a frontend configuration dictionary and a dictionary of values,
113
+ and populates the configuration with the corresponding values. It recursively processes
114
+ nested controls to ensure all values are populated.
115
+
116
+ Args:
117
+ config (dict[str, Any]): The frontend configuration dictionary to be populated.
118
+ values (dict[str, Any]): The dictionary of values to populate the configuration with.
119
+
120
+ Returns:
121
+ dict[str, Any]: The populated frontend configuration dictionary.
122
+ """
123
+ if config.get('controls') and isinstance(config['controls'], list):
124
+ for control in config['controls']:
125
+ populate_frontend_config_with_values(control, values)
126
+
127
+ if config.get('name') in values:
128
+ config['value'] = values[config['name']]
129
+ return config
130
+
131
+
132
+ def get_values_from_response(response: dict[str, Any] | list[dict[str, Any]]) -> dict[str, Any]:
133
+ """
134
+ Extracts values from a response dictionary or list of dictionaries.
135
+
136
+ This function processes a response to extract the relevant values. It checks if the response
137
+ is a dictionary containing a 'rows' key and processes the rows to find the appropriate values.
138
+ If the response is not in the expected format, it returns an empty dictionary.
139
+
140
+ Args:
141
+ response (dict[str, Any] | list[dict[str, Any]]): The response to extract values from.
142
+
143
+ Returns:
144
+ dict[str, Any]: A dictionary containing the extracted values.
145
+ """
146
+ if not isinstance(response, dict) or 'rows' not in response or not response['rows']:
147
+ return {}
148
+
149
+ for row in response['rows']:
150
+ if '_metadata' in row and row['_metadata'].get('next_version') is None:
151
+ return row
152
+
153
+ return response['rows'][0]
154
+
155
+
156
+ def get_default_control(class_name: str) -> dict[str, Any]:
157
+ """
158
+ Retrieves the default frontend control configuration for a given class name.
159
+
160
+ This function attempts to import a class by its name from various schema types.
161
+ If the class is found, it converts it to a frontend configuration dictionary
162
+ and returns it. If the class is not found, it returns an empty dictionary.
163
+
164
+ Args:
165
+ class_name (str): The name of the class to retrieve the default control for.
166
+
167
+ Returns:
168
+ dict[str, Any]: A dictionary representing the frontend control configuration for the given class.
169
+ """
170
+ from amsdal_models.classes.manager import ClassManager
171
+
172
+ from amsdal.contrib.frontend_configs.conversion import convert_to_frontend_config
173
+ from models.contrib.frontend_control_config import FrontendControlConfig # type: ignore[import-not-found]
174
+
175
+ target_class = None
176
+ for schema_type in [SchemaTypes.USER, SchemaTypes.CONTRIB, SchemaTypes.CORE]:
177
+ with contextlib.suppress(AmsdalClassNotFoundError):
178
+ target_class = ClassManager().import_class(class_name, schema_type)
179
+
180
+ if target_class:
181
+ break
182
+
183
+ if not target_class:
184
+ return {}
185
+
186
+ return FrontendControlConfig(**convert_to_frontend_config(target_class)).model_dump(
187
+ exclude_none=True,
188
+ )
189
+
190
+
191
+ class ProcessResponseConsumer(LifecycleConsumer):
192
+ """
193
+ Consumer class for processing responses and populating frontend configurations.
194
+
195
+ This class extends the LifecycleConsumer and processes responses to populate
196
+ frontend configurations based on the class name and values extracted from the response.
197
+ """
198
+
199
+ def on_event(
200
+ self,
201
+ request: Any,
202
+ response: dict[str, Any],
203
+ ) -> None:
204
+ """
205
+ Handles the event by extracting the class name and values from the request and response,
206
+ and populates the frontend configuration accordingly.
207
+
208
+ Args:
209
+ request (Any): The request object containing query and path parameters.
210
+ response (dict[str, Any]): The response dictionary to be processed.
211
+
212
+ Returns:
213
+ None
214
+ """
215
+ from models.contrib.frontend_model_config import FrontendModelConfig # type: ignore[import-not-found]
216
+
217
+ class_name = None
218
+ values = {}
219
+ if hasattr(request, 'query_params') and 'class_name' in request.query_params:
220
+ class_name = request.query_params['class_name']
221
+
222
+ if hasattr(request, 'path_params') and 'address' in request.path_params:
223
+ class_name = Address.from_string(request.path_params['address']).class_name
224
+ values = get_values_from_response(response)
225
+
226
+ if class_name and isinstance(response, dict):
227
+ config = (
228
+ FrontendModelConfig.objects.all()
229
+ .first(
230
+ class_name=class_name,
231
+ _metadata__is_deleted=False,
232
+ _address__object_version=Versions.LATEST,
233
+ )
234
+ .execute()
235
+ )
236
+
237
+ if config and config.control:
238
+ response['control'] = populate_frontend_config_with_values(
239
+ config.control.model_dump(exclude_none=True), values
240
+ )
241
+ else:
242
+ response['control'] = populate_frontend_config_with_values(get_default_control(class_name), values)
@@ -0,0 +1,86 @@
1
+ from _typeshed import Incomplete
2
+ from amsdal_utils.lifecycle.consumer import LifecycleConsumer
3
+ from amsdal_utils.models.data_models.schema import PropertyData
4
+ from typing import Any
5
+
6
+ logger: Incomplete
7
+ core_to_frontend_types: Incomplete
8
+
9
+ def process_property(field_name: str, property_data: PropertyData) -> dict[str, Any]:
10
+ """
11
+ Processes a property and converts it to a frontend configuration dictionary.
12
+
13
+ This function takes a field name and property data, and converts them into a dictionary
14
+ that represents the configuration for a frontend form control. It handles various types
15
+ such as core types, arrays, dictionaries, and files.
16
+
17
+ Args:
18
+ field_name (str): The name of the field to be processed.
19
+ property_data (PropertyData): The property data to be processed.
20
+
21
+ Returns:
22
+ dict[str, Any]: A dictionary representing the frontend configuration for the given property.
23
+ """
24
+ def populate_frontend_config_with_values(config: dict[str, Any], values: dict[str, Any]) -> dict[str, Any]:
25
+ """
26
+ Populates a frontend configuration dictionary with values.
27
+
28
+ This function takes a frontend configuration dictionary and a dictionary of values,
29
+ and populates the configuration with the corresponding values. It recursively processes
30
+ nested controls to ensure all values are populated.
31
+
32
+ Args:
33
+ config (dict[str, Any]): The frontend configuration dictionary to be populated.
34
+ values (dict[str, Any]): The dictionary of values to populate the configuration with.
35
+
36
+ Returns:
37
+ dict[str, Any]: The populated frontend configuration dictionary.
38
+ """
39
+ def get_values_from_response(response: dict[str, Any] | list[dict[str, Any]]) -> dict[str, Any]:
40
+ """
41
+ Extracts values from a response dictionary or list of dictionaries.
42
+
43
+ This function processes a response to extract the relevant values. It checks if the response
44
+ is a dictionary containing a 'rows' key and processes the rows to find the appropriate values.
45
+ If the response is not in the expected format, it returns an empty dictionary.
46
+
47
+ Args:
48
+ response (dict[str, Any] | list[dict[str, Any]]): The response to extract values from.
49
+
50
+ Returns:
51
+ dict[str, Any]: A dictionary containing the extracted values.
52
+ """
53
+ def get_default_control(class_name: str) -> dict[str, Any]:
54
+ """
55
+ Retrieves the default frontend control configuration for a given class name.
56
+
57
+ This function attempts to import a class by its name from various schema types.
58
+ If the class is found, it converts it to a frontend configuration dictionary
59
+ and returns it. If the class is not found, it returns an empty dictionary.
60
+
61
+ Args:
62
+ class_name (str): The name of the class to retrieve the default control for.
63
+
64
+ Returns:
65
+ dict[str, Any]: A dictionary representing the frontend control configuration for the given class.
66
+ """
67
+
68
+ class ProcessResponseConsumer(LifecycleConsumer):
69
+ """
70
+ Consumer class for processing responses and populating frontend configurations.
71
+
72
+ This class extends the LifecycleConsumer and processes responses to populate
73
+ frontend configurations based on the class name and values extracted from the response.
74
+ """
75
+ def on_event(self, request: Any, response: dict[str, Any]) -> None:
76
+ """
77
+ Handles the event by extracting the class name and values from the request and response,
78
+ and populates the frontend configuration accordingly.
79
+
80
+ Args:
81
+ request (Any): The request object containing query and path parameters.
82
+ response (dict[str, Any]): The response dictionary to be processed.
83
+
84
+ Returns:
85
+ None
86
+ """
@@ -0,0 +1,255 @@
1
+ from amsdal_utils.models.enums import SchemaTypes
2
+
3
+ from amsdal.migration import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ operations: list[migrations.Operation] = [
8
+ migrations.CreateClass(
9
+ schema_type=SchemaTypes.CONTRIB,
10
+ class_name='FrontendConfigSkipNoneBase',
11
+ new_schema={
12
+ 'title': 'FrontendConfigSkipNoneBase',
13
+ 'properties': {},
14
+ 'meta_class': 'TypeMeta',
15
+ 'custom_code': "from typing import Any\n\n\ndef model_dump(self, **kwargs: Any) -> dict[str, Any]: # type: ignore[no-untyped-def] # noqa: ARG001\n kwargs['exclude_none'] = True\n\n return super().model_dump(**kwargs) # type: ignore[misc]\n\n\ndef model_dump_json(self, **kwargs: Any) -> str: # type: ignore[no-untyped-def] # noqa: ARG001\n kwargs['exclude_none'] = True\n\n return super().model_dump_json(**kwargs) # type: ignore[misc]",
16
+ },
17
+ ),
18
+ migrations.CreateClass(
19
+ schema_type=SchemaTypes.CONTRIB,
20
+ class_name='FrontendConfigGroupValidator',
21
+ new_schema={
22
+ 'title': 'FrontendConfigGroupValidator',
23
+ 'type': 'FrontendConfigSkipNoneBase',
24
+ 'properties': {
25
+ 'mainControl': {'type': 'string', 'title': 'Main Control'},
26
+ 'dependentControls': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Dependent Controls'},
27
+ 'condition': {
28
+ 'type': 'string',
29
+ 'title': 'Condition',
30
+ 'options': [
31
+ {'key': 'Less Than', 'value': 'lt'},
32
+ {'key': 'Less Than or Equal', 'value': 'lte'},
33
+ {'key': 'Greater Than', 'value': 'gt'},
34
+ {'key': 'Greater Than or Equal', 'value': 'gte'},
35
+ {'key': 'Equal', 'value': 'eq'},
36
+ {'key': 'Not Equal', 'value': 'neq'},
37
+ {'key': 'Exist', 'value': 'exist'},
38
+ ],
39
+ },
40
+ },
41
+ 'meta_class': 'TypeMeta',
42
+ },
43
+ ),
44
+ migrations.CreateClass(
45
+ schema_type=SchemaTypes.CONTRIB,
46
+ class_name='FrontendActivatorConfig',
47
+ new_schema={
48
+ 'title': 'FrontendActivatorConfig',
49
+ 'type': 'FrontendConfigGroupValidator',
50
+ 'properties': {'value': {'type': 'anything', 'title': 'Value'}},
51
+ 'meta_class': 'TypeMeta',
52
+ },
53
+ ),
54
+ migrations.CreateClass(
55
+ schema_type=SchemaTypes.CONTRIB,
56
+ class_name='FrontendConfigTextMask',
57
+ new_schema={
58
+ 'title': 'FrontendConfigTextMask',
59
+ 'type': 'FrontendConfigSkipNoneBase',
60
+ 'required': ['mask_string'],
61
+ 'properties': {
62
+ 'mask_string': {'type': 'string', 'title': 'Mask String'},
63
+ 'prefix': {'type': 'string', 'title': 'Prefix'},
64
+ 'suffix': {'type': 'string', 'title': 'Suffix'},
65
+ 'thousands_separator': {'type': 'string', 'title': 'Thousands Separator'},
66
+ },
67
+ 'meta_class': 'TypeMeta',
68
+ },
69
+ ),
70
+ migrations.CreateClass(
71
+ schema_type=SchemaTypes.CONTRIB,
72
+ class_name='FrontendConfigSliderOption',
73
+ new_schema={
74
+ 'title': 'FrontendConfigSliderOption',
75
+ 'type': 'FrontendConfigSkipNoneBase',
76
+ 'properties': {
77
+ 'min': {'type': 'number', 'title': 'Minimum'},
78
+ 'max': {'type': 'number', 'title': 'Maximum'},
79
+ 'range': {'type': 'boolean', 'title': 'Range'},
80
+ },
81
+ 'meta_class': 'TypeMeta',
82
+ },
83
+ ),
84
+ migrations.CreateClass(
85
+ schema_type=SchemaTypes.CONTRIB,
86
+ class_name='FrontendConfigValidator',
87
+ new_schema={
88
+ 'title': 'FrontendConfigValidator',
89
+ 'type': 'FrontendConfigGroupValidator',
90
+ 'properties': {
91
+ 'function': {
92
+ 'type': 'string',
93
+ 'title': 'Function',
94
+ 'options': [
95
+ {'key': 'Minimum', 'value': 'min'},
96
+ {'key': 'Maximum', 'value': 'max'},
97
+ {'key': 'Minimum Length', 'value': 'minLength'},
98
+ {'key': 'Maximum Length', 'value': 'maxLength'},
99
+ {'key': 'Required', 'value': 'required'},
100
+ {'key': 'Pattern', 'value': 'pattern'},
101
+ ],
102
+ },
103
+ 'value': {'type': 'string', 'title': 'Value'},
104
+ },
105
+ 'meta_class': 'TypeMeta',
106
+ },
107
+ ),
108
+ migrations.CreateClass(
109
+ schema_type=SchemaTypes.CONTRIB,
110
+ class_name='FrontendConfigAsyncValidator',
111
+ new_schema={
112
+ 'title': 'FrontendConfigAsyncValidator',
113
+ 'type': 'FrontendConfigSkipNoneBase',
114
+ 'properties': {'endpoint': {'type': 'string', 'title': 'Endpoint'}},
115
+ 'meta_class': 'TypeMeta',
116
+ },
117
+ ),
118
+ migrations.CreateClass(
119
+ schema_type=SchemaTypes.CONTRIB,
120
+ class_name='FrontendConfigControlAction',
121
+ new_schema={
122
+ 'title': 'FrontendConfigControlAction',
123
+ 'type': 'FrontendConfigSkipNoneBase',
124
+ 'required': ['action', 'text', 'type'],
125
+ 'properties': {
126
+ 'action': {'type': 'string', 'title': 'Action'},
127
+ 'text': {'type': 'string', 'title': 'Text'},
128
+ 'type': {
129
+ 'type': 'string',
130
+ 'title': 'Type',
131
+ 'options': [
132
+ {'key': 'Arrow Next', 'value': 'arrow-next'},
133
+ {'key': 'Arrow Prev', 'value': 'arrow-prev'},
134
+ {'key': 'Action Button', 'value': 'action-button'},
135
+ {'key': 'Text Next', 'value': 'text-next'},
136
+ {'key': 'Text Prev', 'value': 'text-prev'},
137
+ ],
138
+ },
139
+ 'dataLayerEvent': {'type': 'string', 'title': 'Data Layer Event'},
140
+ 'activator': {'type': 'string', 'title': 'Activator'},
141
+ 'icon': {'type': 'string', 'title': 'Icon'},
142
+ },
143
+ 'meta_class': 'TypeMeta',
144
+ 'custom_code': "from pydantic import field_validator\n\n\n@field_validator('action', mode='after') # type: ignore[misc]\n@classmethod\ndef validate_action(cls, v: str) -> str: # type: ignore[no-untyped-def] # noqa: ARG001\n if not v.startswith('navigate::') and v not in [\n 'goPrev',\n 'goNext',\n 'goNextWithSubmit',\n 'submit',\n 'submitWithDataLayer',\n ]:\n msg = 'Action must be one of: goPrev, goNext, goNextWithSubmit, submit, submitWithDataLayer, navigate::{string}'\n raise ValueError(msg)\n\n return v",
145
+ },
146
+ ),
147
+ migrations.CreateClass(
148
+ schema_type=SchemaTypes.CONTRIB,
149
+ class_name='FrontendConfigOption',
150
+ new_schema={
151
+ 'title': 'FrontendConfigOption',
152
+ 'type': 'FrontendConfigSkipNoneBase',
153
+ 'properties': {
154
+ 'label': {'type': 'string', 'title': 'Label'},
155
+ 'value': {'type': 'string', 'title': 'Value'},
156
+ },
157
+ 'meta_class': 'TypeMeta',
158
+ },
159
+ ),
160
+ migrations.CreateClass(
161
+ schema_type=SchemaTypes.CONTRIB,
162
+ class_name='FrontendControlConfig',
163
+ new_schema={
164
+ 'title': 'FrontendControlConfig',
165
+ 'type': 'FrontendConfigSkipNoneBase',
166
+ 'required': ['type', 'name'],
167
+ 'properties': {
168
+ 'type': {
169
+ 'type': 'string',
170
+ 'title': 'Type',
171
+ 'options': [
172
+ {'key': 'Infoscreen', 'value': 'infoscreen'},
173
+ {'key': 'Info Group', 'value': 'info-group'},
174
+ {'key': 'Text', 'value': 'text'},
175
+ {'key': 'Number', 'value': 'number'},
176
+ {'key': 'Select', 'value': 'select'},
177
+ {'key': 'Object Group', 'value': 'object_group'},
178
+ {'key': 'Group', 'value': 'group'},
179
+ {'key': 'Group Toggle', 'value': 'group_toggle'},
180
+ {'key': 'Group Switch', 'value': 'group_switch'},
181
+ {'key': 'Password', 'value': 'password'},
182
+ {'key': 'Email', 'value': 'email'},
183
+ {'key': 'Phone', 'value': 'phone'},
184
+ {'key': 'textarea', 'value': 'textarea'},
185
+ {'key': 'Multiselect', 'value': 'multiselect'},
186
+ {'key': 'number_initial', 'value': 'number_initial'},
187
+ {'key': 'number_plus', 'value': 'number_plus'},
188
+ {'key': 'number_minus', 'value': 'number_minus'},
189
+ {'key': 'number_equals', 'value': 'number_equals'},
190
+ {'key': 'toggle', 'value': 'toggle'},
191
+ {'key': 'radio', 'value': 'radio'},
192
+ {'key': 'checkbox', 'value': 'checkbox'},
193
+ {'key': 'number-slider', 'value': 'number-slider'},
194
+ {'key': 'number-operations', 'value': 'number-operations'},
195
+ {'key': 'date', 'value': 'date'},
196
+ {'key': 'dateTriplet', 'value': 'dateTriplet'},
197
+ {'key': 'array', 'value': 'array'},
198
+ {'key': 'object', 'value': 'object'},
199
+ {'key': 'file', 'value': 'file'},
200
+ {'key': 'dropzone', 'value': 'dropzone'},
201
+ {'key': 'object_latest', 'value': 'object_latest'},
202
+ {'key': 'Dictionary', 'value': 'dict'},
203
+ {'key': 'Time', 'value': 'time'},
204
+ {'key': 'Datetime', 'value': 'datetime'},
205
+ {'key': 'Bytes', 'value': 'Bytes'},
206
+ ],
207
+ },
208
+ 'name': {'type': 'string', 'title': 'Name'},
209
+ 'label': {'type': 'string', 'title': 'Label'},
210
+ 'required': {'type': 'boolean', 'title': 'Required'},
211
+ 'hideLabel': {'type': 'boolean', 'title': 'Hide Label'},
212
+ 'actions': {'type': 'array', 'items': {'type': 'FrontendConfigControlAction'}, 'title': 'Actions'},
213
+ 'validators': {
214
+ 'type': 'array',
215
+ 'items': {'type': 'FrontendConfigValidator'},
216
+ 'title': 'Validators',
217
+ },
218
+ 'asyncValidators': {
219
+ 'type': 'array',
220
+ 'items': {'type': 'FrontendConfigAsyncValidator'},
221
+ 'title': 'Async Validators',
222
+ },
223
+ 'activators': {
224
+ 'type': 'array',
225
+ 'items': {'type': 'FrontendActivatorConfig'},
226
+ 'title': 'Activators',
227
+ },
228
+ 'additionalText': {'type': 'string', 'title': 'Additional Text'},
229
+ 'value': {'type': 'anything', 'title': 'Value'},
230
+ 'placeholder': {'type': 'string', 'title': 'Placeholder'},
231
+ 'options': {'type': 'array', 'items': {'type': 'FrontendConfigOption'}, 'title': 'Options'},
232
+ 'mask': {'type': 'FrontendConfigTextMask', 'title': 'Mask'},
233
+ 'controls': {'type': 'array', 'items': {'type': 'FrontendControlConfig'}, 'title': 'Controls'},
234
+ 'showSearch': {'type': 'boolean', 'title': 'Show Search'},
235
+ 'sliderOptions': {'type': 'FrontendConfigSliderOption', 'title': 'Slider Option'},
236
+ 'customLabel': {'type': 'array', 'items': {'type': 'string'}, 'title': 'Custom Label'},
237
+ 'control': {'type': 'FrontendControlConfig', 'title': 'Control'},
238
+ 'entityType': {'type': 'string', 'title': 'Entity Type'},
239
+ },
240
+ 'meta_class': 'TypeMeta',
241
+ },
242
+ ),
243
+ migrations.CreateClass(
244
+ schema_type=SchemaTypes.CONTRIB,
245
+ class_name='FrontendModelConfig',
246
+ new_schema={
247
+ 'title': 'FrontendModelConfig',
248
+ 'required': ['class_name'],
249
+ 'properties': {
250
+ 'class_name': {'type': 'string', 'title': 'Class Name'},
251
+ 'control': {'type': 'FrontendControlConfig', 'title': 'Control'},
252
+ },
253
+ },
254
+ ),
255
+ ]
@@ -0,0 +1,11 @@
1
+ {
2
+ "title": "FrontendActivatorConfig",
3
+ "type": "FrontendConfigGroupValidator",
4
+ "properties": {
5
+ "value": {
6
+ "title": "Value",
7
+ "type": "anything"
8
+ }
9
+ },
10
+ "meta_class": "TypeMeta"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "title": "FrontendConfigAsyncValidator",
3
+ "type": "FrontendConfigSkipNoneBase",
4
+ "properties": {
5
+ "endpoint": {
6
+ "title": "Endpoint",
7
+ "type": "string"
8
+ }
9
+ },
10
+ "meta_class": "TypeMeta"
11
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "title": "FrontendConfigGroupValidator",
3
+ "type": "FrontendConfigSkipNoneBase",
4
+ "properties": {
5
+ "mainControl": {
6
+ "title": "Main Control",
7
+ "type": "string"
8
+ },
9
+ "dependentControls": {
10
+ "title": "Dependent Controls",
11
+ "type": "array",
12
+ "items": {
13
+ "type": "string"
14
+ }
15
+ },
16
+ "condition": {
17
+ "title": "Condition",
18
+ "type": "string",
19
+ "options": [
20
+ {
21
+ "key": "Less Than",
22
+ "value": "lt"
23
+ },
24
+ {
25
+ "key": "Less Than or Equal",
26
+ "value": "lte"
27
+ },
28
+ {
29
+ "key": "Greater Than",
30
+ "value": "gt"
31
+ },
32
+ {
33
+ "key": "Greater Than or Equal",
34
+ "value": "gte"
35
+ },
36
+ {
37
+ "key": "Equal",
38
+ "value": "eq"
39
+ },
40
+ {
41
+ "key": "Not Equal",
42
+ "value": "neq"
43
+ },
44
+ {
45
+ "key": "Exist",
46
+ "value": "exist"
47
+ }
48
+ ]
49
+ }
50
+ },
51
+ "meta_class": "TypeMeta"
52
+ }