/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
src/liquidcode/commands/make/api.py
229 строк
8 KB
User
v0.4.16: middleware priorities docs, code refactoring, logging and reserved words check
07 июл 2026, 00:02
07 июл 2026, 00:02
6c94e1e
Код
Авторство
О чём код?
"""Генератор API-контроллера для LiquidCode. Команда: lcc make:api <name> [--directory DIR] [--force] [--no-interactive] [--version VERSION] Интерактивный режим позволяет выбрать методы и добавить поля для сериализатора. """ import argparse from ..base import ( generate_from_template, TemplateError, normalize_class_name, normalize_route, ask_fields, ask_methods, normalize_field_type, ) def configure_parser(subparser: argparse.ArgumentParser) -> None: """ Добавляет аргументы для команды make:api. Args: subparser: Объект ArgumentParser для команды. """ subparser.add_argument( "name", nargs="?", help="Имя API-контроллера (например, Product)" ) subparser.add_argument( "--directory", default="src/Controller", help="Целевая директория (по умолчанию: src/Controller)", ) subparser.add_argument( "--force", action="store_true", help="Перезаписать файл, если он существует", ) subparser.add_argument( "--no-interactive", action="store_true", help="Отключить интерактивный режим (использовать значения по умолчанию)", ) subparser.add_argument( "--version", default="v1", help="Версия API (по умолчанию: v1)" ) def run(args: argparse.Namespace) -> None: """ Выполняет команду make:api. Args: args: Объект аргументов командной строки. """ try: # 1. Парсинг имени normalized_name = _parse_name(args) # 2. Парсинг версии version = _parse_version(args) # 3. Получение маршрута normalized_route = _get_route(normalized_name) # 4. Получение полей fields = _get_fields(args) # Нормализуем типы полей for field in fields: field["type"] = normalize_field_type(field["type"], field["nullable"]) # 5. Получение методов selected_methods = _get_methods(args) # 6. Генерация _generate_output(args, normalized_name, normalized_route, version, fields, selected_methods) except (TypeError, ValueError, TemplateError, IOError) as e: print(f"[ERROR] Ошибка: {e}") def _parse_name(args: argparse.Namespace) -> str: """ Получает и нормализует имя API-контроллера. Args: args: Объект аргументов командной строки. Returns: Нормализованное имя (с суффиксом APIController). """ from ..core.naming_utils import API_CONTROLLER_SUFFIX name = args.name if not name: name = input("Введите имя API-контроллера (например, Product): ").strip() if not name: print("[ERROR] Имя не может быть пустым") raise ValueError("Имя не может быть пустым") return normalize_class_name(name, suffix=API_CONTROLLER_SUFFIX) def _parse_version(args: argparse.Namespace) -> str: """ Получает и нормализует версию API. Args: args: Объект аргументов командной строки. Returns: Версия без префикса 'v' (например, '1' для 'v1'). """ return args.version.lstrip("v") def _get_route(normalized_name: str) -> str: """ Формирует маршрут на основе имени контроллера. Args: normalized_name: Нормализованное имя контроллера. Returns: Нормализованный маршрут (например, 'product-api'). """ route = normalized_name.lower().replace("apicontroller", "") return normalize_route(route) def _get_fields(args: argparse.Namespace) -> list: """ Получает список полей для сериализатора. Args: args: Объект аргументов командной строки. Returns: Список полей (пустой если --no-interactive). """ from ..core.naming_utils import RESERVED_WORDS fields = [] if not args.no_interactive: print(f"\nСоздание API-контроллера {args.name or 'APIController'}") print("Добавляйте поля для сериализатора (Pydantic). Оставьте имя пустым для завершения.") fields = ask_fields() else: # В неинтерактивном режиме проверяем --fields if args.fields: fields = [] for field in args.fields: if ':' in field: fname, ftype = field.split(':', 1) else: fname, ftype = field, 'string' # Проверка на зарезервированные слова if fname in RESERVED_WORDS: print(f"⚠️ Поле '{fname}' — зарезервированное слово Python. Будет преобразовано в '{fname}_field'.") fields.append({ 'name': fname, 'type': ftype, 'nullable': False, 'length': None, }) return fields def _get_methods(args: argparse.Namespace) -> list: """ Получает список методов API. Args: args: Объект аргументов командной строки. Returns: Список выбранных методов. """ if not args.no_interactive: return ask_methods() return ["index", "show", "create", "update", "delete"] def _generate_output( args: argparse.Namespace, normalized_name: str, normalized_route: str, version: str, fields: list, selected_methods: list, ) -> None: """ Генерирует API-контроллер и выводит результат. Args: args: Объект аргументов командной строки. normalized_name: Нормализованное имя контроллера. normalized_route: Нормализованный маршрут. version: Версия API. fields: Список полей сериализатора. selected_methods: Список методов. """ extra = { "name": normalized_name, "route": normalized_route, "version": version, "fields": fields, "use_serializer": bool(fields), "methods": selected_methods, } created = generate_from_template( template_name="api", args=args, extra_kwargs=extra, default_filename="{name}APIController.py", default_dir="src/Controller", ) if created: print(f"[OK] Создан API-контроллер: {normalized_name}APIController (v{version})") if fields: print(f" Поля сериализатора: {', '.join(f['name'] for f in fields)}") if selected_methods: print(f" Методы: {', '.join(selected_methods)}") else: print("[WARN] Файл уже существует. Используйте --force для перезаписи.")