coregen-cli 3.1.6__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.
- coregen.py +1585 -0
- coregen_cli-3.1.6.dist-info/METADATA +1211 -0
- coregen_cli-3.1.6.dist-info/RECORD +172 -0
- coregen_cli-3.1.6.dist-info/WHEEL +5 -0
- coregen_cli-3.1.6.dist-info/entry_points.txt +2 -0
- coregen_cli-3.1.6.dist-info/top_level.txt +2 -0
- generators/__init__.py +1 -0
- generators/assets/__init__.py +1 -0
- generators/assets/assets.py +30 -0
- generators/assets/main.py +4 -0
- generators/config/__init__.py +1 -0
- generators/config/analisy_options.py +42 -0
- generators/config/main.py +11 -0
- generators/config/pubspec.py +139 -0
- generators/cursor/__init__.py +3 -0
- generators/cursor/setup.py +87 -0
- generators/helpers/__init__.py +56 -0
- generators/helpers/component.py +1030 -0
- generators/helpers/config.py +255 -0
- generators/helpers/data_source.py +180 -0
- generators/helpers/domain.py +469 -0
- generators/helpers/feature.py +654 -0
- generators/helpers/navigation.py +274 -0
- generators/helpers/page.py +63 -0
- generators/helpers/project.py +33 -0
- generators/helpers/utils.py +338 -0
- generators/helpers/validation.py +364 -0
- generators/initializator.py +68 -0
- generators/main.py +81 -0
- generators/static/assets/logo.png +0 -0
- generators/static/assets/mock/auth_user.json +5 -0
- generators/static/assets/svgs/apple.svg +4 -0
- generators/static/assets/svgs/google.svg +2 -0
- generators/static/cursor/AGENTS.md.jinja +37 -0
- generators/static/cursor/agents/doc-writer.md +20 -0
- generators/static/cursor/agents/epic-orchestrator.md +28 -0
- generators/static/cursor/agents/feature-implementer.md +29 -0
- generators/static/cursor/agents/integration-wiring.md +30 -0
- generators/static/cursor/agents/layer-application.md +21 -0
- generators/static/cursor/agents/layer-guardian.md +21 -0
- generators/static/cursor/agents/layer-infrastructure.md +31 -0
- generators/static/cursor/agents/layer-model.md +24 -0
- generators/static/cursor/agents/layer-presentation.md +33 -0
- generators/static/cursor/docs/architecture/APIS_AND_INTEGRATION.md.jinja +42 -0
- generators/static/cursor/docs/architecture/CARAVAGGIO_COMPONENTS.md.jinja +317 -0
- generators/static/cursor/docs/architecture/DDD_LAYERS.md.jinja +32 -0
- generators/static/cursor/docs/architecture/FILE_TEMPLATES.md.jinja +76 -0
- generators/static/cursor/docs/architecture/MOCK_AND_REMOTE_DATA.md.jinja +87 -0
- generators/static/cursor/docs/architecture/REFERENCE_IMPLEMENTATIONS.md.jinja +48 -0
- generators/static/cursor/docs/architecture/WIDGETS_AND_CARAVAGGIO.md.jinja +76 -0
- generators/static/cursor/docs/epics/README.md +17 -0
- generators/static/cursor/lib/domain/AGENTS.md +23 -0
- generators/static/cursor/lib/features/AGENTS.md +23 -0
- generators/static/cursor/lib/widgets/AGENTS.md +21 -0
- generators/static/cursor/rules/apis-layer.mdc.jinja +21 -0
- generators/static/cursor/rules/application-layer.mdc.jinja +12 -0
- generators/static/cursor/rules/architecture-core.mdc.jinja +43 -0
- generators/static/cursor/rules/dart-conventions.mdc.jinja +14 -0
- generators/static/cursor/rules/domain-layer.mdc.jinja +24 -0
- generators/static/cursor/rules/login-context.mdc.jinja +16 -0
- generators/static/cursor/rules/presentation-layer.mdc.jinja +15 -0
- generators/static/cursor/rules/quality-gate.mdc.jinja +14 -0
- generators/static/cursor/rules/ui-caravaggio.mdc.jinja +22 -0
- generators/static/cursor/skills/caravaggio-ui/SKILL.md +138 -0
- generators/static/cursor/skills/epic-delivery/SKILL.md +74 -0
- generators/static/cursor/skills/epic-delivery/templates/epic-status.md +14 -0
- generators/static/cursor/skills/epic-delivery/templates/epic.md +36 -0
- generators/static/templates/apis/common/constants_template.jinja +48 -0
- generators/static/templates/apis/common/data_source_config_template.jinja +47 -0
- generators/static/templates/apis/core/api_injectable_module_template.jinja +14 -0
- generators/static/templates/apis/interceptors/api_logger_template.jinja +135 -0
- generators/static/templates/apis/interceptors/auth_interceptor_template.jinja +207 -0
- generators/static/templates/auth/application/auth_bloc_template.jinja +36 -0
- generators/static/templates/auth/application/auth_event_template.jinja +7 -0
- generators/static/templates/auth/application/auth_state_template.jinja +8 -0
- generators/static/templates/auth/infrastructure/auth_facade_module_template.jinja +16 -0
- generators/static/templates/auth/infrastructure/auth_facade_template.jinja +288 -0
- generators/static/templates/auth/infrastructure/mock_auth_facade_template.jinja +106 -0
- generators/static/templates/auth/model/auth_failure_template.jinja +11 -0
- generators/static/templates/auth/model/i_auth_facade_template.jinja +24 -0
- generators/static/templates/auth/model/user_template.jinja +34 -0
- generators/static/templates/auth/model/value_objects_template.jinja +54 -0
- generators/static/templates/auth/presentation/login_screen_template.jinja +24 -0
- generators/static/templates/auth/sign_in_form/application/sign_in_form_bloc_template.jinja +139 -0
- generators/static/templates/auth/sign_in_form/application/sign_in_form_event_template.jinja +15 -0
- generators/static/templates/auth/sign_in_form/application/sign_in_form_state_template.jinja +26 -0
- generators/static/templates/auth/sign_in_form/presentation/apple_form_template.jinja +16 -0
- generators/static/templates/auth/sign_in_form/presentation/email_password_form_template_INACTIVE.jinja +94 -0
- generators/static/templates/auth/sign_in_form/presentation/google_form_template.jinja +15 -0
- generators/static/templates/auth/sign_in_form/presentation/sign_in_form_template.jinja +381 -0
- generators/static/templates/component/component_bloc_template.jinja +49 -0
- generators/static/templates/component/component_event_template.jinja +7 -0
- generators/static/templates/component/component_form_bloc_template.jinja +56 -0
- generators/static/templates/component/component_form_event_template.jinja +7 -0
- generators/static/templates/component/component_form_state_template.jinja +18 -0
- generators/static/templates/component/component_form_widget_template.jinja +130 -0
- generators/static/templates/component/component_list_widget_template.jinja +95 -0
- generators/static/templates/component/component_state_template.jinja +9 -0
- generators/static/templates/component/component_widget_template.jinja +113 -0
- generators/static/templates/core/bloc/base_form_bloc_template.jinja +32 -0
- generators/static/templates/core/errors/error_localizer_template.jinja +61 -0
- generators/static/templates/core/infrastructure/base_mapper_template.jinja +21 -0
- generators/static/templates/core/infrastructure/base_repository_mixin_template.jinja +78 -0
- generators/static/templates/core/infrastructure/firebase_injectable_module_template.jinja +11 -0
- generators/static/templates/core/infrastructure/firestore_helpers_template.jinja +22 -0
- generators/static/templates/core/infrastructure/repository_error_handler_template.jinja +44 -0
- generators/static/templates/core/model/common_interfaces_template.jinja +3 -0
- generators/static/templates/core/model/entity_template.jinja +5 -0
- generators/static/templates/core/model/errors_template.jinja +15 -0
- generators/static/templates/core/model/failures_template.jinja +97 -0
- generators/static/templates/core/model/value_objects_template.jinja +135 -0
- generators/static/templates/core/model/value_validators_template.jinja +105 -0
- generators/static/templates/core/presentation/app_drawer_template.jinja +52 -0
- generators/static/templates/core/presentation/app_widget_template.jinja +41 -0
- generators/static/templates/core/presentation/bottom_nav_bar_template.jinja +32 -0
- generators/static/templates/domain/domain_mapper_template.jinja +39 -0
- generators/static/templates/domain/domain_remote_service_template.jinja +46 -0
- generators/static/templates/domain/domain_repository_template.jinja +90 -0
- generators/static/templates/domain/domain_service_module_template.jinja +23 -0
- generators/static/templates/domain/enum_template.jinja +3 -0
- generators/static/templates/domain/i_domain_service_template.jinja +18 -0
- generators/static/templates/domain/mock_domain_service_template.jinja +73 -0
- generators/static/templates/feature/feature_bloc_template.jinja +104 -0
- generators/static/templates/feature/feature_dto_template.jinja +26 -0
- generators/static/templates/feature/feature_entity_template.jinja +23 -0
- generators/static/templates/feature/feature_event_template.jinja +20 -0
- generators/static/templates/feature/feature_extensions_template.jinja +25 -0
- generators/static/templates/feature/feature_failure_template.jinja +11 -0
- generators/static/templates/feature/feature_page_template.jinja +113 -0
- generators/static/templates/feature/feature_repository_template.jinja +112 -0
- generators/static/templates/feature/feature_state_template.jinja +20 -0
- generators/static/templates/feature/i_feature_repository_template.jinja +21 -0
- generators/static/templates/feature/value_object_field_template.jinja +0 -0
- generators/static/templates/feature/value_object_template.jinja +0 -0
- generators/static/templates/feature/value_validators_template.jinja +57 -0
- generators/static/templates/home/home_screen_template.jinja +68 -0
- generators/static/templates/home/presentation/home_screen_template.jinja +52 -0
- generators/static/templates/home/screen_template.jinja +12 -0
- generators/static/templates/injection_template.jinja +8 -0
- generators/static/templates/logging/analytics_logging_template.jinja +42 -0
- generators/static/templates/logging/console_template.jinja +50 -0
- generators/static/templates/logging/logger_injectable_module_template.jinja +24 -0
- generators/static/templates/logging/logger_template.jinja +118 -0
- generators/static/templates/main_template.jinja +43 -0
- generators/static/templates/page_template.jinja +29 -0
- generators/static/templates/router_template.jinja +26 -0
- generators/static/templates/splash/presentation/splash_screen_auth_template.jinja +97 -0
- generators/static/templates/splash/presentation/splash_screen_template.jinja +51 -0
- generators/static/templates/storage/storage_repository_template.jinja +80 -0
- generators/static/templates/user_profile/infrastructure/user_profile_dto_template.jinja +27 -0
- generators/static/templates/user_profile/infrastructure/user_profile_mapper_template.jinja +43 -0
- generators/static/templates/user_profile/infrastructure/user_profile_repository_template.jinja +82 -0
- generators/static/templates/user_profile/infrastructure/user_profile_service_template.jinja +27 -0
- generators/static/templates/user_profile/model/i_user_profile_repository_template.jinja +34 -0
- generators/static/templates/user_profile/model/user_profile_failure_template.jinja +11 -0
- generators/static/templates/user_profile/model/user_profile_template.jinja +31 -0
- generators/static/templates/widgets/common/custom_scaffold_template.jinja +52 -0
- generators/static/templates/widgets/common/error_widget_template.jinja +22 -0
- generators/static/templates/widgets/common/loading_widget_template.jinja +14 -0
- generators/static/templates/widgets/common/unknown_state_widget_template.jinja +23 -0
- generators/templates/__init__.py +1 -0
- generators/templates/_core/core_generator.py +121 -0
- generators/templates/apis/apis_generator.py +50 -0
- generators/templates/auth/auth_generator.py +40 -0
- generators/templates/auth/sign_in_form_generator.py +22 -0
- generators/templates/copier.py +51 -0
- generators/templates/home/home_generator.py +26 -0
- generators/templates/lib/lib_generator.py +40 -0
- generators/templates/logging/logging_generator.py +28 -0
- generators/templates/main.py +75 -0
- generators/templates/splash/splash_generator.py +20 -0
- generators/templates/storage/storage_generator.py +5 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"""Utility functions for CoreGen"""
|
|
2
|
+
|
|
3
|
+
from typing import Optional, Set
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def to_pascal_case(snake_str: str) -> str:
|
|
7
|
+
"""Convert snake_case to PascalCase"""
|
|
8
|
+
return ''.join(word.capitalize() for word in snake_str.split('_'))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def to_camel_case(snake_str: str) -> str:
|
|
12
|
+
"""
|
|
13
|
+
Convert snake_case to camelCase.
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
todo_item → todoItem
|
|
17
|
+
note → note
|
|
18
|
+
"""
|
|
19
|
+
words = snake_str.split('_')
|
|
20
|
+
return words[0] + ''.join(word.capitalize() for word in words[1:])
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def pascal_case_to_camel_case(pascal_str: str) -> str:
|
|
24
|
+
"""
|
|
25
|
+
Convert PascalCase to camelCase.
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
TodoItem → todoItem
|
|
29
|
+
Note → note
|
|
30
|
+
"""
|
|
31
|
+
if not pascal_str:
|
|
32
|
+
return pascal_str
|
|
33
|
+
return pascal_str[0].lower() + pascal_str[1:]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def to_pascal_case_preserve(name: str) -> str:
|
|
37
|
+
"""
|
|
38
|
+
Convert camelCase/snake_case to PascalCase, preserving internal capital letters.
|
|
39
|
+
|
|
40
|
+
- If name is snake_case → uses to_pascal_case()
|
|
41
|
+
- If name is already PascalCase → returns as-is
|
|
42
|
+
- If name is camelCase → converts first letter to uppercase, preserves rest
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
inviteCode → InviteCode
|
|
46
|
+
invite_code → InviteCode
|
|
47
|
+
InviteCode → InviteCode
|
|
48
|
+
userName → UserName
|
|
49
|
+
apiKey → ApiKey
|
|
50
|
+
httpStatusCode → HttpStatusCode
|
|
51
|
+
"""
|
|
52
|
+
if not name:
|
|
53
|
+
return name
|
|
54
|
+
|
|
55
|
+
# Check if already PascalCase (starts with uppercase and has no underscores)
|
|
56
|
+
if name[0].isupper() and '_' not in name:
|
|
57
|
+
return name
|
|
58
|
+
|
|
59
|
+
# Check if snake_case (contains underscores)
|
|
60
|
+
if '_' in name:
|
|
61
|
+
return to_pascal_case(name)
|
|
62
|
+
|
|
63
|
+
# Otherwise, it's camelCase - capitalize first letter, preserve rest
|
|
64
|
+
return name[0].upper() + name[1:] if name else name
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def pascal_case_to_snake_case(pascal_str: str) -> str:
|
|
68
|
+
"""
|
|
69
|
+
Convert PascalCase to snake_case.
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
NoteItem → note_item
|
|
73
|
+
Note → note
|
|
74
|
+
HTTPRequest → http_request
|
|
75
|
+
"""
|
|
76
|
+
if not pascal_str:
|
|
77
|
+
return pascal_str
|
|
78
|
+
|
|
79
|
+
# Insert underscore before uppercase letters (except the first one)
|
|
80
|
+
result = pascal_str[0].lower()
|
|
81
|
+
for char in pascal_str[1:]:
|
|
82
|
+
if char.isupper():
|
|
83
|
+
result += '_' + char.lower()
|
|
84
|
+
else:
|
|
85
|
+
result += char
|
|
86
|
+
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def pascal_case_to_kebab_case(pascal_str: str) -> str:
|
|
91
|
+
"""
|
|
92
|
+
Convert PascalCase to kebab-case.
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
TodoItem → todo-item
|
|
96
|
+
Note → note
|
|
97
|
+
HTTPRequest → http-request
|
|
98
|
+
"""
|
|
99
|
+
if not pascal_str:
|
|
100
|
+
return pascal_str
|
|
101
|
+
|
|
102
|
+
# Insert hyphen before uppercase letters (except the first one)
|
|
103
|
+
result = pascal_str[0].lower()
|
|
104
|
+
for char in pascal_str[1:]:
|
|
105
|
+
if char.isupper():
|
|
106
|
+
result += '-' + char.lower()
|
|
107
|
+
else:
|
|
108
|
+
result += char
|
|
109
|
+
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
PRIMITIVE_TYPES = {'String', 'int', 'double', 'bool', 'DateTime'}
|
|
114
|
+
KNOWN_VALUE_OBJECTS = {'UniqueId'}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def get_form_field_metadata(base_type: str, field_name: str, known_enums: Optional[Set[str]] = None) -> dict:
|
|
118
|
+
"""Return UI-control and code-generation metadata for a form field.
|
|
119
|
+
|
|
120
|
+
The returned dict contains:
|
|
121
|
+
control_type – 'text' | 'number' | 'checkbox' | 'date' | 'dropdown'
|
|
122
|
+
keyboard_type – Dart TextInputType expression (only for 'number')
|
|
123
|
+
validator_input_expr – Dart expression converting the validator param to T
|
|
124
|
+
bloc_parse_expr – Dart expression converting event param to T in bloc handler
|
|
125
|
+
initial_value_expr – Dart literal for FormState.initial()
|
|
126
|
+
mapped_field_type – Dart type string for ValueFailure<T>
|
|
127
|
+
event_param_type – Dart type of the event constructor parameter
|
|
128
|
+
event_param_name – name of the event constructor parameter
|
|
129
|
+
has_value_object – whether the field is wrapped in a ValueObject
|
|
130
|
+
is_enum – True when the field is an enum
|
|
131
|
+
enum_class – enum class name (only when is_enum)
|
|
132
|
+
"""
|
|
133
|
+
_enums = known_enums or set()
|
|
134
|
+
is_enum = base_type in _enums
|
|
135
|
+
|
|
136
|
+
if is_enum:
|
|
137
|
+
return {
|
|
138
|
+
'control_type': 'dropdown',
|
|
139
|
+
'keyboard_type': '',
|
|
140
|
+
'validator_input_expr': '',
|
|
141
|
+
'bloc_parse_expr': f'event.{field_name}Value',
|
|
142
|
+
'initial_value_expr': f'{base_type}.values.first',
|
|
143
|
+
'mapped_field_type': base_type,
|
|
144
|
+
'event_param_type': base_type,
|
|
145
|
+
'event_param_name': f'{field_name}Value',
|
|
146
|
+
'has_value_object': False,
|
|
147
|
+
'is_enum': True,
|
|
148
|
+
'enum_class': base_type,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
dart_type = map_field_type(base_type)
|
|
152
|
+
|
|
153
|
+
if dart_type == 'bool':
|
|
154
|
+
return {
|
|
155
|
+
'control_type': 'checkbox',
|
|
156
|
+
'keyboard_type': '',
|
|
157
|
+
'validator_input_expr': 'value ?? false',
|
|
158
|
+
'bloc_parse_expr': f'event.{field_name}Value',
|
|
159
|
+
'initial_value_expr': 'false',
|
|
160
|
+
'mapped_field_type': 'bool',
|
|
161
|
+
'event_param_type': 'bool',
|
|
162
|
+
'event_param_name': f'{field_name}Value',
|
|
163
|
+
'has_value_object': True,
|
|
164
|
+
'is_enum': False,
|
|
165
|
+
'enum_class': '',
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if dart_type == 'DateTime':
|
|
169
|
+
return {
|
|
170
|
+
'control_type': 'date',
|
|
171
|
+
'keyboard_type': '',
|
|
172
|
+
'validator_input_expr': 'value ?? DateTime(0)',
|
|
173
|
+
'bloc_parse_expr': f'event.{field_name}Value',
|
|
174
|
+
'initial_value_expr': 'DateTime.now()',
|
|
175
|
+
'mapped_field_type': 'DateTime',
|
|
176
|
+
'event_param_type': 'DateTime',
|
|
177
|
+
'event_param_name': f'{field_name}Value',
|
|
178
|
+
'has_value_object': True,
|
|
179
|
+
'is_enum': False,
|
|
180
|
+
'enum_class': '',
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if dart_type == 'int':
|
|
184
|
+
return {
|
|
185
|
+
'control_type': 'number',
|
|
186
|
+
'keyboard_type': 'TextInputType.number',
|
|
187
|
+
'validator_input_expr': "int.tryParse(value ?? '') ?? 0",
|
|
188
|
+
'bloc_parse_expr': f'int.tryParse(event.{field_name}Str) ?? 0',
|
|
189
|
+
'initial_value_expr': '0',
|
|
190
|
+
'mapped_field_type': 'int',
|
|
191
|
+
'event_param_type': 'String',
|
|
192
|
+
'event_param_name': f'{field_name}Str',
|
|
193
|
+
'has_value_object': True,
|
|
194
|
+
'is_enum': False,
|
|
195
|
+
'enum_class': '',
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if dart_type == 'double':
|
|
199
|
+
return {
|
|
200
|
+
'control_type': 'number',
|
|
201
|
+
'keyboard_type': 'const TextInputType.numberWithOptions(decimal: true)',
|
|
202
|
+
'validator_input_expr': "double.tryParse(value ?? '') ?? 0.0",
|
|
203
|
+
'bloc_parse_expr': f'double.tryParse(event.{field_name}Str) ?? 0.0',
|
|
204
|
+
'initial_value_expr': '0.0',
|
|
205
|
+
'mapped_field_type': 'double',
|
|
206
|
+
'event_param_type': 'String',
|
|
207
|
+
'event_param_name': f'{field_name}Str',
|
|
208
|
+
'has_value_object': True,
|
|
209
|
+
'is_enum': False,
|
|
210
|
+
'enum_class': '',
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# Default: String
|
|
214
|
+
return {
|
|
215
|
+
'control_type': 'text',
|
|
216
|
+
'keyboard_type': '',
|
|
217
|
+
'validator_input_expr': "value ?? ''",
|
|
218
|
+
'bloc_parse_expr': f'event.{field_name}Str',
|
|
219
|
+
'initial_value_expr': "''",
|
|
220
|
+
'mapped_field_type': 'String',
|
|
221
|
+
'event_param_type': 'String',
|
|
222
|
+
'event_param_name': f'{field_name}Str',
|
|
223
|
+
'has_value_object': True,
|
|
224
|
+
'is_enum': False,
|
|
225
|
+
'enum_class': '',
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _is_domain_model(t: str, known_enums: Optional[Set[str]] = None) -> bool:
|
|
230
|
+
"""Check if a type is a domain model (PascalCase, not a primitive, known VO, or enum)."""
|
|
231
|
+
if not t or not t[0].isupper():
|
|
232
|
+
return False
|
|
233
|
+
if t in PRIMITIVE_TYPES or t in KNOWN_VALUE_OBJECTS:
|
|
234
|
+
return False
|
|
235
|
+
if known_enums and t in known_enums:
|
|
236
|
+
return False
|
|
237
|
+
return True
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _dto_for_single_type(t: str, known_enums: Optional[Set[str]] = None) -> str:
|
|
241
|
+
"""Map a single (non-generic) type to its DTO equivalent."""
|
|
242
|
+
if t in PRIMITIVE_TYPES:
|
|
243
|
+
return t
|
|
244
|
+
if t in KNOWN_VALUE_OBJECTS:
|
|
245
|
+
return 'String'
|
|
246
|
+
if known_enums and t in known_enums:
|
|
247
|
+
return 'String'
|
|
248
|
+
if t and t[0].isupper():
|
|
249
|
+
return f"{t}Dto"
|
|
250
|
+
return t
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def map_field_type(field_type: str) -> str:
|
|
254
|
+
"""
|
|
255
|
+
Map field type from string to Dart type.
|
|
256
|
+
Supports complex types like List<ModelName>, Option<String>, Map<K, V>.
|
|
257
|
+
For DTOs, use map_field_type_to_dto() instead.
|
|
258
|
+
"""
|
|
259
|
+
if '<' in field_type and '>' in field_type:
|
|
260
|
+
return field_type
|
|
261
|
+
|
|
262
|
+
type_mapping = {
|
|
263
|
+
'string': 'String',
|
|
264
|
+
'int': 'int',
|
|
265
|
+
'double': 'double',
|
|
266
|
+
'bool': 'bool',
|
|
267
|
+
'date': 'DateTime',
|
|
268
|
+
'datetime': 'DateTime',
|
|
269
|
+
}
|
|
270
|
+
return type_mapping.get(field_type.lower(), field_type)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def map_field_type_to_dto(field_type: str, known_enums: Optional[Set[str]] = None) -> str:
|
|
274
|
+
"""
|
|
275
|
+
Map field type from string to Dart type for DTOs.
|
|
276
|
+
|
|
277
|
+
Conversions:
|
|
278
|
+
Type? -> Type? (nullable). UniqueId? -> String?, Model? -> ModelDto?
|
|
279
|
+
Enum -> String (when known_enums is provided and type is in set)
|
|
280
|
+
Option<T> -> T? (nullable, for static templates). If T is domain model, TDto?
|
|
281
|
+
List<Model> -> List<ModelDto>
|
|
282
|
+
Set<Model> -> Set<ModelDto>
|
|
283
|
+
Map<K, V> -> Map<KDto, VDto> (only domain models get Dto suffix)
|
|
284
|
+
UniqueId -> String
|
|
285
|
+
DomainModel -> DomainModelDto
|
|
286
|
+
primitives -> as-is
|
|
287
|
+
"""
|
|
288
|
+
import re
|
|
289
|
+
|
|
290
|
+
# Nullable suffix: Type? -> DtoType? (including List<T>? -> List<TDto>?)
|
|
291
|
+
if field_type.endswith('?'):
|
|
292
|
+
base = field_type[:-1]
|
|
293
|
+
if '<' in base and '>' in base:
|
|
294
|
+
return f"{map_field_type_to_dto(base, known_enums)}?"
|
|
295
|
+
dto_base = _dto_for_single_type(base, known_enums)
|
|
296
|
+
return f"{dto_base}?"
|
|
297
|
+
|
|
298
|
+
if '<' in field_type and '>' in field_type:
|
|
299
|
+
# Option<T> -> T? (kept for backward compat with static templates)
|
|
300
|
+
option_match = re.match(r'^Option\s*<\s*(\w+)\s*>$', field_type)
|
|
301
|
+
if option_match:
|
|
302
|
+
inner = option_match.group(1)
|
|
303
|
+
dto_inner = _dto_for_single_type(inner, known_enums)
|
|
304
|
+
return f"{dto_inner}?"
|
|
305
|
+
|
|
306
|
+
# Map<K, V>
|
|
307
|
+
map_match = re.match(r'^(\w+)\s*<\s*(\w+)\s*,\s*(\w+)\s*>$', field_type)
|
|
308
|
+
if map_match:
|
|
309
|
+
base = map_match.group(1)
|
|
310
|
+
key_type = map_match.group(2)
|
|
311
|
+
val_type = map_match.group(3)
|
|
312
|
+
dto_key = _dto_for_single_type(key_type, known_enums)
|
|
313
|
+
dto_val = _dto_for_single_type(val_type, known_enums)
|
|
314
|
+
return f"{base}<{dto_key}, {dto_val}>"
|
|
315
|
+
|
|
316
|
+
# Single-param generic: List<T>, Set<T>
|
|
317
|
+
single_match = re.match(r'^(\w+)\s*<\s*(\w+)\s*>$', field_type)
|
|
318
|
+
if single_match:
|
|
319
|
+
base = single_match.group(1)
|
|
320
|
+
inner = single_match.group(2)
|
|
321
|
+
dto_inner = _dto_for_single_type(inner, known_enums)
|
|
322
|
+
return f"{base}<{dto_inner}>"
|
|
323
|
+
|
|
324
|
+
return field_type
|
|
325
|
+
|
|
326
|
+
# UniqueId -> String in DTO
|
|
327
|
+
if field_type in KNOWN_VALUE_OBJECTS:
|
|
328
|
+
return 'String'
|
|
329
|
+
|
|
330
|
+
# Enum -> String in DTO
|
|
331
|
+
if known_enums and field_type in known_enums:
|
|
332
|
+
return 'String'
|
|
333
|
+
|
|
334
|
+
# Domain models -> ModelDto
|
|
335
|
+
if _is_domain_model(field_type, known_enums):
|
|
336
|
+
return f"{field_type}Dto"
|
|
337
|
+
|
|
338
|
+
return map_field_type(field_type)
|