Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added createJsonKeys #1401

Merged
merged 13 commits into from
Mar 3, 2024
2 changes: 2 additions & 0 deletions json_annotation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## 4.8.2-wip

- Require Dart 3.0
- Added `JsonSerializable(createJsonKeys: true)`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be 4.9.0 since we're adding new features!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto with json_serial. I'll do it. Just FYI for future.

([#1401](https://github.com/google/json_serializable.dart/pull/1401))

## 4.8.1

Expand Down
16 changes: 16 additions & 0 deletions json_annotation/lib/src/json_serializable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -247,6 +262,7 @@ class JsonSerializable {
this.checked,
this.constructor,
this.createFieldMap,
this.createJsonKeys,
this.createFactory,
this.createToJson,
this.disallowUnrecognizedKeys,
Expand Down
5 changes: 5 additions & 0 deletions json_annotation/lib/src/json_serializable.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions json_serializable/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
1 change: 1 addition & 0 deletions json_serializable/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,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
Expand Down
21 changes: 21 additions & 0 deletions json_serializable/lib/src/encoder_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ 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<FieldElement> accessibleFieldSet) {
assert(config.createJsonKeys);

final buffer = StringBuffer(
'abstract final class _\$${element.name.nonPrivate}JsonKeys {',
);
// ..write('static const _\$${element.name.nonPrivate}JsonKeys();');

for (final field in accessibleFieldSet) {
buffer.writeln(
'static const String ${field.name} = ${escapeDartString(nameAccess(field))};',
);
}

buffer.write('}');

return buffer.toString();
}

Iterable<String> createToJson(Set<FieldElement> accessibleFields) sync* {
assert(config.createToJson);

Expand Down
4 changes: 4 additions & 0 deletions json_serializable/lib/src/generator_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
6 changes: 6 additions & 0 deletions json_serializable/lib/src/type_helpers/config_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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:
Expand Down Expand Up @@ -113,6 +117,7 @@ class ClassConfig {
createFactory: true,
createToJson: true,
createFieldMap: false,
createJsonKeys: false,
createPerFieldToJson: false,
disallowUnrecognizedKeys: false,
explicitToJson: false,
Expand All @@ -129,6 +134,7 @@ class ClassConfig {
createFactory: createFactory,
createToJson: createToJson,
createFieldMap: createFieldMap,
createJsonKeys: createJsonKeys,
createPerFieldToJson: createPerFieldToJson,
ignoreUnannotated: ignoreUnannotated,
explicitToJson: explicitToJson,
Expand Down
2 changes: 2 additions & 0 deletions json_serializable/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions json_serializable/test/config_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions json_serializable/test/integration/integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -471,4 +472,9 @@ void main() {
test('value field index fun', () {
expect(enumValueFieldIndexValues, [0, 701, 2]);
});

test('ModelJsonKeys', () {
expect(js_keys.ModelJsonKeys.firstName, 'first-name');
expect(js_keys.ModelJsonKeys.lastName, 'LAST_NAME');
});
}
28 changes: 28 additions & 0 deletions json_serializable/test/integration/json_keys_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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<String, Object?> 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<String, Object?> toJson() => _$ModelToJson(this);

static const jsonKeys = ModelJsonKeys;
}
24 changes: 24 additions & 0 deletions json_serializable/test/integration/json_keys_example.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions json_serializable/test/shared_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ final generatorConfigNonDefaultJson =
createFactory: false,
createToJson: false,
createFieldMap: true,
createJsonKeys: true,
createPerFieldToJson: true,
disallowUnrecognizedKeys: true,
explicitToJson: true,
Expand Down
1 change: 1 addition & 0 deletions json_serializable/test/test_sources/test_sources.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class ConfigurationImplicitDefaults {
createFactory: true,
createToJson: true,
createFieldMap: false,
createJsonKeys: false,
createPerFieldToJson: false,
disallowUnrecognizedKeys: false,
explicitToJson: false,
Expand Down
1 change: 1 addition & 0 deletions json_serializable/tool/readme/readme_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,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
Expand Down
Loading