From d296db03d19c7bd5b2ec6433b3c23b2c24d8a382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Mon, 19 Feb 2024 16:32:08 +0100 Subject: [PATCH 01/12] Added createJsonKeys --- .../lib/src/json_serializable.dart | 16 ++ .../lib/src/json_serializable.g.dart | 8 +- json_serializable/README.md | 160 +++++++++--------- json_serializable/lib/src/encoder_helper.dart | 20 +++ .../lib/src/generator_helper.dart | 4 + .../lib/src/type_helpers/config_types.dart | 6 + json_serializable/lib/src/utils.dart | 2 + json_serializable/pubspec.yaml | 4 + json_serializable/test/config_test.dart | 1 + .../test/integration/json_keys_example.dart | 44 +++++ .../test/integration/json_keys_example.g.dart | 35 ++++ json_serializable/test/shared_config.dart | 1 + .../test/test_sources/test_sources.dart | 1 + .../tool/readme/readme_template.md | 32 ++-- 14 files changed, 238 insertions(+), 96 deletions(-) create mode 100644 json_serializable/test/integration/json_keys_example.dart create mode 100644 json_serializable/test/integration/json_keys_example.g.dart diff --git a/json_annotation/lib/src/json_serializable.dart b/json_annotation/lib/src/json_serializable.dart index 71a6e4550..fe9b5cc98 100644 --- a/json_annotation/lib/src/json_serializable.dart +++ b/json_annotation/lib/src/json_serializable.dart @@ -87,6 +87,21 @@ class JsonSerializable { /// such as [fieldRename]. final bool? createFieldMap; + /// If `true` (defaults to false), a private class `_$ExampleJsonKeys` + /// constant is created in the generated part file. + /// + /// This class will contain every property, with the json key as value, + /// exposing a secured way to access the json key from the property. + /// + /// ```dart + /// @JsonSerializable(createJsonKeys: true) + /// class Example { + /// // ... + /// static const jsonKeys = _$PublicationImplJsonKeys(); + /// } + /// ``` + final bool? createJsonKeys; + /// If `true` (defaults to false), a private, static `_$ExamplePerFieldToJson` /// abstract class will be generated in the part file. /// @@ -247,6 +262,7 @@ class JsonSerializable { this.checked, this.constructor, this.createFieldMap, + this.createJsonKeys, this.createFactory, this.createToJson, this.disallowUnrecognizedKeys, diff --git a/json_annotation/lib/src/json_serializable.g.dart b/json_annotation/lib/src/json_serializable.g.dart index 9d02a187c..75a7ec47d 100644 --- a/json_annotation/lib/src/json_serializable.g.dart +++ b/json_annotation/lib/src/json_serializable.g.dart @@ -19,6 +19,7 @@ JsonSerializable _$JsonSerializableFromJson(Map json) => 'constructor', 'create_factory', 'create_field_map', + 'create_json_keys', 'create_per_field_to_json', 'create_to_json', 'disallow_unrecognized_keys', @@ -33,9 +34,11 @@ JsonSerializable _$JsonSerializableFromJson(Map json) => anyMap: $checkedConvert('any_map', (v) => v as bool?), checked: $checkedConvert('checked', (v) => v as bool?), constructor: $checkedConvert('constructor', (v) => v as String?), + createFactory: $checkedConvert('create_factory', (v) => v as bool?), createFieldMap: $checkedConvert('create_field_map', (v) => v as bool?), - createFactory: $checkedConvert('create_factory', (v) => v as bool?), + createJsonKeys: + $checkedConvert('create_json_keys', (v) => v as bool?), createToJson: $checkedConvert('create_to_json', (v) => v as bool?), disallowUnrecognizedKeys: $checkedConvert('disallow_unrecognized_keys', (v) => v as bool?), @@ -55,8 +58,9 @@ JsonSerializable _$JsonSerializableFromJson(Map json) => }, fieldKeyMap: const { 'anyMap': 'any_map', - 'createFieldMap': 'create_field_map', 'createFactory': 'create_factory', + 'createFieldMap': 'create_field_map', + 'createJsonKeys': 'create_json_keys', 'createToJson': 'create_to_json', 'disallowUnrecognizedKeys': 'disallow_unrecognized_keys', 'explicitToJson': 'explicit_to_json', diff --git a/json_serializable/README.md b/json_serializable/README.md index cb1eec619..74e5fd573 100644 --- a/json_serializable/README.md +++ b/json_serializable/README.md @@ -1,24 +1,23 @@ [![Pub Package](https://img.shields.io/pub/v/json_serializable.svg)](https://pub.dev/packages/json_serializable) -Provides [Dart Build System] builders for handling JSON. +Provides [Dart Build System][Dart Build System] builders for handling JSON. The builders generate code when they find members annotated with classes defined -in [package:json_annotation]. +in [package:json_annotation][package:json_annotation]. - To generate to/from JSON code for a class, annotate it with [`JsonSerializable`]. You can provide arguments to [`JsonSerializable`] to configure the generated code. You can also customize individual fields by annotating them with [`JsonKey`] and providing custom arguments. See the table below for details on the [annotation values](#annotation-values). - - To generate a Dart field with the contents of a file containing JSON, use the [`JsonLiteral`] annotation. ## Setup To configure your project for the latest released version of -`json_serializable`, see the [example]. +`json_serializable`, see the [example][example]. ## Example @@ -85,8 +84,8 @@ code will be generated when you build. There are three ways to control how code is generated: 1. Setting properties on [`JsonKey`] annotating the target field. -1. Set properties on [`JsonSerializable`] annotating the target type. -1. Add configuration to `build.yaml` – [see below](#build-configuration). +2. Set properties on [`JsonSerializable`] annotating the target type. +3. Add configuration to `build.yaml` – [see below](#build-configuration). Every [`JsonSerializable`] field is configurable via `build.yaml`. If you find you want all or most of your classes with the same configuration, it may be @@ -106,7 +105,7 @@ Annotate `enum` types with [`JsonEnum`] (new in `json_annotation` 4.2.0) to: 1. Specify the default rename logic for each enum value using `fieldRename`. For instance, use `fieldRename: FieldRename.kebab` to encode `enum` value `noGood` as `"no-good"`. -1. Force the generation of the `enum` helpers, even if the `enum` is not +2. Force the generation of the `enum` helpers, even if the `enum` is not referenced in code. This is an edge scenario, but useful for some. Annotate `enum` values with [`JsonValue`] to specify the encoded value to map @@ -147,16 +146,20 @@ enum StatusCodeEnhanced { Out of the box, `json_serializable` supports many common types in the [dart:core](https://api.dart.dev/stable/dart-core/dart-core-library.html) -library: +library: + [`BigInt`], [`bool`], [`DateTime`], [`double`], [`Duration`], [`Enum`], [`int`], [`Iterable`], [`List`], [`Map`], [`num`], [`Object`], [`Record`], [`Set`], [`String`], [`Uri`] The collection types – + [`Iterable`], [`List`], [`Map`], [`Record`], [`Set`] + – can contain values of all the above types. For [`Map`], the key value must be one of + [`BigInt`], [`DateTime`], [`Enum`], [`int`], [`Object`], [`String`], [`Uri`] # Custom types and custom encoding @@ -169,92 +172,90 @@ customize the encoding/decoding of any type, you have a few options. for these types, you don't have to! The generator code only looks for these methods. It doesn't care how they were created. - ```dart - @JsonSerializable() - class Sample1 { - Sample1(this.value); - - factory Sample1.fromJson(Map json) => - _$Sample1FromJson(json); + ```dart + @JsonSerializable() + class Sample1 { + Sample1(this.value); - // Sample2 is NOT annotated with @JsonSerializable(), but that's okay - // The class has a `fromJson` constructor and a `toJson` method, which is - // all that is required. - final Sample2 value; + factory Sample1.fromJson(Map json) => + _$Sample1FromJson(json); - Map toJson() => _$Sample1ToJson(this); - } + // Sample2 is NOT annotated with @JsonSerializable(), but that's okay + // The class has a `fromJson` constructor and a `toJson` method, which is + // all that is required. + final Sample2 value; - class Sample2 { - Sample2(this.value); + Map toJson() => _$Sample1ToJson(this); + } - // The convention is for `fromJson` to take a single parameter of type - // `Map` but any JSON-compatible type is allowed. - factory Sample2.fromJson(int value) => Sample2(value); - final int value; + class Sample2 { + Sample2(this.value); - // The convention is for `toJson` to take return a type of - // `Map` but any JSON-compatible type is allowed. - int toJson() => value; - } - ``` + // The convention is for `fromJson` to take a single parameter of type + // `Map` but any JSON-compatible type is allowed. + factory Sample2.fromJson(int value) => Sample2(value); + final int value; -1. Use the [`JsonKey.toJson`] and [`JsonKey.fromJson`] properties to specify + // The convention is for `toJson` to take return a type of + // `Map` but any JSON-compatible type is allowed. + int toJson() => value; + } + ``` +2. Use the [`JsonKey.toJson`] and [`JsonKey.fromJson`] properties to specify custom conversions on the annotated field. The functions specified must be top-level or static. See the documentation of these properties for details. - ```dart - @JsonSerializable() - class Sample3 { - Sample3(this.value); - - factory Sample3.fromJson(Map json) => - _$Sample3FromJson(json); + ```dart + @JsonSerializable() + class Sample3 { + Sample3(this.value); - @JsonKey( - toJson: _toJson, - fromJson: _fromJson, - ) - final DateTime value; + factory Sample3.fromJson(Map json) => + _$Sample3FromJson(json); - Map toJson() => _$Sample3ToJson(this); + @JsonKey( + toJson: _toJson, + fromJson: _fromJson, + ) + final DateTime value; - static int _toJson(DateTime value) => value.millisecondsSinceEpoch; - static DateTime _fromJson(int value) => - DateTime.fromMillisecondsSinceEpoch(value); - } - ``` + Map toJson() => _$Sample3ToJson(this); -1. Create an implementation of [`JsonConverter`] and annotate either the + static int _toJson(DateTime value) => value.millisecondsSinceEpoch; + static DateTime _fromJson(int value) => + DateTime.fromMillisecondsSinceEpoch(value); + } + ``` +3. Create an implementation of [`JsonConverter`] and annotate either the corresponding field or the containing class. [`JsonConverter`] is convenient if you want to use the same conversion logic on many fields. It also allows you to support a type within collections. Check out [these examples](https://github.com/google/json_serializable.dart/blob/master/example/lib/json_converter_example.dart). - ```dart - @JsonSerializable() - class Sample4 { - Sample4(this.value); + ```dart + @JsonSerializable() + class Sample4 { + Sample4(this.value); - factory Sample4.fromJson(Map json) => - _$Sample4FromJson(json); + factory Sample4.fromJson(Map json) => + _$Sample4FromJson(json); - @EpochDateTimeConverter() - final DateTime value; + @EpochDateTimeConverter() + final DateTime value; - Map toJson() => _$Sample4ToJson(this); - } + Map toJson() => _$Sample4ToJson(this); + } - class EpochDateTimeConverter implements JsonConverter { - const EpochDateTimeConverter(); + class EpochDateTimeConverter implements JsonConverter { + const EpochDateTimeConverter(); - @override - DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json); + @override + DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json); - @override - int toJson(DateTime object) => object.millisecondsSinceEpoch; - } - ``` + @override + int toJson(DateTime object) => object.millisecondsSinceEpoch; + } + ``` # Build configuration @@ -276,6 +277,7 @@ targets: constructor: "" create_factory: true create_field_map: false + create_json_keys: false create_per_field_to_json: false create_to_json: true disallow_unrecognized_keys: false @@ -297,15 +299,15 @@ targets: [`Enum`]: https://api.dart.dev/stable/dart-core/Enum-class.html [`int`]: https://api.dart.dev/stable/dart-core/int-class.html [`Iterable`]: https://api.dart.dev/stable/dart-core/Iterable-class.html -[`JsonConverter`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonConverter-class.html -[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum/valueField.html -[`JsonEnum`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum-class.html -[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/fromJson.html -[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/toJson.html -[`JsonKey`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey-class.html -[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonLiteral-class.html -[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonSerializable-class.html -[`JsonValue`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonValue-class.html +[`JsonConverter`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html +[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum/valueField.html +[`JsonEnum`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum-class.html +[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html +[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html +[`JsonKey`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey-class.html +[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonLiteral-class.html +[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html +[`JsonValue`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonValue-class.html [`List`]: https://api.dart.dev/stable/dart-core/List-class.html [`Map`]: https://api.dart.dev/stable/dart-core/Map-class.html [`num`]: https://api.dart.dev/stable/dart-core/num-class.html diff --git a/json_serializable/lib/src/encoder_helper.dart b/json_serializable/lib/src/encoder_helper.dart index cfc70b3af..df3b724d5 100644 --- a/json_serializable/lib/src/encoder_helper.dart +++ b/json_serializable/lib/src/encoder_helper.dart @@ -63,6 +63,26 @@ mixin EncodeHelper implements HelperCore { return buffer.toString(); } + /// Generates an object containing metadatas related to the encoding, + /// destined to be used by other code-generators. + String createJsonKeys(Set accessibleFieldSet) { + assert(config.createJsonKeys); + + final buffer = StringBuffer( + 'class _\$${element.name.nonPrivate}JsonKeys {', + )..write('const _\$${element.name.nonPrivate}JsonKeys();'); + + for (final field in accessibleFieldSet) { + buffer.writeln( + 'final String ${field.name} = ${escapeDartString(nameAccess(field))};', + ); + } + + buffer.write('}'); + + return buffer.toString(); + } + Iterable createToJson(Set accessibleFields) sync* { assert(config.createToJson); diff --git a/json_serializable/lib/src/generator_helper.dart b/json_serializable/lib/src/generator_helper.dart index 501df9469..8c0e13b4a 100644 --- a/json_serializable/lib/src/generator_helper.dart +++ b/json_serializable/lib/src/generator_helper.dart @@ -132,6 +132,10 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper { yield createFieldMap(accessibleFieldSet); } + if (config.createJsonKeys) { + yield createJsonKeys(accessibleFieldSet); + } + if (config.createPerFieldToJson) { yield createPerFieldToJson(accessibleFieldSet); } diff --git a/json_serializable/lib/src/type_helpers/config_types.dart b/json_serializable/lib/src/type_helpers/config_types.dart index c4bdc260a..227f1890b 100644 --- a/json_serializable/lib/src/type_helpers/config_types.dart +++ b/json_serializable/lib/src/type_helpers/config_types.dart @@ -49,6 +49,7 @@ class ClassConfig { final bool createFactory; final bool createToJson; final bool createFieldMap; + final bool createJsonKeys; final bool createPerFieldToJson; final bool disallowUnrecognizedKeys; final bool explicitToJson; @@ -66,6 +67,7 @@ class ClassConfig { required this.createFactory, required this.createToJson, required this.createFieldMap, + required this.createJsonKeys, required this.createPerFieldToJson, required this.disallowUnrecognizedKeys, required this.explicitToJson, @@ -85,6 +87,8 @@ class ClassConfig { constructor: config.constructor ?? ClassConfig.defaults.constructor, createFieldMap: config.createFieldMap ?? ClassConfig.defaults.createFieldMap, + createJsonKeys: + config.createJsonKeys ?? ClassConfig.defaults.createJsonKeys, createPerFieldToJson: config.createPerFieldToJson ?? ClassConfig.defaults.createPerFieldToJson, createFactory: @@ -113,6 +117,7 @@ class ClassConfig { createFactory: true, createToJson: true, createFieldMap: false, + createJsonKeys: false, createPerFieldToJson: false, disallowUnrecognizedKeys: false, explicitToJson: false, @@ -129,6 +134,7 @@ class ClassConfig { createFactory: createFactory, createToJson: createToJson, createFieldMap: createFieldMap, + createJsonKeys: createJsonKeys, createPerFieldToJson: createPerFieldToJson, ignoreUnannotated: ignoreUnannotated, explicitToJson: explicitToJson, diff --git a/json_serializable/lib/src/utils.dart b/json_serializable/lib/src/utils.dart index c8c727f7d..c74cda361 100644 --- a/json_serializable/lib/src/utils.dart +++ b/json_serializable/lib/src/utils.dart @@ -58,6 +58,7 @@ JsonSerializable _valueForAnnotation(ConstantReader reader) => JsonSerializable( createFactory: reader.read('createFactory').literalValue as bool?, createToJson: reader.read('createToJson').literalValue as bool?, createFieldMap: reader.read('createFieldMap').literalValue as bool?, + createJsonKeys: reader.read('createJsonKeys').literalValue as bool?, createPerFieldToJson: reader.read('createPerFieldToJson').literalValue as bool?, disallowUnrecognizedKeys: @@ -106,6 +107,7 @@ ClassConfig mergeConfig( createFactory: annotation.createFactory ?? config.createFactory, createToJson: annotation.createToJson ?? config.createToJson, createFieldMap: annotation.createFieldMap ?? config.createFieldMap, + createJsonKeys: annotation.createJsonKeys ?? config.createJsonKeys, createPerFieldToJson: annotation.createPerFieldToJson ?? config.createPerFieldToJson, disallowUnrecognizedKeys: diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index 8f55a01f0..1c309e2a8 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -29,6 +29,10 @@ dependencies: source_gen: ^1.3.2 source_helper: ^1.3.0 +dependency_overrides: + json_annotation: + path: ../json_annotation + dev_dependencies: _json_serial_shared_test: path: ../shared_test diff --git a/json_serializable/test/config_test.dart b/json_serializable/test/config_test.dart index 15767a319..2bcaa242a 100644 --- a/json_serializable/test/config_test.dart +++ b/json_serializable/test/config_test.dart @@ -153,6 +153,7 @@ const _invalidConfig = { 'constructor': 42, 'create_factory': 42, 'create_field_map': 42, + 'create_json_keys': 42, 'create_per_field_to_json': 42, 'create_to_json': 42, 'disallow_unrecognized_keys': 42, diff --git a/json_serializable/test/integration/json_keys_example.dart b/json_serializable/test/integration/json_keys_example.dart new file mode 100644 index 000000000..aec76d63a --- /dev/null +++ b/json_serializable/test/integration/json_keys_example.dart @@ -0,0 +1,44 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'json_keys_example.g.dart'; + +@JsonSerializable(createJsonKeys: true, fieldRename: FieldRename.kebab) +class Model { + Model({ + required this.firstName, + required this.lastName, + this.ignoredName, + }); + + factory Model.fromJson(Map json) => _$ModelFromJson(json); + + final String firstName; + + @JsonKey(name: 'LAST_NAME') + final String lastName; + + @JsonKey(includeFromJson: false, includeToJson: false) + final String? ignoredName; + + String get fullName => '$firstName $lastName'; + + Map toJson() => _$ModelToJson(this); + + static const jsonKeys = _$ModelJsonKeys(); +} + +@JsonSerializable( + createJsonKeys: true, + fieldRename: FieldRename.kebab, + createFactory: false, +) +class _PrivateModel { + _PrivateModel(this.fullName); + + final String fullName; + + Map toJson() => _$PrivateModelToJson(this); + + // ignore: unused_field + static const jsonKeys = _$PrivateModelJsonKeys(); +} diff --git a/json_serializable/test/integration/json_keys_example.g.dart b/json_serializable/test/integration/json_keys_example.g.dart new file mode 100644 index 000000000..84a2ea902 --- /dev/null +++ b/json_serializable/test/integration/json_keys_example.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: lines_longer_than_80_chars, text_direction_code_point_in_literal, inference_failure_on_function_invocation, inference_failure_on_collection_literal + +part of 'json_keys_example.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Model _$ModelFromJson(Map json) => Model( + firstName: json['first-name'] as String, + lastName: json['LAST_NAME'] as String, + ); + +class _$ModelJsonKeys { + const _$ModelJsonKeys(); + final String firstName = 'first-name'; + final String lastName = 'LAST_NAME'; +} + +Map _$ModelToJson(Model instance) => { + 'first-name': instance.firstName, + 'LAST_NAME': instance.lastName, + }; + +class _$PrivateModelJsonKeys { + const _$PrivateModelJsonKeys(); + final String fullName = 'full-name'; +} + +Map _$PrivateModelToJson(_PrivateModel instance) => + { + 'full-name': instance.fullName, + }; diff --git a/json_serializable/test/shared_config.dart b/json_serializable/test/shared_config.dart index 957728da3..fcae4282e 100644 --- a/json_serializable/test/shared_config.dart +++ b/json_serializable/test/shared_config.dart @@ -20,6 +20,7 @@ final generatorConfigNonDefaultJson = createFactory: false, createToJson: false, createFieldMap: true, + createJsonKeys: true, createPerFieldToJson: true, disallowUnrecognizedKeys: true, explicitToJson: true, diff --git a/json_serializable/test/test_sources/test_sources.dart b/json_serializable/test/test_sources/test_sources.dart index 06cc495f3..786931080 100644 --- a/json_serializable/test/test_sources/test_sources.dart +++ b/json_serializable/test/test_sources/test_sources.dart @@ -16,6 +16,7 @@ class ConfigurationImplicitDefaults { createFactory: true, createToJson: true, createFieldMap: false, + createJsonKeys: false, createPerFieldToJson: false, disallowUnrecognizedKeys: false, explicitToJson: false, diff --git a/json_serializable/tool/readme/readme_template.md b/json_serializable/tool/readme/readme_template.md index 79ac1c7dd..8bc5860de 100644 --- a/json_serializable/tool/readme/readme_template.md +++ b/json_serializable/tool/readme/readme_template.md @@ -1,23 +1,22 @@ [![Pub Package](https://img.shields.io/pub/v/json_serializable.svg)](https://pub.dev/packages/json_serializable) -Provides [Dart Build System] builders for handling JSON. +Provides [Dart Build System][Dart Build System] builders for handling JSON. The builders generate code when they find members annotated with classes defined -in [package:json_annotation]. +in [package:json_annotation][package:json_annotation]. - To generate to/from JSON code for a class, annotate it with `ja:JsonSerializable`. You can provide arguments to `ja:JsonSerializable` to configure the generated code. You can also customize individual fields by annotating them with `ja:JsonKey` and providing custom arguments. See the table below for details on the [annotation values](#annotation-values). - - To generate a Dart field with the contents of a file containing JSON, use the `ja:JsonLiteral` annotation. ## Setup To configure your project for the latest released version of -`json_serializable`, see the [example]. +`json_serializable`, see the [example][example]. ## Example @@ -45,8 +44,8 @@ code will be generated when you build. There are three ways to control how code is generated: 1. Setting properties on `ja:JsonKey` annotating the target field. -1. Set properties on `ja:JsonSerializable` annotating the target type. -1. Add configuration to `build.yaml` – [see below](#build-configuration). +2. Set properties on `ja:JsonSerializable` annotating the target type. +3. Add configuration to `build.yaml` – [see below](#build-configuration). Every `ja:JsonSerializable` field is configurable via `build.yaml`. If you find you want all or most of your classes with the same configuration, it may be @@ -66,7 +65,7 @@ Annotate `enum` types with `ja:JsonEnum` (new in `json_annotation` 4.2.0) to: 1. Specify the default rename logic for each enum value using `fieldRename`. For instance, use `fieldRename: FieldRename.kebab` to encode `enum` value `noGood` as `"no-good"`. -1. Force the generation of the `enum` helpers, even if the `enum` is not +2. Force the generation of the `enum` helpers, even if the `enum` is not referenced in code. This is an edge scenario, but useful for some. Annotate `enum` values with `ja:JsonValue` to specify the encoded value to map @@ -85,14 +84,18 @@ serialized value. Out of the box, `json_serializable` supports many common types in the [dart:core](https://api.dart.dev/stable/dart-core/dart-core-library.html) -library: +library: + The collection types – + + – can contain values of all the above types. For `core:Map`, the key value must be one of + # Custom types and custom encoding @@ -105,21 +108,19 @@ customize the encoding/decoding of any type, you have a few options. for these types, you don't have to! The generator code only looks for these methods. It doesn't care how they were created. - - -1. Use the `ja:JsonKey.toJson` and `ja:JsonKey.fromJson` properties to specify + +2. Use the `ja:JsonKey.toJson` and `ja:JsonKey.fromJson` properties to specify custom conversions on the annotated field. The functions specified must be top-level or static. See the documentation of these properties for details. - - -1. Create an implementation of `ja:JsonConverter` and annotate either the + +3. Create an implementation of `ja:JsonConverter` and annotate either the corresponding field or the containing class. `ja:JsonConverter` is convenient if you want to use the same conversion logic on many fields. It also allows you to support a type within collections. Check out [these examples](https://github.com/google/json_serializable.dart/blob/master/example/lib/json_converter_example.dart). - + # Build configuration @@ -141,6 +142,7 @@ targets: constructor: "" create_factory: true create_field_map: false + create_json_keys: false create_per_field_to_json: false create_to_json: true disallow_unrecognized_keys: false From 0b833fc6b86f9d4045b18ee38ce140826e02f880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Wed, 21 Feb 2024 10:21:19 +0100 Subject: [PATCH 02/12] Reverted useless changes --- json_serializable/README.md | 159 +++++++++--------- json_serializable/pubspec.yaml | 4 - .../tool/readme/readme_template.md | 31 ++-- 3 files changed, 94 insertions(+), 100 deletions(-) diff --git a/json_serializable/README.md b/json_serializable/README.md index 74e5fd573..e54f21075 100644 --- a/json_serializable/README.md +++ b/json_serializable/README.md @@ -1,23 +1,24 @@ [![Pub Package](https://img.shields.io/pub/v/json_serializable.svg)](https://pub.dev/packages/json_serializable) -Provides [Dart Build System][Dart Build System] builders for handling JSON. +Provides [Dart Build System] builders for handling JSON. The builders generate code when they find members annotated with classes defined -in [package:json_annotation][package:json_annotation]. +in [package:json_annotation]. - To generate to/from JSON code for a class, annotate it with [`JsonSerializable`]. You can provide arguments to [`JsonSerializable`] to configure the generated code. You can also customize individual fields by annotating them with [`JsonKey`] and providing custom arguments. See the table below for details on the [annotation values](#annotation-values). + - To generate a Dart field with the contents of a file containing JSON, use the [`JsonLiteral`] annotation. ## Setup To configure your project for the latest released version of -`json_serializable`, see the [example][example]. +`json_serializable`, see the [example]. ## Example @@ -84,8 +85,8 @@ code will be generated when you build. There are three ways to control how code is generated: 1. Setting properties on [`JsonKey`] annotating the target field. -2. Set properties on [`JsonSerializable`] annotating the target type. -3. Add configuration to `build.yaml` – [see below](#build-configuration). +1. Set properties on [`JsonSerializable`] annotating the target type. +1. Add configuration to `build.yaml` – [see below](#build-configuration). Every [`JsonSerializable`] field is configurable via `build.yaml`. If you find you want all or most of your classes with the same configuration, it may be @@ -105,7 +106,7 @@ Annotate `enum` types with [`JsonEnum`] (new in `json_annotation` 4.2.0) to: 1. Specify the default rename logic for each enum value using `fieldRename`. For instance, use `fieldRename: FieldRename.kebab` to encode `enum` value `noGood` as `"no-good"`. -2. Force the generation of the `enum` helpers, even if the `enum` is not +1. Force the generation of the `enum` helpers, even if the `enum` is not referenced in code. This is an edge scenario, but useful for some. Annotate `enum` values with [`JsonValue`] to specify the encoded value to map @@ -146,20 +147,16 @@ enum StatusCodeEnhanced { Out of the box, `json_serializable` supports many common types in the [dart:core](https://api.dart.dev/stable/dart-core/dart-core-library.html) -library: - +library: [`BigInt`], [`bool`], [`DateTime`], [`double`], [`Duration`], [`Enum`], [`int`], [`Iterable`], [`List`], [`Map`], [`num`], [`Object`], [`Record`], [`Set`], [`String`], [`Uri`] The collection types – - [`Iterable`], [`List`], [`Map`], [`Record`], [`Set`] - – can contain values of all the above types. For [`Map`], the key value must be one of - [`BigInt`], [`DateTime`], [`Enum`], [`int`], [`Object`], [`String`], [`Uri`] # Custom types and custom encoding @@ -172,90 +169,92 @@ customize the encoding/decoding of any type, you have a few options. for these types, you don't have to! The generator code only looks for these methods. It doesn't care how they were created. - ```dart - @JsonSerializable() - class Sample1 { - Sample1(this.value); + ```dart + @JsonSerializable() + class Sample1 { + Sample1(this.value); + + factory Sample1.fromJson(Map json) => + _$Sample1FromJson(json); - factory Sample1.fromJson(Map json) => - _$Sample1FromJson(json); + // Sample2 is NOT annotated with @JsonSerializable(), but that's okay + // The class has a `fromJson` constructor and a `toJson` method, which is + // all that is required. + final Sample2 value; - // Sample2 is NOT annotated with @JsonSerializable(), but that's okay - // The class has a `fromJson` constructor and a `toJson` method, which is - // all that is required. - final Sample2 value; + Map toJson() => _$Sample1ToJson(this); + } - Map toJson() => _$Sample1ToJson(this); - } + class Sample2 { + Sample2(this.value); - class Sample2 { - Sample2(this.value); + // The convention is for `fromJson` to take a single parameter of type + // `Map` but any JSON-compatible type is allowed. + factory Sample2.fromJson(int value) => Sample2(value); + final int value; - // The convention is for `fromJson` to take a single parameter of type - // `Map` but any JSON-compatible type is allowed. - factory Sample2.fromJson(int value) => Sample2(value); - final int value; + // The convention is for `toJson` to take return a type of + // `Map` but any JSON-compatible type is allowed. + int toJson() => value; + } + ``` - // The convention is for `toJson` to take return a type of - // `Map` but any JSON-compatible type is allowed. - int toJson() => value; - } - ``` -2. Use the [`JsonKey.toJson`] and [`JsonKey.fromJson`] properties to specify +1. Use the [`JsonKey.toJson`] and [`JsonKey.fromJson`] properties to specify custom conversions on the annotated field. The functions specified must be top-level or static. See the documentation of these properties for details. - ```dart - @JsonSerializable() - class Sample3 { - Sample3(this.value); + ```dart + @JsonSerializable() + class Sample3 { + Sample3(this.value); + + factory Sample3.fromJson(Map json) => + _$Sample3FromJson(json); - factory Sample3.fromJson(Map json) => - _$Sample3FromJson(json); + @JsonKey( + toJson: _toJson, + fromJson: _fromJson, + ) + final DateTime value; - @JsonKey( - toJson: _toJson, - fromJson: _fromJson, - ) - final DateTime value; + Map toJson() => _$Sample3ToJson(this); - Map toJson() => _$Sample3ToJson(this); + static int _toJson(DateTime value) => value.millisecondsSinceEpoch; + static DateTime _fromJson(int value) => + DateTime.fromMillisecondsSinceEpoch(value); + } + ``` - static int _toJson(DateTime value) => value.millisecondsSinceEpoch; - static DateTime _fromJson(int value) => - DateTime.fromMillisecondsSinceEpoch(value); - } - ``` -3. Create an implementation of [`JsonConverter`] and annotate either the +1. Create an implementation of [`JsonConverter`] and annotate either the corresponding field or the containing class. [`JsonConverter`] is convenient if you want to use the same conversion logic on many fields. It also allows you to support a type within collections. Check out [these examples](https://github.com/google/json_serializable.dart/blob/master/example/lib/json_converter_example.dart). - ```dart - @JsonSerializable() - class Sample4 { - Sample4(this.value); + ```dart + @JsonSerializable() + class Sample4 { + Sample4(this.value); - factory Sample4.fromJson(Map json) => - _$Sample4FromJson(json); + factory Sample4.fromJson(Map json) => + _$Sample4FromJson(json); - @EpochDateTimeConverter() - final DateTime value; + @EpochDateTimeConverter() + final DateTime value; - Map toJson() => _$Sample4ToJson(this); - } + Map toJson() => _$Sample4ToJson(this); + } - class EpochDateTimeConverter implements JsonConverter { - const EpochDateTimeConverter(); + class EpochDateTimeConverter implements JsonConverter { + const EpochDateTimeConverter(); - @override - DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json); + @override + DateTime fromJson(int json) => DateTime.fromMillisecondsSinceEpoch(json); - @override - int toJson(DateTime object) => object.millisecondsSinceEpoch; - } - ``` + @override + int toJson(DateTime object) => object.millisecondsSinceEpoch; + } + ``` # Build configuration @@ -299,15 +298,15 @@ targets: [`Enum`]: https://api.dart.dev/stable/dart-core/Enum-class.html [`int`]: https://api.dart.dev/stable/dart-core/int-class.html [`Iterable`]: https://api.dart.dev/stable/dart-core/Iterable-class.html -[`JsonConverter`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html -[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum/valueField.html -[`JsonEnum`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum-class.html -[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html -[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html -[`JsonKey`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey-class.html -[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonLiteral-class.html -[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html -[`JsonValue`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonValue-class.html +[`JsonConverter`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonConverter-class.html +[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum/valueField.html +[`JsonEnum`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum-class.html +[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/fromJson.html +[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/toJson.html +[`JsonKey`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey-class.html +[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonLiteral-class.html +[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonSerializable-class.html +[`JsonValue`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonValue-class.html [`List`]: https://api.dart.dev/stable/dart-core/List-class.html [`Map`]: https://api.dart.dev/stable/dart-core/Map-class.html [`num`]: https://api.dart.dev/stable/dart-core/num-class.html diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index 1c309e2a8..8f55a01f0 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -29,10 +29,6 @@ dependencies: source_gen: ^1.3.2 source_helper: ^1.3.0 -dependency_overrides: - json_annotation: - path: ../json_annotation - dev_dependencies: _json_serial_shared_test: path: ../shared_test diff --git a/json_serializable/tool/readme/readme_template.md b/json_serializable/tool/readme/readme_template.md index 8bc5860de..c3d6815ab 100644 --- a/json_serializable/tool/readme/readme_template.md +++ b/json_serializable/tool/readme/readme_template.md @@ -1,22 +1,23 @@ [![Pub Package](https://img.shields.io/pub/v/json_serializable.svg)](https://pub.dev/packages/json_serializable) -Provides [Dart Build System][Dart Build System] builders for handling JSON. +Provides [Dart Build System] builders for handling JSON. The builders generate code when they find members annotated with classes defined -in [package:json_annotation][package:json_annotation]. +in [package:json_annotation]. - To generate to/from JSON code for a class, annotate it with `ja:JsonSerializable`. You can provide arguments to `ja:JsonSerializable` to configure the generated code. You can also customize individual fields by annotating them with `ja:JsonKey` and providing custom arguments. See the table below for details on the [annotation values](#annotation-values). + - To generate a Dart field with the contents of a file containing JSON, use the `ja:JsonLiteral` annotation. ## Setup To configure your project for the latest released version of -`json_serializable`, see the [example][example]. +`json_serializable`, see the [example]. ## Example @@ -44,8 +45,8 @@ code will be generated when you build. There are three ways to control how code is generated: 1. Setting properties on `ja:JsonKey` annotating the target field. -2. Set properties on `ja:JsonSerializable` annotating the target type. -3. Add configuration to `build.yaml` – [see below](#build-configuration). +1. Set properties on `ja:JsonSerializable` annotating the target type. +1. Add configuration to `build.yaml` – [see below](#build-configuration). Every `ja:JsonSerializable` field is configurable via `build.yaml`. If you find you want all or most of your classes with the same configuration, it may be @@ -65,7 +66,7 @@ Annotate `enum` types with `ja:JsonEnum` (new in `json_annotation` 4.2.0) to: 1. Specify the default rename logic for each enum value using `fieldRename`. For instance, use `fieldRename: FieldRename.kebab` to encode `enum` value `noGood` as `"no-good"`. -2. Force the generation of the `enum` helpers, even if the `enum` is not +1. Force the generation of the `enum` helpers, even if the `enum` is not referenced in code. This is an edge scenario, but useful for some. Annotate `enum` values with `ja:JsonValue` to specify the encoded value to map @@ -84,18 +85,14 @@ serialized value. Out of the box, `json_serializable` supports many common types in the [dart:core](https://api.dart.dev/stable/dart-core/dart-core-library.html) -library: - +library: The collection types – - - – can contain values of all the above types. For `core:Map`, the key value must be one of - # Custom types and custom encoding @@ -108,19 +105,21 @@ customize the encoding/decoding of any type, you have a few options. for these types, you don't have to! The generator code only looks for these methods. It doesn't care how they were created. - -2. Use the `ja:JsonKey.toJson` and `ja:JsonKey.fromJson` properties to specify + + +1. Use the `ja:JsonKey.toJson` and `ja:JsonKey.fromJson` properties to specify custom conversions on the annotated field. The functions specified must be top-level or static. See the documentation of these properties for details. - -3. Create an implementation of `ja:JsonConverter` and annotate either the + + +1. Create an implementation of `ja:JsonConverter` and annotate either the corresponding field or the containing class. `ja:JsonConverter` is convenient if you want to use the same conversion logic on many fields. It also allows you to support a type within collections. Check out [these examples](https://github.com/google/json_serializable.dart/blob/master/example/lib/json_converter_example.dart). - + # Build configuration From eef5e0f4c2ce9706cc3b7cc6abc549e981bebece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Wed, 21 Feb 2024 10:50:58 +0100 Subject: [PATCH 03/12] Added integration tests --- .../test/integration/integration_test.dart | 11 +++++++++++ .../test/integration/json_keys_example.dart | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/json_serializable/test/integration/integration_test.dart b/json_serializable/test/integration/integration_test.dart index 9305b4f9b..3c0a4970f 100644 --- a/json_serializable/test/integration/integration_test.dart +++ b/json_serializable/test/integration/integration_test.dart @@ -10,6 +10,7 @@ import 'converter_examples.dart'; import 'create_per_field_to_json_example.dart'; import 'field_map_example.dart'; import 'json_enum_example.dart'; +import 'json_keys_example.dart' as js_keys; import 'json_test_common.dart' show Category, Platform, StatusCode; import 'json_test_example.dart'; @@ -471,4 +472,14 @@ void main() { test('value field index fun', () { expect(enumValueFieldIndexValues, [0, 701, 2]); }); + + test(r'_$ModelJsonKeys', () { + expect(js_keys.Model.jsonKeys.firstName, 'first-name'); + expect(js_keys.Model.jsonKeys.lastName, 'LAST_NAME'); + }); + + test(r'Generates _$PrivateModelJsonKeys instead of __$PrivateModelJsonKeys', + () { + expect(js_keys.privateModelJsonKeys.fullName, 'full-name'); + }); } diff --git a/json_serializable/test/integration/json_keys_example.dart b/json_serializable/test/integration/json_keys_example.dart index aec76d63a..5fb2e2d25 100644 --- a/json_serializable/test/integration/json_keys_example.dart +++ b/json_serializable/test/integration/json_keys_example.dart @@ -39,6 +39,7 @@ class _PrivateModel { Map toJson() => _$PrivateModelToJson(this); - // ignore: unused_field static const jsonKeys = _$PrivateModelJsonKeys(); } + +const privateModelJsonKeys = _PrivateModel.jsonKeys; From 59150cc25af0258d2fd13da831ad3fcb5e6c9dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Wed, 28 Feb 2024 10:54:49 +0100 Subject: [PATCH 04/12] Made [Class]JsonKeys a public class --- json_serializable/lib/src/encoder_helper.dart | 7 ++++--- .../test/integration/integration_test.dart | 11 +++-------- .../test/integration/json_keys_example.dart | 19 +------------------ .../test/integration/json_keys_example.g.dart | 17 +++-------------- 4 files changed, 11 insertions(+), 43 deletions(-) diff --git a/json_serializable/lib/src/encoder_helper.dart b/json_serializable/lib/src/encoder_helper.dart index df3b724d5..bc5f849b3 100644 --- a/json_serializable/lib/src/encoder_helper.dart +++ b/json_serializable/lib/src/encoder_helper.dart @@ -69,12 +69,13 @@ mixin EncodeHelper implements HelperCore { assert(config.createJsonKeys); final buffer = StringBuffer( - 'class _\$${element.name.nonPrivate}JsonKeys {', - )..write('const _\$${element.name.nonPrivate}JsonKeys();'); + 'abstract final class _\$${element.name.nonPrivate}JsonKeys {', + ); + // ..write('static const _\$${element.name.nonPrivate}JsonKeys();'); for (final field in accessibleFieldSet) { buffer.writeln( - 'final String ${field.name} = ${escapeDartString(nameAccess(field))};', + 'static const String ${field.name} = ${escapeDartString(nameAccess(field))};', ); } diff --git a/json_serializable/test/integration/integration_test.dart b/json_serializable/test/integration/integration_test.dart index 3c0a4970f..3d948bdbc 100644 --- a/json_serializable/test/integration/integration_test.dart +++ b/json_serializable/test/integration/integration_test.dart @@ -473,13 +473,8 @@ void main() { expect(enumValueFieldIndexValues, [0, 701, 2]); }); - test(r'_$ModelJsonKeys', () { - expect(js_keys.Model.jsonKeys.firstName, 'first-name'); - expect(js_keys.Model.jsonKeys.lastName, 'LAST_NAME'); - }); - - test(r'Generates _$PrivateModelJsonKeys instead of __$PrivateModelJsonKeys', - () { - expect(js_keys.privateModelJsonKeys.fullName, 'full-name'); + test('ModelJsonKeys', () { + expect(js_keys.ModelJsonKeys.firstName, 'first-name'); + expect(js_keys.ModelJsonKeys.lastName, 'LAST_NAME'); }); } diff --git a/json_serializable/test/integration/json_keys_example.dart b/json_serializable/test/integration/json_keys_example.dart index 5fb2e2d25..41c554ea5 100644 --- a/json_serializable/test/integration/json_keys_example.dart +++ b/json_serializable/test/integration/json_keys_example.dart @@ -24,22 +24,5 @@ class Model { Map toJson() => _$ModelToJson(this); - static const jsonKeys = _$ModelJsonKeys(); + static const jsonKeys = ModelJsonKeys; } - -@JsonSerializable( - createJsonKeys: true, - fieldRename: FieldRename.kebab, - createFactory: false, -) -class _PrivateModel { - _PrivateModel(this.fullName); - - final String fullName; - - Map toJson() => _$PrivateModelToJson(this); - - static const jsonKeys = _$PrivateModelJsonKeys(); -} - -const privateModelJsonKeys = _PrivateModel.jsonKeys; diff --git a/json_serializable/test/integration/json_keys_example.g.dart b/json_serializable/test/integration/json_keys_example.g.dart index 84a2ea902..e07388d97 100644 --- a/json_serializable/test/integration/json_keys_example.g.dart +++ b/json_serializable/test/integration/json_keys_example.g.dart @@ -13,23 +13,12 @@ Model _$ModelFromJson(Map json) => Model( lastName: json['LAST_NAME'] as String, ); -class _$ModelJsonKeys { - const _$ModelJsonKeys(); - final String firstName = 'first-name'; - final String lastName = 'LAST_NAME'; +abstract final class ModelJsonKeys { + static const String firstName = 'first-name'; + static const String lastName = 'LAST_NAME'; } Map _$ModelToJson(Model instance) => { 'first-name': instance.firstName, 'LAST_NAME': instance.lastName, }; - -class _$PrivateModelJsonKeys { - const _$PrivateModelJsonKeys(); - final String fullName = 'full-name'; -} - -Map _$PrivateModelToJson(_PrivateModel instance) => - { - 'full-name': instance.fullName, - }; From 98fcded06a58146d7c7e98f715e5cf6fae4dbdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Wed, 28 Feb 2024 11:08:24 +0100 Subject: [PATCH 05/12] Updated json_annotation changelog --- json_annotation/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/json_annotation/CHANGELOG.md b/json_annotation/CHANGELOG.md index 5929a6840..eb1277ace 100644 --- a/json_annotation/CHANGELOG.md +++ b/json_annotation/CHANGELOG.md @@ -1,6 +1,8 @@ ## 4.8.2-wip - Require Dart 3.0 +- Added `JsonSerializable(createJsonKeys: true)`. + ([#1401](https://github.com/google/json_serializable.dart/pull/1401)) ## 4.8.1 From 316cb02029af41f84f6435d4f362448388b73b27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Wed, 28 Feb 2024 11:17:41 +0100 Subject: [PATCH 06/12] Reset like before --- json_annotation/lib/src/json_serializable.g.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/json_annotation/lib/src/json_serializable.g.dart b/json_annotation/lib/src/json_serializable.g.dart index 75a7ec47d..80614717e 100644 --- a/json_annotation/lib/src/json_serializable.g.dart +++ b/json_annotation/lib/src/json_serializable.g.dart @@ -34,11 +34,11 @@ JsonSerializable _$JsonSerializableFromJson(Map json) => anyMap: $checkedConvert('any_map', (v) => v as bool?), checked: $checkedConvert('checked', (v) => v as bool?), constructor: $checkedConvert('constructor', (v) => v as String?), - createFactory: $checkedConvert('create_factory', (v) => v as bool?), createFieldMap: $checkedConvert('create_field_map', (v) => v as bool?), createJsonKeys: $checkedConvert('create_json_keys', (v) => v as bool?), + createFactory: $checkedConvert('create_factory', (v) => v as bool?), createToJson: $checkedConvert('create_to_json', (v) => v as bool?), disallowUnrecognizedKeys: $checkedConvert('disallow_unrecognized_keys', (v) => v as bool?), @@ -58,9 +58,9 @@ JsonSerializable _$JsonSerializableFromJson(Map json) => }, fieldKeyMap: const { 'anyMap': 'any_map', - 'createFactory': 'create_factory', 'createFieldMap': 'create_field_map', 'createJsonKeys': 'create_json_keys', + 'createFactory': 'create_factory', 'createToJson': 'create_to_json', 'disallowUnrecognizedKeys': 'disallow_unrecognized_keys', 'explicitToJson': 'explicit_to_json', @@ -79,6 +79,7 @@ Map _$JsonSerializableToJson(JsonSerializable instance) => 'constructor': instance.constructor, 'create_factory': instance.createFactory, 'create_field_map': instance.createFieldMap, + 'create_json_keys': instance.createJsonKeys, 'create_per_field_to_json': instance.createPerFieldToJson, 'create_to_json': instance.createToJson, 'disallow_unrecognized_keys': instance.disallowUnrecognizedKeys, From e9ff4f989796c31f28867bdcc22d4ccb4d20feca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Wed, 28 Feb 2024 11:22:15 +0100 Subject: [PATCH 07/12] Updated json_serializable changelog --- json_serializable/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/json_serializable/CHANGELOG.md b/json_serializable/CHANGELOG.md index 0d36ca8af..826b34f0a 100644 --- a/json_serializable/CHANGELOG.md +++ b/json_serializable/CHANGELOG.md @@ -1,6 +1,8 @@ ## 6.7.2-wip - Add type arguments to `Map` literals used for `Record` serialization. +- Added support for generating `ExampleJsonKeys`, exposing a secured way to access the json keys from the properties. + ([#1164](https://github.com/google/json_serializable.dart/pull/1164)) ## 6.7.1 From 0a128a662584e13aeb0d6818cc721f818d8fb33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sym=C3=A9on=20ROUGEVIN?= Date: Thu, 29 Feb 2024 12:17:21 +0100 Subject: [PATCH 08/12] Added dependency override for json_annotation --- json_serializable/pubspec.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index 8f55a01f0..1c309e2a8 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -29,6 +29,10 @@ dependencies: source_gen: ^1.3.2 source_helper: ^1.3.0 +dependency_overrides: + json_annotation: + path: ../json_annotation + dev_dependencies: _json_serial_shared_test: path: ../shared_test From 0987633ee126851c66ebe3f7efcac3ce925e254b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 1 Mar 2024 21:11:14 -0800 Subject: [PATCH 09/12] line length --- json_serializable/lib/src/encoder_helper.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/json_serializable/lib/src/encoder_helper.dart b/json_serializable/lib/src/encoder_helper.dart index bc5f849b3..05d4c714d 100644 --- a/json_serializable/lib/src/encoder_helper.dart +++ b/json_serializable/lib/src/encoder_helper.dart @@ -75,7 +75,8 @@ mixin EncodeHelper implements HelperCore { for (final field in accessibleFieldSet) { buffer.writeln( - 'static const String ${field.name} = ${escapeDartString(nameAccess(field))};', + 'static const String ${field.name} = ' + '${escapeDartString(nameAccess(field))};', ); } From f70e589c78f168a58988cba0e4770beabfb7a889 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 2 Mar 2024 15:44:58 -0800 Subject: [PATCH 10/12] fixes, but... Hitting https://github.com/dart-lang/sdk/issues/54543 now --- json_serializable/README.md | 18 +++++++++--------- .../test/integration/json_keys_example.dart | 4 ++-- .../test/integration/json_keys_example.g.dart | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/json_serializable/README.md b/json_serializable/README.md index e54f21075..5d30efd16 100644 --- a/json_serializable/README.md +++ b/json_serializable/README.md @@ -298,15 +298,15 @@ targets: [`Enum`]: https://api.dart.dev/stable/dart-core/Enum-class.html [`int`]: https://api.dart.dev/stable/dart-core/int-class.html [`Iterable`]: https://api.dart.dev/stable/dart-core/Iterable-class.html -[`JsonConverter`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonConverter-class.html -[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum/valueField.html -[`JsonEnum`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonEnum-class.html -[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/fromJson.html -[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey/toJson.html -[`JsonKey`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonKey-class.html -[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonLiteral-class.html -[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonSerializable-class.html -[`JsonValue`]: https://pub.dev/documentation/json_annotation/4.8.1/json_annotation/JsonValue-class.html +[`JsonConverter`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html +[`JsonEnum.valueField`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum/valueField.html +[`JsonEnum`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonEnum-class.html +[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html +[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html +[`JsonKey`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey-class.html +[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonLiteral-class.html +[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html +[`JsonValue`]: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonValue-class.html [`List`]: https://api.dart.dev/stable/dart-core/List-class.html [`Map`]: https://api.dart.dev/stable/dart-core/Map-class.html [`num`]: https://api.dart.dev/stable/dart-core/num-class.html diff --git a/json_serializable/test/integration/json_keys_example.dart b/json_serializable/test/integration/json_keys_example.dart index 41c554ea5..9efdd6b11 100644 --- a/json_serializable/test/integration/json_keys_example.dart +++ b/json_serializable/test/integration/json_keys_example.dart @@ -23,6 +23,6 @@ class Model { String get fullName => '$firstName $lastName'; Map toJson() => _$ModelToJson(this); - - static const jsonKeys = ModelJsonKeys; } + +typedef ModelJsonKeys = _$ModelJsonKeys; diff --git a/json_serializable/test/integration/json_keys_example.g.dart b/json_serializable/test/integration/json_keys_example.g.dart index e07388d97..f68ca8d09 100644 --- a/json_serializable/test/integration/json_keys_example.g.dart +++ b/json_serializable/test/integration/json_keys_example.g.dart @@ -13,7 +13,7 @@ Model _$ModelFromJson(Map json) => Model( lastName: json['LAST_NAME'] as String, ); -abstract final class ModelJsonKeys { +abstract final class _$ModelJsonKeys { static const String firstName = 'first-name'; static const String lastName = 'LAST_NAME'; } From c94920c8caa5af36766c5e960b031689dd2e8eef Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 2 Mar 2024 15:56:49 -0800 Subject: [PATCH 11/12] work around for https://github.com/dart-lang/sdk/issues/54543 --- json_serializable/test/integration/integration_test.dart | 3 +-- json_serializable/test/integration/json_keys_example.dart | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/json_serializable/test/integration/integration_test.dart b/json_serializable/test/integration/integration_test.dart index 3d948bdbc..8c5827ee8 100644 --- a/json_serializable/test/integration/integration_test.dart +++ b/json_serializable/test/integration/integration_test.dart @@ -474,7 +474,6 @@ void main() { }); test('ModelJsonKeys', () { - expect(js_keys.ModelJsonKeys.firstName, 'first-name'); - expect(js_keys.ModelJsonKeys.lastName, 'LAST_NAME'); + expect(js_keys.keys, {'first-name', 'LAST_NAME'}); }); } diff --git a/json_serializable/test/integration/json_keys_example.dart b/json_serializable/test/integration/json_keys_example.dart index 9efdd6b11..e8a6895a2 100644 --- a/json_serializable/test/integration/json_keys_example.dart +++ b/json_serializable/test/integration/json_keys_example.dart @@ -25,4 +25,8 @@ class Model { Map toJson() => _$ModelToJson(this); } +// TODO: use this once https://github.com/dart-lang/sdk/issues/54543 is fixed typedef ModelJsonKeys = _$ModelJsonKeys; + +// Work-around until https://github.com/dart-lang/sdk/issues/54543 is fixed +Set get keys => {_$ModelJsonKeys.firstName, _$ModelJsonKeys.lastName}; From 0134b535f43a16d0915c20187f7b243976d84682 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 2 Mar 2024 16:04:46 -0800 Subject: [PATCH 12/12] minor version bump - because features --- json_annotation/CHANGELOG.md | 2 +- json_annotation/pubspec.yaml | 2 +- json_serializable/CHANGELOG.md | 2 +- json_serializable/pubspec.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/json_annotation/CHANGELOG.md b/json_annotation/CHANGELOG.md index eb1277ace..1b3d6be21 100644 --- a/json_annotation/CHANGELOG.md +++ b/json_annotation/CHANGELOG.md @@ -1,4 +1,4 @@ -## 4.8.2-wip +## 4.9.0-wip - Require Dart 3.0 - Added `JsonSerializable(createJsonKeys: true)`. diff --git a/json_annotation/pubspec.yaml b/json_annotation/pubspec.yaml index a6b97a231..aabbd9681 100644 --- a/json_annotation/pubspec.yaml +++ b/json_annotation/pubspec.yaml @@ -1,5 +1,5 @@ name: json_annotation -version: 4.8.2-wip +version: 4.9.0-wip description: >- Classes and helper functions that support JSON code generation via the `json_serializable` package. diff --git a/json_serializable/CHANGELOG.md b/json_serializable/CHANGELOG.md index 826b34f0a..845d563b2 100644 --- a/json_serializable/CHANGELOG.md +++ b/json_serializable/CHANGELOG.md @@ -1,4 +1,4 @@ -## 6.7.2-wip +## 6.8.0-wip - Add type arguments to `Map` literals used for `Record` serialization. - Added support for generating `ExampleJsonKeys`, exposing a secured way to access the json keys from the properties. diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index 1c309e2a8..307e1f76c 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -1,5 +1,5 @@ name: json_serializable -version: 6.7.2-wip +version: 6.8.0-wip description: >- Automatically generate code for converting to and from JSON by annotating Dart classes.