ppt-tool/backend/utils/tsx_validator.py
Vadym Samoilenko c431d4ab45 Implement critical security fixes and modern design system (Pre-launch P0 tasks)
Security Improvements (P0.0-P0.4):
- P0.0: Migrate to Gemini-only AI stack (simplified, single billing)
- P0.1: Fix CORS to restrict allowed origins from env (was *)
- P0.2: Remove hardcoded dev password, require env var
- P0.3: Add rate limiting (slowapi) - 3-10 req/min on sensitive endpoints
- P0.4: Add request size limits (100MB default via middleware)

New Features:
- Unified LLM service with Google Gemini priority
- OXML geometry extractor for layout parsing
- TSX validator for generated React components
- Client ID support in presentation requests with access control
- Configurable LLM/image timeouts via env vars

Modern Design System (P0.9 - partial):
- Enhanced CSS design tokens (primary, semantic colors, shadows)
- Typography scale (h1-h4, body variants, caption)
- Modern animations (fadeIn, slideIn, scaleIn)
- Updated Button component with better variants and hover effects
- Created unified Card and StatusBadge components
- Applied design system to Dashboard and Settings pages

Backend Improvements:
- Master deck parser simplification
- Slide-to-HTML endpoint cleanup (325 lines removed)
- Better error handling in prompts endpoint

Frontend Improvements:
- Settings UI simplified to show only Google/Gemini
- Dashboard uses CSS variables instead of hardcoded colors
- Improved button transitions and hover states

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-02-27 18:28:24 +00:00

39 lines
1.4 KiB
Python

import ast
def validate_tsx_syntax(ts_code: str) -> bool:
"""
Very crude validation of React/TSX output by parsing it as Python.
While TSX is not Python, basic syntax structures like balanced brackets
often crash the AST if they are heavily truncated.
A more robust validation would require wrapping `esbuild` or `tsc` in a subprocess.
For now, we just ensure it's not completely empty or malformed text.
"""
if not ts_code or len(ts_code) < 50:
return False
# Check for basic required React component signatures
if "export default function" not in ts_code and "export const" not in ts_code and "const" not in ts_code and "function" not in ts_code:
return False
# Check for balanced brackets
brackets = {"{": "}", "[": "]", "(": ")", "<": ">"}
stack = []
# We ignore angle brackets in TSX as they can be JSX tags or type params
# and are notoriously hard to perfectly match without a real parser
for char in ts_code:
if char in "{\[(":
stack.append(char)
elif char in "}\])":
if not stack:
return False # Unmatched closing bracket
last = stack.pop()
if brackets[last] != char:
return False # Mismatched brackets
# If there are unclosed brackets (ignoring angle brackets), it might be truncated
if stack:
return False
return True