A terminal utility to pretty print JSON
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.1 KiB

import 'dart:convert';
import 'dart:io';
import 'package:args/args.dart';
import 'package:json_path/json_path.dart';
import 'package:rfc_6901/rfc_6901.dart';
import 'ppjson.dart';
void main(List<String> arguments) {
final parser = ArgParser()
..addOption('file', abbr: 'f', help: 'Read JSON from file instead of stdin', valueHelp: 'filename')
..addOption('input', help: 'Read JSON as parameter instead of stdin', valueHelp: 'json input')
..addOption('jsonpath', aliases: ['path'], help: 'Display only the matches of the JSON path', valueHelp: 'JSONPath query')
..addOption('jsonpointer', aliases: ['pointer'], abbr: 'p', help: 'Display only the matches of the JSON pointer', valueHelp: 'JSON Pointer')
..addOption('indent', abbr: 'i', help: 'Set space indentation level (prefix with t for tab indentation)', defaultsTo: '2')
..addOption('max-depth', abbr: 'd', help: 'Specify maximum nesting before stopping printing');
// ..addFlag('force-color', help: "Output using colors even when the environment doesn't allow them", hide: true);
final ArgResults parsedArgs;
try {
parsedArgs = parser.parse(arguments);
}
on ArgParserException catch(e) {
print(e.message);
print('');
print(parser.usage);
exit(1);
}
// Get indent
final indentArg = parsedArgs['indent'] as String;
final indent = indentArg[0] == 't' ? '\t' * int.parse(indentArg.substring(1)) : ' ' * int.parse(indentArg);
// Get max depth
final maxDepthArg = parsedArgs['max-depth'] as String?;
final maxDepth = int.tryParse(maxDepthArg ?? '');
// Get JSONPath
final jsonPath = parsedArgs['jsonpath'] as String?;
// Get JSON Pointer
final jsonPointer = parsedArgs['jsonpointer'] as String?;
// Read
String jsonInput;
if (parsedArgs['file'] != null) {
jsonInput = File(parsedArgs['file']).readAsStringSync();
}
else if (parsedArgs['input'] != null) {
jsonInput = parsedArgs['input'];
}
else {
jsonInput = '';
while (true) {
final line = stdin.readLineSync(retainNewlines: true);
if (line != null) {
jsonInput += line;
}
else {
break;
}
}
}
// Parse
final decodedData;
try {
decodedData = jsonDecode(jsonInput);
}
catch(_) {
stderr.writeln('Unable to parse JSON input.');
exit(1);
}
final List<dynamic> data;
try {
data = jsonPath != null ? followJsonPath(decodedData, jsonPath) : jsonPointer != null ? followJsonPointer(decodedData, jsonPointer) : [decodedData];
}
catch (e) {
stderr.writeln('JSONPath Error: $e');
exit(1);
}
// Print
if (data.isEmpty) {
stderr.writeln('No match');
}
else if (data.length == 1) {
stdout.write(prettyPrintJson(data[0], indent, maxDepth));
}
else {
for (final match in data) {
print(prettyPrintJson(match, indent, maxDepth));
}
}
}
List<dynamic> followJsonPath(dynamic object, String jsonPath) {
final path = JsonPath(jsonPath);
return path.read(object).map((e) => e.value).toList(growable: false);
}
List<dynamic> followJsonPointer(dynamic object, String jsonPointer) {
final pointer = JsonPointer(jsonPointer);
return [pointer.read(object)];
}