json-term 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -4
- package/dist/cli.js +28 -1
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +28 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,16 @@ curl -s https://api.com/v2/config | jsonx diff config.v1.json
|
|
|
65
65
|
jsonx diff a.json b.json --no-unchanged
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
### 3.
|
|
68
|
+
### 3. Simple Colorized JSON View (jq-style with Bold Keys)
|
|
69
|
+
```bash
|
|
70
|
+
# Print syntax-highlighted standard JSON format
|
|
71
|
+
jsonx --raw data.json
|
|
72
|
+
|
|
73
|
+
# Piped stream
|
|
74
|
+
curl -s https://api.github.com/users/octocat | jsonx --raw
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 4. Non-Interactive Pretty Tree Print (for scripts & CI)
|
|
69
78
|
```bash
|
|
70
79
|
# Print formatted tree to stdout
|
|
71
80
|
jsonx --print data.json
|
|
@@ -74,6 +83,7 @@ jsonx --print data.json
|
|
|
74
83
|
jsonx data.json --depth 2 --print
|
|
75
84
|
```
|
|
76
85
|
|
|
86
|
+
|
|
77
87
|
---
|
|
78
88
|
|
|
79
89
|
## ⌨️ Interactive TUI Keybindings
|
|
@@ -112,11 +122,15 @@ const data = {
|
|
|
112
122
|
active: true,
|
|
113
123
|
};
|
|
114
124
|
|
|
115
|
-
// 1.
|
|
125
|
+
// 1. Syntax-Highlighted Standard JSON String
|
|
126
|
+
const colored = colorizeJSON(data);
|
|
127
|
+
console.log(colored);
|
|
128
|
+
|
|
129
|
+
// 2. Pretty Print Formatted Tree String
|
|
116
130
|
const tree = buildTree(data, "myService", "$", 0, 2);
|
|
117
131
|
console.log(prettyPrintTree(tree));
|
|
118
132
|
|
|
119
|
-
//
|
|
133
|
+
// 3. Compute Structural Diff
|
|
120
134
|
const oldConfig = { port: 8080, debug: true };
|
|
121
135
|
const newConfig = { port: 8443, debug: true, ssl: true };
|
|
122
136
|
|
|
@@ -125,7 +139,7 @@ const stats = calculateDiffStats(diffTree);
|
|
|
125
139
|
console.log(`Changes: +${stats.added} -${stats.removed} ~${stats.modified}`);
|
|
126
140
|
console.log(prettyPrintDiff(diffTree));
|
|
127
141
|
|
|
128
|
-
//
|
|
142
|
+
// 4. Launch Interactive TUI Programmatically
|
|
129
143
|
const viewer = new InteractiveViewer(tree);
|
|
130
144
|
await viewer.start();
|
|
131
145
|
```
|
|
@@ -136,6 +150,8 @@ await viewer.start();
|
|
|
136
150
|
|
|
137
151
|
| Option | Shorthand | Default | Description |
|
|
138
152
|
| :--- | :--- | :--- | :--- |
|
|
153
|
+
| `--raw` | `-r` | `false` | Print standard syntax-highlighted JSON (bold keys & typed colors) |
|
|
154
|
+
| `--format <type>` | `-F` | `"tree"` | Output format (`tree` or `json`) |
|
|
139
155
|
| `--print` | `-p` | `false` | Non-interactive formatted print to stdout |
|
|
140
156
|
| `--depth <number>` | `-d` | `2` | Initial tree expansion depth |
|
|
141
157
|
| `--search <query>` | `-s` | `""` | Initial filter query for keys/values |
|
|
@@ -143,6 +159,7 @@ await viewer.start();
|
|
|
143
159
|
| `--version` | `-v` | | Output version |
|
|
144
160
|
| `--help` | `-h` | | Display help menu |
|
|
145
161
|
|
|
162
|
+
|
|
146
163
|
---
|
|
147
164
|
|
|
148
165
|
## 🧪 Development & Testing
|
package/dist/cli.js
CHANGED
|
@@ -137,6 +137,29 @@ function prettyPrintTree(node, indent = "", isLast = true) {
|
|
|
137
137
|
}
|
|
138
138
|
return lines.join("\n");
|
|
139
139
|
}
|
|
140
|
+
function colorizeJSON(data, space = 2) {
|
|
141
|
+
const jsonStr = typeof data === "string" ? data : JSON.stringify(data, null, space);
|
|
142
|
+
if (!jsonStr) return "";
|
|
143
|
+
return jsonStr.replace(
|
|
144
|
+
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
|
|
145
|
+
(match) => {
|
|
146
|
+
if (/^"/.test(match)) {
|
|
147
|
+
if (/:$/.test(match)) {
|
|
148
|
+
const keyName = match.slice(0, -1);
|
|
149
|
+
return import_picocolors.default.bold(import_picocolors.default.cyan(keyName)) + import_picocolors.default.dim(":");
|
|
150
|
+
}
|
|
151
|
+
return import_picocolors.default.green(match);
|
|
152
|
+
}
|
|
153
|
+
if (/true|false/.test(match)) {
|
|
154
|
+
return import_picocolors.default.magenta(match);
|
|
155
|
+
}
|
|
156
|
+
if (/null/.test(match)) {
|
|
157
|
+
return import_picocolors.default.dim(match);
|
|
158
|
+
}
|
|
159
|
+
return import_picocolors.default.yellow(match);
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}
|
|
140
163
|
|
|
141
164
|
// src/differ.ts
|
|
142
165
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
@@ -637,7 +660,7 @@ function parseJSON(raw, label = "Input") {
|
|
|
637
660
|
}
|
|
638
661
|
async function main() {
|
|
639
662
|
const program = new import_commander.Command();
|
|
640
|
-
program.name("json-term").description("High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.").version("1.
|
|
663
|
+
program.name("json-term").description("High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.").version("1.1.0", "-v, --version", "Output the current version").argument("[file]", "JSON file to view or compare").option("-p, --print", "Print formatted non-interactive output to stdout", false).option("-F, --format <format>", "Output format: 'tree' or 'json'", "tree").option("-r, --raw", "Print standard syntax-highlighted JSON (shorthand for --format json --print)", false).option("-d, --depth <number>", "Initial tree expansion depth", (val) => parseInt(val, 10), 2).option("-s, --search <query>", "Filter tree by key or value query").action(async (fileArg, options) => {
|
|
641
664
|
try {
|
|
642
665
|
let raw = "";
|
|
643
666
|
if (fileArg) {
|
|
@@ -654,6 +677,10 @@ async function main() {
|
|
|
654
677
|
process.exit(1);
|
|
655
678
|
}
|
|
656
679
|
const data = parseJSON(raw, fileArg || "stdin");
|
|
680
|
+
if (options.raw || options.format === "json") {
|
|
681
|
+
console.log(colorizeJSON(data));
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
657
684
|
const tree = buildTree(data, fileArg || "root", "$", 0, options.depth);
|
|
658
685
|
if (options.print || !process.stdin.isTTY) {
|
|
659
686
|
console.log(prettyPrintTree(tree));
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport fs from \"fs\";\nimport pc from \"picocolors\";\nimport { buildTree, prettyPrintTree } from \"./formatter.js\";\nimport { diffJSON, prettyPrintDiff, calculateDiffStats } from \"./differ.js\";\nimport { InteractiveViewer } from \"./interactive.js\";\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = \"\";\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n process.stdin.on(\"end\", () => {\n resolve(data.trim());\n });\n setTimeout(() => {\n if (!data) resolve(\"\");\n }, 100);\n });\n}\n\nfunction parseJSON(raw: string, label = \"Input\"): any {\n try {\n return JSON.parse(raw);\n } catch (err: any) {\n throw new Error(`Invalid JSON in ${label}: ${err.message}`);\n }\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name(\"json-term\")\n .description(\"High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.\")\n .version(\"1.0.0\", \"-v, --version\", \"Output the current version\")\n .argument(\"[file]\", \"JSON file to view or compare\")\n .option(\"-p, --print\", \"Print formatted non-interactive tree to stdout\", false)\n .option(\"-d, --depth <number>\", \"Initial tree expansion depth\", (val) => parseInt(val, 10), 2)\n .option(\"-s, --search <query>\", \"Filter tree by key or value query\")\n .action(async (fileArg, options) => {\n try {\n let raw = \"\";\n if (fileArg) {\n if (!fs.existsSync(fileArg)) {\n console.error(pc.red(`Error: File not found: ${fileArg}`));\n process.exit(1);\n }\n raw = await fs.promises.readFile(fileArg, \"utf-8\");\n } else {\n raw = await readStdin();\n }\n\n if (!raw) {\n program.help();\n process.exit(1);\n }\n\n const data = parseJSON(raw, fileArg || \"stdin\");\n const tree = buildTree(data, fileArg || \"root\", \"$\", 0, options.depth);\n\n if (options.print || !process.stdin.isTTY) {\n console.log(prettyPrintTree(tree));\n } else {\n const viewer = new InteractiveViewer(tree, false);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n // Diff subcommand\n program\n .command(\"diff <fileA> [fileB]\")\n .description(\"Structural JSON diff between two files or stdin\")\n .option(\"-p, --print\", \"Print formatted non-interactive diff to stdout\", false)\n .option(\"-d, --depth <number>\", \"Initial expansion depth\", (val) => parseInt(val, 10), 3)\n .option(\"--no-unchanged\", \"Hide unchanged nodes from the diff view\", false)\n .action(async (fileA, fileB, diffOptions) => {\n try {\n if (!fs.existsSync(fileA)) {\n console.error(pc.red(`Error: File not found: ${fileA}`));\n process.exit(1);\n }\n const rawA = await fs.promises.readFile(fileA, \"utf-8\");\n const dataA = parseJSON(rawA, fileA);\n\n let dataB: any;\n if (fileB) {\n if (!fs.existsSync(fileB)) {\n console.error(pc.red(`Error: File not found: ${fileB}`));\n process.exit(1);\n }\n const rawB = await fs.promises.readFile(fileB, \"utf-8\");\n dataB = parseJSON(rawB, fileB);\n } else {\n const stdinData = await readStdin();\n if (!stdinData) {\n console.error(pc.red(\"Error: Please specify second file or pipe JSON via stdin.\"));\n process.exit(1);\n }\n dataB = parseJSON(stdinData, \"stdin\");\n }\n\n const diffTree = diffJSON(dataA, dataB, `${fileA} ↔ ${fileB || \"stdin\"}`, \"$\", 0, diffOptions.depth);\n const stats = calculateDiffStats(diffTree);\n\n if (diffOptions.print || !process.stdin.isTTY) {\n console.log(\n pc.bold(\n `Diff Stats: ${pc.green(`+${stats.added}`)} ${pc.red(`-${stats.removed}`)} ${pc.yellow(`~${stats.modified}`)} ${pc.dim(`=${stats.unchanged}`)}\\n`\n )\n );\n console.log(prettyPrintDiff(diffTree, { showUnchanged: diffOptions.unchanged }));\n } else {\n const viewer = new InteractiveViewer(diffTree, true);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((err) => {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n});\n","import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":"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","names":["import_picocolors","pc","import_picocolors","pc","import_picocolors","os","pc","readline","fs","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport fs from \"fs\";\nimport pc from \"picocolors\";\nimport { buildTree, prettyPrintTree, colorizeJSON } from \"./formatter.js\";\nimport { diffJSON, prettyPrintDiff, calculateDiffStats } from \"./differ.js\";\nimport { InteractiveViewer } from \"./interactive.js\";\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = \"\";\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n process.stdin.on(\"end\", () => {\n resolve(data.trim());\n });\n setTimeout(() => {\n if (!data) resolve(\"\");\n }, 100);\n });\n}\n\nfunction parseJSON(raw: string, label = \"Input\"): any {\n try {\n return JSON.parse(raw);\n } catch (err: any) {\n throw new Error(`Invalid JSON in ${label}: ${err.message}`);\n }\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name(\"json-term\")\n .description(\"High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.\")\n .version(\"1.1.0\", \"-v, --version\", \"Output the current version\")\n .argument(\"[file]\", \"JSON file to view or compare\")\n .option(\"-p, --print\", \"Print formatted non-interactive output to stdout\", false)\n .option(\"-F, --format <format>\", \"Output format: 'tree' or 'json'\", \"tree\")\n .option(\"-r, --raw\", \"Print standard syntax-highlighted JSON (shorthand for --format json --print)\", false)\n .option(\"-d, --depth <number>\", \"Initial tree expansion depth\", (val) => parseInt(val, 10), 2)\n .option(\"-s, --search <query>\", \"Filter tree by key or value query\")\n .action(async (fileArg, options) => {\n try {\n let raw = \"\";\n if (fileArg) {\n if (!fs.existsSync(fileArg)) {\n console.error(pc.red(`Error: File not found: ${fileArg}`));\n process.exit(1);\n }\n raw = await fs.promises.readFile(fileArg, \"utf-8\");\n } else {\n raw = await readStdin();\n }\n\n if (!raw) {\n program.help();\n process.exit(1);\n }\n\n const data = parseJSON(raw, fileArg || \"stdin\");\n\n // If raw/json format requested, print colorized JSON directly\n if (options.raw || options.format === \"json\") {\n console.log(colorizeJSON(data));\n return;\n }\n\n const tree = buildTree(data, fileArg || \"root\", \"$\", 0, options.depth);\n\n if (options.print || !process.stdin.isTTY) {\n console.log(prettyPrintTree(tree));\n } else {\n const viewer = new InteractiveViewer(tree, false);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n // Diff subcommand\n program\n .command(\"diff <fileA> [fileB]\")\n .description(\"Structural JSON diff between two files or stdin\")\n .option(\"-p, --print\", \"Print formatted non-interactive diff to stdout\", false)\n .option(\"-d, --depth <number>\", \"Initial expansion depth\", (val) => parseInt(val, 10), 3)\n .option(\"--no-unchanged\", \"Hide unchanged nodes from the diff view\", false)\n .action(async (fileA, fileB, diffOptions) => {\n try {\n if (!fs.existsSync(fileA)) {\n console.error(pc.red(`Error: File not found: ${fileA}`));\n process.exit(1);\n }\n const rawA = await fs.promises.readFile(fileA, \"utf-8\");\n const dataA = parseJSON(rawA, fileA);\n\n let dataB: any;\n if (fileB) {\n if (!fs.existsSync(fileB)) {\n console.error(pc.red(`Error: File not found: ${fileB}`));\n process.exit(1);\n }\n const rawB = await fs.promises.readFile(fileB, \"utf-8\");\n dataB = parseJSON(rawB, fileB);\n } else {\n const stdinData = await readStdin();\n if (!stdinData) {\n console.error(pc.red(\"Error: Please specify second file or pipe JSON via stdin.\"));\n process.exit(1);\n }\n dataB = parseJSON(stdinData, \"stdin\");\n }\n\n const diffTree = diffJSON(dataA, dataB, `${fileA} ↔ ${fileB || \"stdin\"}`, \"$\", 0, diffOptions.depth);\n const stats = calculateDiffStats(diffTree);\n\n if (diffOptions.print || !process.stdin.isTTY) {\n console.log(\n pc.bold(\n `Diff Stats: ${pc.green(`+${stats.added}`)} ${pc.red(`-${stats.removed}`)} ${pc.yellow(`~${stats.modified}`)} ${pc.dim(`=${stats.unchanged}`)}\\n`\n )\n );\n console.log(prettyPrintDiff(diffTree, { showUnchanged: diffOptions.unchanged }));\n } else {\n const viewer = new InteractiveViewer(diffTree, true);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((err) => {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n});\n","import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Colorize and format standard JSON structure with bold keys and typed syntax highlighting.\n */\nexport function colorizeJSON(data: any, space = 2): string {\n const jsonStr = typeof data === \"string\" ? data : JSON.stringify(data, null, space);\n if (!jsonStr) return \"\";\n\n return jsonStr.replace(\n /(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,\n (match) => {\n // Object key with trailing colon\n if (/^\"/.test(match)) {\n if (/:$/.test(match)) {\n const keyName = match.slice(0, -1);\n return pc.bold(pc.cyan(keyName)) + pc.dim(\":\");\n }\n // String value\n return pc.green(match);\n }\n // Boolean value\n if (/true|false/.test(match)) {\n return pc.magenta(match);\n }\n // Null value\n if (/null/.test(match)) {\n return pc.dim(match);\n }\n // Number value\n return pc.yellow(match);\n }\n );\n}\n\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":"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","names":["import_picocolors","pc","import_picocolors","pc","import_picocolors","os","pc","readline","fs","pc"]}
|
package/dist/cli.mjs
CHANGED
|
@@ -114,6 +114,29 @@ function prettyPrintTree(node, indent = "", isLast = true) {
|
|
|
114
114
|
}
|
|
115
115
|
return lines.join("\n");
|
|
116
116
|
}
|
|
117
|
+
function colorizeJSON(data, space = 2) {
|
|
118
|
+
const jsonStr = typeof data === "string" ? data : JSON.stringify(data, null, space);
|
|
119
|
+
if (!jsonStr) return "";
|
|
120
|
+
return jsonStr.replace(
|
|
121
|
+
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
|
|
122
|
+
(match) => {
|
|
123
|
+
if (/^"/.test(match)) {
|
|
124
|
+
if (/:$/.test(match)) {
|
|
125
|
+
const keyName = match.slice(0, -1);
|
|
126
|
+
return pc.bold(pc.cyan(keyName)) + pc.dim(":");
|
|
127
|
+
}
|
|
128
|
+
return pc.green(match);
|
|
129
|
+
}
|
|
130
|
+
if (/true|false/.test(match)) {
|
|
131
|
+
return pc.magenta(match);
|
|
132
|
+
}
|
|
133
|
+
if (/null/.test(match)) {
|
|
134
|
+
return pc.dim(match);
|
|
135
|
+
}
|
|
136
|
+
return pc.yellow(match);
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
}
|
|
117
140
|
|
|
118
141
|
// src/differ.ts
|
|
119
142
|
import pc2 from "picocolors";
|
|
@@ -614,7 +637,7 @@ function parseJSON(raw, label = "Input") {
|
|
|
614
637
|
}
|
|
615
638
|
async function main() {
|
|
616
639
|
const program = new Command();
|
|
617
|
-
program.name("json-term").description("High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.").version("1.
|
|
640
|
+
program.name("json-term").description("High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.").version("1.1.0", "-v, --version", "Output the current version").argument("[file]", "JSON file to view or compare").option("-p, --print", "Print formatted non-interactive output to stdout", false).option("-F, --format <format>", "Output format: 'tree' or 'json'", "tree").option("-r, --raw", "Print standard syntax-highlighted JSON (shorthand for --format json --print)", false).option("-d, --depth <number>", "Initial tree expansion depth", (val) => parseInt(val, 10), 2).option("-s, --search <query>", "Filter tree by key or value query").action(async (fileArg, options) => {
|
|
618
641
|
try {
|
|
619
642
|
let raw = "";
|
|
620
643
|
if (fileArg) {
|
|
@@ -631,6 +654,10 @@ async function main() {
|
|
|
631
654
|
process.exit(1);
|
|
632
655
|
}
|
|
633
656
|
const data = parseJSON(raw, fileArg || "stdin");
|
|
657
|
+
if (options.raw || options.format === "json") {
|
|
658
|
+
console.log(colorizeJSON(data));
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
634
661
|
const tree = buildTree(data, fileArg || "root", "$", 0, options.depth);
|
|
635
662
|
if (options.print || !process.stdin.isTTY) {
|
|
636
663
|
console.log(prettyPrintTree(tree));
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport fs from \"fs\";\nimport pc from \"picocolors\";\nimport { buildTree, prettyPrintTree } from \"./formatter.js\";\nimport { diffJSON, prettyPrintDiff, calculateDiffStats } from \"./differ.js\";\nimport { InteractiveViewer } from \"./interactive.js\";\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = \"\";\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n process.stdin.on(\"end\", () => {\n resolve(data.trim());\n });\n setTimeout(() => {\n if (!data) resolve(\"\");\n }, 100);\n });\n}\n\nfunction parseJSON(raw: string, label = \"Input\"): any {\n try {\n return JSON.parse(raw);\n } catch (err: any) {\n throw new Error(`Invalid JSON in ${label}: ${err.message}`);\n }\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name(\"json-term\")\n .description(\"High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.\")\n .version(\"1.0.0\", \"-v, --version\", \"Output the current version\")\n .argument(\"[file]\", \"JSON file to view or compare\")\n .option(\"-p, --print\", \"Print formatted non-interactive tree to stdout\", false)\n .option(\"-d, --depth <number>\", \"Initial tree expansion depth\", (val) => parseInt(val, 10), 2)\n .option(\"-s, --search <query>\", \"Filter tree by key or value query\")\n .action(async (fileArg, options) => {\n try {\n let raw = \"\";\n if (fileArg) {\n if (!fs.existsSync(fileArg)) {\n console.error(pc.red(`Error: File not found: ${fileArg}`));\n process.exit(1);\n }\n raw = await fs.promises.readFile(fileArg, \"utf-8\");\n } else {\n raw = await readStdin();\n }\n\n if (!raw) {\n program.help();\n process.exit(1);\n }\n\n const data = parseJSON(raw, fileArg || \"stdin\");\n const tree = buildTree(data, fileArg || \"root\", \"$\", 0, options.depth);\n\n if (options.print || !process.stdin.isTTY) {\n console.log(prettyPrintTree(tree));\n } else {\n const viewer = new InteractiveViewer(tree, false);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n // Diff subcommand\n program\n .command(\"diff <fileA> [fileB]\")\n .description(\"Structural JSON diff between two files or stdin\")\n .option(\"-p, --print\", \"Print formatted non-interactive diff to stdout\", false)\n .option(\"-d, --depth <number>\", \"Initial expansion depth\", (val) => parseInt(val, 10), 3)\n .option(\"--no-unchanged\", \"Hide unchanged nodes from the diff view\", false)\n .action(async (fileA, fileB, diffOptions) => {\n try {\n if (!fs.existsSync(fileA)) {\n console.error(pc.red(`Error: File not found: ${fileA}`));\n process.exit(1);\n }\n const rawA = await fs.promises.readFile(fileA, \"utf-8\");\n const dataA = parseJSON(rawA, fileA);\n\n let dataB: any;\n if (fileB) {\n if (!fs.existsSync(fileB)) {\n console.error(pc.red(`Error: File not found: ${fileB}`));\n process.exit(1);\n }\n const rawB = await fs.promises.readFile(fileB, \"utf-8\");\n dataB = parseJSON(rawB, fileB);\n } else {\n const stdinData = await readStdin();\n if (!stdinData) {\n console.error(pc.red(\"Error: Please specify second file or pipe JSON via stdin.\"));\n process.exit(1);\n }\n dataB = parseJSON(stdinData, \"stdin\");\n }\n\n const diffTree = diffJSON(dataA, dataB, `${fileA} ↔ ${fileB || \"stdin\"}`, \"$\", 0, diffOptions.depth);\n const stats = calculateDiffStats(diffTree);\n\n if (diffOptions.print || !process.stdin.isTTY) {\n console.log(\n pc.bold(\n `Diff Stats: ${pc.green(`+${stats.added}`)} ${pc.red(`-${stats.removed}`)} ${pc.yellow(`~${stats.modified}`)} ${pc.dim(`=${stats.unchanged}`)}\\n`\n )\n );\n console.log(prettyPrintDiff(diffTree, { showUnchanged: diffOptions.unchanged }));\n } else {\n const viewer = new InteractiveViewer(diffTree, true);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((err) => {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n});\n","import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,OAAO,QAAQ;AACf,OAAOA,SAAQ;;;ACFf,OAAO,QAAQ;AAMR,SAAS,aAAa,OAA2B;AACtD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,UAAW,QAAO;AAC5B,SAAO;AACT;AAKO,SAAS,YAAY,OAAY,cAAc,IAAY;AAChE,QAAM,OAAO,aAAa,KAAK;AAE/B,UAAQ,MAAM;AAAA,IACZ,KAAK,UAAU;AACb,YAAM,MAAM,KAAK,UAAU,KAAK;AAChC,YAAM,YAAY,IAAI,SAAS,cAAc,IAAI,MAAM,GAAG,cAAc,CAAC,IAAI,SAAS;AACtF,aAAO,GAAG,MAAM,SAAS;AAAA,IAC3B;AAAA,IACA,KAAK;AACH,aAAO,GAAG,OAAO,OAAO,KAAK,CAAC;AAAA,IAChC,KAAK;AACH,aAAO,GAAG,QAAQ,OAAO,KAAK,CAAC;AAAA,IACjC,KAAK;AACH,aAAO,GAAG,IAAI,MAAM;AAAA,IACtB,KAAK;AACH,aAAO,GAAG,IAAI,IAAI,MAAM,MAAM,SAAS;AAAA,IACzC,KAAK;AACH,aAAO,GAAG,IAAI,IAAI,OAAO,KAAK,KAAK,EAAE,MAAM,QAAQ;AAAA,IACrD;AACE,aAAO,OAAO,KAAK;AAAA,EACvB;AACF;AAKO,SAAS,UAAU,KAAqB;AAC7C,SAAO,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC;AAC7B;AAKO,SAAS,UACd,MACA,KACA,OAAO,KACP,QAAQ,GACR,kBAAkB,GAClB,UACU;AACV,QAAM,OAAO,aAAa,IAAI;AAC9B,QAAM,KAAK,GAAG,IAAI,IAAI,OAAO,MAAM,IAAI,KAAK;AAC5C,QAAM,YAAY,SAAS;AAE3B,QAAM,OAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS,YAAY,SAAS,MAAM;AACtC,UAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,SAAK,YAAY,KAAK;AACtB,SAAK,WAAW,KAAK;AAAA,MAAI,CAAC,MACxB;AAAA,QACE,KAAK,CAAC;AAAA,QACN;AAAA,QACA,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;AAAA,QAC/B,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,SAAS,SAAS;AAC3B,SAAK,YAAY,KAAK;AACtB,SAAK,WAAW,KAAK;AAAA,MAAI,CAAC,MAAW,QACnC;AAAA,QACE;AAAA,QACA,IAAI,GAAG;AAAA,QACP,GAAG,IAAI,IAAI,GAAG;AAAA,QACd,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,gBAAgB,MAAgB,SAAS,IAAI,SAAS,MAAc;AAClF,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,SAAS,KAAK,SAAS,YAAY,KAAK,SAAS,UAAW,KAAK,YAAY,GAAG,KAAK,SAAI,IAAI,GAAG,KAAK,SAAI,IAAK,GAAG,IAAI,SAAI;AAE/H,MAAI,OAAO;AACX,MAAI,CAAC,QAAQ;AACX,UAAM,SAAS,SAAS,wBAAS;AACjC,YAAQ,GAAG,IAAI,SAAS,MAAM,IAAI;AAClC,QAAI,KAAK,KAAK;AACZ,cAAQ,UAAU,KAAK,GAAG,IAAI,GAAG,IAAI,IAAI;AAAA,IAC3C;AAAA,EACF,OAAO;AACL,YAAQ,UAAU,KAAK,MAAM,UAAU,KAAK,GAAG,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,GAAG,MAAM,QAAQ,CAAC;AAAA,EAC9F;AAEA,MAAI,KAAK,SAAS,UAAU;AAC1B,YAAQ,GAAG,IAAI,KAAK,KAAK,SAAS,SAAS;AAAA,EAC7C,WAAW,KAAK,SAAS,SAAS;AAChC,YAAQ,GAAG,IAAI,KAAK,KAAK,SAAS,UAAU;AAAA,EAC9C,OAAO;AACL,YAAQ,YAAY,KAAK,KAAK;AAAA,EAChC;AAEA,QAAM,QAAQ,CAAC,IAAI;AAEnB,MAAI,CAAC,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAChE,UAAM,aAAa,SAAS,KAAK,UAAU,SAAS,SAAS;AAC7D,SAAK,SAAS,QAAQ,CAAC,OAAO,UAAU;AACtC,YAAM,cAAc,UAAU,KAAK,SAAU,SAAS;AACtD,YAAM,KAAK,gBAAgB,OAAO,YAAY,WAAW,CAAC;AAAA,IAC5D,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AChJA,OAAOC,SAAQ;AAcR,SAAS,SACd,GACA,GACA,KACA,OAAO,KACP,QAAQ,GACR,kBAAkB,GACR;AACV,QAAM,QAAQ,aAAa,CAAC;AAC5B,QAAM,QAAQ,aAAa,CAAC;AAC5B,QAAM,KAAK,GAAG,IAAI,IAAI,OAAO,MAAM,IAAI,KAAK;AAC5C,QAAM,YAAY,SAAS;AAG3B,MAAI,MAAM,UAAa,MAAM,QAAW;AACtC,UAAM,OAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AACA,QAAI,UAAU,YAAY,MAAM,MAAM;AACpC,WAAK,YAAY,OAAO,KAAK,CAAC,EAAE;AAChC,WAAK,WAAW,OAAO,KAAK,CAAC,EAAE;AAAA,QAAI,CAAC,MAClC,SAAS,QAAW,EAAE,CAAC,GAAG,GAAG,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,QAAQ,GAAG,eAAe;AAAA,MAC5F;AAAA,IACF,WAAW,UAAU,SAAS;AAC5B,WAAK,YAAY,EAAE;AACnB,WAAK,WAAW,EAAE;AAAA,QAAI,CAAC,MAAW,QAChC,SAAS,QAAW,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,IAAI,GAAG,KAAK,QAAQ,GAAG,eAAe;AAAA,MACrF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,UAAa,MAAM,QAAW;AACtC,UAAM,OAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AACA,QAAI,UAAU,YAAY,MAAM,MAAM;AACpC,WAAK,YAAY,OAAO,KAAK,CAAC,EAAE;AAChC,WAAK,WAAW,OAAO,KAAK,CAAC,EAAE;AAAA,QAAI,CAAC,MAClC,SAAS,EAAE,CAAC,GAAG,QAAW,GAAG,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,QAAQ,GAAG,eAAe;AAAA,MAC5F;AAAA,IACF,WAAW,UAAU,SAAS;AAC5B,WAAK,YAAY,EAAE;AACnB,WAAK,WAAW,EAAE;AAAA,QAAI,CAAC,MAAW,QAChC,SAAS,MAAM,QAAW,IAAI,GAAG,KAAK,GAAG,IAAI,IAAI,GAAG,KAAK,QAAQ,GAAG,eAAe;AAAA,MACrF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,UAAU,OAAO;AACnB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,EACF;AAGA,MAAI,UAAU,YAAY,MAAM,QAAQ,MAAM,MAAM;AAClD,UAAM,UAAU,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,UAAM,WAAuB,CAAC;AAC9B,QAAI,mBAAmB;AAEvB,eAAW,KAAK,SAAS;AACvB,YAAM,QAAQ;AAAA,QACZ,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH;AAAA,QACA,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;AAAA,QAC/B,QAAQ;AAAA,QACR;AAAA,MACF;AACA,UAAI,MAAM,WAAW,YAAa,oBAAmB;AACrD,eAAS,KAAK,KAAK;AAAA,IACrB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,mBAAmB,aAAa;AAAA,MACxC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU,SAAS;AACrB,UAAM,SAAS,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAM,WAAuB,CAAC;AAC9B,QAAI,mBAAmB;AAEvB,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,YAAM,QAAQ;AAAA,QACZ,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH,IAAI,CAAC;AAAA,QACL,GAAG,IAAI,IAAI,CAAC;AAAA,QACZ,QAAQ;AAAA,QACR;AAAA,MACF;AACA,UAAI,MAAM,WAAW,YAAa,oBAAmB;AACrD,eAAS,KAAK,KAAK;AAAA,IACrB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,mBAAmB,aAAa;AAAA,MACxC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN;AAAA,EACF;AACF;AAKO,SAAS,mBAAmB,MAA2B;AAC5D,QAAM,QAAmB,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,EAAE;AAE3E,WAAS,SAAS,GAAa;AAC7B,QAAI,EAAE,YAAY,EAAE,SAAS,SAAS,GAAG;AACvC,QAAE,SAAS,QAAQ,QAAQ;AAAA,IAC7B,OAAO;AACL,YAAM,EAAE,MAAM;AAAA,IAChB;AAAA,EACF;AAEA,WAAS,IAAI;AACb,SAAO;AACT;AAKO,SAAS,gBACd,MACA,UAAuC,CAAC,GACxC,SAAS,IACT,SAAS,MACD;AACR,QAAM,gBAAgB,QAAQ,iBAAiB;AAE/C,MAAI,CAAC,iBAAiB,KAAK,WAAW,gBAAgB,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,IAAI;AACnG,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,KAAK,UAAU;AAC9B,MAAI,SAAS;AACb,MAAI,cAAcC,IAAG;AAErB,MAAI,KAAK,WAAW,SAAS;AAC3B,aAASA,IAAG,MAAM,IAAI;AACtB,kBAAcA,IAAG;AAAA,EACnB,WAAW,KAAK,WAAW,WAAW;AACpC,aAASA,IAAG,IAAI,IAAI;AACpB,kBAAcA,IAAG;AAAA,EACnB,WAAW,KAAK,WAAW,YAAY;AACrC,aAASA,IAAG,OAAO,IAAI;AACvB,kBAAcA,IAAG;AAAA,EACnB;AAEA,MAAI,OAAO;AACX,MAAI,CAAC,QAAQ;AACX,UAAM,SAAS,SAAS,wBAAS;AACjC,YAAQA,IAAG,IAAI,SAAS,MAAM;AAC9B,QAAI,KAAK,KAAK;AACZ,cAAQ,UAAU,KAAK,GAAG,IAAIA,IAAG,IAAI,IAAI;AAAA,IAC3C;AAAA,EACF,OAAO;AACL,YAAQ,KAAK,MAAM,UAAU,KAAK,GAAG,IAAIA,IAAG,IAAI,IAAI,IAAIA,IAAG,KAAK,QAAQ;AAAA,EAC1E;AAEA,MAAI,KAAK,WAAW,SAAS;AAC3B,YAAQ,YAAY,YAAY,KAAK,QAAQ,CAAC;AAAA,EAChD,WAAW,KAAK,WAAW,WAAW;AACpC,YAAQ,YAAY,YAAY,KAAK,QAAQ,CAAC;AAAA,EAChD,WAAW,KAAK,WAAW,YAAY;AACrC,QAAI,KAAK,SAAS,YAAY,KAAK,SAAS,SAAS;AACnD,cAAQ,YAAY,KAAK,KAAK,SAAS,mBAAmB;AAAA,IAC5D,OAAO;AACL,cAAQ,GAAGA,IAAG,IAAI,YAAY,KAAK,QAAQ,CAAC,CAAC,IAAIA,IAAG,IAAI,IAAI,CAAC,IAAIA,IAAG,MAAM,YAAY,KAAK,QAAQ,CAAC,CAAC;AAAA,IACvG;AAAA,EACF,OAAO;AAEL,YAAQA,IAAG,IAAI,YAAY,KAAK,QAAQ,CAAC;AAAA,EAC3C;AAEA,QAAM,QAAQ,CAAC,IAAI;AAEnB,MAAI,CAAC,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAChE,UAAM,aAAa,SAAS,KAAK,UAAU,SAAS,SAAS;AAC7D,SAAK,SAAS,QAAQ,CAAC,OAAO,UAAU;AACtC,YAAM,cAAc,UAAU,KAAK,SAAU,SAAS;AACtD,YAAM,WAAW,gBAAgB,OAAO,SAAS,YAAY,WAAW;AACxE,UAAI,SAAU,OAAM,KAAK,QAAQ;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACrRA,OAAO,cAAc;AACrB,OAAOC,SAAQ;;;ACDf,SAAS,YAAY;AACrB,OAAO,QAAQ;AAKf,eAAsB,gBAAgB,MAAgC;AACpE,QAAM,WAAW,GAAG,SAAS;AAE7B,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI;AACJ,QAAI,aAAa,UAAU;AACzB,aAAO,KAAK,UAAU,CAAC,QAAQ,QAAQ,CAAC,GAAG,CAAC;AAAA,IAC9C,WAAW,aAAa,SAAS;AAC/B,aAAO,KAAK,QAAQ,CAAC,QAAQ,QAAQ,CAAC,GAAG,CAAC;AAAA,IAC5C,OAAO;AAEL,aAAO,KAAK,6FAA6F,CAAC,QAAQ;AAChH,gBAAQ,CAAC,GAAG;AAAA,MACd,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,MAAM,IAAI;AACrB,WAAK,MAAM,IAAI;AAAA,IACjB,OAAO;AACL,cAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH;;;ADZO,IAAM,oBAAN,MAAwB;AAAA,EACrB;AAAA,EACA,WAAuB,CAAC;AAAA,EACxB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,oBAA2C;AAAA,EAC3C;AAAA,EAER,YAAY,MAAe,SAAS,OAAO;AACzC,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,WAAW,MAAiC;AAClD,WAAO,KAAK,UAAU,YAAY;AAAA,EACpC;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,OAAmB,CAAC;AAE1B,UAAM,WAAW,CAAC,MAAe,iBAAyB;AAExD,UAAI,KAAK,aAAa;AACpB,cAAM,QAAQ,KAAK,YAAY,YAAY;AAC3C,cAAM,WAAW,KAAK,OAAO,KAAK,IAAI,YAAY,EAAE,SAAS,KAAK;AAClE,cAAM,YAAY,KAAK,QAAQ,KAAK,KAAK,YAAY,EAAE,SAAS,KAAK;AACrE,cAAM,WACJ,WAAW,OACP,KAAK,UAAU,KAAK,KAAK,EAAE,YAAY,EAAE,SAAS,KAAK,IACvD,cAAc,OACd,KAAK,UAAU,KAAK,QAAQ,EAAE,YAAY,EAAE,SAAS,KAAK,IAC1D;AAEN,YAAI,CAAC,YAAY,CAAC,aAAa,CAAC,aAAa,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,IAAI;AAC1F;AAAA,QACF;AAAA,MACF;AAEA,WAAK,KAAK,EAAE,MAAM,OAAO,cAAc,QAAQ,KAAK,OAAO,CAAC;AAE5D,UAAI,CAAC,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAChE,mBAAW,SAAS,KAAK,UAAU;AACjC,mBAAS,OAAO,eAAe,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,aAAS,KAAK,MAAM,CAAC;AACrB,SAAK,WAAW;AAEhB,QAAI,KAAK,iBAAiB,KAAK,SAAS,QAAQ;AAC9C,WAAK,gBAAgB,KAAK,IAAI,GAAG,KAAK,SAAS,SAAS,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EAEQ,gBAAgB,KAAmB;AACzC,SAAK,eAAe;AACpB,QAAI,KAAK,kBAAmB,cAAa,KAAK,iBAAiB;AAC/D,SAAK,oBAAoB,WAAW,MAAM;AACxC,WAAK,eAAe;AACpB,WAAK,OAAO;AAAA,IACd,GAAG,IAAI;AAAA,EACT;AAAA,EAEQ,SAAe;AACrB,UAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,UAAM,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC;AAG3C,QAAI,WAAW;AACf,QAAI,KAAK,iBAAiB,gBAAgB;AACxC,iBAAW,KAAK,gBAAgB,iBAAiB;AAAA,IACnD;AACA,UAAM,SAAS,KAAK,IAAI,KAAK,SAAS,QAAQ,WAAW,cAAc;AAGvE,YAAQ,OAAO,MAAM,+BAA+B;AAGpD,UAAM,QAAQ,KAAK,SAAS,oCAAoC;AAChE,YAAQ,IAAIC,IAAG,OAAOA,IAAG,MAAMA,IAAG,KAAK,IAAI,KAAK,GAAG,CAAC,IAAIA,IAAG,IAAI,kBAAkB,KAAK,SAAS,MAAM,GAAG,CAAC,CAAC;AAG1G,aAAS,IAAI,UAAU,IAAI,QAAQ,KAAK;AACtC,YAAM,EAAE,MAAM,MAAM,IAAI,KAAK,SAAS,CAAC;AACvC,YAAM,aAAa,MAAM,KAAK;AAC9B,YAAM,SAAS,KAAK,OAAO,KAAK;AAEhC,UAAI,SAAS;AACb,UAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC7C,iBAAS,KAAK,YAAY,YAAO;AAAA,MACnC;AAEA,UAAI,cAAc;AAElB,UAAI,KAAK,WAAW,IAAI,GAAG;AACzB,YAAI,aAAa;AACjB,YAAI,KAAK,WAAW,QAAS,cAAaA,IAAG,MAAM,IAAI;AAAA,iBAC9C,KAAK,WAAW,UAAW,cAAaA,IAAG,IAAI,IAAI;AAAA,iBACnD,KAAK,WAAW,WAAY,cAAaA,IAAG,OAAO,IAAI;AAEhE,sBAAc,aAAa,SAAS;AACpC,YAAI,KAAK,IAAK,gBAAe,UAAU,KAAK,GAAG,IAAIA,IAAG,IAAI,IAAI;AAE9D,YAAI,KAAK,WAAW,SAAS;AAC3B,yBAAeA,IAAG,MAAM,YAAY,KAAK,UAAU,EAAE,CAAC;AAAA,QACxD,WAAW,KAAK,WAAW,WAAW;AACpC,yBAAeA,IAAG,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;AAAA,QACtD,WAAW,KAAK,WAAW,YAAY;AACrC,cAAI,KAAK,SAAS,YAAY,KAAK,SAAS,SAAS;AACnD,2BAAeA,IAAG,OAAO,KAAK,KAAK,SAAS,aAAa;AAAA,UAC3D,OAAO;AACL,2BAAe,GAAGA,IAAG,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC,CAAC,OAAOA,IAAG,MAAM,YAAY,KAAK,UAAU,EAAE,CAAC,CAAC;AAAA,UACzG;AAAA,QACF,OAAO;AACL,yBAAeA,IAAG,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;AAAA,QACtD;AAAA,MACF,OAAO;AACL,cAAM,WAAW;AACjB,sBAAc,SAAS;AACvB,YAAI,SAAS,IAAK,gBAAe,UAAU,SAAS,GAAG,IAAIA,IAAG,IAAI,IAAI;AAEtE,YAAI,SAAS,SAAS,UAAU;AAC9B,yBAAeA,IAAG,IAAI,KAAK,SAAS,SAAS,SAAS;AAAA,QACxD,WAAW,SAAS,SAAS,SAAS;AACpC,yBAAeA,IAAG,IAAI,KAAK,SAAS,SAAS,UAAU;AAAA,QACzD,OAAO;AACL,yBAAe,YAAY,SAAS,OAAO,EAAE;AAAA,QAC/C;AAAA,MACF;AAEA,UAAI,YAAY;AACd,gBAAQ,IAAIA,IAAG,OAAOA,IAAG,MAAMA,IAAG,KAAK,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC;AAAA,MAC9D,OAAO;AACL,gBAAQ,IAAI,KAAK,WAAW,EAAE;AAAA,MAChC;AAAA,IACF;AAGA,UAAM,eAAe,KAAK,SAAS,KAAK,aAAa;AACrD,UAAM,cAAc,eAAe,aAAa,KAAK,OAAO;AAE5D,YAAQ,IAAI,OAAOA,IAAG,IAAI,SAAI,OAAO,KAAK,IAAI,QAAQ,OAAO,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;AACjF,QAAI,KAAK,cAAc;AACrB,cAAQ,IAAIA,IAAG,MAAMA,IAAG,KAAK,IAAI,KAAK,YAAY,EAAE,CAAC,CAAC;AAAA,IACxD,WAAW,KAAK,aAAa;AAC3B,cAAQ,IAAIA,IAAG,OAAOA,IAAG,KAAK,aAAa,KAAK,WAAW,QAAG,CAAC,CAAC;AAAA,IAClE,OAAO;AACL,cAAQ,IAAIA,IAAG,KAAKA,IAAG,KAAK,UAAU,WAAW,EAAE,CAAC,CAAC;AACrD,cAAQ;AAAA,QACNA,IAAG,IAAI,kIAAwH;AAAA,MACjI;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAU,MAAqB;AACrC,SAAK,YAAY;AACjB,QAAI,KAAK,SAAU,MAAK,SAAS,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,EACnE;AAAA,EAEQ,YAAY,MAAqB;AACvC,QAAI,KAAK,QAAQ,EAAG,MAAK,YAAY;AACrC,QAAI,KAAK,SAAU,MAAK,SAAS,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;AAAA,EACrE;AAAA,EAEA,MAAa,QAAuB;AAClC,QAAI,CAAC,QAAQ,MAAM,OAAO;AACxB;AAAA,IACF;AAEA,aAAS,mBAAmB,QAAQ,KAAK;AACzC,YAAQ,MAAM,WAAW,IAAI;AAC7B,YAAQ,MAAM,OAAO;AAErB,SAAK,OAAO;AAEZ,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,aAAa,OAAO,KAAa,QAAsB;AAC3D,YAAI,KAAK,aAAa;AACpB,cAAI,IAAI,SAAS,UAAU;AACzB,iBAAK,cAAc,KAAK;AACxB,iBAAK,cAAc;AACnB,iBAAK,gBAAgB;AACrB,iBAAK,OAAO;AACZ;AAAA,UACF;AACA,cAAI,IAAI,SAAS,UAAU;AACzB,iBAAK,cAAc;AACnB,iBAAK,cAAc;AACnB,iBAAK,OAAO;AACZ;AAAA,UACF;AACA,cAAI,IAAI,SAAS,aAAa;AAC5B,iBAAK,cAAc,KAAK,YAAY,MAAM,GAAG,EAAE;AAC/C,iBAAK,OAAO;AACZ;AAAA,UACF;AACA,cAAI,OAAO,IAAI,WAAW,GAAG;AAC3B,iBAAK,eAAe;AACpB,iBAAK,OAAO;AACZ;AAAA,UACF;AAAA,QACF;AAGA,YAAI,IAAI,SAAS,QAAQ,IAAI,SAAS,KAAK;AACzC,cAAI,KAAK,gBAAgB,GAAG;AAC1B,iBAAK;AACL,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,WAAW,IAAI,SAAS,UAAU,IAAI,SAAS,KAAK;AAClD,cAAI,KAAK,gBAAgB,KAAK,SAAS,SAAS,GAAG;AACjD,iBAAK;AACL,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,WAAW,IAAI,SAAS,YAAY,IAAI,SAAS,WAAW,IAAI,SAAS,WAAW,IAAI,SAAS,QAAQ;AACvG,gBAAM,OAAO,KAAK,SAAS,KAAK,aAAa;AAC7C,cAAI,QAAQ,KAAK,KAAK,YAAY,KAAK,KAAK,SAAS,SAAS,GAAG;AAC/D,iBAAK,KAAK,YAAY,CAAC,KAAK,KAAK;AACjC,iBAAK,gBAAgB;AACrB,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,eAAK,UAAU,KAAK,IAAI;AACxB,eAAK,gBAAgB;AACrB,eAAK,OAAO;AAAA,QACd,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,eAAK,YAAY,KAAK,IAAI;AAC1B,eAAK,gBAAgB;AACrB,eAAK,OAAO;AAAA,QACd,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,gBAAM,OAAO,KAAK,SAAS,KAAK,aAAa;AAC7C,cAAI,MAAM;AACR,kBAAM,gBAAgB,KAAK,KAAK,IAAI;AACpC,iBAAK,gBAAgB,2BAAsB,KAAK,KAAK,IAAI,EAAE;AAAA,UAC7D;AAAA,QACF,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,gBAAM,OAAO,KAAK,SAAS,KAAK,aAAa;AAC7C,cAAI,MAAM;AACR,kBAAM,MAAM,WAAW,KAAK,OAAO,KAAK,KAAK,QAAS,KAAK,KAAkB;AAC7E,kBAAM,aAAa,OAAO,QAAQ,WAAW,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI,OAAO,GAAG;AACtF,kBAAM,gBAAgB,UAAU;AAChC,iBAAK,gBAAgB,mCAA8B;AAAA,UACrD;AAAA,QACF,WAAW,QAAQ,KAAK;AACtB,eAAK,cAAc;AACnB,eAAK,cAAc;AACnB,eAAK,OAAO;AAAA,QACd,WAAW,IAAI,QAAQ,IAAI,SAAS,OAAO,IAAI,SAAS,YAAY,QAAQ,OAAO,QAAQ,KAAK;AAE9F,kBAAQ,MAAM,eAAe,YAAY,UAAU;AACnD,kBAAQ,MAAM,WAAW,KAAK;AAC9B,kBAAQ,MAAM,MAAM;AACpB,kBAAQ,OAAO,MAAM,aAAa;AAClC,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,cAAQ,MAAM,GAAG,YAAY,UAAU;AAAA,IACzC,CAAC;AAAA,EACH;AACF;;;AHnRA,eAAe,YAA6B;AAC1C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,OAAO;AACX,QAAI,QAAQ,MAAM,OAAO;AACvB,cAAQ,EAAE;AACV;AAAA,IACF;AAEA,YAAQ,MAAM,YAAY,OAAO;AACjC,YAAQ,MAAM,GAAG,QAAQ,CAAC,UAAU;AAClC,cAAQ;AAAA,IACV,CAAC;AACD,YAAQ,MAAM,GAAG,OAAO,MAAM;AAC5B,cAAQ,KAAK,KAAK,CAAC;AAAA,IACrB,CAAC;AACD,eAAW,MAAM;AACf,UAAI,CAAC,KAAM,SAAQ,EAAE;AAAA,IACvB,GAAG,GAAG;AAAA,EACR,CAAC;AACH;AAEA,SAAS,UAAU,KAAa,QAAQ,SAAc;AACpD,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,SAAS,KAAU;AACjB,UAAM,IAAI,MAAM,mBAAmB,KAAK,KAAK,IAAI,OAAO,EAAE;AAAA,EAC5D;AACF;AAEA,eAAe,OAAO;AACpB,QAAM,UAAU,IAAI,QAAQ;AAE5B,UACG,KAAK,WAAW,EAChB,YAAY,+HAA+H,EAC3I,QAAQ,SAAS,iBAAiB,4BAA4B,EAC9D,SAAS,UAAU,8BAA8B,EACjD,OAAO,eAAe,kDAAkD,KAAK,EAC7E,OAAO,wBAAwB,gCAAgC,CAAC,QAAQ,SAAS,KAAK,EAAE,GAAG,CAAC,EAC5F,OAAO,wBAAwB,mCAAmC,EAClE,OAAO,OAAO,SAAS,YAAY;AAClC,QAAI;AACF,UAAI,MAAM;AACV,UAAI,SAAS;AACX,YAAI,CAAC,GAAG,WAAW,OAAO,GAAG;AAC3B,kBAAQ,MAAMC,IAAG,IAAI,0BAA0B,OAAO,EAAE,CAAC;AACzD,kBAAQ,KAAK,CAAC;AAAA,QAChB;AACA,cAAM,MAAM,GAAG,SAAS,SAAS,SAAS,OAAO;AAAA,MACnD,OAAO;AACL,cAAM,MAAM,UAAU;AAAA,MACxB;AAEA,UAAI,CAAC,KAAK;AACR,gBAAQ,KAAK;AACb,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,OAAO,UAAU,KAAK,WAAW,OAAO;AAC9C,YAAM,OAAO,UAAU,MAAM,WAAW,QAAQ,KAAK,GAAG,QAAQ,KAAK;AAErE,UAAI,QAAQ,SAAS,CAAC,QAAQ,MAAM,OAAO;AACzC,gBAAQ,IAAI,gBAAgB,IAAI,CAAC;AAAA,MACnC,OAAO;AACL,cAAM,SAAS,IAAI,kBAAkB,MAAM,KAAK;AAChD,cAAM,OAAO,MAAM;AAAA,MACrB;AAAA,IACF,SAAS,KAAU;AACjB,cAAQ,MAAMA,IAAG,IAAI,UAAU,IAAI,WAAW,GAAG,EAAE,CAAC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAGH,UACG,QAAQ,sBAAsB,EAC9B,YAAY,iDAAiD,EAC7D,OAAO,eAAe,kDAAkD,KAAK,EAC7E,OAAO,wBAAwB,2BAA2B,CAAC,QAAQ,SAAS,KAAK,EAAE,GAAG,CAAC,EACvF,OAAO,kBAAkB,2CAA2C,KAAK,EACzE,OAAO,OAAO,OAAO,OAAO,gBAAgB;AAC3C,QAAI;AACF,UAAI,CAAC,GAAG,WAAW,KAAK,GAAG;AACzB,gBAAQ,MAAMA,IAAG,IAAI,0BAA0B,KAAK,EAAE,CAAC;AACvD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM,OAAO,MAAM,GAAG,SAAS,SAAS,OAAO,OAAO;AACtD,YAAM,QAAQ,UAAU,MAAM,KAAK;AAEnC,UAAI;AACJ,UAAI,OAAO;AACT,YAAI,CAAC,GAAG,WAAW,KAAK,GAAG;AACzB,kBAAQ,MAAMA,IAAG,IAAI,0BAA0B,KAAK,EAAE,CAAC;AACvD,kBAAQ,KAAK,CAAC;AAAA,QAChB;AACA,cAAM,OAAO,MAAM,GAAG,SAAS,SAAS,OAAO,OAAO;AACtD,gBAAQ,UAAU,MAAM,KAAK;AAAA,MAC/B,OAAO;AACL,cAAM,YAAY,MAAM,UAAU;AAClC,YAAI,CAAC,WAAW;AACd,kBAAQ,MAAMA,IAAG,IAAI,2DAA2D,CAAC;AACjF,kBAAQ,KAAK,CAAC;AAAA,QAChB;AACA,gBAAQ,UAAU,WAAW,OAAO;AAAA,MACtC;AAEA,YAAM,WAAW,SAAS,OAAO,OAAO,GAAG,KAAK,WAAM,SAAS,OAAO,IAAI,KAAK,GAAG,YAAY,KAAK;AACnG,YAAM,QAAQ,mBAAmB,QAAQ;AAEzC,UAAI,YAAY,SAAS,CAAC,QAAQ,MAAM,OAAO;AAC7C,gBAAQ;AAAA,UACNA,IAAG;AAAA,YACD,eAAeA,IAAG,MAAM,IAAI,MAAM,KAAK,EAAE,CAAC,IAAIA,IAAG,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,IAAIA,IAAG,OAAO,IAAI,MAAM,QAAQ,EAAE,CAAC,IAAIA,IAAG,IAAI,IAAI,MAAM,SAAS,EAAE,CAAC;AAAA;AAAA,UAC/I;AAAA,QACF;AACA,gBAAQ,IAAI,gBAAgB,UAAU,EAAE,eAAe,YAAY,UAAU,CAAC,CAAC;AAAA,MACjF,OAAO;AACL,cAAM,SAAS,IAAI,kBAAkB,UAAU,IAAI;AACnD,cAAM,OAAO,MAAM;AAAA,MACrB;AAAA,IACF,SAAS,KAAU;AACjB,cAAQ,MAAMA,IAAG,IAAI,UAAU,IAAI,WAAW,GAAG,EAAE,CAAC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,QAAM,QAAQ,WAAW,QAAQ,IAAI;AACvC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAMA,IAAG,IAAI,UAAU,IAAI,WAAW,GAAG,EAAE,CAAC;AACpD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["pc","pc","pc","pc","pc","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport fs from \"fs\";\nimport pc from \"picocolors\";\nimport { buildTree, prettyPrintTree, colorizeJSON } from \"./formatter.js\";\nimport { diffJSON, prettyPrintDiff, calculateDiffStats } from \"./differ.js\";\nimport { InteractiveViewer } from \"./interactive.js\";\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve) => {\n let data = \"\";\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n process.stdin.on(\"end\", () => {\n resolve(data.trim());\n });\n setTimeout(() => {\n if (!data) resolve(\"\");\n }, 100);\n });\n}\n\nfunction parseJSON(raw: string, label = \"Input\"): any {\n try {\n return JSON.parse(raw);\n } catch (err: any) {\n throw new Error(`Invalid JSON in ${label}: ${err.message}`);\n }\n}\n\nasync function main() {\n const program = new Command();\n\n program\n .name(\"json-term\")\n .description(\"High-fidelity interactive terminal JSON viewer, collapsible tree explorer, type syntax highlighter, and structural diff tool.\")\n .version(\"1.1.0\", \"-v, --version\", \"Output the current version\")\n .argument(\"[file]\", \"JSON file to view or compare\")\n .option(\"-p, --print\", \"Print formatted non-interactive output to stdout\", false)\n .option(\"-F, --format <format>\", \"Output format: 'tree' or 'json'\", \"tree\")\n .option(\"-r, --raw\", \"Print standard syntax-highlighted JSON (shorthand for --format json --print)\", false)\n .option(\"-d, --depth <number>\", \"Initial tree expansion depth\", (val) => parseInt(val, 10), 2)\n .option(\"-s, --search <query>\", \"Filter tree by key or value query\")\n .action(async (fileArg, options) => {\n try {\n let raw = \"\";\n if (fileArg) {\n if (!fs.existsSync(fileArg)) {\n console.error(pc.red(`Error: File not found: ${fileArg}`));\n process.exit(1);\n }\n raw = await fs.promises.readFile(fileArg, \"utf-8\");\n } else {\n raw = await readStdin();\n }\n\n if (!raw) {\n program.help();\n process.exit(1);\n }\n\n const data = parseJSON(raw, fileArg || \"stdin\");\n\n // If raw/json format requested, print colorized JSON directly\n if (options.raw || options.format === \"json\") {\n console.log(colorizeJSON(data));\n return;\n }\n\n const tree = buildTree(data, fileArg || \"root\", \"$\", 0, options.depth);\n\n if (options.print || !process.stdin.isTTY) {\n console.log(prettyPrintTree(tree));\n } else {\n const viewer = new InteractiveViewer(tree, false);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n // Diff subcommand\n program\n .command(\"diff <fileA> [fileB]\")\n .description(\"Structural JSON diff between two files or stdin\")\n .option(\"-p, --print\", \"Print formatted non-interactive diff to stdout\", false)\n .option(\"-d, --depth <number>\", \"Initial expansion depth\", (val) => parseInt(val, 10), 3)\n .option(\"--no-unchanged\", \"Hide unchanged nodes from the diff view\", false)\n .action(async (fileA, fileB, diffOptions) => {\n try {\n if (!fs.existsSync(fileA)) {\n console.error(pc.red(`Error: File not found: ${fileA}`));\n process.exit(1);\n }\n const rawA = await fs.promises.readFile(fileA, \"utf-8\");\n const dataA = parseJSON(rawA, fileA);\n\n let dataB: any;\n if (fileB) {\n if (!fs.existsSync(fileB)) {\n console.error(pc.red(`Error: File not found: ${fileB}`));\n process.exit(1);\n }\n const rawB = await fs.promises.readFile(fileB, \"utf-8\");\n dataB = parseJSON(rawB, fileB);\n } else {\n const stdinData = await readStdin();\n if (!stdinData) {\n console.error(pc.red(\"Error: Please specify second file or pipe JSON via stdin.\"));\n process.exit(1);\n }\n dataB = parseJSON(stdinData, \"stdin\");\n }\n\n const diffTree = diffJSON(dataA, dataB, `${fileA} ↔ ${fileB || \"stdin\"}`, \"$\", 0, diffOptions.depth);\n const stats = calculateDiffStats(diffTree);\n\n if (diffOptions.print || !process.stdin.isTTY) {\n console.log(\n pc.bold(\n `Diff Stats: ${pc.green(`+${stats.added}`)} ${pc.red(`-${stats.removed}`)} ${pc.yellow(`~${stats.modified}`)} ${pc.dim(`=${stats.unchanged}`)}\\n`\n )\n );\n console.log(prettyPrintDiff(diffTree, { showUnchanged: diffOptions.unchanged }));\n } else {\n const viewer = new InteractiveViewer(diffTree, true);\n await viewer.start();\n }\n } catch (err: any) {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n }\n });\n\n await program.parseAsync(process.argv);\n}\n\nmain().catch((err) => {\n console.error(pc.red(`Error: ${err.message || err}`));\n process.exit(1);\n});\n","import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Colorize and format standard JSON structure with bold keys and typed syntax highlighting.\n */\nexport function colorizeJSON(data: any, space = 2): string {\n const jsonStr = typeof data === \"string\" ? data : JSON.stringify(data, null, space);\n if (!jsonStr) return \"\";\n\n return jsonStr.replace(\n /(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,\n (match) => {\n // Object key with trailing colon\n if (/^\"/.test(match)) {\n if (/:$/.test(match)) {\n const keyName = match.slice(0, -1);\n return pc.bold(pc.cyan(keyName)) + pc.dim(\":\");\n }\n // String value\n return pc.green(match);\n }\n // Boolean value\n if (/true|false/.test(match)) {\n return pc.magenta(match);\n }\n // Null value\n if (/null/.test(match)) {\n return pc.dim(match);\n }\n // Number value\n return pc.yellow(match);\n }\n );\n}\n\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":"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","names":["pc","pc","pc","pc","pc","pc"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -57,6 +57,10 @@ declare function buildTree(data: any, key?: string, path?: string, depth?: numbe
|
|
|
57
57
|
* Pretty-print JSON tree structure to terminal string.
|
|
58
58
|
*/
|
|
59
59
|
declare function prettyPrintTree(node: TreeNode, indent?: string, isLast?: boolean): string;
|
|
60
|
+
/**
|
|
61
|
+
* Colorize and format standard JSON structure with bold keys and typed syntax highlighting.
|
|
62
|
+
*/
|
|
63
|
+
declare function colorizeJSON(data: any, space?: number): string;
|
|
60
64
|
|
|
61
65
|
interface DiffStats {
|
|
62
66
|
added: number;
|
|
@@ -108,4 +112,4 @@ declare class InteractiveViewer {
|
|
|
108
112
|
*/
|
|
109
113
|
declare function copyToClipboard(text: string): Promise<boolean>;
|
|
110
114
|
|
|
111
|
-
export { type DiffNode, type DiffOptions, type DiffStats, type DiffStatus, InteractiveViewer, type JSONValueType, type TreeNode, type ViewerOptions, buildTree, calculateDiffStats, copyToClipboard, diffJSON, formatKey, formatValue, getValueType, prettyPrintDiff, prettyPrintTree };
|
|
115
|
+
export { type DiffNode, type DiffOptions, type DiffStats, type DiffStatus, InteractiveViewer, type JSONValueType, type TreeNode, type ViewerOptions, buildTree, calculateDiffStats, colorizeJSON, copyToClipboard, diffJSON, formatKey, formatValue, getValueType, prettyPrintDiff, prettyPrintTree };
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,10 @@ declare function buildTree(data: any, key?: string, path?: string, depth?: numbe
|
|
|
57
57
|
* Pretty-print JSON tree structure to terminal string.
|
|
58
58
|
*/
|
|
59
59
|
declare function prettyPrintTree(node: TreeNode, indent?: string, isLast?: boolean): string;
|
|
60
|
+
/**
|
|
61
|
+
* Colorize and format standard JSON structure with bold keys and typed syntax highlighting.
|
|
62
|
+
*/
|
|
63
|
+
declare function colorizeJSON(data: any, space?: number): string;
|
|
60
64
|
|
|
61
65
|
interface DiffStats {
|
|
62
66
|
added: number;
|
|
@@ -108,4 +112,4 @@ declare class InteractiveViewer {
|
|
|
108
112
|
*/
|
|
109
113
|
declare function copyToClipboard(text: string): Promise<boolean>;
|
|
110
114
|
|
|
111
|
-
export { type DiffNode, type DiffOptions, type DiffStats, type DiffStatus, InteractiveViewer, type JSONValueType, type TreeNode, type ViewerOptions, buildTree, calculateDiffStats, copyToClipboard, diffJSON, formatKey, formatValue, getValueType, prettyPrintDiff, prettyPrintTree };
|
|
115
|
+
export { type DiffNode, type DiffOptions, type DiffStats, type DiffStatus, InteractiveViewer, type JSONValueType, type TreeNode, type ViewerOptions, buildTree, calculateDiffStats, colorizeJSON, copyToClipboard, diffJSON, formatKey, formatValue, getValueType, prettyPrintDiff, prettyPrintTree };
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
InteractiveViewer: () => InteractiveViewer,
|
|
34
34
|
buildTree: () => buildTree,
|
|
35
35
|
calculateDiffStats: () => calculateDiffStats,
|
|
36
|
+
colorizeJSON: () => colorizeJSON,
|
|
36
37
|
copyToClipboard: () => copyToClipboard,
|
|
37
38
|
diffJSON: () => diffJSON,
|
|
38
39
|
formatKey: () => formatKey,
|
|
@@ -152,6 +153,29 @@ function prettyPrintTree(node, indent = "", isLast = true) {
|
|
|
152
153
|
}
|
|
153
154
|
return lines.join("\n");
|
|
154
155
|
}
|
|
156
|
+
function colorizeJSON(data, space = 2) {
|
|
157
|
+
const jsonStr = typeof data === "string" ? data : JSON.stringify(data, null, space);
|
|
158
|
+
if (!jsonStr) return "";
|
|
159
|
+
return jsonStr.replace(
|
|
160
|
+
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
|
|
161
|
+
(match) => {
|
|
162
|
+
if (/^"/.test(match)) {
|
|
163
|
+
if (/:$/.test(match)) {
|
|
164
|
+
const keyName = match.slice(0, -1);
|
|
165
|
+
return import_picocolors.default.bold(import_picocolors.default.cyan(keyName)) + import_picocolors.default.dim(":");
|
|
166
|
+
}
|
|
167
|
+
return import_picocolors.default.green(match);
|
|
168
|
+
}
|
|
169
|
+
if (/true|false/.test(match)) {
|
|
170
|
+
return import_picocolors.default.magenta(match);
|
|
171
|
+
}
|
|
172
|
+
if (/null/.test(match)) {
|
|
173
|
+
return import_picocolors.default.dim(match);
|
|
174
|
+
}
|
|
175
|
+
return import_picocolors.default.yellow(match);
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
}
|
|
155
179
|
|
|
156
180
|
// src/differ.ts
|
|
157
181
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
@@ -627,6 +651,7 @@ var InteractiveViewer = class {
|
|
|
627
651
|
InteractiveViewer,
|
|
628
652
|
buildTree,
|
|
629
653
|
calculateDiffStats,
|
|
654
|
+
colorizeJSON,
|
|
630
655
|
copyToClipboard,
|
|
631
656
|
diffJSON,
|
|
632
657
|
formatKey,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["export * from \"./types.js\";\nexport * from \"./formatter.js\";\nexport * from \"./differ.js\";\nexport * from \"./interactive.js\";\nexport * from \"./utils/clipboard.js\";\n","import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":"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","names":["pc","import_picocolors","pc","import_picocolors","os","pc","readline"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["export * from \"./types.js\";\nexport * from \"./formatter.js\";\nexport * from \"./differ.js\";\nexport * from \"./interactive.js\";\nexport * from \"./utils/clipboard.js\";\n","import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Colorize and format standard JSON structure with bold keys and typed syntax highlighting.\n */\nexport function colorizeJSON(data: any, space = 2): string {\n const jsonStr = typeof data === \"string\" ? data : JSON.stringify(data, null, space);\n if (!jsonStr) return \"\";\n\n return jsonStr.replace(\n /(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,\n (match) => {\n // Object key with trailing colon\n if (/^\"/.test(match)) {\n if (/:$/.test(match)) {\n const keyName = match.slice(0, -1);\n return pc.bold(pc.cyan(keyName)) + pc.dim(\":\");\n }\n // String value\n return pc.green(match);\n }\n // Boolean value\n if (/true|false/.test(match)) {\n return pc.magenta(match);\n }\n // Null value\n if (/null/.test(match)) {\n return pc.dim(match);\n }\n // Number value\n return pc.yellow(match);\n }\n );\n}\n\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,wBAAe;AAMR,SAAS,aAAa,OAA2B;AACtD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,SAAU,QAAO;AAC3B,MAAI,MAAM,UAAW,QAAO;AAC5B,SAAO;AACT;AAKO,SAAS,YAAY,OAAY,cAAc,IAAY;AAChE,QAAM,OAAO,aAAa,KAAK;AAE/B,UAAQ,MAAM;AAAA,IACZ,KAAK,UAAU;AACb,YAAM,MAAM,KAAK,UAAU,KAAK;AAChC,YAAM,YAAY,IAAI,SAAS,cAAc,IAAI,MAAM,GAAG,cAAc,CAAC,IAAI,SAAS;AACtF,aAAO,kBAAAA,QAAG,MAAM,SAAS;AAAA,IAC3B;AAAA,IACA,KAAK;AACH,aAAO,kBAAAA,QAAG,OAAO,OAAO,KAAK,CAAC;AAAA,IAChC,KAAK;AACH,aAAO,kBAAAA,QAAG,QAAQ,OAAO,KAAK,CAAC;AAAA,IACjC,KAAK;AACH,aAAO,kBAAAA,QAAG,IAAI,MAAM;AAAA,IACtB,KAAK;AACH,aAAO,kBAAAA,QAAG,IAAI,IAAI,MAAM,MAAM,SAAS;AAAA,IACzC,KAAK;AACH,aAAO,kBAAAA,QAAG,IAAI,IAAI,OAAO,KAAK,KAAK,EAAE,MAAM,QAAQ;AAAA,IACrD;AACE,aAAO,OAAO,KAAK;AAAA,EACvB;AACF;AAKO,SAAS,UAAU,KAAqB;AAC7C,SAAO,kBAAAA,QAAG,KAAK,kBAAAA,QAAG,KAAK,GAAG,CAAC;AAC7B;AAKO,SAAS,UACd,MACA,KACA,OAAO,KACP,QAAQ,GACR,kBAAkB,GAClB,UACU;AACV,QAAM,OAAO,aAAa,IAAI;AAC9B,QAAM,KAAK,GAAG,IAAI,IAAI,OAAO,MAAM,IAAI,KAAK;AAC5C,QAAM,YAAY,SAAS;AAE3B,QAAM,OAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS,YAAY,SAAS,MAAM;AACtC,UAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,SAAK,YAAY,KAAK;AACtB,SAAK,WAAW,KAAK;AAAA,MAAI,CAAC,MACxB;AAAA,QACE,KAAK,CAAC;AAAA,QACN;AAAA,QACA,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;AAAA,QAC/B,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,SAAS,SAAS;AAC3B,SAAK,YAAY,KAAK;AACtB,SAAK,WAAW,KAAK;AAAA,MAAI,CAAC,MAAW,QACnC;AAAA,QACE;AAAA,QACA,IAAI,GAAG;AAAA,QACP,GAAG,IAAI,IAAI,GAAG;AAAA,QACd,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,gBAAgB,MAAgB,SAAS,IAAI,SAAS,MAAc;AAClF,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,SAAS,KAAK,SAAS,YAAY,KAAK,SAAS,UAAW,KAAK,YAAY,kBAAAA,QAAG,KAAK,SAAI,IAAI,kBAAAA,QAAG,KAAK,SAAI,IAAK,kBAAAA,QAAG,IAAI,SAAI;AAE/H,MAAI,OAAO;AACX,MAAI,CAAC,QAAQ;AACX,UAAM,SAAS,SAAS,wBAAS;AACjC,YAAQ,kBAAAA,QAAG,IAAI,SAAS,MAAM,IAAI;AAClC,QAAI,KAAK,KAAK;AACZ,cAAQ,UAAU,KAAK,GAAG,IAAI,kBAAAA,QAAG,IAAI,IAAI;AAAA,IAC3C;AAAA,EACF,OAAO;AACL,YAAQ,UAAU,KAAK,MAAM,UAAU,KAAK,GAAG,IAAI,kBAAAA,QAAG,IAAI,IAAI,IAAI,kBAAAA,QAAG,KAAK,kBAAAA,QAAG,MAAM,QAAQ,CAAC;AAAA,EAC9F;AAEA,MAAI,KAAK,SAAS,UAAU;AAC1B,YAAQ,kBAAAA,QAAG,IAAI,KAAK,KAAK,SAAS,SAAS;AAAA,EAC7C,WAAW,KAAK,SAAS,SAAS;AAChC,YAAQ,kBAAAA,QAAG,IAAI,KAAK,KAAK,SAAS,UAAU;AAAA,EAC9C,OAAO;AACL,YAAQ,YAAY,KAAK,KAAK;AAAA,EAChC;AAEA,QAAM,QAAQ,CAAC,IAAI;AAEnB,MAAI,CAAC,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAChE,UAAM,aAAa,SAAS,KAAK,UAAU,SAAS,SAAS;AAC7D,SAAK,SAAS,QAAQ,CAAC,OAAO,UAAU;AACtC,YAAM,cAAc,UAAU,KAAK,SAAU,SAAS;AACtD,YAAM,KAAK,gBAAgB,OAAO,YAAY,WAAW,CAAC;AAAA,IAC5D,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAKO,SAAS,aAAa,MAAW,QAAQ,GAAW;AACzD,QAAM,UAAU,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,MAAM,MAAM,KAAK;AAClF,MAAI,CAAC,QAAS,QAAO;AAErB,SAAO,QAAQ;AAAA,IACb;AAAA,IACA,CAAC,UAAU;AAET,UAAI,KAAK,KAAK,KAAK,GAAG;AACpB,YAAI,KAAK,KAAK,KAAK,GAAG;AACpB,gBAAM,UAAU,MAAM,MAAM,GAAG,EAAE;AACjC,iBAAO,kBAAAA,QAAG,KAAK,kBAAAA,QAAG,KAAK,OAAO,CAAC,IAAI,kBAAAA,QAAG,IAAI,GAAG;AAAA,QAC/C;AAEA,eAAO,kBAAAA,QAAG,MAAM,KAAK;AAAA,MACvB;AAEA,UAAI,aAAa,KAAK,KAAK,GAAG;AAC5B,eAAO,kBAAAA,QAAG,QAAQ,KAAK;AAAA,MACzB;AAEA,UAAI,OAAO,KAAK,KAAK,GAAG;AACtB,eAAO,kBAAAA,QAAG,IAAI,KAAK;AAAA,MACrB;AAEA,aAAO,kBAAAA,QAAG,OAAO,KAAK;AAAA,IACxB;AAAA,EACF;AACF;;;ACjLA,IAAAC,qBAAe;AAcR,SAAS,SACd,GACA,GACA,KACA,OAAO,KACP,QAAQ,GACR,kBAAkB,GACR;AACV,QAAM,QAAQ,aAAa,CAAC;AAC5B,QAAM,QAAQ,aAAa,CAAC;AAC5B,QAAM,KAAK,GAAG,IAAI,IAAI,OAAO,MAAM,IAAI,KAAK;AAC5C,QAAM,YAAY,SAAS;AAG3B,MAAI,MAAM,UAAa,MAAM,QAAW;AACtC,UAAM,OAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AACA,QAAI,UAAU,YAAY,MAAM,MAAM;AACpC,WAAK,YAAY,OAAO,KAAK,CAAC,EAAE;AAChC,WAAK,WAAW,OAAO,KAAK,CAAC,EAAE;AAAA,QAAI,CAAC,MAClC,SAAS,QAAW,EAAE,CAAC,GAAG,GAAG,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,QAAQ,GAAG,eAAe;AAAA,MAC5F;AAAA,IACF,WAAW,UAAU,SAAS;AAC5B,WAAK,YAAY,EAAE;AACnB,WAAK,WAAW,EAAE;AAAA,QAAI,CAAC,MAAW,QAChC,SAAS,QAAW,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,IAAI,GAAG,KAAK,QAAQ,GAAG,eAAe;AAAA,MACrF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,UAAa,MAAM,QAAW;AACtC,UAAM,OAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AACA,QAAI,UAAU,YAAY,MAAM,MAAM;AACpC,WAAK,YAAY,OAAO,KAAK,CAAC,EAAE;AAChC,WAAK,WAAW,OAAO,KAAK,CAAC,EAAE;AAAA,QAAI,CAAC,MAClC,SAAS,EAAE,CAAC,GAAG,QAAW,GAAG,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,QAAQ,GAAG,eAAe;AAAA,MAC5F;AAAA,IACF,WAAW,UAAU,SAAS;AAC5B,WAAK,YAAY,EAAE;AACnB,WAAK,WAAW,EAAE;AAAA,QAAI,CAAC,MAAW,QAChC,SAAS,MAAM,QAAW,IAAI,GAAG,KAAK,GAAG,IAAI,IAAI,GAAG,KAAK,QAAQ,GAAG,eAAe;AAAA,MACrF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,MAAI,UAAU,OAAO;AACnB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,EACF;AAGA,MAAI,UAAU,YAAY,MAAM,QAAQ,MAAM,MAAM;AAClD,UAAM,UAAU,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,UAAM,WAAuB,CAAC;AAC9B,QAAI,mBAAmB;AAEvB,eAAW,KAAK,SAAS;AACvB,YAAM,QAAQ;AAAA,QACZ,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH;AAAA,QACA,SAAS,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;AAAA,QAC/B,QAAQ;AAAA,QACR;AAAA,MACF;AACA,UAAI,MAAM,WAAW,YAAa,oBAAmB;AACrD,eAAS,KAAK,KAAK;AAAA,IACrB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,mBAAmB,aAAa;AAAA,MACxC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU,SAAS;AACrB,UAAM,SAAS,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AAC1C,UAAM,WAAuB,CAAC;AAC9B,QAAI,mBAAmB;AAEvB,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,YAAM,QAAQ;AAAA,QACZ,EAAE,CAAC;AAAA,QACH,EAAE,CAAC;AAAA,QACH,IAAI,CAAC;AAAA,QACL,GAAG,IAAI,IAAI,CAAC;AAAA,QACZ,QAAQ;AAAA,QACR;AAAA,MACF;AACA,UAAI,MAAM,WAAW,YAAa,oBAAmB;AACrD,eAAS,KAAK,KAAK;AAAA,IACrB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,mBAAmB,aAAa;AAAA,MACxC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,MACX;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,EACF;AAGA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,MAAM;AAAA,IACN;AAAA,EACF;AACF;AAKO,SAAS,mBAAmB,MAA2B;AAC5D,QAAM,QAAmB,EAAE,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,EAAE;AAE3E,WAAS,SAAS,GAAa;AAC7B,QAAI,EAAE,YAAY,EAAE,SAAS,SAAS,GAAG;AACvC,QAAE,SAAS,QAAQ,QAAQ;AAAA,IAC7B,OAAO;AACL,YAAM,EAAE,MAAM;AAAA,IAChB;AAAA,EACF;AAEA,WAAS,IAAI;AACb,SAAO;AACT;AAKO,SAAS,gBACd,MACA,UAAuC,CAAC,GACxC,SAAS,IACT,SAAS,MACD;AACR,QAAM,gBAAgB,QAAQ,iBAAiB;AAE/C,MAAI,CAAC,iBAAiB,KAAK,WAAW,gBAAgB,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,IAAI;AACnG,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,KAAK,UAAU;AAC9B,MAAI,SAAS;AACb,MAAI,cAAc,mBAAAC,QAAG;AAErB,MAAI,KAAK,WAAW,SAAS;AAC3B,aAAS,mBAAAA,QAAG,MAAM,IAAI;AACtB,kBAAc,mBAAAA,QAAG;AAAA,EACnB,WAAW,KAAK,WAAW,WAAW;AACpC,aAAS,mBAAAA,QAAG,IAAI,IAAI;AACpB,kBAAc,mBAAAA,QAAG;AAAA,EACnB,WAAW,KAAK,WAAW,YAAY;AACrC,aAAS,mBAAAA,QAAG,OAAO,IAAI;AACvB,kBAAc,mBAAAA,QAAG;AAAA,EACnB;AAEA,MAAI,OAAO;AACX,MAAI,CAAC,QAAQ;AACX,UAAM,SAAS,SAAS,wBAAS;AACjC,YAAQ,mBAAAA,QAAG,IAAI,SAAS,MAAM;AAC9B,QAAI,KAAK,KAAK;AACZ,cAAQ,UAAU,KAAK,GAAG,IAAI,mBAAAA,QAAG,IAAI,IAAI;AAAA,IAC3C;AAAA,EACF,OAAO;AACL,YAAQ,KAAK,MAAM,UAAU,KAAK,GAAG,IAAI,mBAAAA,QAAG,IAAI,IAAI,IAAI,mBAAAA,QAAG,KAAK,QAAQ;AAAA,EAC1E;AAEA,MAAI,KAAK,WAAW,SAAS;AAC3B,YAAQ,YAAY,YAAY,KAAK,QAAQ,CAAC;AAAA,EAChD,WAAW,KAAK,WAAW,WAAW;AACpC,YAAQ,YAAY,YAAY,KAAK,QAAQ,CAAC;AAAA,EAChD,WAAW,KAAK,WAAW,YAAY;AACrC,QAAI,KAAK,SAAS,YAAY,KAAK,SAAS,SAAS;AACnD,cAAQ,YAAY,KAAK,KAAK,SAAS,mBAAmB;AAAA,IAC5D,OAAO;AACL,cAAQ,GAAG,mBAAAA,QAAG,IAAI,YAAY,KAAK,QAAQ,CAAC,CAAC,IAAI,mBAAAA,QAAG,IAAI,IAAI,CAAC,IAAI,mBAAAA,QAAG,MAAM,YAAY,KAAK,QAAQ,CAAC,CAAC;AAAA,IACvG;AAAA,EACF,OAAO;AAEL,YAAQ,mBAAAA,QAAG,IAAI,YAAY,KAAK,QAAQ,CAAC;AAAA,EAC3C;AAEA,QAAM,QAAQ,CAAC,IAAI;AAEnB,MAAI,CAAC,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAChE,UAAM,aAAa,SAAS,KAAK,UAAU,SAAS,SAAS;AAC7D,SAAK,SAAS,QAAQ,CAAC,OAAO,UAAU;AACtC,YAAM,cAAc,UAAU,KAAK,SAAU,SAAS;AACtD,YAAM,WAAW,gBAAgB,OAAO,SAAS,YAAY,WAAW;AACxE,UAAI,SAAU,OAAM,KAAK,QAAQ;AAAA,IACnC,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACrRA,sBAAqB;AACrB,IAAAC,qBAAe;;;ACDf,2BAAqB;AACrB,gBAAe;AAKf,eAAsB,gBAAgB,MAAgC;AACpE,QAAM,WAAW,UAAAC,QAAG,SAAS;AAE7B,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI;AACJ,QAAI,aAAa,UAAU;AACzB,iBAAO,2BAAK,UAAU,CAAC,QAAQ,QAAQ,CAAC,GAAG,CAAC;AAAA,IAC9C,WAAW,aAAa,SAAS;AAC/B,iBAAO,2BAAK,QAAQ,CAAC,QAAQ,QAAQ,CAAC,GAAG,CAAC;AAAA,IAC5C,OAAO;AAEL,iBAAO,2BAAK,6FAA6F,CAAC,QAAQ;AAChH,gBAAQ,CAAC,GAAG;AAAA,MACd,CAAC;AAAA,IACH;AAEA,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,MAAM,IAAI;AACrB,WAAK,MAAM,IAAI;AAAA,IACjB,OAAO;AACL,cAAQ,KAAK;AAAA,IACf;AAAA,EACF,CAAC;AACH;;;ADZO,IAAM,oBAAN,MAAwB;AAAA,EACrB;AAAA,EACA,WAAuB,CAAC;AAAA,EACxB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,oBAA2C;AAAA,EAC3C;AAAA,EAER,YAAY,MAAe,SAAS,OAAO;AACzC,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,WAAW,MAAiC;AAClD,WAAO,KAAK,UAAU,YAAY;AAAA,EACpC;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,OAAmB,CAAC;AAE1B,UAAM,WAAW,CAAC,MAAe,iBAAyB;AAExD,UAAI,KAAK,aAAa;AACpB,cAAM,QAAQ,KAAK,YAAY,YAAY;AAC3C,cAAM,WAAW,KAAK,OAAO,KAAK,IAAI,YAAY,EAAE,SAAS,KAAK;AAClE,cAAM,YAAY,KAAK,QAAQ,KAAK,KAAK,YAAY,EAAE,SAAS,KAAK;AACrE,cAAM,WACJ,WAAW,OACP,KAAK,UAAU,KAAK,KAAK,EAAE,YAAY,EAAE,SAAS,KAAK,IACvD,cAAc,OACd,KAAK,UAAU,KAAK,QAAQ,EAAE,YAAY,EAAE,SAAS,KAAK,IAC1D;AAEN,YAAI,CAAC,YAAY,CAAC,aAAa,CAAC,aAAa,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,IAAI;AAC1F;AAAA,QACF;AAAA,MACF;AAEA,WAAK,KAAK,EAAE,MAAM,OAAO,cAAc,QAAQ,KAAK,OAAO,CAAC;AAE5D,UAAI,CAAC,KAAK,aAAa,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAChE,mBAAW,SAAS,KAAK,UAAU;AACjC,mBAAS,OAAO,eAAe,CAAC;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAEA,aAAS,KAAK,MAAM,CAAC;AACrB,SAAK,WAAW;AAEhB,QAAI,KAAK,iBAAiB,KAAK,SAAS,QAAQ;AAC9C,WAAK,gBAAgB,KAAK,IAAI,GAAG,KAAK,SAAS,SAAS,CAAC;AAAA,IAC3D;AAAA,EACF;AAAA,EAEQ,gBAAgB,KAAmB;AACzC,SAAK,eAAe;AACpB,QAAI,KAAK,kBAAmB,cAAa,KAAK,iBAAiB;AAC/D,SAAK,oBAAoB,WAAW,MAAM;AACxC,WAAK,eAAe;AACpB,WAAK,OAAO;AAAA,IACd,GAAG,IAAI;AAAA,EACT;AAAA,EAEQ,SAAe;AACrB,UAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,UAAM,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC;AAG3C,QAAI,WAAW;AACf,QAAI,KAAK,iBAAiB,gBAAgB;AACxC,iBAAW,KAAK,gBAAgB,iBAAiB;AAAA,IACnD;AACA,UAAM,SAAS,KAAK,IAAI,KAAK,SAAS,QAAQ,WAAW,cAAc;AAGvE,YAAQ,OAAO,MAAM,+BAA+B;AAGpD,UAAM,QAAQ,KAAK,SAAS,oCAAoC;AAChE,YAAQ,IAAI,mBAAAC,QAAG,OAAO,mBAAAA,QAAG,MAAM,mBAAAA,QAAG,KAAK,IAAI,KAAK,GAAG,CAAC,IAAI,mBAAAA,QAAG,IAAI,kBAAkB,KAAK,SAAS,MAAM,GAAG,CAAC,CAAC;AAG1G,aAAS,IAAI,UAAU,IAAI,QAAQ,KAAK;AACtC,YAAM,EAAE,MAAM,MAAM,IAAI,KAAK,SAAS,CAAC;AACvC,YAAM,aAAa,MAAM,KAAK;AAC9B,YAAM,SAAS,KAAK,OAAO,KAAK;AAEhC,UAAI,SAAS;AACb,UAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC7C,iBAAS,KAAK,YAAY,YAAO;AAAA,MACnC;AAEA,UAAI,cAAc;AAElB,UAAI,KAAK,WAAW,IAAI,GAAG;AACzB,YAAI,aAAa;AACjB,YAAI,KAAK,WAAW,QAAS,cAAa,mBAAAA,QAAG,MAAM,IAAI;AAAA,iBAC9C,KAAK,WAAW,UAAW,cAAa,mBAAAA,QAAG,IAAI,IAAI;AAAA,iBACnD,KAAK,WAAW,WAAY,cAAa,mBAAAA,QAAG,OAAO,IAAI;AAEhE,sBAAc,aAAa,SAAS;AACpC,YAAI,KAAK,IAAK,gBAAe,UAAU,KAAK,GAAG,IAAI,mBAAAA,QAAG,IAAI,IAAI;AAE9D,YAAI,KAAK,WAAW,SAAS;AAC3B,yBAAe,mBAAAA,QAAG,MAAM,YAAY,KAAK,UAAU,EAAE,CAAC;AAAA,QACxD,WAAW,KAAK,WAAW,WAAW;AACpC,yBAAe,mBAAAA,QAAG,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;AAAA,QACtD,WAAW,KAAK,WAAW,YAAY;AACrC,cAAI,KAAK,SAAS,YAAY,KAAK,SAAS,SAAS;AACnD,2BAAe,mBAAAA,QAAG,OAAO,KAAK,KAAK,SAAS,aAAa;AAAA,UAC3D,OAAO;AACL,2BAAe,GAAG,mBAAAA,QAAG,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC,CAAC,OAAO,mBAAAA,QAAG,MAAM,YAAY,KAAK,UAAU,EAAE,CAAC,CAAC;AAAA,UACzG;AAAA,QACF,OAAO;AACL,yBAAe,mBAAAA,QAAG,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;AAAA,QACtD;AAAA,MACF,OAAO;AACL,cAAM,WAAW;AACjB,sBAAc,SAAS;AACvB,YAAI,SAAS,IAAK,gBAAe,UAAU,SAAS,GAAG,IAAI,mBAAAA,QAAG,IAAI,IAAI;AAEtE,YAAI,SAAS,SAAS,UAAU;AAC9B,yBAAe,mBAAAA,QAAG,IAAI,KAAK,SAAS,SAAS,SAAS;AAAA,QACxD,WAAW,SAAS,SAAS,SAAS;AACpC,yBAAe,mBAAAA,QAAG,IAAI,KAAK,SAAS,SAAS,UAAU;AAAA,QACzD,OAAO;AACL,yBAAe,YAAY,SAAS,OAAO,EAAE;AAAA,QAC/C;AAAA,MACF;AAEA,UAAI,YAAY;AACd,gBAAQ,IAAI,mBAAAA,QAAG,OAAO,mBAAAA,QAAG,MAAM,mBAAAA,QAAG,KAAK,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC;AAAA,MAC9D,OAAO;AACL,gBAAQ,IAAI,KAAK,WAAW,EAAE;AAAA,MAChC;AAAA,IACF;AAGA,UAAM,eAAe,KAAK,SAAS,KAAK,aAAa;AACrD,UAAM,cAAc,eAAe,aAAa,KAAK,OAAO;AAE5D,YAAQ,IAAI,OAAO,mBAAAA,QAAG,IAAI,SAAI,OAAO,KAAK,IAAI,QAAQ,OAAO,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;AACjF,QAAI,KAAK,cAAc;AACrB,cAAQ,IAAI,mBAAAA,QAAG,MAAM,mBAAAA,QAAG,KAAK,IAAI,KAAK,YAAY,EAAE,CAAC,CAAC;AAAA,IACxD,WAAW,KAAK,aAAa;AAC3B,cAAQ,IAAI,mBAAAA,QAAG,OAAO,mBAAAA,QAAG,KAAK,aAAa,KAAK,WAAW,QAAG,CAAC,CAAC;AAAA,IAClE,OAAO;AACL,cAAQ,IAAI,mBAAAA,QAAG,KAAK,mBAAAA,QAAG,KAAK,UAAU,WAAW,EAAE,CAAC,CAAC;AACrD,cAAQ;AAAA,QACN,mBAAAA,QAAG,IAAI,kIAAwH;AAAA,MACjI;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAU,MAAqB;AACrC,SAAK,YAAY;AACjB,QAAI,KAAK,SAAU,MAAK,SAAS,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;AAAA,EACnE;AAAA,EAEQ,YAAY,MAAqB;AACvC,QAAI,KAAK,QAAQ,EAAG,MAAK,YAAY;AACrC,QAAI,KAAK,SAAU,MAAK,SAAS,QAAQ,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;AAAA,EACrE;AAAA,EAEA,MAAa,QAAuB;AAClC,QAAI,CAAC,QAAQ,MAAM,OAAO;AACxB;AAAA,IACF;AAEA,oBAAAC,QAAS,mBAAmB,QAAQ,KAAK;AACzC,YAAQ,MAAM,WAAW,IAAI;AAC7B,YAAQ,MAAM,OAAO;AAErB,SAAK,OAAO;AAEZ,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,aAAa,OAAO,KAAa,QAAsB;AAC3D,YAAI,KAAK,aAAa;AACpB,cAAI,IAAI,SAAS,UAAU;AACzB,iBAAK,cAAc,KAAK;AACxB,iBAAK,cAAc;AACnB,iBAAK,gBAAgB;AACrB,iBAAK,OAAO;AACZ;AAAA,UACF;AACA,cAAI,IAAI,SAAS,UAAU;AACzB,iBAAK,cAAc;AACnB,iBAAK,cAAc;AACnB,iBAAK,OAAO;AACZ;AAAA,UACF;AACA,cAAI,IAAI,SAAS,aAAa;AAC5B,iBAAK,cAAc,KAAK,YAAY,MAAM,GAAG,EAAE;AAC/C,iBAAK,OAAO;AACZ;AAAA,UACF;AACA,cAAI,OAAO,IAAI,WAAW,GAAG;AAC3B,iBAAK,eAAe;AACpB,iBAAK,OAAO;AACZ;AAAA,UACF;AAAA,QACF;AAGA,YAAI,IAAI,SAAS,QAAQ,IAAI,SAAS,KAAK;AACzC,cAAI,KAAK,gBAAgB,GAAG;AAC1B,iBAAK;AACL,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,WAAW,IAAI,SAAS,UAAU,IAAI,SAAS,KAAK;AAClD,cAAI,KAAK,gBAAgB,KAAK,SAAS,SAAS,GAAG;AACjD,iBAAK;AACL,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,WAAW,IAAI,SAAS,YAAY,IAAI,SAAS,WAAW,IAAI,SAAS,WAAW,IAAI,SAAS,QAAQ;AACvG,gBAAM,OAAO,KAAK,SAAS,KAAK,aAAa;AAC7C,cAAI,QAAQ,KAAK,KAAK,YAAY,KAAK,KAAK,SAAS,SAAS,GAAG;AAC/D,iBAAK,KAAK,YAAY,CAAC,KAAK,KAAK;AACjC,iBAAK,gBAAgB;AACrB,iBAAK,OAAO;AAAA,UACd;AAAA,QACF,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,eAAK,UAAU,KAAK,IAAI;AACxB,eAAK,gBAAgB;AACrB,eAAK,OAAO;AAAA,QACd,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,eAAK,YAAY,KAAK,IAAI;AAC1B,eAAK,gBAAgB;AACrB,eAAK,OAAO;AAAA,QACd,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,gBAAM,OAAO,KAAK,SAAS,KAAK,aAAa;AAC7C,cAAI,MAAM;AACR,kBAAM,gBAAgB,KAAK,KAAK,IAAI;AACpC,iBAAK,gBAAgB,2BAAsB,KAAK,KAAK,IAAI,EAAE;AAAA,UAC7D;AAAA,QACF,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,gBAAM,OAAO,KAAK,SAAS,KAAK,aAAa;AAC7C,cAAI,MAAM;AACR,kBAAM,MAAM,WAAW,KAAK,OAAO,KAAK,KAAK,QAAS,KAAK,KAAkB;AAC7E,kBAAM,aAAa,OAAO,QAAQ,WAAW,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI,OAAO,GAAG;AACtF,kBAAM,gBAAgB,UAAU;AAChC,iBAAK,gBAAgB,mCAA8B;AAAA,UACrD;AAAA,QACF,WAAW,QAAQ,KAAK;AACtB,eAAK,cAAc;AACnB,eAAK,cAAc;AACnB,eAAK,OAAO;AAAA,QACd,WAAW,IAAI,QAAQ,IAAI,SAAS,OAAO,IAAI,SAAS,YAAY,QAAQ,OAAO,QAAQ,KAAK;AAE9F,kBAAQ,MAAM,eAAe,YAAY,UAAU;AACnD,kBAAQ,MAAM,WAAW,KAAK;AAC9B,kBAAQ,MAAM,MAAM;AACpB,kBAAQ,OAAO,MAAM,aAAa;AAClC,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,cAAQ,MAAM,GAAG,YAAY,UAAU;AAAA,IACzC,CAAC;AAAA,EACH;AACF;","names":["pc","import_picocolors","pc","import_picocolors","os","pc","readline"]}
|
package/dist/index.mjs
CHANGED
|
@@ -107,6 +107,29 @@ function prettyPrintTree(node, indent = "", isLast = true) {
|
|
|
107
107
|
}
|
|
108
108
|
return lines.join("\n");
|
|
109
109
|
}
|
|
110
|
+
function colorizeJSON(data, space = 2) {
|
|
111
|
+
const jsonStr = typeof data === "string" ? data : JSON.stringify(data, null, space);
|
|
112
|
+
if (!jsonStr) return "";
|
|
113
|
+
return jsonStr.replace(
|
|
114
|
+
/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
|
|
115
|
+
(match) => {
|
|
116
|
+
if (/^"/.test(match)) {
|
|
117
|
+
if (/:$/.test(match)) {
|
|
118
|
+
const keyName = match.slice(0, -1);
|
|
119
|
+
return pc.bold(pc.cyan(keyName)) + pc.dim(":");
|
|
120
|
+
}
|
|
121
|
+
return pc.green(match);
|
|
122
|
+
}
|
|
123
|
+
if (/true|false/.test(match)) {
|
|
124
|
+
return pc.magenta(match);
|
|
125
|
+
}
|
|
126
|
+
if (/null/.test(match)) {
|
|
127
|
+
return pc.dim(match);
|
|
128
|
+
}
|
|
129
|
+
return pc.yellow(match);
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
}
|
|
110
133
|
|
|
111
134
|
// src/differ.ts
|
|
112
135
|
import pc2 from "picocolors";
|
|
@@ -581,6 +604,7 @@ export {
|
|
|
581
604
|
InteractiveViewer,
|
|
582
605
|
buildTree,
|
|
583
606
|
calculateDiffStats,
|
|
607
|
+
colorizeJSON,
|
|
584
608
|
copyToClipboard,
|
|
585
609
|
diffJSON,
|
|
586
610
|
formatKey,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":"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","names":["pc","pc","pc","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/formatter.ts","../src/differ.ts","../src/interactive.ts","../src/utils/clipboard.ts"],"sourcesContent":["import pc from \"picocolors\";\nimport { JSONValueType, TreeNode } from \"./types.js\";\n\n/**\n * Determine the JSON value type.\n */\nexport function getValueType(value: any): JSONValueType {\n if (value === null || value === undefined) return \"null\";\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"string\") return \"string\";\n if (t === \"number\") return \"number\";\n if (t === \"boolean\") return \"boolean\";\n return \"string\";\n}\n\n/**\n * Colorize and format a single JSON value according to its type.\n */\nexport function formatValue(value: any, truncateLen = 80): string {\n const type = getValueType(value);\n\n switch (type) {\n case \"string\": {\n const str = JSON.stringify(value);\n const truncated = str.length > truncateLen ? str.slice(0, truncateLen - 3) + '...\"' : str;\n return pc.green(truncated);\n }\n case \"number\":\n return pc.yellow(String(value));\n case \"boolean\":\n return pc.magenta(String(value));\n case \"null\":\n return pc.dim(\"null\");\n case \"array\":\n return pc.dim(`[${value.length} items]`);\n case \"object\":\n return pc.dim(`{${Object.keys(value).length} keys}`);\n default:\n return String(value);\n }\n}\n\n/**\n * Format an object key with bold coloring.\n */\nexport function formatKey(key: string): string {\n return pc.bold(pc.cyan(key));\n}\n\n/**\n * Build a flat or nested TreeNode hierarchy from any JavaScript/JSON data.\n */\nexport function buildTree(\n data: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 2,\n parentId?: string\n): TreeNode {\n const type = getValueType(data);\n const id = `${path}-${key || \"root\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n const node: TreeNode = {\n id,\n key,\n value: data,\n type,\n depth,\n path,\n collapsed,\n parentId,\n };\n\n if (type === \"object\" && data !== null) {\n const keys = Object.keys(data);\n node.itemCount = keys.length;\n node.children = keys.map((k) =>\n buildTree(\n data[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n } else if (type === \"array\") {\n node.itemCount = data.length;\n node.children = data.map((item: any, idx: number) =>\n buildTree(\n item,\n `[${idx}]`,\n `${path}[${idx}]`,\n depth + 1,\n maxInitialDepth,\n id\n )\n );\n }\n\n return node;\n}\n\n/**\n * Pretty-print JSON tree structure to terminal string.\n */\nexport function prettyPrintTree(node: TreeNode, indent = \"\", isLast = true): string {\n const isRoot = node.depth === 0;\n const marker = node.type === \"object\" || node.type === \"array\" ? (node.collapsed ? pc.cyan(\"▶ \") : pc.cyan(\"▼ \")) : pc.dim(\"• \");\n\n let line = \"\";\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch) + marker;\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += marker + (node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(pc.white(\"root: \")));\n }\n\n if (node.type === \"object\") {\n line += pc.dim(`{ ${node.itemCount} keys }`);\n } else if (node.type === \"array\") {\n line += pc.dim(`[ ${node.itemCount} items ]`);\n } else {\n line += formatValue(node.value);\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n lines.push(prettyPrintTree(child, nextIndent, childIsLast));\n });\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Colorize and format standard JSON structure with bold keys and typed syntax highlighting.\n */\nexport function colorizeJSON(data: any, space = 2): string {\n const jsonStr = typeof data === \"string\" ? data : JSON.stringify(data, null, space);\n if (!jsonStr) return \"\";\n\n return jsonStr.replace(\n /(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,\n (match) => {\n // Object key with trailing colon\n if (/^\"/.test(match)) {\n if (/:$/.test(match)) {\n const keyName = match.slice(0, -1);\n return pc.bold(pc.cyan(keyName)) + pc.dim(\":\");\n }\n // String value\n return pc.green(match);\n }\n // Boolean value\n if (/true|false/.test(match)) {\n return pc.magenta(match);\n }\n // Null value\n if (/null/.test(match)) {\n return pc.dim(match);\n }\n // Number value\n return pc.yellow(match);\n }\n );\n}\n\n","import pc from \"picocolors\";\nimport { DiffNode, DiffStatus, JSONValueType } from \"./types.js\";\nimport { getValueType, formatValue, formatKey } from \"./formatter.js\";\n\nexport interface DiffStats {\n added: number;\n removed: number;\n modified: number;\n unchanged: number;\n}\n\n/**\n * Compare two JSON values structurally and return a recursive DiffNode tree.\n */\nexport function diffJSON(\n a: any,\n b: any,\n key?: string,\n path = \"$\",\n depth = 0,\n maxInitialDepth = 3\n): DiffNode {\n const typeA = getValueType(a);\n const typeB = getValueType(b);\n const id = `${path}-${key || \"diff\"}-${depth}`;\n const collapsed = depth >= maxInitialDepth;\n\n // Case 1: Value added (a is undefined, b exists)\n if (a === undefined && b !== undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"added\",\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n if (typeB === \"object\" && b !== null) {\n node.itemCount = Object.keys(b).length;\n node.children = Object.keys(b).map((k) =>\n diffJSON(undefined, b[k], k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeB === \"array\") {\n node.itemCount = b.length;\n node.children = b.map((item: any, idx: number) =>\n diffJSON(undefined, item, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 2: Value removed (a exists, b is undefined)\n if (a !== undefined && b === undefined) {\n const node: DiffNode = {\n id,\n key,\n path,\n depth,\n status: \"removed\",\n oldValue: a,\n type: typeA,\n collapsed: false,\n };\n if (typeA === \"object\" && a !== null) {\n node.itemCount = Object.keys(a).length;\n node.children = Object.keys(a).map((k) =>\n diffJSON(a[k], undefined, k, path === \"$\" ? k : `${path}.${k}`, depth + 1, maxInitialDepth)\n );\n } else if (typeA === \"array\") {\n node.itemCount = a.length;\n node.children = a.map((item: any, idx: number) =>\n diffJSON(item, undefined, `[${idx}]`, `${path}[${idx}]`, depth + 1, maxInitialDepth)\n );\n }\n return node;\n }\n\n // Case 3: Type changed (e.g. from string to number or object to array)\n if (typeA !== typeB) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Case 4: Both are Objects\n if (typeA === \"object\" && a !== null && b !== null) {\n const allKeys = Array.from(new Set([...Object.keys(a), ...Object.keys(b)]));\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (const k of allKeys) {\n const child = diffJSON(\n a[k],\n b[k],\n k,\n path === \"$\" ? k : `${path}.${k}`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"object\",\n itemCount: allKeys.length,\n collapsed,\n children,\n };\n }\n\n // Case 5: Both are Arrays\n if (typeA === \"array\") {\n const maxLen = Math.max(a.length, b.length);\n const children: DiffNode[] = [];\n let hasModifications = false;\n\n for (let i = 0; i < maxLen; i++) {\n const child = diffJSON(\n a[i],\n b[i],\n `[${i}]`,\n `${path}[${i}]`,\n depth + 1,\n maxInitialDepth\n );\n if (child.status !== \"unchanged\") hasModifications = true;\n children.push(child);\n }\n\n return {\n id,\n key,\n path,\n depth,\n status: hasModifications ? \"modified\" : \"unchanged\",\n oldValue: a,\n newValue: b,\n type: \"array\",\n itemCount: maxLen,\n collapsed,\n children,\n };\n }\n\n // Case 6: Primitive values comparison\n if (a !== b) {\n return {\n id,\n key,\n path,\n depth,\n status: \"modified\",\n oldValue: a,\n newValue: b,\n type: typeB,\n collapsed: false,\n };\n }\n\n // Unchanged primitive\n return {\n id,\n key,\n path,\n depth,\n status: \"unchanged\",\n oldValue: a,\n newValue: b,\n type: typeA,\n collapsed,\n };\n}\n\n/**\n * Calculate summary metrics for the diff.\n */\nexport function calculateDiffStats(node: DiffNode): DiffStats {\n const stats: DiffStats = { added: 0, removed: 0, modified: 0, unchanged: 0 };\n\n function traverse(n: DiffNode) {\n if (n.children && n.children.length > 0) {\n n.children.forEach(traverse);\n } else {\n stats[n.status]++;\n }\n }\n\n traverse(node);\n return stats;\n}\n\n/**\n * Pretty-print structural diff to terminal string.\n */\nexport function prettyPrintDiff(\n node: DiffNode,\n options: { showUnchanged?: boolean } = {},\n indent = \"\",\n isLast = true\n): string {\n const showUnchanged = options.showUnchanged ?? true;\n\n if (!showUnchanged && node.status === \"unchanged\" && (!node.children || node.children.length === 0)) {\n return \"\";\n }\n\n const isRoot = node.depth === 0;\n let prefix = \" \";\n let statusColor = pc.dim;\n\n if (node.status === \"added\") {\n prefix = pc.green(\"+ \");\n statusColor = pc.green;\n } else if (node.status === \"removed\") {\n prefix = pc.red(\"- \");\n statusColor = pc.red;\n } else if (node.status === \"modified\") {\n prefix = pc.yellow(\"~ \");\n statusColor = pc.yellow;\n }\n\n let line = prefix;\n if (!isRoot) {\n const branch = isLast ? \"└── \" : \"├── \";\n line += pc.dim(indent + branch);\n if (node.key) {\n line += formatKey(node.key) + pc.dim(\": \");\n }\n } else {\n line += node.key ? formatKey(node.key) + pc.dim(\": \") : pc.bold(\"diff: \");\n }\n\n if (node.status === \"added\") {\n line += statusColor(formatValue(node.newValue));\n } else if (node.status === \"removed\") {\n line += statusColor(formatValue(node.oldValue));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n line += statusColor(`{ ${node.itemCount} items modified }`);\n } else {\n line += `${pc.red(formatValue(node.oldValue))} ${pc.dim(\"->\")} ${pc.green(formatValue(node.newValue))}`;\n }\n } else {\n // Unchanged\n line += pc.dim(formatValue(node.newValue));\n }\n\n const lines = [line];\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n const nextIndent = isRoot ? \"\" : indent + (isLast ? \" \" : \"│ \");\n node.children.forEach((child, index) => {\n const childIsLast = index === node.children!.length - 1;\n const childStr = prettyPrintDiff(child, options, nextIndent, childIsLast);\n if (childStr) lines.push(childStr);\n });\n }\n\n return lines.join(\"\\n\");\n}\n","import readline from \"readline\";\nimport pc from \"picocolors\";\nimport { TreeNode, DiffNode } from \"./types.js\";\nimport { formatKey, formatValue } from \"./formatter.js\";\nimport { copyToClipboard } from \"./utils/clipboard.js\";\n\ntype AnyNode = TreeNode | DiffNode;\n\ninterface FlatItem {\n node: AnyNode;\n depth: number;\n isDiff: boolean;\n}\n\n/**\n * Interactive Terminal Tree Explorer for JSON data and Diffs.\n */\nexport class InteractiveViewer {\n private root: AnyNode;\n private flatList: FlatItem[] = [];\n private selectedIndex = 0;\n private searchQuery = \"\";\n private isSearching = false;\n private searchInput = \"\";\n private notification = \"\";\n private notificationTimer: NodeJS.Timeout | null = null;\n private isDiff: boolean;\n\n constructor(root: AnyNode, isDiff = false) {\n this.root = root;\n this.isDiff = isDiff;\n this.rebuildFlatList();\n }\n\n private isDiffNode(node: AnyNode): node is DiffNode {\n return this.isDiff && \"status\" in node;\n }\n\n private rebuildFlatList(): void {\n const list: FlatItem[] = [];\n\n const traverse = (node: AnyNode, currentDepth: number) => {\n // If search query is active, filter matching nodes or their parents\n if (this.searchQuery) {\n const query = this.searchQuery.toLowerCase();\n const keyMatch = node.key && node.key.toLowerCase().includes(query);\n const pathMatch = node.path && node.path.toLowerCase().includes(query);\n const valMatch =\n \"value\" in node\n ? JSON.stringify(node.value).toLowerCase().includes(query)\n : \"newValue\" in node\n ? JSON.stringify(node.newValue).toLowerCase().includes(query)\n : false;\n\n if (!keyMatch && !pathMatch && !valMatch && (!node.children || node.children.length === 0)) {\n return;\n }\n }\n\n list.push({ node, depth: currentDepth, isDiff: this.isDiff });\n\n if (!node.collapsed && node.children && node.children.length > 0) {\n for (const child of node.children) {\n traverse(child, currentDepth + 1);\n }\n }\n };\n\n traverse(this.root, 0);\n this.flatList = list;\n\n if (this.selectedIndex >= this.flatList.length) {\n this.selectedIndex = Math.max(0, this.flatList.length - 1);\n }\n }\n\n private setNotification(msg: string): void {\n this.notification = msg;\n if (this.notificationTimer) clearTimeout(this.notificationTimer);\n this.notificationTimer = setTimeout(() => {\n this.notification = \"\";\n this.render();\n }, 2500);\n }\n\n private render(): void {\n const rows = process.stdout.rows || 24;\n const maxVisibleRows = Math.max(5, rows - 5);\n\n // Calculate window scroll offset\n let startIdx = 0;\n if (this.selectedIndex >= maxVisibleRows) {\n startIdx = this.selectedIndex - maxVisibleRows + 1;\n }\n const endIdx = Math.min(this.flatList.length, startIdx + maxVisibleRows);\n\n // Clear terminal screen\n process.stdout.write(\"\\x1b[2J\\x1b[3J\\x1b[H\\x1b[?25l\"); // hide cursor\n\n // 1. Header Bar\n const title = this.isDiff ? \" JSON Structural Diff Explorer \" : \" Interactive JSON Tree Explorer \";\n console.log(pc.bgCyan(pc.black(pc.bold(` ${title} `)) + pc.dim(` [Total items: ${this.flatList.length}]`)));\n\n // 2. Render visible items\n for (let i = startIdx; i < endIdx; i++) {\n const { node, depth } = this.flatList[i];\n const isSelected = i === this.selectedIndex;\n const indent = \" \".repeat(depth);\n\n let marker = \"• \";\n if (node.children && node.children.length > 0) {\n marker = node.collapsed ? \"▶ \" : \"▼ \";\n }\n\n let lineContent = \"\";\n\n if (this.isDiffNode(node)) {\n let diffPrefix = \" \";\n if (node.status === \"added\") diffPrefix = pc.green(\"+ \");\n else if (node.status === \"removed\") diffPrefix = pc.red(\"- \");\n else if (node.status === \"modified\") diffPrefix = pc.yellow(\"~ \");\n\n lineContent = diffPrefix + indent + marker;\n if (node.key) lineContent += formatKey(node.key) + pc.dim(\": \");\n\n if (node.status === \"added\") {\n lineContent += pc.green(formatValue(node.newValue, 50));\n } else if (node.status === \"removed\") {\n lineContent += pc.red(formatValue(node.oldValue, 50));\n } else if (node.status === \"modified\") {\n if (node.type === \"object\" || node.type === \"array\") {\n lineContent += pc.yellow(`{ ${node.itemCount} modified }`);\n } else {\n lineContent += `${pc.red(formatValue(node.oldValue, 25))} -> ${pc.green(formatValue(node.newValue, 25))}`;\n }\n } else {\n lineContent += pc.dim(formatValue(node.newValue, 50));\n }\n } else {\n const treeNode = node as TreeNode;\n lineContent = indent + marker;\n if (treeNode.key) lineContent += formatKey(treeNode.key) + pc.dim(\": \");\n\n if (treeNode.type === \"object\") {\n lineContent += pc.dim(`{ ${treeNode.itemCount} keys }`);\n } else if (treeNode.type === \"array\") {\n lineContent += pc.dim(`[ ${treeNode.itemCount} items ]`);\n } else {\n lineContent += formatValue(treeNode.value, 60);\n }\n }\n\n if (isSelected) {\n console.log(pc.bgBlue(pc.white(pc.bold(`> ${lineContent}`))));\n } else {\n console.log(` ${lineContent}`);\n }\n }\n\n // 3. Status Bar & Footer\n const selectedItem = this.flatList[this.selectedIndex];\n const currentPath = selectedItem ? selectedItem.node.path : \"$\";\n\n console.log(\"\\n\" + pc.dim(\"─\".repeat(Math.min(process.stdout.columns || 80, 80))));\n if (this.notification) {\n console.log(pc.green(pc.bold(` ${this.notification}`)));\n } else if (this.isSearching) {\n console.log(pc.yellow(pc.bold(` Search: /${this.searchInput}█`)));\n } else {\n console.log(pc.bold(pc.cyan(` Path: ${currentPath}`)));\n console.log(\n pc.dim(\" [↑/↓] Move [Enter/Space] Toggle [e] Expand All [c] Collapse All [p] Copy Path [y] Copy Val [/] Search [q] Exit\")\n );\n }\n }\n\n private expandAll(node: AnyNode): void {\n node.collapsed = false;\n if (node.children) node.children.forEach((c) => this.expandAll(c));\n }\n\n private collapseAll(node: AnyNode): void {\n if (node.depth > 0) node.collapsed = true;\n if (node.children) node.children.forEach((c) => this.collapseAll(c));\n }\n\n public async start(): Promise<void> {\n if (!process.stdin.isTTY) {\n return;\n }\n\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n this.render();\n\n return new Promise((resolve) => {\n const onKeypress = async (str: string, key: readline.Key) => {\n if (this.isSearching) {\n if (key.name === \"return\") {\n this.searchQuery = this.searchInput;\n this.isSearching = false;\n this.rebuildFlatList();\n this.render();\n return;\n }\n if (key.name === \"escape\") {\n this.isSearching = false;\n this.searchInput = \"\";\n this.render();\n return;\n }\n if (key.name === \"backspace\") {\n this.searchInput = this.searchInput.slice(0, -1);\n this.render();\n return;\n }\n if (str && str.length === 1) {\n this.searchInput += str;\n this.render();\n return;\n }\n }\n\n // Navigation\n if (key.name === \"up\" || key.name === \"k\") {\n if (this.selectedIndex > 0) {\n this.selectedIndex--;\n this.render();\n }\n } else if (key.name === \"down\" || key.name === \"j\") {\n if (this.selectedIndex < this.flatList.length - 1) {\n this.selectedIndex++;\n this.render();\n }\n } else if (key.name === \"return\" || key.name === \"space\" || key.name === \"right\" || key.name === \"left\") {\n const item = this.flatList[this.selectedIndex];\n if (item && item.node.children && item.node.children.length > 0) {\n item.node.collapsed = !item.node.collapsed;\n this.rebuildFlatList();\n this.render();\n }\n } else if (str === \"e\" || str === \"E\") {\n this.expandAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"c\" || str === \"C\") {\n this.collapseAll(this.root);\n this.rebuildFlatList();\n this.render();\n } else if (str === \"p\" || str === \"P\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n await copyToClipboard(item.node.path);\n this.setNotification(`✔ Copied JSONPath: ${item.node.path}`);\n }\n } else if (str === \"y\" || str === \"Y\") {\n const item = this.flatList[this.selectedIndex];\n if (item) {\n const val = \"value\" in item.node ? item.node.value : (item.node as DiffNode).newValue;\n const textToCopy = typeof val === \"object\" ? JSON.stringify(val, null, 2) : String(val);\n await copyToClipboard(textToCopy);\n this.setNotification(`✔ Copied value to clipboard!`);\n }\n } else if (str === \"/\") {\n this.isSearching = true;\n this.searchInput = \"\";\n this.render();\n } else if (key.ctrl && key.name === \"c\" || key.name === \"escape\" || str === \"q\" || str === \"Q\") {\n // Cleanup & Exit\n process.stdin.removeListener(\"keypress\", onKeypress);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdout.write(\"\\x1b[?25h\\n\"); // show cursor\n resolve();\n }\n };\n\n process.stdin.on(\"keypress\", onKeypress);\n });\n }\n}\n","import { exec } from \"child_process\";\nimport os from \"os\";\n\n/**\n * Copy text to system clipboard across macOS, Linux, and Windows.\n */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const platform = os.platform();\n\n return new Promise((resolve) => {\n let proc;\n if (platform === \"darwin\") {\n proc = exec(\"pbcopy\", (err) => resolve(!err));\n } else if (platform === \"win32\") {\n proc = exec(\"clip\", (err) => resolve(!err));\n } else {\n // Linux: Try wl-copy then xclip\n proc = exec(\"wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || xsel --clipboard --input\", (err) => {\n resolve(!err);\n });\n }\n\n if (proc.stdin) {\n proc.stdin.write(text);\n proc.stdin.end();\n } else {\n resolve(false);\n }\n });\n}\n"],"mappings":"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","names":["pc","pc","pc","pc"]}
|
package/package.json
CHANGED