"""JavaScript code generator.""" import json from curlconverter.parser import ParsedCurl from curlconverter.generators import register_generator def _detect_content_type(headers: dict, data: str) -> str: """Detect content type from headers or data.""" if "Content-Type" in headers: return headers["Content-Type"] if "content-type" in headers: return headers["content-type"] if data: try: json.loads(data) return "application/json" except (json.JSONDecodeError, TypeError): pass return "application/x-www-form-urlencoded" @register_generator("javascript") def generate_javascript(parsed: ParsedCurl) -> str: """Generate JavaScript fetch code from parsed curl data.""" lines = [] lines.append("const url = " + repr(parsed.url) + ";") lines.append("") options = {"method": parsed.method} headers = dict(parsed.headers) if parsed.headers else {} if parsed.user_agent and "User-Agent" not in headers and "user-agent" not in headers: headers["User-Agent"] = parsed.user_agent if parsed.data: content_type = _detect_content_type(headers, parsed.data) if content_type == "application/json": try: json_data = json.loads(parsed.data) lines.append("const jsonData = " + json.dumps(json_data, indent=2) + ";") options["body"] = "JSON.stringify(jsonData)" if "Content-Type" not in headers and "content-type" not in headers: headers["Content-Type"] = "application/json" except (json.JSONDecodeError, TypeError): lines.append("const data = " + repr(parsed.data) + ";") options["body"] = "data" else: lines.append("const data = " + repr(parsed.data) + ";") options["body"] = "data" if parsed.cookies: if "Cookie" not in headers and "cookie" not in headers: headers["Cookie"] = parsed.cookies if headers: lines.append("const headers = " + _format_object(headers) + ";") options["headers"] = "headers" if parsed.auth: auth_str = f"{parsed.auth[0]}:{parsed.auth[1]}" import base64 encoded = base64.b64encode(auth_str.encode()).decode() lines.append("const auth = " + repr(encoded) + ";") if "Authorization" not in headers and "content-type" not in headers: lines.append("const headersWithAuth = {") lines.append(" ...headers,") lines.append(' "Authorization": `Basic ${auth}`') lines.append("};") options["headers"] = "headersWithAuth" options_str = _format_options(options) lines.append("") lines.append(f"fetch(url, {options_str})") lines.append(" .then(response => {") lines.append(" console.log(response.status);") lines.append(" return response.text();") lines.append(" })") lines.append(" .then(data => console.log(data))") lines.append(" .catch(error => console.error(error));") return "\n".join(lines) def _format_object(obj: dict) -> str: """Format an object for JavaScript code.""" if not obj: return "{}" items = [] for k, v in obj.items(): items.append(f' {repr(k)}: {repr(v)}') return "{\n" + ",\n".join(items) + "\n}" def _format_options(opts: dict) -> str: """Format fetch options for JavaScript code.""" if not opts: return "{}" items = [] for k, v in opts.items(): items.append(f" {k}: {v}") return "{\n" + ",\n".join(items) + "\n }"