From 16c8142ac7d6736c159540ae0db2a4d131833900 Mon Sep 17 00:00:00 2001 From: Ernesto Ramirez Date: Wed, 19 Feb 2025 20:25:06 -0600 Subject: [PATCH 1/2] [go_router] add initial json support #110781 --- packages/go_router/CHANGELOG.md | 5 ++- packages/go_router/lib/go_router.dart | 1 + .../lib/src/misc/custom_parameter.dart | 40 +++++++++++++++++++ packages/go_router/pubspec.yaml | 2 +- packages/go_router/test/route_data_test.dart | 19 +++++++++ 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 packages/go_router/lib/src/misc/custom_parameter.dart diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index b4f32dc31eda..51885216ad87 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,6 @@ +## 16.1.0 +- Adds annotation for go_router_builder that enable custom string encoder/decoder [#110781](https://github.com/flutter/flutter/issues/110781). **Requires go_router_builder >= 3.1.0**. + ## 16.0.0 - **BREAKING CHANGE** @@ -35,7 +38,7 @@ ## 14.8.1 - Secured canPop method for the lack of matches in routerDelegate's configuration. - + ## 14.8.0 - Adds `preload` parameter to `StatefulShellBranchData.$branch`. diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index d2728a077c08..b16c7aa5e010 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -11,6 +11,7 @@ export 'src/configuration.dart'; export 'src/delegate.dart'; export 'src/information_provider.dart'; export 'src/match.dart' hide RouteMatchListCodec; +export 'src/misc/custom_parameter.dart'; export 'src/misc/errors.dart'; export 'src/misc/extensions.dart'; export 'src/misc/inherited_router.dart'; diff --git a/packages/go_router/lib/src/misc/custom_parameter.dart b/packages/go_router/lib/src/misc/custom_parameter.dart new file mode 100644 index 000000000000..94cd6d148888 --- /dev/null +++ b/packages/go_router/lib/src/misc/custom_parameter.dart @@ -0,0 +1,40 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta_meta.dart'; + +/// annotation to define a custom parameter decoder/encoder +/// this is useful when the is encoded/decoded in a non-standard way like base64 +/// this must be used as an annotation on a field +/// ```dart +/// String fromBase64(String value) { +/// return const Utf8Decoder().convert(base64.decode(value)); +/// } +/// String toBase64(String value) { +/// return base64.encode(const Utf8Encoder().convert(value)); +/// } +/// class MyRoute { +/// @CustomParameterCodec( +/// encode: toBase64, +/// decode: fromBase64, +/// ) +/// final String data; +/// MyRoute(this.data); +/// } +/// ``` +@Target({TargetKind.field}) +class CustomParameterCodec { + /// create a custom parameter codec + /// + const CustomParameterCodec({ + required this.encode, + required this.decode, + }); + + /// custom function to encode the field + final String Function(String json) encode; + + /// custom function to decode the field + final String Function(String json) decode; +} diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 3debeeaf158e..d65266828293 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -1,7 +1,7 @@ name: go_router description: A declarative router for Flutter based on Navigation 2 supporting deep linking, data-driven routes and more -version: 16.0.0 +version: 16.1.0 repository: https://github.com/flutter/packages/tree/main/packages/go_router issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 diff --git a/packages/go_router/test/route_data_test.dart b/packages/go_router/test/route_data_test.dart index 218caef690d5..a3b7485748d4 100644 --- a/packages/go_router/test/route_data_test.dart +++ b/packages/go_router/test/route_data_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -226,6 +227,14 @@ final List _routes = [ _goRouteDataRedirect, ]; +String fromBase64(String value) { + return const Utf8Decoder().convert(base64.decode(value)); +} + +String toBase64(String value) { + return base64.encode(const Utf8Encoder().convert(value)); +} + void main() { group('GoRouteData', () { testWidgets( @@ -633,4 +642,14 @@ void main() { ), ); }); + + test('CustomParameterCodec with required parameters', () { + const CustomParameterCodec customParameterCodec = CustomParameterCodec( + encode: toBase64, + decode: fromBase64, + ); + + expect(customParameterCodec.encode, toBase64); + expect(customParameterCodec.decode, fromBase64); + }); } From 50abfad5b45387556a530ad288e8869c7f606d8f Mon Sep 17 00:00:00 2001 From: Ernesto Ramirez Date: Fri, 25 Jul 2025 11:43:48 -0600 Subject: [PATCH 2/2] [go_router] update doc for CustomParameterCodec --- .../lib/src/misc/custom_parameter.dart | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/go_router/lib/src/misc/custom_parameter.dart b/packages/go_router/lib/src/misc/custom_parameter.dart index 94cd6d148888..54fa0f06c964 100644 --- a/packages/go_router/lib/src/misc/custom_parameter.dart +++ b/packages/go_router/lib/src/misc/custom_parameter.dart @@ -2,29 +2,31 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:meta/meta_meta.dart'; +import 'package:meta/meta_meta.dart' show Target, TargetKind; /// annotation to define a custom parameter decoder/encoder -/// this is useful when the is encoded/decoded in a non-standard way like base64 +/// this is useful when the is encoded/decoded in a non-standard way like base64Url /// this must be used as an annotation on a field /// ```dart /// String fromBase64(String value) { -/// return const Utf8Decoder().convert(base64.decode(value)); +/// return const Utf8Decoder() +/// .convert(base64Url.decode(base64Url.normalize(value))); /// } /// String toBase64(String value) { -/// return base64.encode(const Utf8Encoder().convert(value)); +/// return base64Url.encode(const Utf8Encoder().convert(value)); /// } -/// class MyRoute { +/// @TypedGoRoute(path: 'json') +/// class JsonRoute extends GoRouteData with _$EncodedRoute { /// @CustomParameterCodec( /// encode: toBase64, /// decode: fromBase64, /// ) /// final String data; -/// MyRoute(this.data); +/// JsonRoute(this.data); /// } /// ``` @Target({TargetKind.field}) -class CustomParameterCodec { +final class CustomParameterCodec { /// create a custom parameter codec /// const CustomParameterCodec({ @@ -33,8 +35,8 @@ class CustomParameterCodec { }); /// custom function to encode the field - final String Function(String json) encode; + final String Function(String field) encode; /// custom function to decode the field - final String Function(String json) decode; + final String Function(String field) decode; }