gateway/modules/shared/frontendOptionsTypes.py
2025-12-07 23:51:05 +01:00

136 lines
3.9 KiB
Python

"""
Type definitions and utilities for frontend_options attribute.
The frontend_options attribute supports two formats:
1. Static List: A list of option dictionaries for static options
2. String Reference: A string identifier that references dynamic options from /api/options/{optionsName}
"""
from typing import List, Dict, Any, Union
try:
from typing import TypeAlias # Python 3.10+
except ImportError:
from typing_extensions import TypeAlias # Python < 3.10
# Type definition for a single option item
OptionItem: TypeAlias = Dict[str, Any]
"""
Single option item format:
{
"value": str, # The value to be stored/returned
"label": { # Multilingual labels
"en": str,
"fr": str,
...
}
}
"""
# Type definition for frontend_options - can be either a list or string reference
FrontendOptions: TypeAlias = Union[List[OptionItem], str]
"""
frontend_options can be either:
1. List[OptionItem]: Static list of options
Example: [{"value": "a", "label": {"en": "All", "fr": "Tous"}}]
2. str: String reference to dynamic options API
Example: "user.role" -> Frontend fetches from /api/options/user.role
"""
def isStringReference(frontendOptions: FrontendOptions) -> bool:
"""
Check if frontend_options is a string reference (dynamic) or a list (static).
Args:
frontendOptions: The frontend_options value to check
Returns:
True if it's a string reference, False if it's a list
"""
return isinstance(frontendOptions, str)
def isStaticList(frontendOptions: FrontendOptions) -> bool:
"""
Check if frontend_options is a static list or a string reference.
Args:
frontendOptions: The frontend_options value to check
Returns:
True if it's a static list, False if it's a string reference
"""
return isinstance(frontendOptions, list)
def validateFrontendOptions(frontendOptions: FrontendOptions) -> bool:
"""
Validate that frontend_options is in the correct format.
Args:
frontendOptions: The frontend_options value to validate
Returns:
True if valid, False otherwise
"""
if isinstance(frontendOptions, str):
# String reference: should be a non-empty string
return bool(frontendOptions.strip())
elif isinstance(frontendOptions, list):
# Static list: should contain option dictionaries
if not frontendOptions:
return True # Empty list is valid (no options)
for option in frontendOptions:
if not isinstance(option, dict):
return False
if "value" not in option:
return False
if "label" not in option:
return False
if not isinstance(option["label"], dict):
return False
return True
else:
return False
def getOptionsName(frontendOptions: FrontendOptions) -> str:
"""
Get the options name from a string reference.
Args:
frontendOptions: The frontend_options value (must be a string reference)
Returns:
The options name (e.g., "user.role")
Raises:
ValueError: If frontendOptions is not a string reference
"""
if not isStringReference(frontendOptions):
raise ValueError(f"frontend_options is not a string reference: {type(frontendOptions)}")
return frontendOptions
def getStaticOptions(frontendOptions: FrontendOptions) -> List[OptionItem]:
"""
Get the static options list.
Args:
frontendOptions: The frontend_options value (must be a static list)
Returns:
The list of option items
Raises:
ValueError: If frontendOptions is not a static list
"""
if not isStaticList(frontendOptions):
raise ValueError(f"frontend_options is not a static list: {type(frontendOptions)}")
return frontendOptions