orionis 0.405.0__py3-none-any.whl → 0.407.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. orionis/console/base/command.py +57 -50
  2. orionis/console/base/contracts/command.py +68 -0
  3. orionis/console/dynamic/contracts/progress_bar.py +3 -3
  4. orionis/console/dynamic/progress_bar.py +8 -8
  5. orionis/console/output/console.py +8 -2
  6. orionis/console/output/contracts/console.py +1 -1
  7. orionis/container/container.py +2 -2
  8. orionis/container/context/scope.py +4 -1
  9. orionis/container/contracts/service_provider.py +2 -2
  10. orionis/container/entities/binding.py +31 -44
  11. orionis/container/enums/lifetimes.py +22 -1
  12. orionis/container/facades/facade.py +1 -2
  13. orionis/container/providers/service_provider.py +2 -2
  14. orionis/foundation/application.py +542 -248
  15. orionis/foundation/config/app/entities/app.py +107 -90
  16. orionis/foundation/config/auth/entities/auth.py +4 -33
  17. orionis/foundation/config/cache/entities/cache.py +18 -41
  18. orionis/foundation/config/cache/entities/file.py +8 -35
  19. orionis/foundation/config/cache/entities/stores.py +17 -38
  20. orionis/foundation/config/cors/entities/cors.py +41 -54
  21. orionis/foundation/config/database/entities/connections.py +40 -56
  22. orionis/foundation/config/database/entities/database.py +11 -38
  23. orionis/foundation/config/database/entities/mysql.py +48 -76
  24. orionis/foundation/config/database/entities/oracle.py +30 -57
  25. orionis/foundation/config/database/entities/pgsql.py +45 -61
  26. orionis/foundation/config/database/entities/sqlite.py +26 -53
  27. orionis/foundation/config/filesystems/entitites/aws.py +28 -49
  28. orionis/foundation/config/filesystems/entitites/disks.py +27 -47
  29. orionis/foundation/config/filesystems/entitites/filesystems.py +15 -37
  30. orionis/foundation/config/filesystems/entitites/local.py +9 -35
  31. orionis/foundation/config/filesystems/entitites/public.py +14 -41
  32. orionis/foundation/config/logging/entities/channels.py +56 -86
  33. orionis/foundation/config/logging/entities/chunked.py +9 -9
  34. orionis/foundation/config/logging/entities/daily.py +8 -8
  35. orionis/foundation/config/logging/entities/hourly.py +6 -6
  36. orionis/foundation/config/logging/entities/logging.py +12 -18
  37. orionis/foundation/config/logging/entities/monthly.py +7 -7
  38. orionis/foundation/config/logging/entities/stack.py +5 -5
  39. orionis/foundation/config/logging/entities/weekly.py +6 -6
  40. orionis/foundation/config/mail/entities/file.py +9 -36
  41. orionis/foundation/config/mail/entities/mail.py +22 -40
  42. orionis/foundation/config/mail/entities/mailers.py +29 -44
  43. orionis/foundation/config/mail/entities/smtp.py +47 -48
  44. orionis/foundation/config/queue/entities/brokers.py +19 -41
  45. orionis/foundation/config/queue/entities/database.py +24 -46
  46. orionis/foundation/config/queue/entities/queue.py +28 -40
  47. orionis/foundation/config/roots/paths.py +272 -468
  48. orionis/foundation/config/session/entities/session.py +23 -53
  49. orionis/foundation/config/startup.py +165 -135
  50. orionis/foundation/config/testing/entities/testing.py +137 -122
  51. orionis/foundation/config/testing/enums/__init__.py +6 -2
  52. orionis/foundation/config/testing/enums/drivers.py +16 -0
  53. orionis/foundation/config/testing/enums/verbosity.py +18 -0
  54. orionis/foundation/contracts/application.py +152 -362
  55. orionis/foundation/providers/console_provider.py +24 -2
  56. orionis/foundation/providers/dumper_provider.py +24 -2
  57. orionis/foundation/providers/logger_provider.py +24 -2
  58. orionis/foundation/providers/path_resolver_provider.py +25 -2
  59. orionis/foundation/providers/progress_bar_provider.py +24 -2
  60. orionis/foundation/providers/testing_provider.py +39 -0
  61. orionis/foundation/providers/workers_provider.py +24 -2
  62. orionis/metadata/framework.py +1 -1
  63. orionis/services/asynchrony/contracts/coroutines.py +13 -5
  64. orionis/services/asynchrony/coroutines.py +33 -29
  65. orionis/services/asynchrony/exceptions/exception.py +9 -1
  66. orionis/services/environment/core/dot_env.py +46 -34
  67. orionis/services/environment/enums/__init__.py +0 -0
  68. orionis/services/environment/enums/cast_type.py +42 -0
  69. orionis/services/environment/helpers/functions.py +1 -2
  70. orionis/services/environment/key/__init__.py +0 -0
  71. orionis/services/environment/key/key_generator.py +37 -0
  72. orionis/services/environment/serializer/__init__.py +0 -0
  73. orionis/services/environment/serializer/values.py +21 -0
  74. orionis/services/environment/validators/__init__.py +0 -0
  75. orionis/services/environment/validators/key_name.py +46 -0
  76. orionis/services/environment/validators/types.py +45 -0
  77. orionis/services/system/contracts/imports.py +38 -18
  78. orionis/services/system/contracts/workers.py +29 -12
  79. orionis/services/system/imports.py +65 -25
  80. orionis/services/system/runtime/imports.py +18 -9
  81. orionis/services/system/workers.py +49 -16
  82. orionis/support/entities/__init__.py +0 -0
  83. orionis/support/entities/base.py +104 -0
  84. orionis/support/facades/testing.py +15 -0
  85. orionis/support/facades/workers.py +1 -1
  86. orionis/test/cases/asynchronous.py +0 -11
  87. orionis/test/cases/synchronous.py +0 -9
  88. orionis/test/contracts/dumper.py +11 -4
  89. orionis/test/contracts/kernel.py +5 -110
  90. orionis/test/contracts/logs.py +27 -65
  91. orionis/test/contracts/printer.py +16 -128
  92. orionis/test/contracts/test_result.py +100 -0
  93. orionis/test/contracts/unit_test.py +87 -150
  94. orionis/test/core/unit_test.py +608 -554
  95. orionis/test/entities/result.py +22 -2
  96. orionis/test/enums/__init__.py +0 -2
  97. orionis/test/enums/status.py +14 -9
  98. orionis/test/exceptions/config.py +9 -1
  99. orionis/test/exceptions/failure.py +34 -11
  100. orionis/test/exceptions/persistence.py +10 -2
  101. orionis/test/exceptions/runtime.py +9 -1
  102. orionis/test/exceptions/value.py +13 -1
  103. orionis/test/kernel.py +87 -289
  104. orionis/test/output/dumper.py +83 -18
  105. orionis/test/output/printer.py +399 -156
  106. orionis/test/records/logs.py +203 -82
  107. orionis/test/validators/__init__.py +33 -0
  108. orionis/test/validators/base_path.py +45 -0
  109. orionis/test/validators/execution_mode.py +45 -0
  110. orionis/test/validators/fail_fast.py +37 -0
  111. orionis/test/validators/folder_path.py +34 -0
  112. orionis/test/validators/module_name.py +31 -0
  113. orionis/test/validators/name_pattern.py +40 -0
  114. orionis/test/validators/pattern.py +36 -0
  115. orionis/test/validators/persistent.py +42 -0
  116. orionis/test/validators/persistent_driver.py +43 -0
  117. orionis/test/validators/print_result.py +37 -0
  118. orionis/test/validators/tags.py +37 -0
  119. orionis/test/validators/throw_exception.py +39 -0
  120. orionis/test/validators/verbosity.py +37 -0
  121. orionis/test/validators/web_report.py +35 -0
  122. orionis/test/validators/workers.py +31 -0
  123. orionis/test/view/render.py +48 -54
  124. {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/METADATA +1 -1
  125. {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/RECORD +170 -112
  126. tests/container/__init__.py +0 -0
  127. tests/container/context/__init__.py +0 -0
  128. tests/container/context/test_manager.py +27 -0
  129. tests/container/context/test_scope.py +23 -0
  130. tests/container/entities/__init__.py +0 -0
  131. tests/container/entities/test_binding.py +133 -0
  132. tests/container/enums/__init__.py +0 -0
  133. tests/container/enums/test_lifetimes.py +63 -0
  134. tests/container/facades/__init__.py +0 -0
  135. tests/container/facades/test_facade.py +61 -0
  136. tests/container/mocks/__init__.py +0 -0
  137. tests/container/mocks/mock_complex_classes.py +482 -0
  138. tests/container/mocks/mock_simple_classes.py +32 -0
  139. tests/container/providers/__init__.py +0 -0
  140. tests/container/providers/test_providers.py +48 -0
  141. tests/container/resolver/__init__.py +0 -0
  142. tests/container/resolver/test_resolver.py +55 -0
  143. tests/container/test_container.py +254 -0
  144. tests/container/test_singleton.py +98 -0
  145. tests/container/test_thread_safety.py +217 -0
  146. tests/container/validators/__init__.py +0 -0
  147. tests/container/validators/test_implements.py +140 -0
  148. tests/container/validators/test_is_abstract_class.py +99 -0
  149. tests/container/validators/test_is_callable.py +73 -0
  150. tests/container/validators/test_is_concrete_class.py +97 -0
  151. tests/container/validators/test_is_instance.py +105 -0
  152. tests/container/validators/test_is_not_subclass.py +117 -0
  153. tests/container/validators/test_is_subclass.py +115 -0
  154. tests/container/validators/test_is_valid_alias.py +113 -0
  155. tests/container/validators/test_lifetime.py +75 -0
  156. tests/example/test_example.py +2 -2
  157. tests/foundation/config/testing/test_foundation_config_testing.py +1 -1
  158. tests/metadata/test_metadata_framework.py +89 -24
  159. tests/metadata/test_metadata_package.py +55 -10
  160. tests/services/asynchrony/test_services_asynchrony_coroutine.py +52 -7
  161. tests/services/system/test_services_system_imports.py +119 -16
  162. tests/services/system/test_services_system_workers.py +71 -30
  163. tests/testing/test_testing_result.py +117 -117
  164. tests/testing/test_testing_unit.py +209 -209
  165. orionis/foundation/config/base.py +0 -112
  166. orionis/test/arguments/parser.py +0 -187
  167. orionis/test/contracts/parser.py +0 -43
  168. orionis/test/entities/arguments.py +0 -38
  169. orionis/test/enums/execution_mode.py +0 -16
  170. /orionis/{test/arguments → console/base/contracts}/__init__.py +0 -0
  171. /orionis/foundation/config/testing/enums/{test_mode.py → mode.py} +0 -0
  172. {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/WHEEL +0 -0
  173. {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/licenses/LICENCE +0 -0
  174. {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/top_level.txt +0 -0
  175. {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/zip-safe +0 -0
@@ -1,141 +1,171 @@
1
- from dataclasses import asdict, dataclass, field, fields
1
+ from dataclasses import dataclass, field
2
2
  from orionis.foundation.config.app.enums import Cipher, Environments
3
3
  from orionis.foundation.exceptions import OrionisIntegrityException
4
4
  from orionis.services.environment.env import Env
5
+ from orionis.services.environment.key.key_generator import SecureKeyGenerator
5
6
  from orionis.services.system.workers import Workers
7
+ from orionis.support.entities.base import BaseEntity
6
8
 
7
9
  @dataclass(unsafe_hash=True, kw_only=True)
8
- class App:
10
+ class App(BaseEntity):
9
11
  """
10
- Represents the configuration settings for the application.
11
- Attributes:
12
- name (str): The name of the application. Defaults to 'Orionis Application'.
13
- env (Environments): The environment in which the application is running. Defaults to 'DEVELOPMENT'.
14
- debug (bool): Flag indicating whether debug mode is enabled. Defaults to True.
15
- url (str): The base URL of the application. Defaults to 'http://127.0.0.1'.
16
- port (int): The port on which the application will run. Defaults to 8000.
17
- workers (int): The number of worker processes to handle requests. Defaults to the maximum available workers.
18
- reload (bool): Flag indicating whether the application should reload on code changes. Defaults to True.
19
- timezone (str): The timezone of the application. Defaults to 'UTC'.
20
- locale (str): The locale for the application. Defaults to 'en'.
21
- fallback_locale (str): The fallback locale for the application. Defaults to 'en'.
22
- cipher (Cipher): The cipher used for encryption. Defaults to 'AES_256_CBC'.
23
- key (str or None): The encryption key for the application. Defaults to None.
24
- maintenance (Maintenance): The maintenance configuration for the application. Defaults to '/maintenance'.
25
- Methods:
26
- __post_init__():
12
+ Application configuration settings.
13
+
14
+ Parameters
15
+ ----------
16
+ name : str, optional
17
+ The name of the application. Default is 'Orionis Application'.
18
+ env : str or Environments, optional
19
+ The environment in which the application is running. Default is 'DEVELOPMENT'.
20
+ debug : bool, optional
21
+ Whether debug mode is enabled. Default is True.
22
+ url : str, optional
23
+ The base URL of the application. Default is 'http://127.0.0.1'.
24
+ port : int, optional
25
+ The port on which the application will run. Default is 8000.
26
+ workers : int, optional
27
+ Number of worker processes to handle requests. Default is maximum available workers.
28
+ reload : bool, optional
29
+ Whether the application should reload on code changes. Default is True.
30
+ timezone : str, optional
31
+ The timezone of the application. Default is 'UTC'.
32
+ locale : str, optional
33
+ The locale for the application. Default is 'en'.
34
+ fallback_locale : str, optional
35
+ The fallback locale for the application. Default is 'en'.
36
+ cipher : str or Cipher, optional
37
+ The cipher used for encryption. Default is 'AES_256_CBC'.
38
+ key : str, optional
39
+ The encryption key for the application. Default is None.
40
+ maintenance : str, optional
41
+ The maintenance route for the application. Default is '/maintenance'.
42
+
43
+ Methods
44
+ -------
45
+ __post_init__()
46
+ Validates and normalizes the attributes after dataclass initialization.
27
47
  """
28
48
 
29
49
  name: str = field(
30
- default_factory=lambda: Env.get('APP_NAME', 'Orionis Application'),
31
- metadata={
50
+ default = Env.get('APP_NAME', 'Orionis Application'),
51
+ metadata = {
32
52
  "description": "The name of the application. Defaults to 'Orionis Application'.",
33
- "default": "Orionis Application"
53
+ "default": 'Orionis Application'
34
54
  }
35
55
  )
36
56
 
37
57
  env: str | Environments = field(
38
- default_factory=lambda: Env.get('APP_ENV', Environments.DEVELOPMENT),
39
- metadata={
58
+ default = Env.get('APP_ENV', Environments.DEVELOPMENT.value),
59
+ metadata = {
40
60
  "description": "The environment in which the application is running. Defaults to 'DEVELOPMENT'.",
41
- "default": "Environments.DEVELOPMENT"
61
+ "default": Environments.DEVELOPMENT.value
42
62
  }
43
63
  )
44
64
 
45
65
  debug: bool = field(
46
- default_factory=lambda: Env.get('APP_DEBUG', True),
47
- metadata={
66
+ default = Env.get('APP_DEBUG', True),
67
+ metadata = {
48
68
  "description": "Flag indicating whether debug mode is enabled. Defaults to False.",
49
69
  "default": True
50
70
  }
51
71
  )
52
72
 
53
73
  url: str = field(
54
- default_factory=lambda: Env.get('APP_URL', 'http://127.0.0.1'),
55
- metadata={
74
+ default = Env.get('APP_URL', 'http://127.0.0.1'),
75
+ metadata = {
56
76
  "description": "The base URL of the application. Defaults to 'http://127.0.0.1'.",
57
- "default": "http://127.0.0.1"
77
+ "default": 'http://127.0.0.1'
58
78
  }
59
79
  )
60
80
 
61
81
  port: int = field(
62
- default_factory=lambda: Env.get('APP_PORT', 8000),
63
- metadata={
82
+ default = Env.get('APP_PORT', 8000),
83
+ metadata = {
64
84
  "description": "The port on which the application will run. Defaults to 8000.",
65
85
  "default": 8000
66
86
  }
67
87
  )
68
88
 
69
89
  workers: int = field(
70
- default_factory=lambda: Env.get('APP_WORKERS', Workers().calculate()),
71
- metadata={
90
+ default = Env.get('APP_WORKERS', Workers().calculate()),
91
+ metadata = {
72
92
  "description": "The number of worker processes to handle requests. Defaults to the maximum available workers.",
73
- "default": "Calculated by Workers()."
93
+ "default": Workers().calculate()
74
94
  }
75
95
  )
76
96
 
77
97
  reload: bool = field(
78
- default_factory=lambda: Env.get('APP_RELOAD', True),
79
- metadata={
98
+ default = Env.get('APP_RELOAD', True),
99
+ metadata = {
80
100
  "description": "Flag indicating whether the application should reload on code changes. Defaults to True.",
81
101
  "default": True
82
102
  }
83
103
  )
84
104
 
85
105
  timezone: str = field(
86
- default_factory=lambda: Env.get('APP_TIMEZONE', 'UTC'),
87
- metadata={
106
+ default = Env.get('APP_TIMEZONE', 'UTC'),
107
+ metadata = {
88
108
  "description": "The timezone of the application. Defaults to 'UTC'.",
89
- "default": "UTC"
109
+ "default": 'UTC'
90
110
  }
91
111
  )
92
112
 
93
113
  locale: str = field(
94
- default_factory=lambda: Env.get('APP_LOCALE', 'en'),
95
- metadata={
114
+ default = Env.get('APP_LOCALE', 'en'),
115
+ metadata = {
96
116
  "description": "The locale for the application. Defaults to 'en'.",
97
- "default": "en"
117
+ "default": 'en'
98
118
  }
99
119
  )
100
120
 
101
121
  fallback_locale: str = field(
102
- default_factory=lambda: Env.get('APP_FALLBACK_LOCALE', 'en'),
103
- metadata={
122
+ default = Env.get('APP_FALLBACK_LOCALE', 'en'),
123
+ metadata = {
104
124
  "description": "The fallback locale for the application. Defaults to 'en'.",
105
- "default": "en"
125
+ "default": 'en'
106
126
  }
107
127
  )
108
128
 
109
129
  cipher: str | Cipher = field(
110
- default_factory=lambda: Env.get('APP_CIPHER', Cipher.AES_256_CBC),
111
- metadata={
130
+ default = Env.get('APP_CIPHER', Cipher.AES_256_CBC.value),
131
+ metadata = {
112
132
  "description": "The cipher used for encryption. Defaults to 'AES_256_CBC'.",
113
- "default": "Cipher.AES_256_CBC"
133
+ "default": Cipher.AES_256_CBC.value
114
134
  }
115
135
  )
116
136
 
117
137
  key: str = field(
118
- default_factory=lambda: Env.get('APP_KEY'),
119
- metadata={
138
+ default = Env.get('APP_KEY'),
139
+ metadata = {
120
140
  "description": "The encryption key for the application. Defaults to None.",
121
141
  "default": None
122
142
  }
123
143
  )
124
144
 
125
145
  maintenance: str = field(
126
- default_factory=lambda: Env.get('APP_MAINTENANCE', '/maintenance'),
127
- metadata={
146
+ default = Env.get('APP_MAINTENANCE', '/maintenance'),
147
+ metadata = {
128
148
  "description": "The maintenance configuration for the application. Defaults to '/maintenance'.",
129
- "default": "/maintenance"
149
+ "default": '/maintenance'
130
150
  }
131
151
  )
132
152
 
133
153
  def __post_init__(self):
134
154
  """
135
- Validates and normalizes the attributes after dataclass initialization.
155
+ Validate and normalize attributes after dataclass initialization.
156
+
157
+ This method checks that all configuration fields have the correct types and valid values.
158
+ If any field is invalid, an OrionisIntegrityException is raised to prevent misconfiguration.
136
159
 
137
- Ensures that all fields have the correct types and values, raising TypeError
138
- if any field is invalid. This helps catch configuration errors early.
160
+ Raises
161
+ ------
162
+ OrionisIntegrityException
163
+ If any attribute does not meet the required type or value constraints.
164
+
165
+ Notes
166
+ -----
167
+ This method is automatically called after the dataclass is instantiated to ensure
168
+ application configuration integrity and catch errors early in the lifecycle.
139
169
  """
140
170
 
141
171
  # Validate `name` attribute
@@ -153,30 +183,43 @@ class App:
153
183
  elif isinstance(self.env, Environments):
154
184
  self.env = self.env.value
155
185
 
186
+ # Validate `debug` attribute
156
187
  if not isinstance(self.debug, bool):
157
188
  raise OrionisIntegrityException("The 'debug' attribute must be a boolean.")
158
189
 
190
+ # Validate `url` attribute
159
191
  if not isinstance(self.url, str) or not self.url.strip():
160
192
  raise OrionisIntegrityException("The 'url' attribute must be a non-empty string.")
161
193
 
194
+ # Validate `port` attribute
162
195
  if not isinstance(self.port, int):
163
196
  raise OrionisIntegrityException("The 'port' attribute must be an integer.")
164
197
 
198
+ # Validate `workers` attribute
165
199
  if not isinstance(self.workers, int):
166
200
  raise OrionisIntegrityException("The 'workers' attribute must be an integer.")
167
201
 
202
+ real_workers = Workers().calculate()
203
+ if self.workers < 1 or self.workers > real_workers:
204
+ raise OrionisIntegrityException(f"The 'workers' attribute must be between 1 and {real_workers}.")
205
+
206
+ # Validate `reload` attribute
168
207
  if not isinstance(self.reload, bool):
169
208
  raise OrionisIntegrityException("The 'reload' attribute must be a boolean.")
170
209
 
210
+ # Validate `timezone` attribute
171
211
  if not isinstance(self.timezone, str) or not self.timezone.strip():
172
212
  raise OrionisIntegrityException("The 'timezone' attribute must be a non-empty string.")
173
213
 
214
+ # Validate `locale` attribute
174
215
  if not isinstance(self.locale, str) or not self.locale.strip():
175
216
  raise OrionisIntegrityException("The 'locale' attribute must be a non-empty string.")
176
217
 
218
+ # Validate `fallback_locale` attribute
177
219
  if not isinstance(self.fallback_locale, str) or not self.fallback_locale.strip():
178
220
  raise OrionisIntegrityException("The 'fallback_locale' attribute must be a non-empty string.")
179
221
 
222
+ # Validate `cipher` attribute
180
223
  options_cipher = Cipher._member_names_
181
224
  if not isinstance(self.cipher, (Cipher, str)):
182
225
  raise OrionisIntegrityException("The 'cipher' attribute must be a Cipher or a string.")
@@ -190,38 +233,12 @@ class App:
190
233
  elif isinstance(self.cipher, Cipher):
191
234
  self.cipher = self.cipher.value
192
235
 
193
- if self.key is not None and not isinstance(self.key, str):
194
- raise OrionisIntegrityException("The 'key' attribute must be a string or None.")
236
+ # Validate `key` attribute
237
+ if self.key is None:
238
+ self.key = SecureKeyGenerator.generate()
239
+ if not isinstance(self.key, str):
240
+ raise OrionisIntegrityException("The 'key' attribute must be a string.")
195
241
 
242
+ # Validate `maintenance` attribute
196
243
  if not isinstance(self.maintenance, str) or not self.name.strip() or not self.maintenance.startswith('/'):
197
- raise OrionisIntegrityException("The 'maintenance' attribute must be a non-empty string representing a valid route (e.g., '/maintenance').")
198
-
199
- def toDict(self) -> dict:
200
- """
201
- Convert the object to a dictionary representation.
202
- Returns:
203
- dict: A dictionary representation of the Dataclass object.
204
- """
205
- return asdict(self)
206
-
207
- def getFields(self):
208
- """
209
- Retrieves a list of field information for the current dataclass instance.
210
-
211
- Returns:
212
- list: A list of dictionaries, each containing details about a field:
213
- - name (str): The name of the field.
214
- - type (type): The type of the field.
215
- - default: The default value of the field, if specified; otherwise, the value from metadata or None.
216
- - metadata (mapping): The metadata associated with the field.
217
- """
218
- __fields = []
219
- for field in fields(self):
220
- __metadata = dict(field.metadata) or {}
221
- __fields.append({
222
- "name": field.name,
223
- "type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
224
- "default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
225
- "metadata": __metadata
226
- })
227
- return __fields
244
+ raise OrionisIntegrityException("The 'maintenance' attribute must be a non-empty string representing a valid route (e.g., '/maintenance').")
@@ -1,41 +1,12 @@
1
- from dataclasses import asdict, dataclass, fields
1
+ from dataclasses import dataclass
2
+ from orionis.support.entities.base import BaseEntity
2
3
 
3
4
  @dataclass(unsafe_hash=True, kw_only=True)
4
- class Auth:
5
+ class Auth(BaseEntity):
5
6
  """
6
7
  Represents the authentication entity within the system.
7
8
 
8
9
  This class serves as a placeholder for authentication-related attributes and methods.
9
10
  Extend this class to implement authentication logic such as user credentials, token management, or session handling.
10
11
  """
11
- pass
12
-
13
- def toDict(self) -> dict:
14
- """
15
- Convert the object to a dictionary representation.
16
- Returns:
17
- dict: A dictionary representation of the Dataclass object.
18
- """
19
- return asdict(self)
20
-
21
- def getFields(self):
22
- """
23
- Retrieves a list of field information for the current dataclass instance.
24
-
25
- Returns:
26
- list: A list of dictionaries, each containing details about a field:
27
- - name (str): The name of the field.
28
- - type (type): The type of the field.
29
- - default: The default value of the field, if specified; otherwise, the value from metadata or None.
30
- - metadata (mapping): The metadata associated with the field.
31
- """
32
- __fields = []
33
- for field in fields(self):
34
- __metadata = dict(field.metadata) or {}
35
- __fields.append({
36
- "name": field.name,
37
- "type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
38
- "default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
39
- "metadata": __metadata
40
- })
41
- return __fields
12
+ pass
@@ -1,18 +1,21 @@
1
- from dataclasses import asdict, dataclass, field, fields
1
+ from dataclasses import dataclass, field
2
2
  from orionis.foundation.config.cache.entities.stores import Stores
3
3
  from orionis.foundation.config.cache.enums import Drivers
4
4
  from orionis.foundation.exceptions import OrionisIntegrityException
5
5
  from orionis.services.environment.env import Env
6
+ from orionis.support.entities.base import BaseEntity
6
7
 
7
8
  @dataclass(unsafe_hash=True, kw_only=True)
8
- class Cache:
9
+ class Cache(BaseEntity):
9
10
  """
10
11
  Represents the cache configuration for the application.
12
+
11
13
  Attributes:
12
14
  default (Drivers | str): The default cache storage type. Can be a member of the Drivers enum or a string
13
15
  (e.g., 'memory', 'file'). Defaults to the value of the 'CACHE_STORE' environment variable or Drivers.MEMORY.
14
16
  stores (Stores): The configuration for available cache stores. Defaults to a Stores instance with a file store
15
17
  at the path specified by the 'CACHE_PATH' environment variable or "storage/framework/cache/data".
18
+
16
19
  Methods:
17
20
  __post_init__():
18
21
  - Validates that 'default' is either a Drivers enum member or a string.
@@ -21,28 +24,30 @@ class Cache:
21
24
  """
22
25
 
23
26
  default: Drivers | str = field(
24
- default_factory=lambda:Env.get("CACHE_STORE", Drivers.MEMORY),
25
- metadata={
27
+ default_factory = lambda : Env.get("CACHE_STORE", Drivers.MEMORY),
28
+ metadata = {
26
29
  "description": "The default cache storage type. Can be a member of the Drivers enum or a string (e.g., 'memory', 'file').",
27
- "default": "Drivers.MEMORY",
30
+ "default": Drivers.MEMORY.value
28
31
  },
29
32
  )
30
33
 
31
- stores: Stores = field(
32
- default_factory=Stores,
33
- metadata={
34
+ stores: Stores | dict = field(
35
+ default_factory = lambda: Stores(),
36
+ metadata = {
34
37
  "description": "The configuration for available cache stores. Defaults to a file store at the specified path.",
35
- "default": "file=File(path='storage/framework/cache/data')",
38
+ "default": lambda: Stores().toDict()
36
39
  }
37
40
  )
38
41
 
39
42
  def __post_init__(self):
40
43
  """
41
44
  Post-initialization method for validating and normalizing cache configuration.
45
+
42
46
  Ensures that:
43
47
  - The `default` attribute is either an instance of `Drivers` or a string representing a valid driver name.
44
48
  - If `default` is a string, it is converted to the corresponding `Drivers` enum member after validation.
45
49
  - The `stores` attribute is an instance of `Stores`.
50
+
46
51
  Raises:
47
52
  OrionisIntegrityException: If `default` is not a valid driver or if `stores` is not an instance of `Stores`.
48
53
  """
@@ -62,35 +67,7 @@ class Cache:
62
67
  self.default = self.default.value
63
68
 
64
69
  # Validate the 'stores' attribute to ensure it is an instance of Stores
65
- if not isinstance(self.stores, Stores):
66
- raise OrionisIntegrityException("The stores must be an instance of Stores.")
67
-
68
- def toDict(self) -> dict:
69
- """
70
- Convert the object to a dictionary representation.
71
- Returns:
72
- dict: A dictionary representation of the Dataclass object.
73
- """
74
- return asdict(self)
75
-
76
- def getFields(self):
77
- """
78
- Retrieves a list of field information for the current dataclass instance.
79
-
80
- Returns:
81
- list: A list of dictionaries, each containing details about a field:
82
- - name (str): The name of the field.
83
- - type (type): The type of the field.
84
- - default: The default value of the field, if specified; otherwise, the value from metadata or None.
85
- - metadata (mapping): The metadata associated with the field.
86
- """
87
- __fields = []
88
- for field in fields(self):
89
- __metadata = dict(field.metadata) or {}
90
- __fields.append({
91
- "name": field.name,
92
- "type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
93
- "default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
94
- "metadata": __metadata
95
- })
96
- return __fields
70
+ if not isinstance(self.stores, (Stores, dict)):
71
+ raise OrionisIntegrityException("The stores configuration must be an instance of Stores or a dictionary.")
72
+ if isinstance(self.stores, dict):
73
+ self.stores = Stores(**self.stores)
@@ -1,13 +1,16 @@
1
- from dataclasses import asdict, dataclass, field, fields
1
+ from dataclasses import dataclass, field
2
2
  from orionis.foundation.exceptions import OrionisIntegrityException
3
+ from orionis.support.entities.base import BaseEntity
3
4
 
4
5
  @dataclass(unsafe_hash=True, kw_only=True)
5
- class File:
6
+ class File(BaseEntity):
6
7
  """
7
8
  Represents the configuration entity for a file-based cache store.
9
+
8
10
  Attributes:
9
11
  path (str): The file system path where cache data will be stored. By default, this is set to
10
12
  'storage/framework/cache/data' using a relative path resolver.
13
+
11
14
  Methods:
12
15
  __post_init__():
13
16
  Validates the 'path' attribute after dataclass initialization. Raises an
@@ -15,8 +18,8 @@ class File:
15
18
  """
16
19
 
17
20
  path: str = field(
18
- default='storage/framework/cache/data',
19
- metadata={
21
+ default = 'storage/framework/cache/data',
22
+ metadata = {
20
23
  "description": "The configuration for available cache stores. Defaults to a file store at the specified path.",
21
24
  "default": "storage/framework/cache/data"
22
25
  },
@@ -35,34 +38,4 @@ class File:
35
38
  if not self.path:
36
39
  raise OrionisIntegrityException("File cache configuration error: 'path' cannot be empty. Please provide a valid file path.")
37
40
  if not isinstance(self.path, str):
38
- raise OrionisIntegrityException(f"File cache configuration error: 'path' must be a string, got {type(self.path).__name__}.")
39
-
40
- def toDict(self) -> dict:
41
- """
42
- Convert the object to a dictionary representation.
43
- Returns:
44
- dict: A dictionary representation of the Dataclass object.
45
- """
46
- return asdict(self)
47
-
48
- def getFields(self):
49
- """
50
- Retrieves a list of field information for the current dataclass instance.
51
-
52
- Returns:
53
- list: A list of dictionaries, each containing details about a field:
54
- - name (str): The name of the field.
55
- - type (type): The type of the field.
56
- - default: The default value of the field, if specified; otherwise, the value from metadata or None.
57
- - metadata (mapping): The metadata associated with the field.
58
- """
59
- __fields = []
60
- for field in fields(self):
61
- __metadata = dict(field.metadata) or {}
62
- __fields.append({
63
- "name": field.name,
64
- "type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
65
- "default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
66
- "metadata": __metadata
67
- })
68
- return __fields
41
+ raise OrionisIntegrityException(f"File cache configuration error: 'path' must be a string, got {type(self.path).__name__}.")
@@ -1,26 +1,29 @@
1
- from dataclasses import asdict, dataclass, field, fields
1
+ from dataclasses import dataclass, field
2
2
  from orionis.foundation.config.cache.entities.file import File
3
3
  from orionis.foundation.exceptions import OrionisIntegrityException
4
+ from orionis.support.entities.base import BaseEntity
4
5
 
5
6
  @dataclass(unsafe_hash=True, kw_only=True)
6
- class Stores:
7
+ class Stores(BaseEntity):
7
8
  """
8
9
  Represents a collection of cache storage backends for the application.
10
+
9
11
  Attributes:
10
12
  file (File): An instance of `File` representing file-based cache storage.
11
13
  The default path is set to 'storage/framework/cache/data', resolved
12
14
  relative to the application's root directory.
15
+
13
16
  Methods:
14
17
  __post_init__():
15
18
  Ensures that the 'file' attribute is properly initialized as an instance of `File`.
16
19
  Raises a TypeError if the type check fails.
17
20
  """
18
21
 
19
- file: File = field(
20
- default_factory=File,
21
- metadata={
22
+ file: File | dict = field(
23
+ default_factory = lambda: File(),
24
+ metadata = {
22
25
  "description": "An instance of `File` representing file-based cache storage.",
23
- "default": "File(path='storage/framework/cache/data')",
26
+ "default": lambda: File().toDict()
24
27
  },
25
28
  )
26
29
 
@@ -29,40 +32,16 @@ class Stores:
29
32
  Post-initialization method to validate the 'file' attribute.
30
33
 
31
34
  Ensures that the 'file' attribute is an instance of the File class.
35
+
32
36
  Raises:
33
37
  OrionisIntegrityException: If 'file' is not an instance of File, with a descriptive error message.
34
38
  """
35
- if not isinstance(self.file, File):
39
+
40
+ # Validate `file` atribute
41
+ if not isinstance(self.file, (File, dict)):
36
42
  raise OrionisIntegrityException(
37
- f"The 'file' attribute must be an instance of File, but got {type(self.file).__name__}."
43
+ f"The 'file' attribute must be an instance of File or a dict, "
44
+ f"but got {type(self.file).__name__}."
38
45
  )
39
-
40
- def toDict(self) -> dict:
41
- """
42
- Convert the object to a dictionary representation.
43
- Returns:
44
- dict: A dictionary representation of the Dataclass object.
45
- """
46
- return asdict(self)
47
-
48
- def getFields(self):
49
- """
50
- Retrieves a list of field information for the current dataclass instance.
51
-
52
- Returns:
53
- list: A list of dictionaries, each containing details about a field:
54
- - name (str): The name of the field.
55
- - type (type): The type of the field.
56
- - default: The default value of the field, if specified; otherwise, the value from metadata or None.
57
- - metadata (mapping): The metadata associated with the field.
58
- """
59
- __fields = []
60
- for field in fields(self):
61
- __metadata = dict(field.metadata) or {}
62
- __fields.append({
63
- "name": field.name,
64
- "type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
65
- "default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
66
- "metadata": __metadata
67
- })
68
- return __fields
46
+ if isinstance(self.file, dict):
47
+ self.file = File(**self.file)