Skip to content

Commit

Permalink
Merge pull request #49 from MaxOpperman/master
Browse files Browse the repository at this point in the history
Add enum choice key functionality to CLI
  • Loading branch information
adenh93 authored Sep 6, 2023
2 parents 751efc7 + 8207e27 commit b4bfe2b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ Special thanks to @bigpe for brewing up the first version of this CLI!
--annotations, -a Add js doc annotations for validations (eg. for Zod)
--enum_choices, -ec Add choices to external enum type instead union
--enum_values, -ev Add enum to obtain display name for choices field
--enum_keys, -ev Add enum to obtain the choices field keys by values
```

Using the new `generate_ts` management command, you can fine tune the generation of your interfaces similarly to how you would via the decorator method, with some additional functionality. For example, you can call the command with the `--all` flag and get all the generated types to the folder specified (they will be grouped by the application name, all external applications will be excluded, only the project applications).
Expand Down
38 changes: 27 additions & 11 deletions django_typomatic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ def __map_choices_to_enum_values(enum_name, choices):

def __map_choices_to_enum_keys_by_values(enum_name, choices):
'''
Generates and returns a TS enum values (display name) for all values in the provided choices OrderedDict
Generates and returns a TS enum values (display name) for all keys by the values in the
provided choices OrderedDict. Format as follows:
"export enum FieldNameChoiceEnumKeys { VALUE1 = 'key1', VALUE2 = 'key2' }"
'''
if not choices:
_LOG.warning(f'No choices specified for Enum Field: {enum_name}')
Expand Down Expand Up @@ -292,6 +294,15 @@ def __process_generic_type(return_type):


def __process_choice_field(field_name, choices, enum_choices, enum_values, enum_keys):
'''
Get the typescript enums of a Choices field
:param field_name: name of the Choices field
:param choices: possibilities of the Choices field
:param enum_choices: whether the regular choice enum should be returned
:param enum_values: whether the values choice enum should be returned
:param enum_keys: whether the keys choice enum should be returned
:return: strings of all the extracted typescript enums
'''
ts_enum = None
ts_enum_value = None
ts_enum_key = None
Expand All @@ -308,6 +319,9 @@ def __process_choice_field(field_name, choices, enum_choices, enum_values, enum_


def __process_method_field(field_name, return_type, enum_choices, enum_values, enum_keys, many=False):
'''
Function to set the typescript mapping for a Django Method Field
'''
if inspect.isclass(return_type) and issubclass(return_type, Choices):
choices = {key: value for key, value in return_type.choices}

Expand Down Expand Up @@ -375,6 +389,10 @@ def __generate_interfaces(context, trim_serializer_output, camelize, enum_choice


def __generate_enums(context, enum_choices, enum_values, enum_keys):
'''
Function to generate a string of all the possible enums (including possible duplicates). This
does not change the mapping of the interfaces but only generates enums from used choice fields.
'''
enums = []
if context not in __serializers:
return []
Expand Down Expand Up @@ -421,18 +439,16 @@ def __extract_field_enums(enum_choices, enum_values, enum_keys, field, field_nam
return ts_enum, ts_enum_value, ts_enum_key


def __get_enums_and_interfaces_from_generated(interfaces, enums):
def __remove_duplicate_enums(enums):
'''
Get the interfaces and enums from the generated interfaces and enums.
Works by splitting the tuples into two lists, one for interfaces and one for enums.
The interfaces are not changed. The enums are compared such that there are no duplicates
between interfaces. Then the enums are returned in string format with blank lines in between.
The enums are compared such that there are no duplicates between interfaces. Then the enums are
returned in string format with blank lines in between.
'''
enums_string = ''
if any(elem is not None for elem in enums):
distinct_enums = sorted(list(set(list(filter(lambda x: x is not None, enums)))))
enums_string = '\n'.join(distinct_enums) + '\n\n'
return enums_string, interfaces
return enums_string


def __get_annotations(field, ts_type):
Expand Down Expand Up @@ -494,10 +510,10 @@ def generate_ts(output_path, context='default', trim_serializer_output=False, ca
with open(output_path, 'w') as output_file:
interfaces = __generate_interfaces(context, trim_serializer_output, camelize, enum_choices,
enum_values, enum_keys, annotations)
enums = ''
enums = []
if enum_choices or enum_values or enum_keys:
enums = __generate_enums(context, enum_choices, enum_values, enum_keys)
enums_string, interfaces = __get_enums_and_interfaces_from_generated(interfaces, enums)
enums_string = __remove_duplicate_enums(enums)
output_file.write(enums_string + ''.join(interfaces))


Expand All @@ -510,8 +526,8 @@ def get_ts(context='default', trim_serializer_output=False, camelize=False, enum
'''
interfaces = __generate_interfaces(context, trim_serializer_output, camelize, enum_choices,
enum_values, enum_keys, annotations)
enums = ''
enums = []
if enum_choices or enum_values or enum_keys:
enums = __generate_enums(context, enum_choices, enum_values, enum_keys)
enums_string, interfaces = __get_enums_and_interfaces_from_generated(interfaces, enums)
enums_string = __remove_duplicate_enums(enums)
return enums_string + ''.join(interfaces)
10 changes: 9 additions & 1 deletion django_typomatic/management/commands/generate_ts.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ def add_arguments(self, parser):
default=False,
action='store_true'
)
parser.add_argument(
'--enum_keys',
'-ek',
help='Add enum keys by values for obtain display name for choices field',
default=False,
action='store_true'
)
parser.add_argument(
'-o',
'--output',
Expand Down Expand Up @@ -114,8 +121,9 @@ def _generate_ts(self, app_name, serializer_name, output, **options):
generate_ts(
output_path,
context=app_name,
enum_values=options['enum_values'],
enum_choices=options['enum_choices'],
enum_values=options['enum_values'],
enum_keys=options['enum_keys'],
camelize=options['camelize'],
trim_serializer_output=options['trim'],
annotations=options['annotations']
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setuptools.setup(
name="django-typomatic",
version="2.4.0",
version="2.4.1",
url="https://github.com/adenh93/django-typomatic",

author="Aden Herold",
Expand Down

0 comments on commit b4bfe2b

Please sign in to comment.