import React, { useState, useEffect } from "react"; import { Box, Typography, Paper, TextField, Button, Tooltip, IconButton, Alert, Stack, Divider, } from "@mui/material"; import { Search as SearchIcon, DataObject as DataObjectIcon, Output as OutputIcon, UploadFile as UploadFileIcon, FileOpen as FileOpenIcon, Restore as RestoreIcon, FormatAlignLeft as FormatAlignLeftIcon, Clear as ClearIcon, ContentCopy as ContentCopyIcon, Download as DownloadIcon, Check as CheckIcon, Refresh as RefreshIcon, } from "@mui/icons-material"; import Grid from "@mui/material/Grid"; import jmespath from "jmespath"; function MainPage({ showReloadButton, onReloadSampleData, jmespathExpression, setJmespathExpression, jsonData, setJsonData, }) { const [result, setResult] = useState(""); const [error, setError] = useState(""); const [jsonError, setJsonError] = useState(""); const [copySuccess, setCopySuccess] = useState(false); const evaluateExpression = () => { try { // Clear previous errors setError(""); setJsonError(""); // Validate and parse JSON let parsedData; try { parsedData = JSON.parse(jsonData); } catch (jsonErr) { setJsonError(`Invalid JSON: ${jsonErr.message}`); setResult(""); return; } // Evaluate JMESPath expression const queryResult = jmespath.search(parsedData, jmespathExpression); // Format the result if (queryResult === null || queryResult === undefined) { setResult("null"); } else { setResult(JSON.stringify(queryResult, null, 2)); } } catch (jmesErr) { setError(`JMESPath Error: ${jmesErr.message}`); setResult(""); } }; // Auto-evaluate when inputs change useEffect(() => { if (jmespathExpression && jsonData) { evaluateExpression(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [jmespathExpression, jsonData]); const handleJmespathChange = (e) => { setJmespathExpression(e.target.value); }; const handleJsonChange = (e) => { setJsonData(e.target.value); }; const formatJson = () => { try { const parsed = JSON.parse(jsonData); setJsonData(JSON.stringify(parsed, null, 2)); } catch (err) { // If JSON is invalid, don't format } }; const clearAll = () => { setJmespathExpression(""); setJsonData(""); setResult(""); setError(""); setJsonError(""); }; const copyToClipboard = async () => { try { await navigator.clipboard.writeText(result); setCopySuccess(true); setTimeout(() => setCopySuccess(false), 2000); } catch (err) { console.error("Failed to copy!", err); } }; const downloadResult = () => { const blob = new Blob([result], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "result.json"; a.click(); URL.revokeObjectURL(url); }; const loadSample = () => { const sampleData = { users: [ { name: "Alice", age: 30, city: "New York" }, { name: "Bob", age: 25, city: "San Francisco" }, { name: "Charlie", age: 35, city: "Chicago" }, ], total: 3, }; setJsonData(JSON.stringify(sampleData, null, 2)); setJmespathExpression("users[?age > `30`].name"); }; const loadFromDisk = () => { const input = document.createElement("input"); input.type = "file"; input.accept = ".json"; input.onchange = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { try { const content = e.target.result; const parsed = JSON.parse(content); setJsonData(JSON.stringify(parsed, null, 2)); } catch (error) { alert("Invalid JSON file"); } }; reader.readAsText(file); } }; input.click(); }; const loadLogFile = () => { const input = document.createElement("input"); input.type = "file"; input.accept = ".log,.jsonl,.ndjson"; input.onchange = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { try { const content = e.target.result; const lines = content.trim().split("\n"); const logs = lines.map((line) => JSON.parse(line)); setJsonData(JSON.stringify(logs, null, 2)); setJmespathExpression("[*].message"); } catch (error) { alert("Invalid JSON Lines file"); } }; reader.readAsText(file); } }; input.click(); }; return ( Validate and test JMESPath expressions against JSON data in real-time. Enter your JMESPath query and JSON data below to see the results instantly. JMESPath Expression JSON Input {showReloadButton && ( )} {jsonError && ( {jsonError} )} Query Result {copySuccess ? : } ); } export default MainPage;