/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
src/liquidcode/commands/core/naming_utils.py
145 строк
5 KB
User
v0.4.16: middleware priorities docs, code refactoring, logging and reserved words check
07 июл 2026, 00:02
07 июл 2026, 00:02
6c94e1e
Код
Авторство
О чём код?
import re from typing import List # Маппинг псевдонимов типов к Python-типам TYPE_MAP = { 'string': 'str', 'int': 'int', 'float': 'float', 'bool': 'bool', 'list': 'list', 'dict': 'dict', 'tuple': 'tuple', 'set': 'set', } # Зарезервированные слова Python, которые нельзя использовать как имена полей RESERVED_WORDS = { 'class', 'from', 'import', 'return', 'yield', 'lambda', 'pass', 'break', 'continue', 'del', 'elif', 'else', 'except', 'finally', 'for', 'global', 'if', 'in', 'is', 'nonlocal', 'not', 'or', 'raise', 'try', 'while', 'with', 'assert', 'async', 'await', 'def', 'and', 'as', 'None', 'True', 'False' } # Константы суффиксов для классов CONTROLLER_SUFFIX = "Controller" API_CONTROLLER_SUFFIX = "APIController" DTO_SUFFIX = "DTO" MIDDLEWARE_SUFFIX = "Middleware" ENTITY_SUFFIX = "" SERVICE_SUFFIX = "" VALIDATOR_SUFFIX = "Validator" SUBSCRIBER_SUFFIX = "Subscriber" REPOSITORY_SUFFIX = "Repository" def normalize_class_name(name: str, suffix: str = '') -> str: """ Приводит имя класса к формату CamelCase и добавляет суффикс при необходимости. Args: name: Исходное имя (например, 'user', 'UserController'). suffix: Суффикс, который нужно добавить к имени (например, 'Controller'). Returns: Нормализованное имя (например, 'User' или 'UserController'). Raises: ValueError: Если имя пустое или содержит недопустимые символы. """ name = name.strip().replace(' ', '') if not name: raise ValueError("Имя не может быть пустым") if not name[0].isalpha(): raise ValueError("Имя должно начинаться с буквы") if not name.isalnum(): raise ValueError("Имя должно содержать только буквы и цифры") normalized = name[0].upper() + name[1:] if name else '' # Если суффикс уже есть (например UserDTO), удаляем его, чтобы добавить заново if suffix and normalized.endswith(suffix) and normalized != suffix: normalized = normalized[:-len(suffix)] # Добавляем суффикс, если он указан if suffix and not normalized.endswith(suffix): normalized = normalized + suffix return normalized def normalize_route(route: str) -> str: """ Приводит маршрут к нормальному виду: добавляет начальный слеш, убирает пробелы. Args: route: Исходный маршрут (например, 'users', '/users'). Returns: Нормализованный маршрут (например, '/users'). Raises: ValueError: Если маршрут содержит пробелы или недопустимые символы. """ route = route.strip() if ' ' in route: raise ValueError("Маршрут не должен содержать пробелы") if not re.match(r'^[a-zA-Z0-9_\-/:{}]*$', route): raise ValueError("Маршрут содержит недопустимые символы") # Убираем начальный и конечный слеши, затем добавляем начальный route = route.strip('/') if route and not route.startswith('/'): route = '/' + route return route def safe_field_name(name: str) -> str: """ Возвращает безопасное имя поля, добавляя суффикс `_field`, если имя совпадает с зарезервированным словом Python. Args: name: Исходное имя поля. Returns: Безопасное имя поля. """ if name in RESERVED_WORDS: return f"{name}_field" return name def extract_routes_from_file(filepath: str) -> List[str]: """ Извлекает все маршруты из файла контроллера (строки с @route). Возвращает список путей. """ routes = [] try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() # Ищем строки типа @route('/path') или @route(r'/path') pattern = r'@route\s*\(\s*r?(["\'])([^"\']+)\1' matches = re.findall(pattern, content) for match in matches: routes.append(match[1]) except Exception: pass return routes def normalize_field_type(ftype: str, nullable: bool = False) -> str: """ Приводит тип поля к корректному имени Python с учётом Optional. Args: ftype: Исходный тип (например, 'string'). nullable: Флаг, указывающий, может ли поле быть None. Returns: Нормализованный тип (например, 'str' или 'Optional[str]'). """ normalized = TYPE_MAP.get(ftype, ftype) if nullable: normalized = f"Optional[{normalized}]" return normalized