From c10c375d79ec54d02da4055fa91d543ab839ff93 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:45:18 +0000 Subject: [PATCH 1/2] Initial plan From 0ff75fe2654fb9f6858b72cdcf2b2c654745109a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:49:24 +0000 Subject: [PATCH 2/2] feat: add compact JSON formatter option --- .../talker/lib/src/utils/json_formatter.dart | 20 ++++++++++---- packages/talker/test/json_formatter_test.dart | 9 +++++++ packages/talker_dio_logger/README.md | 11 +++++++- .../lib/talker_dio_logger_settings.dart | 1 + .../talker_dio_logger/test/logs_test.dart | 27 +++++++++++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) diff --git a/packages/talker/lib/src/utils/json_formatter.dart b/packages/talker/lib/src/utils/json_formatter.dart index d08d935c..d2a460b8 100644 --- a/packages/talker/lib/src/utils/json_formatter.dart +++ b/packages/talker/lib/src/utils/json_formatter.dart @@ -1,26 +1,35 @@ import 'dart:convert'; +const _compactEncoder = JsonEncoder(); const _defaultEncoder = JsonEncoder.withIndent(' '); /// Formatter for converting data to pretty JSON strings. /// /// Use `const TalkerJsonFormatter()` for standard JSON formatting, +/// `TalkerJsonFormatter(prettyPrint: false)` for compact single-line JSON, /// `TalkerJsonFormatter(stripQuotes: true)` to strip quotes, /// or `TalkerJsonFormatter.custom(fn)` for custom formatting. class TalkerJsonFormatter { - /// Creates a formatter with optional quote stripping. + /// Creates a formatter with optional quote stripping and pretty printing. /// /// If [stripQuotes] is true, double quotes will be stripped from /// the JSON output (except escaped quotes within values). - const TalkerJsonFormatter({this.stripQuotes = false}) - : _customFormatter = null; + const TalkerJsonFormatter({ + this.stripQuotes = false, + this.prettyPrint = true, + }) : _customFormatter = null; /// Creates a formatter with a custom formatting function. - const TalkerJsonFormatter.custom(this._customFormatter) : stripQuotes = false; + const TalkerJsonFormatter.custom(this._customFormatter) + : stripQuotes = false, + prettyPrint = true; /// Whether to strip double quotes from JSON output. final bool stripQuotes; + /// Whether to format JSON with indentation. + final bool prettyPrint; + final String Function(dynamic data)? _customFormatter; /// Formats the given data to a pretty JSON string. @@ -28,7 +37,8 @@ class TalkerJsonFormatter { if (_customFormatter != null) { return _customFormatter!(data); } - final json = _defaultEncoder.convert(data); + final json = + (prettyPrint ? _defaultEncoder : _compactEncoder).convert(data); if (stripQuotes) { // Use \x00 (null byte) as a temporary placeholder for escaped quotes. // This is safe because JsonEncoder escapes control characters (U+0000-U+001F) diff --git a/packages/talker/test/json_formatter_test.dart b/packages/talker/test/json_formatter_test.dart index bb932a9c..dc07e65e 100644 --- a/packages/talker/test/json_formatter_test.dart +++ b/packages/talker/test/json_formatter_test.dart @@ -31,6 +31,14 @@ void main() { expect(result, contains('2')); expect(result, contains('3')); }); + + test('formats single-line JSON when prettyPrint is false', () { + const formatter = TalkerJsonFormatter(prettyPrint: false); + final result = formatter.format({'name': 'John', 'age': 30}); + + expect(result, equals('{"name":"John","age":30}')); + expect(result, isNot(contains('\n'))); + }); }); group('stripQuotes', () { @@ -96,6 +104,7 @@ void main() { final formatter = TalkerJsonFormatter.custom((data) => 'CUSTOM: $data'); expect(formatter.stripQuotes, isFalse); + expect(formatter.prettyPrint, isTrue); }); }); diff --git a/packages/talker_dio_logger/README.md b/packages/talker_dio_logger/README.md index b1c5276a..8fad4074 100644 --- a/packages/talker_dio_logger/README.md +++ b/packages/talker_dio_logger/README.md @@ -104,6 +104,16 @@ TalkerDioLoggerSettings( ) ``` +### Log JSON in a single line + +If you need copy-friendly JSON output, disable pretty printing in the formatter. + +```dart +TalkerDioLoggerSettings( + jsonFormatter: const TalkerJsonFormatter(prettyPrint: false), +) +``` + ## Using with Talker You can add your talker instance for TalkerDioLogger if your app already uses Talker. In this case, all logs and errors will fall into your unified tracking system @@ -118,4 +128,3 @@ dio.interceptors.add(TalkerDioLogger(talker: talker)); ## Additional information The project is under development and ready for your pull-requests and issues 👍
Thank you for support ❤️ - diff --git a/packages/talker_dio_logger/lib/talker_dio_logger_settings.dart b/packages/talker_dio_logger/lib/talker_dio_logger_settings.dart index d413615b..95e7dbf4 100644 --- a/packages/talker_dio_logger/lib/talker_dio_logger_settings.dart +++ b/packages/talker_dio_logger/lib/talker_dio_logger_settings.dart @@ -110,6 +110,7 @@ class TalkerDioLoggerSettings { /// JSON formatter for converting data to pretty string. /// Use [TalkerJsonFormatter] for default formatting, + /// [TalkerJsonFormatter(prettyPrint: false)] for single-line JSON, /// [TalkerJsonFormatter(stripQuotes: true)] to strip quotes, /// or [TalkerJsonFormatter.custom(fn)] for custom formatting. final TalkerJsonFormatter jsonFormatter; diff --git a/packages/talker_dio_logger/test/logs_test.dart b/packages/talker_dio_logger/test/logs_test.dart index a15e9ae2..4ac942ae 100644 --- a/packages/talker_dio_logger/test/logs_test.dart +++ b/packages/talker_dio_logger/test/logs_test.dart @@ -632,6 +632,33 @@ void main() { expect(result, contains('Data: CUSTOM:{key: value}')); }); + test('generateTextMessage should support single-line JSON formatting', () { + final response = Response( + requestOptions: RequestOptions(path: '/test', method: 'GET'), + statusCode: 200, + data: { + 'key': 'value', + 'nested': {'id': 1} + }, + ); + final settings = TalkerDioLoggerSettings( + jsonFormatter: TalkerJsonFormatter(prettyPrint: false), + ); + final dioResponseLog = DioResponseLog( + 'Test message', + response: response, + settings: settings, + ); + + final result = dioResponseLog.generateTextMessage(); + + expect( + result, + contains('Data: {"key":"value","nested":{"id":1}}'), + ); + expect(result, isNot(contains('\n "key"'))); + }); + test('generateTextMessage should strip quotes in headers', () { final response = Response( requestOptions: RequestOptions(path: '/test', method: 'GET'),