import os import subprocess import sys import shutil from typing import Optional PLATFORM = sys.platform NODE = 'node' if PLATFORM in ['linux', 'darwin'] else 'node.exe' def _find_node_path() -> Optional[str]: """Try multiple ways to find Node.js path.""" local_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), f'binaries/{NODE}') if os.path.isfile(local_path): return local_path system_path = shutil.which(NODE) if system_path: return system_path return NODE NODE_PATH = _find_node_path() VM_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'vm/botGuard.js') def generate_po_token(visitor_data: str) -> str: """ Run nodejs to generate poToken through botGuard. Raises: RuntimeError: If Node.js is not available """ try: result = subprocess.check_output( [NODE_PATH, VM_PATH, visitor_data], stderr=subprocess.PIPE ).decode() return result.replace("\n", "") except FileNotFoundError as e: raise RuntimeError( f"Node.js is required but not found. Tried path: {NODE_PATH}\n" "Please install Node.js or ensure it's in your PATH." ) from e except subprocess.CalledProcessError as e: raise RuntimeError( f"Failed to execute botGuard.js: {e.stderr.decode().strip()}" ) from e